abhishek-akbari01 commited on
Commit
9c63b5a
·
1 Parent(s): 185ec1f

create separate service file for property ware syncs

Browse files
src/controllers/propertyware/bills.controller.ts CHANGED
@@ -1,13 +1,5 @@
1
  import { Request, Response } from 'express';
2
- import { logger } from '../../utils/logger';
3
- import Invoice from '../../models/invoice';
4
- import InvoiceDetail from '../../models/invoicedetail';
5
- import { createBill, uploadBill } from '../../shared/services/propertyware.service';
6
- import { formatDate } from '../../utils/dataUtils';
7
- import ErrorLog from '../../models/errorLog';
8
- import { createAuditLog } from '../auditLog.controller';
9
- import { updateInvoiceData } from '../invoice/invoice.controller';
10
- import { getDownloadUrl } from '../../shared/services/invoice.service';
11
 
12
  interface ErrorResponse {
13
  response: {
@@ -27,122 +19,3 @@ export const syncInvoices = async (req: Request, res: Response): Promise<void> =
27
  res.status(500).send((error as Error).message);
28
  }
29
  };
30
-
31
- export const syncInvoicesService = async (): Promise<string> => {
32
- try {
33
- const invoices = await Invoice.findAll({
34
- where: { status: 'Approved' },
35
- include: [{ model: InvoiceDetail }]
36
- });
37
-
38
- if (invoices.length === 0) {
39
- return "No invoice to sync";
40
- }
41
-
42
- const syncPromises = invoices.map(async (invoice) => {
43
- const bill = {
44
- billDate: formatDate(invoice.invoice_date),
45
- billSplits: invoice.InvoiceDetails.map(detail => ({
46
- amount: detail.amount as number,
47
- glAccountID: detail.pw_gl_account_id,
48
- portfolioID: detail.pw_portfolio_id,
49
- buildingID: detail.pw_building_id,
50
- comments: detail.description,
51
- paid: false,
52
- unitID: detail.pw_unit_id
53
- })),
54
- dueDate: invoice.due_date ? formatDate(invoice.due_date) : null,
55
- vendorID: invoice.pw_vendor_id?.toString(),
56
- comments: invoice.description,
57
- refNo: invoice.reference_number,
58
- terms: invoice.term,
59
- workOrderID: invoice.pw_work_order_id,
60
- };
61
-
62
- try {
63
- const response = await createBill(bill);
64
-
65
- // Add audit log for Update Invoice
66
- const auditLogData = {
67
- invoice_id: invoice.id as number,
68
- action_by: 1,
69
- action: 'Invoice sync to PW',
70
- details: `Bill for invoice ${bill.refNo} synced successfully. PW invoice id: ${response.id}`
71
- };
72
- await createAuditLog(auditLogData);
73
-
74
- try {
75
-
76
- // upload invoice file to propertyware
77
- if (invoice.filename) {
78
- const formData = new FormData();
79
- formData.append('file', invoice.pdf_url as string);
80
- const PWBillUploadResult = await uploadBill(response.id, formData);
81
- }
82
-
83
- } catch (error) {
84
- console.log("invoice file upload failed : ", error);
85
- }
86
- // Update Invoice status
87
- await updateInvoiceData(invoice.id as number, { status: 'Sync success' }, 1);
88
-
89
- logger.info(`Bill for invoice ${bill.refNo} synced successfully`);
90
- } catch (error) {
91
- let errorMessage = `Error syncing bill for invoice ${bill.refNo}.`;
92
- const errorobj = (error as ErrorResponse);
93
-
94
- const errordata = errorobj.response.data;
95
- console.log(errordata);
96
- if (errordata) {
97
- if (errordata.errors && Array.isArray(errordata.errors)) {
98
- errorMessage += ` Errors: ${errordata.errors.map(e => `${e.key}: ${e.message}`).join(', ')}`;
99
- } else {
100
- errorMessage += ` ${errordata.userMessage}`;
101
- }
102
-
103
- logger.error(errorMessage);
104
-
105
- // Add entry to error log
106
- const errorLogData = {
107
- invoice_id: invoice.id as number,
108
- error_type: 'PW Sync Failed',
109
- error_details: errorMessage
110
- };
111
- await ErrorLog.create(errorLogData);
112
- } else if (error instanceof Error) {
113
-
114
- logger.error(`Error syncing bill for invoice ${bill.refNo}: ${error.message}`);
115
-
116
- // Add entry to error log
117
- const errorLogData = {
118
- invoice_id: invoice.id as number,
119
- error_type: 'PW Sync Failed',
120
- error_details: `Error syncing bill for invoice ${bill.refNo}. ${error.message}`
121
- };
122
-
123
- await ErrorLog.create(errorLogData);
124
- } else {
125
-
126
- logger.error(`Unknown error syncing bill for invoice ${bill.refNo}`);
127
- logger.error(error);
128
-
129
- // Add entry to error log
130
- const errorLogData = {
131
- invoice_id: invoice.id as number,
132
- error_type: 'PW Sync Failed',
133
- error_details: `Unknown error syncing bill for invoice ${bill.refNo}`
134
- };
135
- await ErrorLog.create(errorLogData);
136
- }
137
- await updateInvoiceData(invoice.id as number, { status: 'Sync Failed' }, 1);
138
- }
139
- });
140
-
141
- await Promise.all(syncPromises);
142
-
143
- return "Invoice data sync process completed successfully";
144
- } catch (error) {
145
- logger.error('Error while syncing invoices to propertyware:', error);
146
- throw new Error('Error while syncing invoices to propertyware');
147
- }
148
- };
 
