Bansari Akhani commited on
Commit
9d33d07
·
1 Parent(s): aee85dc

#8641 - sync workorders from json url, remove sync from PW api

Browse files
.env.example CHANGED
@@ -36,4 +36,5 @@ SMTP_SENDER_EMAIL=
36
  FRONTEND_URL=
37
 
38
  CRON_SCHEDULE="0 0 * * *"
39
- SYNC_INVOICES=true
 
 
36
  FRONTEND_URL=
37
 
38
  CRON_SCHEDULE="0 0 * * *"
39
+ SYNC_INVOICES=true
40
+ PW_FETCH_ALL_WORKORDERS=
src/config/app.config.ts CHANGED
@@ -23,3 +23,10 @@ export const SMTP_CONFIG = {
23
  SECURE: process.env.SMTP_SECURE,
24
  SENDER: process.env.SMTP_SENDER_EMAIL,
25
  };
 
 
 
 
 
 
 
 
23
  SECURE: process.env.SMTP_SECURE,
24
  SENDER: process.env.SMTP_SENDER_EMAIL,
25
  };
26
+
27
+
28
+ export const PW_CONFIG= {
29
+ PW_FETCH_ALL_UNITS:process.env.PW_FETCH_ALL_UNITS || '',
30
+ PW_FETCH_ALL_WORKORDERS:process.env.PW_FETCH_ALL_WORKORDERS || '',
31
+ PW_FETCH_LATEST_WORKORDERS:process.env.PW_FETCH_LATEST_WORKORDERS || ''
32
+ };
src/controllers/propertyware/workorders.controller.ts CHANGED
@@ -1,6 +1,6 @@
1
  import { Request, Response } from 'express';
2
  import { logger } from '../../utils/logger';
3
- import { syncWorkOrderDataService } from '../../shared/services/workorder.service';
4
  import PwWorkOrders from '../../models/pwWorkOrders';
5
 
6
  export const fetchWorkorders = async (req: Request, res: Response) => {
@@ -27,9 +27,10 @@ export const fetchWorkorders = async (req: Request, res: Response) => {
27
 
28
  export const syncWorkOrders = async (req: Request, res: Response) => {
29
  try {
30
- const result = await syncWorkOrderDataService();
 
31
  res.status(200).send(result);
32
  } catch (error) {
33
  res.status(500).send((error as Error).message);
34
  }
35
- };
 
1
  import { Request, Response } from 'express';
2
  import { logger } from '../../utils/logger';
3
+ import { syncWorkOrderDataFromJsonService, syncWorkOrderDataService } from '../../shared/services/workorder.service';
4
  import PwWorkOrders from '../../models/pwWorkOrders';
5
 
6
  export const fetchWorkorders = async (req: Request, res: Response) => {
 
27
 
28
  export const syncWorkOrders = async (req: Request, res: Response) => {
29
  try {
30
+ const syncAll = true;
31
+ const result = await syncWorkOrderDataFromJsonService(syncAll);
32
  res.status(200).send(result);
33
  } catch (error) {
34
  res.status(500).send((error as Error).message);
35
  }
36
+ };
src/shared/interfaces/pwWorkOrdersInterface.ts CHANGED
@@ -8,4 +8,17 @@ export interface PwWorkOrdersInterface {
8
  unit_id: number;
9
  status: string;
10
  assigned_vendors: string[];
11
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  unit_id: number;
9
  status: string;
10
  assigned_vendors: string[];
11
+ }
12
+
13
+ export interface Column {
14
+ index: string;
15
+ dataType: string;
16
+ label: string;
17
+ }
18
+
19
+ export interface DataStructure {
20
+ totalCount: number;
21
+ columns: Column[];
22
+ records: any[];
23
+ }
24
+
src/shared/services/cronJobs.ts CHANGED
@@ -2,7 +2,7 @@ import cron from 'node-cron';
2
  import { logger } from '../../utils/logger';
3
  import { syncInvoicesService } from './bills.service';
4
  import { syncUnitsDataFromUrlService } from './units.service';
5
- import { syncWorkOrderDataService } from './workorder.service';
6
 
7
  const CRON_SCHEDULE = process.env.CRON_SCHEDULE || '0 0 * * *';
8
  const SYNC_INVOICES = process.env.SYNC_INVOICES;
@@ -28,7 +28,7 @@ export const setupCronJobs = () => {
28
  await syncUnitsDataFromUrlService();
29
  logger.info('Scheduled properties sync completed successfully');
30
 
31
- await syncWorkOrderDataService();
32
  logger.info('Scheduled work order sync completed successfully');
33
 
34
  if (SYNC_INVOICES === "true") {
 
2
  import { logger } from '../../utils/logger';
3
  import { syncInvoicesService } from './bills.service';
4
  import { syncUnitsDataFromUrlService } from './units.service';
5
+ import { syncWorkOrderDataFromJsonService } from './workorder.service';
6
 
7
  const CRON_SCHEDULE = process.env.CRON_SCHEDULE || '0 0 * * *';
8
  const SYNC_INVOICES = process.env.SYNC_INVOICES;
 
28
  await syncUnitsDataFromUrlService();
29
  logger.info('Scheduled properties sync completed successfully');
30
 
31
+ await syncWorkOrderDataFromJsonService();
32
  logger.info('Scheduled work order sync completed successfully');
33
 
34
  if (SYNC_INVOICES === "true") {
src/shared/services/propertyware.service.ts CHANGED
@@ -1,3 +1,5 @@
 
 
1
  import { apiClientPW } from "./api.service";
2
  import axios from 'axios';
3
 
@@ -81,9 +83,23 @@ export const fetchAllWorkorders = async () => {
81
  };
82
 
83
 
84
- export const fetchUnitsJson = async (params: Record<string, string> = {}) => {
85
- const url = 'https://app.propertyware.com/pw/00a/3861938176/JSON?2kTLuin&shardKey=6848514';
86
- const response = await axios.get(url);
87
  return response.data;
88
  };
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Column, DataStructure } from "shared/interfaces/pwWorkOrdersInterface";
2
+ import { PW_CONFIG } from "../../config/app.config";
3
  import { apiClientPW } from "./api.service";
4
  import axios from 'axios';
5
 
 
83
  };
84
 
85
 
86
+ export const fetchUnitsJson = async () => {
87
+ const response = await axios.get(PW_CONFIG.PW_FETCH_ALL_UNITS);
 
88
  return response.data;
89
  };
90
 
91
+ export const fetchAllWorkordersJson = async () => {
92
+ const response = await axios.get(PW_CONFIG.PW_FETCH_ALL_WORKORDERS);
93
+ return response.data;
94
+ };
95
+
96
+ export const fetchLatestWorkordersJson = async () => {
97
+ const response = await axios.get(PW_CONFIG.PW_FETCH_LATEST_WORKORDERS);
98
+ return response.data;
99
+ };
100
+
101
+ export const getIndexByLabel = (data: Column[], label: string): number | undefined => {
102
+ const column = data.find((col) => col.label === label);
103
+ return column ? parseInt(column.index) : undefined;
104
+ };
105
+
src/shared/services/units.service.ts CHANGED
@@ -46,10 +46,10 @@ export const syncUnitsDataFromUrlService = async (): Promise<string> => {
46
  });
47
 
48
  unitsBulkData.push({
49
- pw_id: record['8'], // Unit ID Number
50
  name: record['1'], // Unit Name
51
  pw_portfolio_id: record['10'], // Portfolio ID
52
- pw_building_id: record['7'], // Building ID
53
  });
54
  }
55
 
 
46
  });
47
 
48
  unitsBulkData.push({
49
+ pw_id: record['9'], // Unit Entity ID
50
  name: record['1'], // Unit Name
51
  pw_portfolio_id: record['10'], // Portfolio ID
52
+ pw_building_id: record['7'], // Building ID Number
53
  });
54
  }
55
 
src/shared/services/workorder.service.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { fetchAllWorkorders, } from './propertyware.service';
2
  import { logger } from '../../utils/logger';