1
  import { Request, Response } from 'express';
2
+ import { syncInvoicesService } from '../../shared/services/bills.service';
 
 
 
 
 
 
 
 
3
 
4
  interface ErrorResponse {
5
  response: {
 
19
  res.status(500).send((error as Error).message);
20
  }
21
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/controllers/propertyware/buildings.controller.ts CHANGED
@@ -3,6 +3,7 @@ import { Request, Response } from 'express';
3
  import { fetchBuildings } from '../../shared/services/propertyware.service';
4
  import PwBuildings from '../../models/pwBuildings';
5
  import { logger } from '../../utils/logger';
 
6
 
7
  export const syncBuildingsData = async (req: Request, res: Response) => {
8
  try {
@@ -12,24 +13,3 @@ export const syncBuildingsData = async (req: Request, res: Response) => {
12
  res.status(500).send((error as Error).message);
13
  }
14
  };
15
-
16
- export const syncBuildingsDataService = async (): Promise<string> => {
17
- try {
18
- const buildingsData = await fetchBuildings();
19
- const buildingsResponseData = buildingsData.map((building: Record<string, string>) => ({
20
- pw_id: building.id,
21
- name: building.name,
22
- pw_portfolio_id: building.portfolioID
23
- }));
24
-
25
- await PwBuildings.bulkCreate(buildingsResponseData, {
26
- updateOnDuplicate: ['name', 'pw_portfolio_id'],
27
- });
28
-
29
- logger.info("Buildings data synced successfully");
30
- return "Buildings data synced successfully";
31
- } catch (error) {
32
- logger.error("Error syncing Buildings: ", error);
33
- throw new Error("Error syncing Buildings");
34
- }
35
- };
 
3
  import { fetchBuildings } from '../../shared/services/propertyware.service';
4
  import PwBuildings from '../../models/pwBuildings';
5
  import { logger } from '../../utils/logger';
6
+ import { syncBuildingsDataService } from '../../shared/services/buildings.service';
7
 
8
  export const syncBuildingsData = async (req: Request, res: Response) => {
9
  try {
 
13
  res.status(500).send((error as Error).message);
14
  }
15
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/controllers/propertyware/portfolio.controller.ts CHANGED
@@ -3,6 +3,7 @@ import { Request, Response } from 'express';
3
  import { fetchPortfolio } from '../../shared/services/propertyware.service';
4
  import PwPortfolio from './../../models/pwPortfolio';
5
  import { logger } from '../../utils/logger';
 
6
 
7
  export const syncPortfolioData = async (req: Request, res: Response) => {
8
  try {
@@ -12,23 +13,3 @@ export const syncPortfolioData = async (req: Request, res: Response) => {
12
  res.status(500).send((error as Error).message);
13
  }
14
  };
15
-
16
- export const syncPortfolioDataService = async (): Promise<string> => {
17
- try {
18
- const portfolioData = await fetchPortfolio();
19
- const portfolioResponseData = portfolioData.map((portfolio: { id: any; name: any; }) => ({
20
- pw_id: portfolio.id,
21
- name: portfolio.name,
22
- }));
23
-
24
- await PwPortfolio.bulkCreate(portfolioResponseData, {
25
- updateOnDuplicate: ['name'],
26
- });
27
-
28
- logger.info("Portfolio data synced successfully");
29
- return "Portfolio data synced successfully";
30
- } catch (error) {
31
- logger.error("Error syncing Portfolio: ", error);
32
- throw new Error("Error syncing Portfolio");
33
- }
34
- };
 
3
  import { fetchPortfolio } from '../../shared/services/propertyware.service';
4
  import PwPortfolio from './../../models/pwPortfolio';
5
  import { logger } from '../../utils/logger';
6
+ import { syncPortfolioDataService } from '../../shared/services/portfolio.service';
7
 
8
  export const syncPortfolioData = async (req: Request, res: Response) => {
9
  try {
 
13
  res.status(500).send((error as Error).message);
14
  }
15
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/controllers/propertyware/units.controller.ts CHANGED
@@ -1,9 +1,9 @@
1
  import { Request, Response } from 'express';
2
 
3
  import { fetchBuildings, fetchPortfolio, fetchUnits } from '../../shared/services/propertyware.service';
4
- import PwUnits from './../../models/pwUnits';
5
  import { extractIdAndName } from '../../utils/dataUtils';
6
  import { logger } from '../../utils/logger';
 
7
 
8
  export const syncUnitsData = async (req: Request, res: Response) => {
9
  try {
@@ -14,28 +14,6 @@ export const syncUnitsData = async (req: Request, res: Response) => {
14
  }
15
  };
16
 
17
- export const syncUnitsDataService = async (): Promise<string> => {
18
- try {
19
- const unitsData = await fetchUnits();
20
- const unitsResponseData = unitsData.map((unit: Record<string, string>) => ({
21
- pw_id: unit.id,
22
- name: unit.name,
23
- pw_portfolio_id: unit.portfolioID,
24
- pw_building_id: unit.buildingID
25
- }));
26
-
27
- await PwUnits.bulkCreate(unitsResponseData, {
28
- updateOnDuplicate: ['name', 'pw_portfolio_id', 'pw_building_id'],
29
- });
30
-
31
- logger.info("Units data synced successfully");
32
- return "Units data synced successfully";
33
- } catch (error) {
34
- logger.error("Error syncing Units: ", error);
35
- throw new Error("Error syncing Units");
36
- }
37
- };
38
-
39
  export const LocationLookup = async (req: Request, res: Response) => {
40
  try {
41
  // Fetch portfolios
 
1
  import { Request, Response } from 'express';
2
 
3
  import { fetchBuildings, fetchPortfolio, fetchUnits } from '../../shared/services/propertyware.service';
 
4
  import { extractIdAndName } from '../../utils/dataUtils';
5
  import { logger } from '../../utils/logger';
6
+ import { syncUnitsDataService } from '../../shared/services/units.service';
7
 
8
  export const syncUnitsData = async (req: Request, res: Response) => {
9
  try {
 
14
  }
15
  };
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  export const LocationLookup = async (req: Request, res: Response) => {
18
  try {
19
  // Fetch portfolios
src/shared/services/bills.service.ts ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Request, Response } from 'express';
2
+ import { logger } from '../../utils/logger';
3
+ import Invoice from '../../models/invoice';
4
+ import InvoiceDetail from '../../models/invoicedetail';
5
+ import { createBill, uploadBill } from './propertyware.service';
6
+ import { formatDate } from '../../utils/dataUtils';
7
+ import ErrorLog from '../../models/errorLog';
8
+ import { createAuditLog } from '../../controllers/auditLog.controller';
9
+ import { updateInvoiceData } from '../../controllers/invoice/invoice.controller';
10
+
11
+ interface ErrorResponse {
12
+ response: {
13
+ data: {
14
+ userMessage: string;
15
+ errorCode: string;
16
+ errors?: Array<{ key: string; message: string }>;
17
+ }
18
+ }
19
+ }
20
+
21
+ export const syncInvoicesService = async (): Promise<string> => {
22
+ try {
23
+ const invoices = await Invoice.findAll({
24
+ where: { status: 'Approved' },
25
+ include: [{ model: InvoiceDetail }]
26
+ });
27
+
28
+ if (invoices.length === 0) {
29
+ return "No invoice to sync";
30
+ }
31
+
32
+ const syncPromises = invoices.map(async (invoice) => {
33
+ const bill = {
34
+ billDate: formatDate(invoice.invoice_date),
35
+ billSplits: invoice.InvoiceDetails.map(detail => ({
36
+ amount: detail.amount as number,
37
+ glAccountID: detail.pw_gl_account_id,
38
+ portfolioID: detail.pw_portfolio_id,
39
+ buildingID: detail.pw_building_id,
40
+ comments: detail.description,
41
+ paid: false,
42
+ unitID: detail.pw_unit_id
43
+ })),
44
+ dueDate: invoice.due_date ? formatDate(invoice.due_date) : null,
45
+ vendorID: invoice.pw_vendor_id?.toString(),
46
+ comments: invoice.description,
47
+ refNo: invoice.reference_number,
48
+ terms: invoice.term,
49
+ workOrderID: invoice.pw_work_order_id,
50
+ };
51
+
52
+ try {
53
+ const response = await createBill(bill);
54
+
55
+ // Add audit log for Update Invoice
56
+ const auditLogData = {
57
+ invoice_id: invoice.id as number,
58
+ action_by: 1,
59
+ action: 'Invoice sync to PW',
60
+ details: `Bill for invoice ${bill.refNo} synced successfully. PW invoice id: ${response.id}`
61
+ };
62
+ await createAuditLog(auditLogData);
63
+
64
+ try {
65
+
66
+ // upload invoice file to propertyware
67
+ if (invoice.filename) {
68
+ const formData = new FormData();
69
+ formData.append('file', invoice.pdf_url as string);
70
+ const PWBillUploadResult = await uploadBill(response.id, formData);
71
+ }
72
+
73
+ } catch (error) {
74
+ console.log("invoice file upload failed : ", error);
75
+ }
76
+ // Update Invoice status
77
+ await updateInvoiceData(invoice.id as number, { status: 'Sync success' }, 1);
78
+
79
+ logger.info(`Bill for invoice ${bill.refNo} synced successfully`);
80
+ } catch (error) {
81
+ let errorMessage = `Error syncing bill for invoice ${bill.refNo}.`;
82
+ const errorobj = (error as ErrorResponse);
83
+
84
+ const errordata = errorobj.response.data;
85
+ console.log(errordata);
86
+ if (errordata) {
87
+ if (errordata.errors && Array.isArray(errordata.errors)) {
88
+ errorMessage += ` Errors: ${errordata.errors.map(e => `${e.key}: ${e.message}`).join(', ')}`;
89
+ } else {
90
+ errorMessage += ` ${errordata.userMessage}`;
91
+ }
92
+
93
+ logger.error(errorMessage);
94
+
95
+ // Add entry to error log
96
+ const errorLogData = {
97
+ invoice_id: invoice.id as number,
98
+ error_type: 'PW Sync Failed',
99
+ error_details: errorMessage
100
+ };
101
+ await ErrorLog.create(errorLogData);
102
+ } else if (error instanceof Error) {
103
+
104
+ logger.error(`Error syncing bill for invoice ${bill.refNo}: ${error.message}`);
105
+
106
+ // Add entry to error log
107
+ const errorLogData = {
108
+ invoice_id: invoice.id as number,
109
+ error_type: 'PW Sync Failed',
110
+ error_details: `Error syncing bill for invoice ${bill.refNo}. ${error.message}`
111
+ };
112
+
113
+ await ErrorLog.create(errorLogData);
114
+ } else {
115
+
116
+ logger.error(`Unknown error syncing bill for invoice ${bill.refNo}`);
117
+ logger.error(error);
118
+
119
+ // Add entry to error log
120
+ const errorLogData = {
121
+ invoice_id: invoice.id as number,
122
+ error_type: 'PW Sync Failed',
123
+ error_details: `Unknown error syncing bill for invoice ${bill.refNo}`
124
+ };
125
+ await ErrorLog.create(errorLogData);
126
+ }
127
+ await updateInvoiceData(invoice.id as number, { status: 'Sync Failed' }, 1);
128
+ }
129
+ });
130
+
131
+ await Promise.all(syncPromises);
132
+
133
+ return "Invoice data sync process completed successfully";
134
+ } catch (error) {
135
+ logger.error('Error while syncing invoices to propertyware:', error);
136
+ throw new Error('Error while syncing invoices to propertyware');
137
+ }
138
+ };
src/shared/services/buildings.service.ts ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { fetchBuildings } from './propertyware.service';
2
+ import PwBuildings from '../../models/pwBuildings';
3
+ import { logger } from '../../utils/logger';
4
+
5
+ export const syncBuildingsDataService = async (): Promise<string> => {
6
+ try {
7
+ const buildingsData = await fetchBuildings();
8
+ const buildingsResponseData = buildingsData.map((building: Record<string, string>) => ({
9
+ pw_id: building.id,
10
+ name: building.name,
11
+ pw_portfolio_id: building.portfolioID
12
+ }));
13
+
14
+ await PwBuildings.bulkCreate(buildingsResponseData, {
15
+ updateOnDuplicate: ['name', 'pw_portfolio_id'],
16
+ });
17
+
18
+ logger.info("Buildings data synced successfully");
19
+ return "Buildings data synced successfully";
20
+ } catch (error) {
21
+ logger.error("Error syncing Buildings: ", error);
22
+ throw new Error("Error syncing Buildings");
23
+ }
24
+ };
src/shared/services/cronJobs.ts CHANGED
@@ -1,9 +1,9 @@
1
  import cron from 'node-cron';
2
  import { logger } from '../../utils/logger';
3
- import { syncPortfolioDataService } from '../../controllers/propertyware/portfolio.controller';
4
- import { syncBuildingsDataService } from '../../controllers/propertyware/buildings.controller';
5
- import { syncUnitsDataService } from '../../controllers/propertyware/units.controller';
6
- import { syncInvoicesService } from '../../controllers/propertyware/bills.controller';
7
 
8
  export const setupCronJobs = () => {
9
  cron.schedule('0 0 * * *', async () => {
 
1
  import cron from 'node-cron';
2
  import { logger } from '../../utils/logger';
3
+ import { syncBuildingsDataService } from './buildings.service';
4
+ import { syncPortfolioDataService } from './portfolio.service';
5
+ import { syncInvoicesService } from './bills.service';
6
+ import { syncUnitsDataService } from './units.service';
7
 
8
  export const setupCronJobs = () => {
9
  cron.schedule('0 0 * * *', async () => {
src/shared/services/portfolio.service.ts ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { fetchPortfolio } from './propertyware.service';
2
+ import PwPortfolio from '../../models/pwPortfolio';
3
+ import { logger } from '../../utils/logger';
4
+
5
+ export const syncPortfolioDataService = async (): Promise<string> => {
6
+ try {
7
+ const portfolioData = await fetchPortfolio();
8
+ const portfolioResponseData = portfolioData.map((portfolio: { id: any; name: any; }) => ({
9
+ pw_id: portfolio.id,
10
+ name: portfolio.name,
11
+ }));
12
+
13
+ await PwPortfolio.bulkCreate(portfolioResponseData, {
14
+ updateOnDuplicate: ['name'],
15
+ });
16
+
17
+ logger.info("Portfolio data synced successfully");
18
+ return "Portfolio data synced successfully";
19
+ } catch (error) {
20
+ logger.error("Error syncing Portfolio: ", error);
21
+ throw new Error("Error syncing Portfolio");
22
+ }
23
+ };
src/shared/services/units.service.ts ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { fetchUnits } from './propertyware.service';
2
+ import PwUnits from '../../models/pwUnits';
3
+ import { logger } from '../../utils/logger';
4
+
5
+ export const syncUnitsDataService = async (): Promise<string> => {
6
+ try {
7
+ const unitsData = await fetchUnits();
8
+ const unitsResponseData = unitsData.map((unit: Record<string, string>) => ({
9
+ pw_id: unit.id,
10
+ name: unit.name,
11
+ pw_portfolio_id: unit.portfolioID,
12
+ pw_building_id: unit.buildingID
13
+ }));
14
+
15
+ await PwUnits.bulkCreate(unitsResponseData, {
16
+ updateOnDuplicate: ['name', 'pw_portfolio_id', 'pw_building_id'],
17
+ });
18
+
19
+ logger.info("Units data synced successfully");
20
+ return "Units data synced successfully";
21
+ } catch (error) {
22
+ logger.error("Error syncing Units: ", error);
23
+ throw new Error("Error syncing Units");
24
+ }
25
+ };