3
  import PwWorkOrders from '../../models/pwWorkOrders';
 
4
 
5
  export const syncWorkOrderDataService = async (): Promise<string> => {
6
  try {
@@ -35,4 +36,63 @@ export const syncWorkOrderDataService = async (): Promise<string> => {
35
  logger.error("Error syncing Work order: ", error);
36
  throw new Error("Error syncing Work order");
37
  }
38
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { fetchAllWorkorders, fetchAllWorkordersJson, fetchLatestWorkordersJson, getIndexByLabel } from './propertyware.service';
2
  import { logger } from '../../utils/logger';
3
  import PwWorkOrders from '../../models/pwWorkOrders';
4
+ import PwUnit from '../../models/pwUnits';
5
 
6
  export const syncWorkOrderDataService = async (): Promise<string> => {
7
  try {
 
36
  logger.error("Error syncing Work order: ", error);
37
  throw new Error("Error syncing Work order");
38
  }
39
+ };
40
+
41
+ export const syncWorkOrderDataFromJsonService = async (syncAll = false): Promise<string> => {
42
+ try {
43
+ let workOrderData;
44
+ if (syncAll) {
45
+ workOrderData = await fetchAllWorkordersJson();
46
+ } else {
47
+ workOrderData = await fetchLatestWorkordersJson();
48
+ }
49
+ const indexes = {
50
+ pw_id: getIndexByLabel(workOrderData.columns, "WO Entity ID"),
51
+ number:getIndexByLabel(workOrderData.columns, "WO#"),
52
+ portfolio: getIndexByLabel(workOrderData.columns, "Portfolio"),
53
+ building: getIndexByLabel(workOrderData.columns, "Building"),
54
+ unit: getIndexByLabel(workOrderData.columns, "Unit"),
55
+ buildingID: getIndexByLabel(workOrderData.columns, "Building ID"),
56
+ unitID: getIndexByLabel(workOrderData.columns, "Unit ID"),
57
+ status: getIndexByLabel(workOrderData.columns, "Status"),
58
+ assignedVendors: getIndexByLabel(workOrderData.columns, "Vendors"),
59
+ };
60
+ const workOrderResponseData: any[] = [];
61
+
62
+ for (const record of workOrderData.records) {
63
+ const portfolioData = await PwUnit.findOne({
64
+ where: {
65
+ pw_id: record[indexes.unitID as number],
66
+ },
67
+ attributes: ['pw_portfolio_id'],
68
+ });
69
+
70
+ const portfolio_id= portfolioData ? portfolioData.getDataValue('pw_portfolio_id') : null;
71
+ workOrderResponseData.push({
72
+ pw_id: record[indexes.pw_id as number],
73
+ number: extractWorkOrderNumber(record[indexes.number as number]),
74
+ portfolio_id: portfolio_id,
75
+ building_id: record[indexes.buildingID as number],
76
+ unit_id: record[indexes.unitID as number],
77
+ location: record[indexes.portfolio as number] + " " + record[indexes.building as number] + " " + record[indexes.unit as number],
78
+ status: record[indexes.status as number],
79
+ assigned_vendors: record[indexes.assignedVendors as number] || []
80
+ });
81
+ }
82
+ await PwWorkOrders.bulkCreate(workOrderResponseData, {
83
+ updateOnDuplicate: ['number', 'location', 'portfolio_id', 'building_id', 'unit_id', 'status', 'assigned_vendors'],
84
+ });
85
+
86
+ logger.info("Total " + workOrderResponseData.length + "Work orders synced successfully");
87
+ return "Total " + workOrderResponseData.length + "Work orders synced successfully";
88
+ } catch (error) {
89
+ console.log(error);
90
+ logger.error("Error syncing Work order: ", error);
91
+ throw new Error("Error syncing Work order");
92
+ }
93
+ };
94
+
95
+ const extractWorkOrderNumber = (workOrder: string): string | null => {
96
+ const match = workOrder.match(/#(\d+)/); // Matches "#" followed by one or more digits
97
+ return match ? match[1] : null;
98
+ }