Compare commits
42 Commits
feature/IO
...
feature/IO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91de311351 | ||
|
|
1a6e8bc5ba | ||
|
|
dd4ba8a467 | ||
|
|
80b66fd7e8 | ||
|
|
45ac56e0bc | ||
|
|
1ff1de8739 | ||
|
|
ea1cc23ee7 | ||
|
|
7cbabf8697 | ||
|
|
289a666b6d | ||
|
|
b8836c7ae1 | ||
|
|
eca31c5618 | ||
|
|
7fdbedefce | ||
|
|
7140b8d585 | ||
|
|
5eed8d9809 | ||
|
|
57fe5b4c46 | ||
|
|
f266ee1cfe | ||
|
|
9550de5131 | ||
|
|
1f76ff882c | ||
|
|
749f73a272 | ||
|
|
9c1774c417 | ||
|
|
26b3a43ce5 | ||
|
|
78678dd3dc | ||
|
|
9dc4546b2e | ||
|
|
95aa0e45a6 | ||
|
|
ce9a77efcf | ||
|
|
e9e1e820a7 | ||
|
|
b027a4e618 | ||
|
|
c7fc75aa5c | ||
|
|
98d2372daf | ||
|
|
bf51380167 | ||
|
|
1ec827097f | ||
|
|
ff7dd7d3ea | ||
|
|
8cc4f88fa7 | ||
|
|
7e6ab3a5ff | ||
|
|
34f876f838 | ||
|
|
2f3eccf3d8 | ||
|
|
2b3e64d607 | ||
|
|
05b20505bb | ||
|
|
bddeae945c | ||
|
|
5b267f03b9 | ||
|
|
9aab47d8f8 | ||
|
|
f2f84e2da8 |
30
.vscode/settings.json
vendored
30
.vscode/settings.json
vendored
@@ -8,5 +8,35 @@
|
|||||||
"pattern": "**/IMEX.xml",
|
"pattern": "**/IMEX.xml",
|
||||||
"systemId": "logs/IMEX.xsd"
|
"systemId": "logs/IMEX.xsd"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"cSpell.words": [
|
||||||
|
"antd",
|
||||||
|
"appointmentconfirmation",
|
||||||
|
"appt",
|
||||||
|
"autohouse",
|
||||||
|
"autohouseid",
|
||||||
|
"billlines",
|
||||||
|
"bodyshop",
|
||||||
|
"bodyshopid",
|
||||||
|
"bodyshops",
|
||||||
|
"CIECA",
|
||||||
|
"claimscorp",
|
||||||
|
"claimscorpid",
|
||||||
|
"Dinero",
|
||||||
|
"driveable",
|
||||||
|
"IMEX",
|
||||||
|
"imexshopid",
|
||||||
|
"jobid",
|
||||||
|
"joblines",
|
||||||
|
"Kaizen",
|
||||||
|
"labhrs",
|
||||||
|
"larhrs",
|
||||||
|
"mixdata",
|
||||||
|
"ownr",
|
||||||
|
"promanager",
|
||||||
|
"shopname",
|
||||||
|
"smartscheduling",
|
||||||
|
"timetickets",
|
||||||
|
"touchtime"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11156,6 +11156,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>imexpay</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>insurancecos</name>
|
<name>insurancecos</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -11198,27 +11219,6 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
<concept_node>
|
|
||||||
<name>intellipay</name>
|
|
||||||
<definition_loaded>false</definition_loaded>
|
|
||||||
<description></description>
|
|
||||||
<comment></comment>
|
|
||||||
<default_text></default_text>
|
|
||||||
<translations>
|
|
||||||
<translation>
|
|
||||||
<language>en-US</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
<translation>
|
|
||||||
<language>es-MX</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
<translation>
|
|
||||||
<language>fr-CA</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
</translations>
|
|
||||||
</concept_node>
|
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>intellipay_cash_discount</name>
|
<name>intellipay_cash_discount</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -11747,6 +11747,48 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>ttl_adjustment</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>ttl_tax_adjustment</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
</children>
|
</children>
|
||||||
</folder_node>
|
</folder_node>
|
||||||
<folder_node>
|
<folder_node>
|
||||||
@@ -11775,6 +11817,27 @@
|
|||||||
</concept_node>
|
</concept_node>
|
||||||
</children>
|
</children>
|
||||||
</folder_node>
|
</folder_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>romepay</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>scheduling</name>
|
<name>scheduling</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -36253,6 +36316,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>total_cust_payable_cash_discount</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>total_repairs</name>
|
<name>total_repairs</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -48360,6 +48444,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>tasks_in_view</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>tasks_on_board</name>
|
<name>tasks_on_board</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -48402,6 +48507,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>total_amount_in_view</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>total_amount_on_board</name>
|
<name>total_amount_on_board</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -48444,6 +48570,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>total_hours_in_view</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>total_hours_on_board</name>
|
<name>total_hours_on_board</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -48465,6 +48612,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>total_jobs_in_view</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>total_jobs_on_board</name>
|
<name>total_jobs_on_board</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -48507,6 +48675,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>total_lab_in_view</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>total_lab_on_board</name>
|
<name>total_lab_on_board</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -48549,6 +48738,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>total_lar_in_view</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>total_lar_on_board</name>
|
<name>total_lar_on_board</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -48724,6 +48934,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>tasks_in_view</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>tasks_on_board</name>
|
<name>tasks_on_board</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -48766,6 +48997,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>total_amount_in_view</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>total_amount_on_board</name>
|
<name>total_amount_on_board</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -48808,6 +49060,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>total_hours_in_view</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>total_hours_on_board</name>
|
<name>total_hours_on_board</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -48829,6 +49102,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>total_jobs_in_view</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>total_jobs_on_board</name>
|
<name>total_jobs_on_board</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -48871,6 +49165,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>total_lab_in_view</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>total_lab_on_board</name>
|
<name>total_lab_on_board</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -48913,6 +49228,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>total_lar_in_view</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>total_lar_on_board</name>
|
<name>total_lar_on_board</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -51761,6 +52097,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>production_not_production_status</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>production_over_time</name>
|
<name>production_over_time</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -54225,6 +54582,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>created_by</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>description</name>
|
<name>description</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -54487,6 +54865,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>related_items</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>remind_at</name>
|
<name>remind_at</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
|
|||||||
12
certs/io-ftp-test.key
Normal file
12
certs/io-ftp-test.key
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS
|
||||||
|
1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQBYJnAujo17diR0fM2Ze1d1Ft6XHm5
|
||||||
|
U31pXdFEN+rGC4SoYTdZE8q3relxMS5GwwBOvgvVUuayfid2XS8ls/CMDiMBJAYqEK4CRY
|
||||||
|
PbbPB7lLnMWsF7muFhvs+SIpPQC+vtDwM2TKlxF0Y8p+iVRpvCADoggsSze7skmJWKmMTt
|
||||||
|
8jEdEOcAAAEQIyXsOSMl7DkAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ
|
||||||
|
AAAIUEAWCZwLo6Ne3YkdHzNmXtXdRbelx5uVN9aV3RRDfqxguEqGE3WRPKt63pcTEuRsMA
|
||||||
|
Tr4L1VLmsn4ndl0vJbPwjA4jASQGKhCuAkWD22zwe5S5zFrBe5rhYb7PkiKT0Avr7Q8DNk
|
||||||
|
ypcRdGPKfolUabwgA6IILEs3u7JJiVipjE7fIxHRDnAAAAQUO5dO9G7i0bxGTP0zV3eIwv
|
||||||
|
5g0NhrQJfW/bMHS6XWwaxdpr+QZ+DbBJVzZPwYC0wLMW4bJAf+kjqUnj4wGocoTeAAAAD2
|
||||||
|
lvLWZ0cC10ZXN0LWtleQECAwQ=
|
||||||
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
1
certs/io-ftp-test.key.pub
Normal file
1
certs/io-ftp-test.key.pub
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFgmcC6OjXt2JHR8zZl7V3UW3pceblTfWld0UQ36sYLhKhhN1kTyret6XExLkbDAE6+C9VS5rJ+J3ZdLyWz8IwOIwEkBioQrgJFg9ts8HuUucxawXua4WG+z5Iik9AL6+0PAzZMqXEXRjyn6JVGm8IAOiCCxLN7uySYlYqYxO3yMR0Q5w== io-ftp-test-key
|
||||||
12
certs/io-ftp-test.ppk
Normal file
12
certs/io-ftp-test.ppk
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
PuTTY-User-Key-File-3: ecdsa-sha2-nistp521
|
||||||
|
Encryption: none
|
||||||
|
Comment: io-ftp-test-key
|
||||||
|
Public-Lines: 4
|
||||||
|
AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFgmcC6OjXt
|
||||||
|
2JHR8zZl7V3UW3pceblTfWld0UQ36sYLhKhhN1kTyret6XExLkbDAE6+C9VS5rJ+
|
||||||
|
J3ZdLyWz8IwOIwEkBioQrgJFg9ts8HuUucxawXua4WG+z5Iik9AL6+0PAzZMqXEX
|
||||||
|
Rjyn6JVGm8IAOiCCxLN7uySYlYqYxO3yMR0Q5w==
|
||||||
|
Private-Lines: 2
|
||||||
|
AAAAQUO5dO9G7i0bxGTP0zV3eIwv5g0NhrQJfW/bMHS6XWwaxdpr+QZ+DbBJVzZP
|
||||||
|
wYC0wLMW4bJAf+kjqUnj4wGocoTe
|
||||||
|
Private-MAC: d67001d47e13c43dc8bdb9c68a25356a96c1c4a6714f3c5a1836fca646b78b54
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { DatePicker } from "antd";
|
import { DatePicker, Space, TimePicker } from "antd";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import React, { useCallback, useState } from "react";
|
import React, { useCallback, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@@ -20,6 +20,7 @@ const DateTimePicker = ({
|
|||||||
onlyFuture,
|
onlyFuture,
|
||||||
onlyToday,
|
onlyToday,
|
||||||
isDateOnly = false,
|
isDateOnly = false,
|
||||||
|
isSeparatedTime = false,
|
||||||
bodyshop,
|
bodyshop,
|
||||||
...restProps
|
...restProps
|
||||||
}) => {
|
}) => {
|
||||||
@@ -87,24 +88,57 @@ const DateTimePicker = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div onKeyDown={handleKeyDown} id={id} style={{ width: "100%" }}>
|
<div onKeyDown={handleKeyDown} id={id} style={{ width: "100%" }}>
|
||||||
<DatePicker
|
{isSeparatedTime && (
|
||||||
showTime={
|
<Space direction="vertical" style={{ width: "100%" }}>
|
||||||
isDateOnly
|
<DatePicker
|
||||||
? false
|
showTime={false}
|
||||||
: {
|
format="MM/DD/YYYY"
|
||||||
format: "hh:mm a",
|
value={value ? dayjs(value) : null}
|
||||||
minuteStep: 15,
|
onChange={handleChange}
|
||||||
defaultValue: dayjs(dayjs(), "HH:mm:ss")
|
placeholder={t("general.labels.date")}
|
||||||
}
|
onBlur={handleBlur}
|
||||||
}
|
disabledDate={handleDisabledDate}
|
||||||
format={isDateOnly ? "MM/DD/YYYY" : "MM/DD/YYYY hh:mm a"}
|
isDateOnly={true}
|
||||||
value={value ? dayjs(value) : null}
|
{...restProps}
|
||||||
onChange={handleChange}
|
/>
|
||||||
placeholder={isDateOnly ? t("general.labels.date") : t("general.labels.datetime")}
|
{value && (
|
||||||
onBlur={onBlur || handleBlur}
|
<TimePicker
|
||||||
disabledDate={handleDisabledDate}
|
format="hh:mm a"
|
||||||
{...restProps}
|
minuteStep={15}
|
||||||
/>
|
defaultOpenValue={dayjs(value)
|
||||||
|
.hour(dayjs().hour())
|
||||||
|
.minute(Math.floor(dayjs().minute() / 15) * 15)
|
||||||
|
.second(0)}
|
||||||
|
onChange={(value) => {
|
||||||
|
handleChange(value);
|
||||||
|
onBlur();
|
||||||
|
}}
|
||||||
|
placeholder={t("general.labels.time")}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
{!isSeparatedTime && (
|
||||||
|
<DatePicker
|
||||||
|
showTime={
|
||||||
|
isDateOnly
|
||||||
|
? false
|
||||||
|
: {
|
||||||
|
format: "hh:mm a",
|
||||||
|
minuteStep: 15,
|
||||||
|
defaultValue: dayjs(dayjs(), "HH:mm:ss")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
format={isDateOnly ? "MM/DD/YYYY" : "MM/DD/YYYY hh:mm a"}
|
||||||
|
value={value ? dayjs(value) : null}
|
||||||
|
onChange={handleChange}
|
||||||
|
placeholder={isDateOnly ? t("general.labels.date") : t("general.labels.datetime")}
|
||||||
|
onBlur={onBlur || handleBlur}
|
||||||
|
disabledDate={handleDisabledDate}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -116,7 +150,8 @@ DateTimePicker.propTypes = {
|
|||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
onlyFuture: PropTypes.bool,
|
onlyFuture: PropTypes.bool,
|
||||||
onlyToday: PropTypes.bool,
|
onlyToday: PropTypes.bool,
|
||||||
isDateOnly: PropTypes.bool
|
isDateOnly: PropTypes.bool,
|
||||||
|
isSeparatedTime: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, null)(DateTimePicker);
|
export default connect(mapStateToProps, null)(DateTimePicker);
|
||||||
|
|||||||
@@ -118,8 +118,7 @@ export function JobLinesComponent({
|
|||||||
...(record.critical ? { boxShadow: " -.5em 0 0 #FFC107" } : {})
|
...(record.critical ? { boxShadow: " -.5em 0 0 #FFC107" } : {})
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
sortOrder: state.sortedInfo.columnKey === "line_desc" && state.sortedInfo.order,
|
sortOrder: state.sortedInfo.columnKey === "line_desc" && state.sortedInfo.order
|
||||||
ellipsis: true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("joblines.fields.oem_partno"),
|
title: t("joblines.fields.oem_partno"),
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ export default function JobLineNotePopup({ jobline, disabled }) {
|
|||||||
if (editing)
|
if (editing)
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Input
|
<Input.TextArea
|
||||||
|
autoSize
|
||||||
autoFocus
|
autoFocus
|
||||||
suffix={loading ? <LoadingSpinner /> : null}
|
suffix={loading ? <LoadingSpinner /> : null}
|
||||||
value={note}
|
value={note}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
|
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||||
import { Form, Input, InputNumber, Modal, Select, Switch } from "antd";
|
import { Form, Input, InputNumber, Modal, Select, Switch } from "antd";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import InputCurrency from "../form-items-formatted/currency-form-item.component";
|
import InputCurrency from "../form-items-formatted/currency-form-item.component";
|
||||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
|
||||||
import JoblinesPreset from "../job-lines-preset-button/job-lines-preset-button.component";
|
import JoblinesPreset from "../job-lines-preset-button/job-lines-preset-button.component";
|
||||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
|
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
@@ -61,7 +61,7 @@ export function JobLinesUpsertModalComponent({ bodyshop, open, jobLine, handleCa
|
|||||||
]}
|
]}
|
||||||
name="line_desc"
|
name="line_desc"
|
||||||
>
|
>
|
||||||
<Input />
|
<Input.TextArea autoSize />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<JoblinesPreset form={form} />
|
<JoblinesPreset form={form} />
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
|
|||||||
@@ -141,14 +141,16 @@ export function JobTotalsTableTotals({ bodyshop, job }) {
|
|||||||
key: t("jobs.fields.ded_amt"),
|
key: t("jobs.fields.ded_amt"),
|
||||||
total: job.job_totals.totals.custPayable.deductible
|
total: job.job_totals.totals.custPayable.deductible
|
||||||
},
|
},
|
||||||
...(InstanceRenderManager({
|
...InstanceRenderManager({
|
||||||
imex: [{
|
imex: [
|
||||||
key: t("jobs.fields.federal_tax_payable"),
|
{
|
||||||
total: job.job_totals.totals.custPayable.federal_tax
|
key: t("jobs.fields.federal_tax_payable"),
|
||||||
}],
|
total: job.job_totals.totals.custPayable.federal_tax
|
||||||
|
}
|
||||||
|
],
|
||||||
rome: [],
|
rome: [],
|
||||||
promanager: "USE_ROME"
|
promanager: "USE_ROME"
|
||||||
})),
|
}),
|
||||||
{
|
{
|
||||||
key: t("jobs.fields.other_amount_payable"),
|
key: t("jobs.fields.other_amount_payable"),
|
||||||
total: job.job_totals.totals.custPayable.other_customer_amount
|
total: job.job_totals.totals.custPayable.other_customer_amount
|
||||||
@@ -158,11 +160,32 @@ export function JobTotalsTableTotals({ bodyshop, job }) {
|
|||||||
total: job.job_totals.totals.custPayable.dep_taxes
|
total: job.job_totals.totals.custPayable.dep_taxes
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
...(bodyshop.intellipay_config?.enable_cash_discount
|
||||||
key: t("jobs.labels.total_cust_payable"),
|
? [
|
||||||
total: job.job_totals.totals.custPayable.total,
|
{
|
||||||
bold: true
|
key: t("jobs.labels.total_cust_payable_cash_discount"),
|
||||||
},
|
total: job.job_totals.totals.custPayable.total,
|
||||||
|
bold: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: t("jobs.labels.total_cust_payable"),
|
||||||
|
total: Dinero(job.job_totals.totals.custPayable.total)
|
||||||
|
.add(
|
||||||
|
Dinero(job.job_totals.totals.custPayable.total).percentage(
|
||||||
|
bodyshop.intellipay_config?.cash_discount_percentage || 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.toJSON(),
|
||||||
|
bold: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
key: t("jobs.labels.total_cust_payable"),
|
||||||
|
total: job.job_totals.totals.custPayable.total,
|
||||||
|
bold: true
|
||||||
|
}
|
||||||
|
]),
|
||||||
{
|
{
|
||||||
key: t("jobs.labels.net_repairs"),
|
key: t("jobs.labels.net_repairs"),
|
||||||
total: job.job_totals.totals.net_repairs,
|
total: job.job_totals.totals.net_repairs,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { connect } from "react-redux";
|
|||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx";
|
||||||
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
||||||
import FormItemEmail from "../form-items-formatted/email-form-item.component";
|
import FormItemEmail from "../form-items-formatted/email-form-item.component";
|
||||||
import FormItemPhone, { PhoneItemFormatterValidation } from "../form-items-formatted/phone-form-item.component";
|
import FormItemPhone, { PhoneItemFormatterValidation } from "../form-items-formatted/phone-form-item.component";
|
||||||
@@ -12,7 +13,6 @@ import Car from "../job-damage-visual/job-damage-visual.component";
|
|||||||
import JobsDetailChangeEstimator from "../jobs-detail-change-estimator/jobs-detail-change-estimator.component";
|
import JobsDetailChangeEstimator from "../jobs-detail-change-estimator/jobs-detail-change-estimator.component";
|
||||||
import JobsDetailChangeFileHandler from "../jobs-detail-change-filehandler/jobs-detail-change-filehandler.component";
|
import JobsDetailChangeFileHandler from "../jobs-detail-change-filehandler/jobs-detail-change-filehandler.component";
|
||||||
import FormRow from "../layout-form-row/layout-form-row.component";
|
import FormRow from "../layout-form-row/layout-form-row.component";
|
||||||
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
jobRO: selectJobReadOnly,
|
jobRO: selectJobReadOnly,
|
||||||
@@ -185,6 +185,9 @@ export function JobsDetailGeneral({ bodyshop, jobRO, job, form }) {
|
|||||||
<Form.Item label={t("jobs.fields.towin")} name="towin" valuePropName="checked">
|
<Form.Item label={t("jobs.fields.towin")} name="towin" valuePropName="checked">
|
||||||
<Switch disabled={jobRO} />
|
<Switch disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item label={t("jobs.fields.tlos_ind")} name="tlos_ind" valuePropName="checked">
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
</FormRow>
|
</FormRow>
|
||||||
</Col>
|
</Col>
|
||||||
<Col {...lossColDamage}>
|
<Col {...lossColDamage}>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Button, Col, Form, Input, Row, Select, Space, Switch, Typography } from "antd";
|
import { Button, Col, Form, Input, Row, Select, Space, Switch, Typography } from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import dayjs from "../../utils/day";
|
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
@@ -8,13 +7,14 @@ import { createStructuredSelector } from "reselect";
|
|||||||
import { calculateScheduleLoad } from "../../redux/application/application.actions";
|
import { calculateScheduleLoad } from "../../redux/application/application.actions";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import { DateFormatter } from "../../utils/DateFormatter";
|
import { DateFormatter } from "../../utils/DateFormatter";
|
||||||
|
import dayjs from "../../utils/day";
|
||||||
|
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||||
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component";
|
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component";
|
||||||
import EmailInput from "../form-items-formatted/email-form-item.component";
|
import EmailInput from "../form-items-formatted/email-form-item.component";
|
||||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
import ScheduleDayViewContainer from "../schedule-day-view/schedule-day-view.container";
|
import ScheduleDayViewContainer from "../schedule-day-view/schedule-day-view.container";
|
||||||
import ScheduleExistingAppointmentsList from "../schedule-existing-appointments-list/schedule-existing-appointments-list.component";
|
import ScheduleExistingAppointmentsList from "../schedule-existing-appointments-list/schedule-existing-appointments-list.component";
|
||||||
import "./schedule-job-modal.scss";
|
import "./schedule-job-modal.scss";
|
||||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop
|
bodyshop: selectBodyshop
|
||||||
@@ -84,7 +84,7 @@ export function ScheduleJobModalComponent({
|
|||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<DateTimePicker onBlur={handleDateBlur} onlyFuture />
|
<DateTimePicker onBlur={handleDateBlur} onlyFuture isSeparatedTime />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="scheduled_completion"
|
name="scheduled_completion"
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ export function ShopInfoComponent({ bodyshop, form, saveLoading }) {
|
|||||||
rome: [
|
rome: [
|
||||||
{
|
{
|
||||||
key: "intellipay",
|
key: "intellipay",
|
||||||
label: t("bodyshop.labels.intellipay"),
|
label: InstanceRenderManager({ rome: t("bodyshop.labels.romepay"), imex: t("bodyshop.labels.imexpay") }),
|
||||||
children: <ShopInfoIntellipay form={form} />
|
children: <ShopInfoIntellipay form={form} />
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -676,7 +676,7 @@ export function ShopInfoGeneral({ form, bodyshop }) {
|
|||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Input.TextArea rows={3} />
|
<Input.TextArea autoSize />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
<DeleteFilled
|
<DeleteFilled
|
||||||
@@ -737,7 +737,7 @@ export function ShopInfoGeneral({ form, bodyshop }) {
|
|||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Input.TextArea rows={3} />
|
<Input.TextArea autoSize />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
<DeleteFilled
|
<DeleteFilled
|
||||||
@@ -1187,7 +1187,7 @@ export function ShopInfoGeneral({ form, bodyshop }) {
|
|||||||
key={`${index}line_desc`}
|
key={`${index}line_desc`}
|
||||||
name={[field.name, "line_desc"]}
|
name={[field.name, "line_desc"]}
|
||||||
>
|
>
|
||||||
<Input />
|
<Input.TextArea autoSize />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("joblines.fields.mod_lbr_ty")}
|
label={t("joblines.fields.mod_lbr_ty")}
|
||||||
@@ -1330,7 +1330,7 @@ export function ShopInfoGeneral({ form, bodyshop }) {
|
|||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Input />
|
<Input.TextArea autoSize />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
|
|||||||
@@ -39,14 +39,13 @@ export function ShopInfoIntellipay({ bodyshop, form }) {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("bodyshop.fields.intellipay_config.cash_discount_percentage")}
|
label={t("bodyshop.fields.intellipay_config.cash_discount_percentage")}
|
||||||
valuePropName="checked"
|
|
||||||
dependencies={[["intellipay_config", "enable_cash_discount"]]}
|
dependencies={[["intellipay_config", "enable_cash_discount"]]}
|
||||||
name={["intellipay_config", "cash_discount_percentage"]}
|
name={["intellipay_config", "cash_discount_percentage"]}
|
||||||
rules={[
|
rules={[
|
||||||
({ getFieldsValue }) => ({ required: form.getFieldValue(["intellipay_config", "enable_cash_discount"]) })
|
({ getFieldsValue }) => ({ required: form.getFieldValue(["intellipay_config", "enable_cash_discount"]) })
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} precision={1} suffix='%'/>
|
<InputNumber min={0} max={100} precision={1} suffix="%" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -81,14 +81,14 @@ export const logImEXEvent = (eventName, additionalParams, stateProp = null) => {
|
|||||||
user: (state.user && state.user.currentUser && state.user.currentUser.email) || null,
|
user: (state.user && state.user.currentUser && state.user.currentUser.email) || null,
|
||||||
...additionalParams
|
...additionalParams
|
||||||
};
|
};
|
||||||
axios.post("/ioevent", {
|
// axios.post("/ioevent", {
|
||||||
useremail: (state.user && state.user.currentUser && state.user.currentUser.email) || null,
|
// useremail: (state.user && state.user.currentUser && state.user.currentUser.email) || null,
|
||||||
bodyshopid: (state.user && state.user.bodyshop && state.user.bodyshop.id) || null,
|
// bodyshopid: (state.user && state.user.bodyshop && state.user.bodyshop.id) || null,
|
||||||
operationName: eventName,
|
// operationName: eventName,
|
||||||
variables: additionalParams,
|
// variables: additionalParams,
|
||||||
dbevent: false,
|
// dbevent: false,
|
||||||
env: `master-AIO|${import.meta.env.VITE_APP_GIT_SHA_DATE}`
|
// env: `master-AIO|${import.meta.env.VITE_APP_GIT_SHA_DATE}`
|
||||||
});
|
// });
|
||||||
// console.log(
|
// console.log(
|
||||||
// "%c[Analytics]",
|
// "%c[Analytics]",
|
||||||
// "background-color: green ;font-weight:bold;",
|
// "background-color: green ;font-weight:bold;",
|
||||||
|
|||||||
@@ -692,6 +692,7 @@ export const GET_JOB_BY_PK = gql`
|
|||||||
tax_str_rt
|
tax_str_rt
|
||||||
tax_sub_rt
|
tax_sub_rt
|
||||||
tax_tow_rt
|
tax_tow_rt
|
||||||
|
tlos_ind
|
||||||
towin
|
towin
|
||||||
towing_payable
|
towing_payable
|
||||||
unit_number
|
unit_number
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
14
docker-build.ps1
Normal file
14
docker-build.ps1
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Stop and remove all containers, images, and networks from the Compose file
|
||||||
|
docker compose down --rmi all
|
||||||
|
|
||||||
|
# Prune all unused Docker objects including volumes
|
||||||
|
docker system prune --all --volumes --force
|
||||||
|
|
||||||
|
# Prune unused build cache
|
||||||
|
docker builder prune --all --force
|
||||||
|
|
||||||
|
# Prune all unused volumes
|
||||||
|
docker volume prune --all --force
|
||||||
|
|
||||||
|
# Rebuild and start the containers
|
||||||
|
docker compose up --build
|
||||||
16
docker-build.sh
Normal file
16
docker-build.sh
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Stop and remove all containers, images, and networks from the Compose file
|
||||||
|
docker compose down --rmi all
|
||||||
|
|
||||||
|
# Prune all unused Docker objects including volumes
|
||||||
|
docker system prune --all --volumes --force
|
||||||
|
|
||||||
|
# Prune unused build cache
|
||||||
|
docker builder prune --all --force
|
||||||
|
|
||||||
|
# Prune all unused volumes
|
||||||
|
docker volume prune --all --force
|
||||||
|
|
||||||
|
# Rebuild and start the containers
|
||||||
|
docker compose up --build
|
||||||
@@ -114,8 +114,8 @@ services:
|
|||||||
"
|
"
|
||||||
aws --endpoint-url=http://localstack:4566 ses verify-domain-identity --domain imex.online --region ca-central-1
|
aws --endpoint-url=http://localstack:4566 ses verify-domain-identity --domain imex.online --region ca-central-1
|
||||||
aws --endpoint-url=http://localstack:4566 ses verify-email-identity --email-address noreply@imex.online --region ca-central-1
|
aws --endpoint-url=http://localstack:4566 ses verify-email-identity --email-address noreply@imex.online --region ca-central-1
|
||||||
aws --endpoint-url=http://localstack:4566 secretsmanager create-secret --name CHATTER_PRIVATE_KEY --secret-string file:///tmp/certs/id_rsa
|
aws --endpoint-url=http://localstack:4566 secretsmanager create-secret --name CHATTER_PRIVATE_KEY --secret-string file:///tmp/certs/io-ftp-test.key
|
||||||
aws --endpoint-url=http://localstack:4566 logs create-log-group --log-group-name development --region ca-central-1
|
aws --endpoint-url=http://localstack:4566 logs create-log-group --log-group-name development --region ca-central-1
|
||||||
aws --endpoint-url=http://localstack:4566 s3api create-bucket --bucket imex-large-log --create-bucket-configuration LocationConstraint=ca-central-1
|
aws --endpoint-url=http://localstack:4566 s3api create-bucket --bucket imex-large-log --create-bucket-configuration LocationConstraint=ca-central-1
|
||||||
"
|
"
|
||||||
# Node App: The Main IMEX API
|
# Node App: The Main IMEX API
|
||||||
@@ -169,7 +169,7 @@ services:
|
|||||||
# - redis-insight-data:/db
|
# - redis-insight-data:/db
|
||||||
|
|
||||||
# ##Optional Container for SFTP/SSH Server for testing
|
# ##Optional Container for SFTP/SSH Server for testing
|
||||||
# ssh-sftp-server:
|
# ssh-sftp-server:
|
||||||
# image: atmoz/sftp:alpine # Using an image with SFTP support
|
# image: atmoz/sftp:alpine # Using an image with SFTP support
|
||||||
# container_name: ssh-sftp-server
|
# container_name: ssh-sftp-server
|
||||||
# hostname: ssh-sftp-server
|
# hostname: ssh-sftp-server
|
||||||
@@ -178,9 +178,10 @@ services:
|
|||||||
# ports:
|
# ports:
|
||||||
# - "2222:22" # Expose port 22 for SSH/SFTP (mapped to 2222 on the host)
|
# - "2222:22" # Expose port 22 for SSH/SFTP (mapped to 2222 on the host)
|
||||||
# volumes:
|
# volumes:
|
||||||
# - ./certs/id_rsa.pub:/home/user/.ssh/keys/id_rsa.pub:ro # Mount the SSH public key
|
# - ./certs/io-ftp-test.key.pub:/home/user/.ssh/keys/io-ftp-test.key.pub:ro # Mount the SSH public key as authorized_keys
|
||||||
# - ./upload:/home/user/upload # Mount a local directory for SFTP uploads
|
# - ./upload:/home/user/upload # Mount a local directory for SFTP uploads
|
||||||
# environment:
|
# environment:
|
||||||
|
# # - SFTP_USERS=user::1000::upload
|
||||||
# - SFTP_USERS=user:password:1000::upload
|
# - SFTP_USERS=user:password:1000::upload
|
||||||
# command: >
|
# command: >
|
||||||
# /bin/sh -c "
|
# /bin/sh -c "
|
||||||
|
|||||||
@@ -6,6 +6,15 @@
|
|||||||
headers:
|
headers:
|
||||||
- name: x-imex-auth
|
- name: x-imex-auth
|
||||||
value_from_env: DATAPUMP_AUTH
|
value_from_env: DATAPUMP_AUTH
|
||||||
|
- name: Chatter Data Pump
|
||||||
|
webhook: '{{HASURA_API_URL}}/data/chatter'
|
||||||
|
schedule: 45 5 * * *
|
||||||
|
include_in_metadata: true
|
||||||
|
payload: {}
|
||||||
|
headers:
|
||||||
|
- name: x-imex-auth
|
||||||
|
value_from_env: DATAPUMP_AUTH
|
||||||
|
comment: ""
|
||||||
- name: Claimscorp Data Pump
|
- name: Claimscorp Data Pump
|
||||||
webhook: '{{HASURA_API_URL}}/data/cc'
|
webhook: '{{HASURA_API_URL}}/data/cc'
|
||||||
schedule: 30 6 * * *
|
schedule: 30 6 * * *
|
||||||
|
|||||||
10
hasura/migrations/1731471670370_run_sql_migration/down.sql
Normal file
10
hasura/migrations/1731471670370_run_sql_migration/down.sql
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- CREATE INDEX jobs_search_gin_ro_number ON jobs USING GIN ((ro_number) gin_trgm_ops);
|
||||||
|
-- CREATE INDEX jobs_search_gin_ownrfn ON jobs USING GIN ((ownr_fn) gin_trgm_ops);
|
||||||
|
-- CREATE INDEX jobs_search_gin_clm_no ON jobs USING GIN ((clm_no) gin_trgm_ops);
|
||||||
|
-- CREATE INDEX jobs_search_gin_plate_no ON jobs USING GIN ((plate_no) gin_trgm_ops);
|
||||||
|
-- CREATE INDEX jobs_search_gin_v_make_desc ON jobs USING GIN (( v_make_desc) gin_trgm_ops);
|
||||||
|
-- CREATE INDEX jobs_search_gin_v_model_desc ON jobs USING GIN (( v_model_desc) gin_trgm_ops);
|
||||||
|
-- CREATE INDEX jobs_search_gin_ownr_ln ON jobs USING GIN (( ownr_ln) gin_trgm_ops);
|
||||||
|
-- CREATE INDEX jobs_search_gin_ownr_co_nm ON jobs USING GIN (( ownr_co_nm) gin_trgm_ops);
|
||||||
8
hasura/migrations/1731471670370_run_sql_migration/up.sql
Normal file
8
hasura/migrations/1731471670370_run_sql_migration/up.sql
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
CREATE INDEX jobs_search_gin_ro_number ON jobs USING GIN ((ro_number) gin_trgm_ops);
|
||||||
|
CREATE INDEX jobs_search_gin_ownrfn ON jobs USING GIN ((ownr_fn) gin_trgm_ops);
|
||||||
|
CREATE INDEX jobs_search_gin_clm_no ON jobs USING GIN ((clm_no) gin_trgm_ops);
|
||||||
|
CREATE INDEX jobs_search_gin_plate_no ON jobs USING GIN ((plate_no) gin_trgm_ops);
|
||||||
|
CREATE INDEX jobs_search_gin_v_make_desc ON jobs USING GIN (( v_make_desc) gin_trgm_ops);
|
||||||
|
CREATE INDEX jobs_search_gin_v_model_desc ON jobs USING GIN (( v_model_desc) gin_trgm_ops);
|
||||||
|
CREATE INDEX jobs_search_gin_ownr_ln ON jobs USING GIN (( ownr_ln) gin_trgm_ops);
|
||||||
|
CREATE INDEX jobs_search_gin_ownr_co_nm ON jobs USING GIN (( ownr_co_nm) gin_trgm_ops);
|
||||||
11
package-lock.json
generated
11
package-lock.json
generated
@@ -54,7 +54,7 @@
|
|||||||
"soap": "^1.1.5",
|
"soap": "^1.1.5",
|
||||||
"socket.io": "^4.8.0",
|
"socket.io": "^4.8.0",
|
||||||
"socket.io-adapter": "^2.5.5",
|
"socket.io-adapter": "^2.5.5",
|
||||||
"ssh2-sftp-client": "^10.0.3",
|
"ssh2-sftp-client": "^11.0.0",
|
||||||
"twilio": "^4.23.0",
|
"twilio": "^4.23.0",
|
||||||
"uuid": "^10.0.0",
|
"uuid": "^10.0.0",
|
||||||
"winston": "^3.15.0",
|
"winston": "^3.15.0",
|
||||||
@@ -8740,16 +8740,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ssh2-sftp-client": {
|
"node_modules/ssh2-sftp-client": {
|
||||||
"version": "10.0.3",
|
"version": "11.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ssh2-sftp-client/-/ssh2-sftp-client-10.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/ssh2-sftp-client/-/ssh2-sftp-client-11.0.0.tgz",
|
||||||
"integrity": "sha512-Wlhasz/OCgrlqC8IlBZhF19Uw/X/dHI8ug4sFQybPE+0sDztvgvDf7Om6o7LbRLe68E7XkFZf3qMnqAvqn1vkQ==",
|
"integrity": "sha512-lOjgNYtioYquhtgyHwPryFNhllkuENjvCKkUXo18w/Q4UpEffCnEUBfiOTlwFdKIhG1rhrOGnA6DeKPSF2CP6w==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"concat-stream": "^2.0.0",
|
"concat-stream": "^2.0.0",
|
||||||
"promise-retry": "^2.0.1",
|
"promise-retry": "^2.0.1",
|
||||||
"ssh2": "^1.15.0"
|
"ssh2": "^1.15.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.20.2"
|
"node": ">=18.20.4"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
"soap": "^1.1.5",
|
"soap": "^1.1.5",
|
||||||
"socket.io": "^4.8.0",
|
"socket.io": "^4.8.0",
|
||||||
"socket.io-adapter": "^2.5.5",
|
"socket.io-adapter": "^2.5.5",
|
||||||
"ssh2-sftp-client": "^10.0.3",
|
"ssh2-sftp-client": "^11.0.0",
|
||||||
"twilio": "^4.23.0",
|
"twilio": "^4.23.0",
|
||||||
"uuid": "^10.0.0",
|
"uuid": "^10.0.0",
|
||||||
"winston": "^3.15.0",
|
"winston": "^3.15.0",
|
||||||
|
|||||||
@@ -219,6 +219,11 @@ async function InsertPayment(oauthClient, qbo_realmId, req, payment, parentRef,
|
|||||||
PaymentMethodRef: {
|
PaymentMethodRef: {
|
||||||
value: paymentMethods[payment.type]
|
value: paymentMethods[payment.type]
|
||||||
},
|
},
|
||||||
|
PrivateNote: payment.memo
|
||||||
|
? payment.memo.length > 4000
|
||||||
|
? payment.memo.substring(0, 4000).trim()
|
||||||
|
: payment.memo.trim()
|
||||||
|
: "",
|
||||||
PaymentRefNum: payment.transactionid,
|
PaymentRefNum: payment.transactionid,
|
||||||
...(invoices && invoices.length === 1 && invoices[0]
|
...(invoices && invoices.length === 1 && invoices[0]
|
||||||
? {
|
? {
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ const ftpSetup = {
|
|||||||
port: process.env.AUTOHOUSE_PORT,
|
port: process.env.AUTOHOUSE_PORT,
|
||||||
username: process.env.AUTOHOUSE_USER,
|
username: process.env.AUTOHOUSE_USER,
|
||||||
password: process.env.AUTOHOUSE_PASSWORD,
|
password: process.env.AUTOHOUSE_PASSWORD,
|
||||||
debug: (message, ...data) => logger.log(message, "DEBUG", "api", null, data),
|
debug: process.env.NODE_ENV !== "production"
|
||||||
|
? (message, ...data) => logger.log(message, "DEBUG", "api", null, data)
|
||||||
|
: () => {},
|
||||||
algorithms: {
|
algorithms: {
|
||||||
serverHostKey: ["ssh-rsa", "ssh-dss", "rsa-sha2-256", "rsa-sha2-512", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384"]
|
serverHostKey: ["ssh-rsa", "ssh-dss", "rsa-sha2-256", "rsa-sha2-512", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384"]
|
||||||
}
|
}
|
||||||
@@ -47,7 +49,11 @@ exports.default = async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send immediate response and continue processing.
|
// Send immediate response and continue processing.
|
||||||
res.status(200).send();
|
res.status(202).json({
|
||||||
|
success: true,
|
||||||
|
message: "Processing request ...",
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.log("autohouse-start", "DEBUG", "api", null, null);
|
logger.log("autohouse-start", "DEBUG", "api", null, null);
|
||||||
@@ -146,7 +152,7 @@ async function processBatch(batch, start, end) {
|
|||||||
allErrors.push({
|
allErrors.push({
|
||||||
bodyshopid: bodyshop.id,
|
bodyshopid: bodyshop.id,
|
||||||
imexshopid: bodyshop.imexshopid,
|
imexshopid: bodyshop.imexshopid,
|
||||||
autuhouseid: bodyshop.autuhouseid,
|
autohouseid: bodyshop.autohouseid,
|
||||||
fatal: true,
|
fatal: true,
|
||||||
errors: [error.toString()]
|
errors: [error.toString()]
|
||||||
});
|
});
|
||||||
@@ -154,7 +160,7 @@ async function processBatch(batch, start, end) {
|
|||||||
allErrors.push({
|
allErrors.push({
|
||||||
bodyshopid: bodyshop.id,
|
bodyshopid: bodyshop.id,
|
||||||
imexshopid: bodyshop.imexshopid,
|
imexshopid: bodyshop.imexshopid,
|
||||||
autuhouseid: bodyshop.autuhouseid,
|
autohouseid: bodyshop.autohouseid,
|
||||||
errors: erroredJobs.map((ej) => ({
|
errors: erroredJobs.map((ej) => ({
|
||||||
ro_number: ej.job?.ro_number,
|
ro_number: ej.job?.ro_number,
|
||||||
jobid: ej.job?.id,
|
jobid: ej.job?.id,
|
||||||
@@ -176,9 +182,8 @@ async function uploadViaSFTP(allxmlsToUpload) {
|
|||||||
|
|
||||||
for (const xmlObj of allxmlsToUpload) {
|
for (const xmlObj of allxmlsToUpload) {
|
||||||
try {
|
try {
|
||||||
logger.log("autohouse-sftp-upload", "DEBUG", "api", null, { filename: xmlObj.filename });
|
|
||||||
xmlObj.result = await sftp.put(Buffer.from(xmlObj.xml), `${xmlObj.filename}`);
|
xmlObj.result = await sftp.put(Buffer.from(xmlObj.xml), `${xmlObj.filename}`);
|
||||||
logger.log("autohouse-sftp-upload-result", "DEBUG", "api", null, {
|
logger.log("autohouse-sftp-upload", "DEBUG", "api", null, {
|
||||||
filename: xmlObj.filename,
|
filename: xmlObj.filename,
|
||||||
result: xmlObj.result
|
result: xmlObj.result
|
||||||
});
|
});
|
||||||
@@ -609,10 +614,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
|||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log("autohouse-job-calculate-error", "ERROR", "api", null, {
|
logger.log("autohouse-job-calculate-error", "ERROR", "api", null, { error: error.message, stack: error.stack });
|
||||||
error
|
|
||||||
});
|
|
||||||
|
|
||||||
errorCallback({ jobid: job.id, ro_number: job.ro_number, error });
|
errorCallback({ jobid: job.id, ro_number: job.ro_number, error });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,15 +17,15 @@ const ftpSetup = {
|
|||||||
port: process.env.CHATTER_PORT,
|
port: process.env.CHATTER_PORT,
|
||||||
username: process.env.CHATTER_USER,
|
username: process.env.CHATTER_USER,
|
||||||
privateKey: null,
|
privateKey: null,
|
||||||
debug: (message, ...data) => logger.log(message, "DEBUG", "api", null, data),
|
debug:
|
||||||
|
process.env.NODE_ENV !== "production"
|
||||||
|
? (message, ...data) => logger.log(message, "DEBUG", "api", null, data)
|
||||||
|
: () => {},
|
||||||
algorithms: {
|
algorithms: {
|
||||||
serverHostKey: ["ssh-rsa", "ssh-dss", "rsa-sha2-256", "rsa-sha2-512", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384"]
|
serverHostKey: ["ssh-rsa", "ssh-dss", "rsa-sha2-256", "rsa-sha2-512", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384"]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const allcsvsToUpload = [];
|
|
||||||
const allErrors = [];
|
|
||||||
|
|
||||||
exports.default = async (req, res) => {
|
exports.default = async (req, res) => {
|
||||||
// Only process if in production environment.
|
// Only process if in production environment.
|
||||||
if (process.env.NODE_ENV !== "production") {
|
if (process.env.NODE_ENV !== "production") {
|
||||||
@@ -39,16 +39,21 @@ exports.default = async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send immediate response and continue processing.
|
// Send immediate response and continue processing.
|
||||||
res.status(200).send();
|
res.status(202).json({
|
||||||
|
success: true,
|
||||||
|
message: "Processing request ...",
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.log("chatter-start", "DEBUG", "api", null, null);
|
logger.log("chatter-start", "DEBUG", "api", null, null);
|
||||||
|
const allChatterObjects = [];
|
||||||
|
const allErrors = [];
|
||||||
|
|
||||||
const { bodyshops } = await client.request(queries.GET_CHATTER_SHOPS); //Query for the List of Bodyshop Clients.
|
const { bodyshops } = await client.request(queries.GET_CHATTER_SHOPS); //Query for the List of Bodyshop Clients.
|
||||||
const specificShopIds = req.body.bodyshopIds; // ['uuid];
|
const specificShopIds = req.body.bodyshopIds; // ['uuid];
|
||||||
const { start, end, skipUpload } = req.body; //YYYY-MM-DD
|
const { start, end, skipUpload } = req.body; //YYYY-MM-DD
|
||||||
|
|
||||||
const batchSize = 10;
|
|
||||||
|
|
||||||
const shopsToProcess =
|
const shopsToProcess =
|
||||||
specificShopIds?.length > 0 ? bodyshops.filter((shop) => specificShopIds.includes(shop.id)) : bodyshops;
|
specificShopIds?.length > 0 ? bodyshops.filter((shop) => specificShopIds.includes(shop.id)) : bodyshops;
|
||||||
logger.log("chatter-shopsToProcess-generated", "DEBUG", "api", null, null);
|
logger.log("chatter-shopsToProcess-generated", "DEBUG", "api", null, null);
|
||||||
@@ -58,29 +63,24 @@ exports.default = async (req, res) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const batchPromises = [];
|
await processBatch(shopsToProcess, start, end, allChatterObjects, allErrors);
|
||||||
for (let i = 0; i < shopsToProcess.length; i += batchSize) {
|
|
||||||
const batch = shopsToProcess.slice(i, i + batchSize);
|
const csvToUpload = {
|
||||||
const batchPromise = (async () => {
|
count: allChatterObjects.length,
|
||||||
await processBatch(batch, start, end);
|
csv: converter.json2csv(allChatterObjects, { emptyFieldValue: "" }),
|
||||||
if (skipUpload) {
|
filename: `IMEX_ONLINE_solicitation_${moment().format("YYYYMMDD")}.csv`
|
||||||
for (const csvObj of allcsvsToUpload) {
|
};
|
||||||
await fs.promises.writeFile(`./logs/${csvObj.filename}`, csvObj.csv);
|
|
||||||
}
|
if (skipUpload) {
|
||||||
} else {
|
await fs.promises.writeFile(`./logs/${csvToUpload.filename}`, csvToUpload.csv);
|
||||||
await uploadViaSFTP(allcsvsToUpload);
|
} else {
|
||||||
}
|
await uploadViaSFTP(csvToUpload);
|
||||||
})();
|
|
||||||
batchPromises.push(batchPromise);
|
|
||||||
}
|
}
|
||||||
await Promise.all(batchPromises);
|
|
||||||
await sendServerEmail({
|
await sendServerEmail({
|
||||||
subject: `Chatter Report ${moment().format("MM-DD-YY")}`,
|
subject: `Chatter Report ${moment().format("MM-DD-YY")}`,
|
||||||
text: `Errors:\n${JSON.stringify(allErrors, null, 2)}\n\nUploaded:\n${JSON.stringify(
|
text: `Errors:\n${JSON.stringify(allErrors, null, 2)}\n\n
|
||||||
allcsvsToUpload.map((x) => ({ filename: x.filename, count: x.count, result: x.result })),
|
Uploaded:\n${JSON.stringify({ filename: csvToUpload.filename, count: csvToUpload.count, result: csvToUpload.result }, null, 2)}`
|
||||||
null,
|
|
||||||
2
|
|
||||||
)}`
|
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.log("chatter-end", "DEBUG", "api", null, null);
|
logger.log("chatter-end", "DEBUG", "api", null, null);
|
||||||
@@ -89,8 +89,8 @@ exports.default = async (req, res) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async function processBatch(batch, start, end) {
|
async function processBatch(shopsToProcess, start, end, allChatterObjects, allErrors) {
|
||||||
for (const bodyshop of batch) {
|
for (const bodyshop of shopsToProcess) {
|
||||||
try {
|
try {
|
||||||
logger.log("chatter-start-shop-extract", "DEBUG", "api", bodyshop.id, {
|
logger.log("chatter-start-shop-extract", "DEBUG", "api", bodyshop.id, {
|
||||||
shopname: bodyshop.shopname
|
shopname: bodyshop.shopname
|
||||||
@@ -109,18 +109,11 @@ async function processBatch(batch, start, end) {
|
|||||||
lastname: j.ownr_co_nm ? j.ownr_co_nm : j.ownr_ln,
|
lastname: j.ownr_co_nm ? j.ownr_co_nm : j.ownr_ln,
|
||||||
transaction_id: j.ro_number,
|
transaction_id: j.ro_number,
|
||||||
email: j.ownr_ea,
|
email: j.ownr_ea,
|
||||||
phone_number: j.ownr_ph1
|
phone_number: j.ownr_ph1,
|
||||||
|
transaction_time: (j.actual_delivery && moment(j.actual_delivery).tz(bodyshop.timezone).format("YYYYMMDD-HHmm")) || ""
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
allChatterObjects.push(...chatterObject);
|
||||||
const ret = converter.json2csv(chatterObject, { emptyFieldValue: "" });
|
|
||||||
|
|
||||||
allcsvsToUpload.push({
|
|
||||||
count: chatterObject.length,
|
|
||||||
csv: ret,
|
|
||||||
filename: `${bodyshop.shopname}_solicitation_${moment().format("YYYYMMDD")}.csv`
|
|
||||||
});
|
|
||||||
|
|
||||||
logger.log("chatter-end-shop-extract", "DEBUG", "api", bodyshop.id, {
|
logger.log("chatter-end-shop-extract", "DEBUG", "api", bodyshop.id, {
|
||||||
shopname: bodyshop.shopname
|
shopname: bodyshop.shopname
|
||||||
});
|
});
|
||||||
@@ -162,7 +155,7 @@ async function getPrivateKey() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function uploadViaSFTP(allcsvsToUpload) {
|
async function uploadViaSFTP(csvToUpload) {
|
||||||
const sftp = new Client();
|
const sftp = new Client();
|
||||||
sftp.on("error", (errors) =>
|
sftp.on("error", (errors) =>
|
||||||
logger.log("chatter-sftp-connection-error", "ERROR", "api", null, { error: errors.message, stack: errors.stack })
|
logger.log("chatter-sftp-connection-error", "ERROR", "api", null, { error: errors.message, stack: errors.stack })
|
||||||
@@ -174,22 +167,19 @@ async function uploadViaSFTP(allcsvsToUpload) {
|
|||||||
//Connect to the FTP and upload all.
|
//Connect to the FTP and upload all.
|
||||||
await sftp.connect({ ...ftpSetup, privateKey });
|
await sftp.connect({ ...ftpSetup, privateKey });
|
||||||
|
|
||||||
for (const csvObj of allcsvsToUpload) {
|
try {
|
||||||
try {
|
csvToUpload.result = await sftp.put(Buffer.from(csvToUpload.csv), `${csvToUpload.filename}`);
|
||||||
logger.log("chatter-sftp-upload", "DEBUG", "api", null, { filename: csvObj.filename });
|
logger.log("chatter-sftp-upload", "DEBUG", "api", null, {
|
||||||
csvObj.result = await sftp.put(Buffer.from(csvObj.csv), `${csvObj.filename}`);
|
filename: csvToUpload.filename,
|
||||||
logger.log("chatter-sftp-upload-result", "DEBUG", "api", null, {
|
result: csvToUpload.result
|
||||||
filename: csvObj.filename,
|
});
|
||||||
result: csvObj.result
|
} catch (error) {
|
||||||
});
|
logger.log("chatter-sftp-upload-error", "ERROR", "api", null, {
|
||||||
} catch (error) {
|
filename: csvToUpload.filename,
|
||||||
logger.log("chatter-sftp-upload-error", "ERROR", "api", null, {
|
error: csvToUpload.message,
|
||||||
filename: csvObj.filename,
|
stack: csvToUpload.stack
|
||||||
error: error.message,
|
});
|
||||||
stack: error.stack
|
throw error;
|
||||||
});
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log("chatter-sftp-error", "ERROR", "api", null, { error: error.message, stack: error.stack });
|
logger.log("chatter-sftp-error", "ERROR", "api", null, { error: error.message, stack: error.stack });
|
||||||
|
|||||||
@@ -24,176 +24,188 @@ const ftpSetup = {
|
|||||||
port: process.env.CLAIMSCORP_PORT,
|
port: process.env.CLAIMSCORP_PORT,
|
||||||
username: process.env.CLAIMSCORP_USER,
|
username: process.env.CLAIMSCORP_USER,
|
||||||
password: process.env.CLAIMSCORP_PASSWORD,
|
password: process.env.CLAIMSCORP_PASSWORD,
|
||||||
debug: (message, ...data) => logger.log(message, "DEBUG", "api", null, data),
|
debug: process.env.NODE_ENV !== "production"
|
||||||
|
? (message, ...data) => logger.log(message, "DEBUG", "api", null, data)
|
||||||
|
: () => {},
|
||||||
algorithms: {
|
algorithms: {
|
||||||
serverHostKey: ["ssh-rsa", "ssh-dss"]
|
serverHostKey: ["ssh-rsa", "ssh-dss", "rsa-sha2-256", "rsa-sha2-512", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384"]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const allxmlsToUpload = [];
|
||||||
|
const allErrors = [];
|
||||||
|
|
||||||
exports.default = async (req, res) => {
|
exports.default = async (req, res) => {
|
||||||
// Only process if in production environment.
|
// Only process if in production environment.
|
||||||
if (process.env.NODE_ENV !== "production") {
|
if (process.env.NODE_ENV !== "production") {
|
||||||
res.sendStatus(403);
|
res.sendStatus(403);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Only process if the appropriate token is provided.
|
||||||
//Query for the List of Bodyshop Clients.
|
|
||||||
logger.log("claimscorp-start", "DEBUG", "api", null, null);
|
|
||||||
const { bodyshops } = await client.request(queries.GET_CLAIMSCORP_SHOPS);
|
|
||||||
|
|
||||||
const specificShopIds = req.body.bodyshopIds; // ['uuid]
|
|
||||||
const { start, end, skipUpload } = req.body; //YYYY-MM-DD
|
|
||||||
if (req.headers["x-imex-auth"] !== process.env.AUTOHOUSE_AUTH_TOKEN) {
|
if (req.headers["x-imex-auth"] !== process.env.AUTOHOUSE_AUTH_TOKEN) {
|
||||||
res.sendStatus(401);
|
res.sendStatus(401);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const allxmlsToUpload = [];
|
|
||||||
const allErrors = [];
|
// Send immediate response and continue processing.
|
||||||
|
res.status(202).json({
|
||||||
|
success: true,
|
||||||
|
message: "Processing request ...",
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const bodyshop of specificShopIds ? bodyshops.filter((b) => specificShopIds.includes(b.id)) : bodyshops) {
|
logger.log("claimscorp-start", "DEBUG", "api", null, null);
|
||||||
|
const { bodyshops } = await client.request(queries.GET_CLAIMSCORP_SHOPS); //Query for the List of Bodyshop Clients.
|
||||||
|
const specificShopIds = req.body.bodyshopIds; // ['uuid];
|
||||||
|
const { start, end, skipUpload } = req.body; //YYYY-MM-DD
|
||||||
|
|
||||||
|
const batchSize = 10;
|
||||||
|
|
||||||
|
const shopsToProcess =
|
||||||
|
specificShopIds?.length > 0 ? bodyshops.filter((shop) => specificShopIds.includes(shop.id)) : bodyshops;
|
||||||
|
logger.log("claimscorp-shopsToProcess-generated", "DEBUG", "api", null, null);
|
||||||
|
|
||||||
|
if (shopsToProcess.length === 0) {
|
||||||
|
logger.log("claimscorp-shopsToProcess-empty", "DEBUG", "api", null, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const batchPromises = [];
|
||||||
|
for (let i = 0; i < shopsToProcess.length; i += batchSize) {
|
||||||
|
const batch = shopsToProcess.slice(i, i + batchSize);
|
||||||
|
const batchPromise = (async () => {
|
||||||
|
await processBatch(batch, start, end);
|
||||||
|
|
||||||
|
if (skipUpload) {
|
||||||
|
for (const xmlObj of allxmlsToUpload) {
|
||||||
|
fs.writeFileSync(`./logs/${xmlObj.filename}`, xmlObj.xml);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await uploadViaSFTP(allxmlsToUpload);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
batchPromises.push(batchPromise);
|
||||||
|
}
|
||||||
|
await Promise.all(batchPromises);
|
||||||
|
await sendServerEmail({
|
||||||
|
subject: `ClaimsCorp Report ${moment().format("MM-DD-YY")}`,
|
||||||
|
text: `Errors:\n${JSON.stringify(allErrors, null, 2)}\n\nUploaded:\n${JSON.stringify(
|
||||||
|
allxmlsToUpload.map((x) => ({ filename: x.filename, count: x.count, result: x.result })),
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)}`
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.log("claimscorp-end", "DEBUG", "api", null, null);
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("claimscorp-error", "ERROR", "api", null, { error: error.message, stack: error.stack });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function processBatch(batch, start, end) {
|
||||||
|
for (const bodyshop of batch) {
|
||||||
|
const erroredJobs = [];
|
||||||
|
try {
|
||||||
logger.log("claimscorp-start-shop-extract", "DEBUG", "api", bodyshop.id, {
|
logger.log("claimscorp-start-shop-extract", "DEBUG", "api", bodyshop.id, {
|
||||||
shopname: bodyshop.shopname
|
shopname: bodyshop.shopname
|
||||||
});
|
});
|
||||||
const erroredJobs = [];
|
|
||||||
try {
|
|
||||||
const { jobs, bodyshops_by_pk } = await client.request(queries.CLAIMSCORP_QUERY, {
|
|
||||||
bodyshopid: bodyshop.id,
|
|
||||||
start: start ? moment(start).startOf("day") : moment().subtract(5, "days").startOf("day"),
|
|
||||||
...(end && { end: moment(end).endOf("day") })
|
|
||||||
});
|
|
||||||
|
|
||||||
const claimsCorpObject = {
|
const { jobs, bodyshops_by_pk } = await client.request(queries.CLAIMSCORP_QUERY, {
|
||||||
DataFeed: {
|
bodyshopid: bodyshop.id,
|
||||||
ShopInfo: {
|
start: start ? moment(start).startOf("day") : moment().subtract(5, "days").startOf("day"),
|
||||||
ShopID: bodyshops_by_pk.claimscorpid,
|
...(end && { end: moment(end).endOf("day") })
|
||||||
ShopName: bodyshops_by_pk.shopname,
|
|
||||||
RO: jobs.map((j) =>
|
|
||||||
CreateRepairOrderTag({ ...j, bodyshop: bodyshops_by_pk }, function ({ job, error }) {
|
|
||||||
erroredJobs.push({ job: job, error: error.toString() });
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (erroredJobs.length > 0) {
|
|
||||||
logger.log("claimscorp-failed-jobs", "ERROR", "api", bodyshop.id, {
|
|
||||||
count: erroredJobs.length,
|
|
||||||
jobs: JSON.stringify(erroredJobs.map((j) => j.job.ro_number))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var ret = builder
|
|
||||||
.create(
|
|
||||||
{
|
|
||||||
// version: "1.0",
|
|
||||||
// encoding: "UTF-8",
|
|
||||||
//keepNullNodes: true,
|
|
||||||
},
|
|
||||||
claimsCorpObject
|
|
||||||
)
|
|
||||||
.end({ allowEmptyTags: true });
|
|
||||||
|
|
||||||
allxmlsToUpload.push({
|
|
||||||
count: claimsCorpObject.DataFeed.ShopInfo.RO.length,
|
|
||||||
xml: ret,
|
|
||||||
filename: `${bodyshop.claimscorpid}-${moment().format("YYYYMMDDTHHMMss")}.xml`
|
|
||||||
});
|
|
||||||
|
|
||||||
logger.log("claimscorp-end-shop-extract", "DEBUG", "api", bodyshop.id, {
|
|
||||||
shopname: bodyshop.shopname
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
//Error at the shop level.
|
|
||||||
logger.log("claimscorp-error-shop", "ERROR", "api", bodyshop.id, {
|
|
||||||
...error
|
|
||||||
});
|
|
||||||
|
|
||||||
allErrors.push({
|
|
||||||
bodyshopid: bodyshop.id,
|
|
||||||
imexshopid: bodyshop.imexshopid,
|
|
||||||
claimscorpid: bodyshop.claimscorpid,
|
|
||||||
fatal: true,
|
|
||||||
errors: [error.toString()]
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
allErrors.push({
|
|
||||||
bodyshopid: bodyshop.id,
|
|
||||||
imexshopid: bodyshop.imexshopid,
|
|
||||||
claimscorpid: bodyshop.claimscorpid,
|
|
||||||
errors: erroredJobs.map((ej) => ({
|
|
||||||
ro_number: ej.job?.ro_number,
|
|
||||||
jobid: ej.job?.id,
|
|
||||||
error: ej.error
|
|
||||||
}))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skipUpload) {
|
|
||||||
for (const xmlObj of allxmlsToUpload) {
|
|
||||||
fs.writeFileSync(`./logs/${xmlObj.filename}`, xmlObj.xml);
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(allxmlsToUpload);
|
|
||||||
sendServerEmail({
|
|
||||||
subject: `ClaimsCorp Report ${moment().format("MM-DD-YY")}`,
|
|
||||||
text: `Errors: ${allErrors.map((e) => JSON.stringify(e, null, 2))}
|
|
||||||
Uploaded: ${JSON.stringify(
|
|
||||||
allxmlsToUpload.map((x) => ({ filename: x.filename, count: x.count })),
|
|
||||||
null,
|
|
||||||
2
|
|
||||||
)}
|
|
||||||
`
|
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let sftp = new Client();
|
const claimsCorpObject = {
|
||||||
sftp.on("error", (errors) =>
|
DataFeed: {
|
||||||
logger.log("claimscorp-sftp-error", "ERROR", "api", null, {
|
ShopInfo: {
|
||||||
...errors
|
ShopID: bodyshops_by_pk.claimscorpid,
|
||||||
})
|
ShopName: bodyshops_by_pk.shopname,
|
||||||
);
|
RO: jobs.map((j) =>
|
||||||
try {
|
CreateRepairOrderTag({ ...j, bodyshop: bodyshops_by_pk }, function ({ job, error }) {
|
||||||
//Connect to the FTP and upload all.
|
erroredJobs.push({ job: job, error: error.toString() });
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
await sftp.connect(ftpSetup);
|
if (erroredJobs.length > 0) {
|
||||||
|
logger.log("claimscorp-failed-jobs", "ERROR", "api", bodyshop.id, {
|
||||||
for (const xmlObj of allxmlsToUpload) {
|
count: erroredJobs.length,
|
||||||
logger.log("claimscorp-sftp-upload", "DEBUG", "api", null, {
|
jobs: JSON.stringify(erroredJobs.map((j) => j.job.ro_number))
|
||||||
filename: xmlObj.filename
|
|
||||||
});
|
|
||||||
|
|
||||||
const uploadResult = await sftp.put(Buffer.from(xmlObj.xml), `/${xmlObj.filename}`);
|
|
||||||
logger.log("claimscorp-sftp-upload-result", "DEBUG", "api", null, {
|
|
||||||
uploadResult
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//***TODO Change filing naming when creating the cron job. IM_ShopInternalName_DDMMYYYY_HHMMSS.xml
|
const ret = builder.create({}, claimsCorpObject).end({ allowEmptyTags: true });
|
||||||
|
|
||||||
|
allxmlsToUpload.push({
|
||||||
|
count: claimsCorpObject.DataFeed.ShopInfo.RO.length,
|
||||||
|
xml: ret,
|
||||||
|
filename: `${bodyshop.claimscorpid}-${moment().format("YYYYMMDDTHHMMss")}.xml`
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.log("claimscorp-end-shop-extract", "DEBUG", "api", bodyshop.id, {
|
||||||
|
shopname: bodyshop.shopname
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log("claimscorp-sftp-error", "ERROR", "api", null, {
|
//Error at the shop level.
|
||||||
...error
|
logger.log("claimscorp-error-shop", "ERROR", "api", bodyshop.id, { error: error.message, stack: error.stack });
|
||||||
|
|
||||||
|
allErrors.push({
|
||||||
|
bodyshopid: bodyshop.id,
|
||||||
|
imexshopid: bodyshop.imexshopid,
|
||||||
|
claimscorpid: bodyshop.claimscorpid,
|
||||||
|
fatal: true,
|
||||||
|
errors: [error.toString()]
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
sftp.end();
|
allErrors.push({
|
||||||
|
bodyshopid: bodyshop.id,
|
||||||
|
imexshopid: bodyshop.imexshopid,
|
||||||
|
claimscorpid: bodyshop.claimscorpid,
|
||||||
|
errors: erroredJobs.map((ej) => ({
|
||||||
|
ro_number: ej.job?.ro_number,
|
||||||
|
jobid: ej.job?.id,
|
||||||
|
error: ej.error
|
||||||
|
}))
|
||||||
|
});
|
||||||
}
|
}
|
||||||
sendServerEmail({
|
|
||||||
subject: `ClaimsCorp Report ${moment().format("MM-DD-YY")}`,
|
|
||||||
text: `Errors: ${allErrors.map((e) => JSON.stringify(e, null, 2))}
|
|
||||||
Uploaded: ${JSON.stringify(
|
|
||||||
allxmlsToUpload.map((x) => ({ filename: x.filename, count: x.count })),
|
|
||||||
null,
|
|
||||||
2
|
|
||||||
)}
|
|
||||||
`
|
|
||||||
});
|
|
||||||
res.sendStatus(200);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(200).json(error);
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
async function uploadViaSFTP(allxmlsToUpload) {
|
||||||
|
const sftp = new Client();
|
||||||
|
sftp.on("error", (errors) =>
|
||||||
|
logger.log("claimscorp-sftp-connection-error", "ERROR", "api", null, { error: errors.message, stack: errors.stack })
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
//Connect to the FTP and upload all.
|
||||||
|
await sftp.connect(ftpSetup);
|
||||||
|
|
||||||
|
for (const xmlObj of allxmlsToUpload) {
|
||||||
|
try {
|
||||||
|
xmlObj.result = await sftp.put(Buffer.from(xmlObj.xml), `${xmlObj.filename}`);
|
||||||
|
logger.log("claimscorp-sftp-upload", "DEBUG", "api", null, {
|
||||||
|
filename: xmlObj.filename,
|
||||||
|
result: xmlObj.result
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("claimscorp-sftp-upload-error", "ERROR", "api", null, {
|
||||||
|
filename: xmlObj.filename,
|
||||||
|
error: error.message,
|
||||||
|
stack: error.stack
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("claimscorp-sftp-error", "ERROR", "api", null, { error: error.message, stack: error.stack });
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
sftp.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const CreateRepairOrderTag = (job, errorCallback) => {
|
const CreateRepairOrderTag = (job, errorCallback) => {
|
||||||
//Level 2
|
//Level 2
|
||||||
@@ -445,10 +457,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
|||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log("claimscorp-job-calculate-error", "ERROR", "api", null, {
|
logger.log("claimscorp-job-calculate-error", "ERROR", "api", null, { error: error.message, stack: error.stack });
|
||||||
error
|
|
||||||
});
|
|
||||||
|
|
||||||
errorCallback({ jobid: job.id, ro_number: job.ro_number, error });
|
errorCallback({ jobid: job.id, ro_number: job.ro_number, error });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,187 +16,194 @@ const { sendServerEmail } = require("../email/sendemail");
|
|||||||
const DineroFormat = "0,0.00";
|
const DineroFormat = "0,0.00";
|
||||||
const DateFormat = "MM/DD/YYYY";
|
const DateFormat = "MM/DD/YYYY";
|
||||||
|
|
||||||
const repairOpCodes = ["OP4", "OP9", "OP10"];
|
const kaizenShopsIDs = ["SUMMIT", "STRATHMORE", "SUNRIDGE", "SHAW"];
|
||||||
const replaceOpCodes = ["OP2", "OP5", "OP11", "OP12"];
|
|
||||||
|
|
||||||
const ftpSetup = {
|
const ftpSetup = {
|
||||||
host: process.env.KAIZEN_HOST,
|
host: process.env.KAIZEN_HOST,
|
||||||
port: process.env.KAIZEN_PORT,
|
port: process.env.KAIZEN_PORT,
|
||||||
username: process.env.KAIZEN_USER,
|
username: process.env.KAIZEN_USER,
|
||||||
password: process.env.KAIZEN_PASSWORD,
|
password: process.env.KAIZEN_PASSWORD,
|
||||||
debug: (message, ...data) => logger.log(message, "DEBUG", "api", null, data),
|
debug: process.env.NODE_ENV !== "production"
|
||||||
|
? (message, ...data) => logger.log(message, "DEBUG", "api", null, data)
|
||||||
|
: () => {},
|
||||||
algorithms: {
|
algorithms: {
|
||||||
serverHostKey: ["ssh-rsa", "ssh-dss", "rsa-sha2-256", "rsa-sha2-512", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384"]
|
serverHostKey: ["ssh-rsa", "ssh-dss", "rsa-sha2-256", "rsa-sha2-512", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384"]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const allxmlsToUpload = [];
|
||||||
|
const allErrors = [];
|
||||||
|
|
||||||
exports.default = async (req, res) => {
|
exports.default = async (req, res) => {
|
||||||
// Only process if in production environment.
|
// Only process if in production environment.
|
||||||
if (process.env.NODE_ENV !== "production") {
|
if (process.env.NODE_ENV !== "production") {
|
||||||
res.sendStatus(403);
|
res.sendStatus(403);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Only process if the appropriate token is provided.
|
||||||
//Query for the List of Bodyshop Clients.
|
|
||||||
logger.log("kaizen-start", "DEBUG", "api", null, null);
|
|
||||||
const kaizenShopsIDs = ["SUMMIT", "STRATHMORE", "SUNRIDGE", "SHAW"];
|
|
||||||
|
|
||||||
const { bodyshops } = await client.request(queries.GET_KAIZEN_SHOPS, {
|
|
||||||
imexshopid: kaizenShopsIDs
|
|
||||||
});
|
|
||||||
|
|
||||||
const specificShopIds = req.body.bodyshopIds; // ['uuid]
|
|
||||||
const { start, end, skipUpload } = req.body; //YYYY-MM-DD
|
|
||||||
if (req.headers["x-imex-auth"] !== process.env.AUTOHOUSE_AUTH_TOKEN) {
|
if (req.headers["x-imex-auth"] !== process.env.AUTOHOUSE_AUTH_TOKEN) {
|
||||||
res.sendStatus(401);
|
res.sendStatus(401);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const allxmlsToUpload = [];
|
|
||||||
const allErrors = [];
|
// Send immediate response and continue processing.
|
||||||
|
res.status(202).json({
|
||||||
|
success: true,
|
||||||
|
message: "Processing request ...",
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const bodyshop of specificShopIds ? bodyshops.filter((b) => specificShopIds.includes(b.id)) : bodyshops) {
|
logger.log("kaizen-start", "DEBUG", "api", null, null);
|
||||||
|
const { bodyshops } = await client.request(queries.GET_KAIZEN_SHOPS, { imexshopid: kaizenShopsIDs }); //Query for the List of Bodyshop Clients.
|
||||||
|
const specificShopIds = req.body.bodyshopIds; // ['uuid];
|
||||||
|
const { start, end, skipUpload } = req.body; //YYYY-MM-DD
|
||||||
|
|
||||||
|
const batchSize = 10;
|
||||||
|
|
||||||
|
const shopsToProcess =
|
||||||
|
specificShopIds?.length > 0 ? bodyshops.filter((shop) => specificShopIds.includes(shop.id)) : bodyshops;
|
||||||
|
logger.log("kaizen-shopsToProcess-generated", "DEBUG", "api", null, null);
|
||||||
|
|
||||||
|
if (shopsToProcess.length === 0) {
|
||||||
|
logger.log("kaizen-shopsToProcess-empty", "DEBUG", "api", null, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const batchPromises = [];
|
||||||
|
for (let i = 0; i < shopsToProcess.length; i += batchSize) {
|
||||||
|
const batch = shopsToProcess.slice(i, i + batchSize);
|
||||||
|
const batchPromise = (async () => {
|
||||||
|
await processBatch(batch, start, end);
|
||||||
|
|
||||||
|
if (skipUpload) {
|
||||||
|
for (const xmlObj of allxmlsToUpload) {
|
||||||
|
fs.writeFileSync(`./logs/${xmlObj.filename}`, xmlObj.xml);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await uploadViaSFTP(allxmlsToUpload);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
batchPromises.push(batchPromise);
|
||||||
|
}
|
||||||
|
await Promise.all(batchPromises);
|
||||||
|
await sendServerEmail({
|
||||||
|
subject: `Kaizen Report ${moment().format("MM-DD-YY")}`,
|
||||||
|
text: `Errors:\n${JSON.stringify(allErrors, null, 2)}\n\nUploaded:\n${JSON.stringify(
|
||||||
|
allxmlsToUpload.map((x) => ({ filename: x.filename, count: x.count, result: x.result })),
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)}`
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.log("kaizen-end", "DEBUG", "api", null, null);
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("kaizen-error", "ERROR", "api", null, { error: error.message, stack: error.stack });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function processBatch(batch, start, end) {
|
||||||
|
for (const bodyshop of batch) {
|
||||||
|
const erroredJobs = [];
|
||||||
|
try {
|
||||||
logger.log("kaizen-start-shop-extract", "DEBUG", "api", bodyshop.id, {
|
logger.log("kaizen-start-shop-extract", "DEBUG", "api", bodyshop.id, {
|
||||||
shopname: bodyshop.shopname
|
shopname: bodyshop.shopname
|
||||||
});
|
});
|
||||||
const erroredJobs = [];
|
|
||||||
try {
|
|
||||||
const { jobs, bodyshops_by_pk } = await client.request(queries.KAIZEN_QUERY, {
|
|
||||||
bodyshopid: bodyshop.id,
|
|
||||||
start: start ? moment(start).startOf("day") : moment().subtract(5, "days").startOf("day"),
|
|
||||||
...(end && { end: moment(end).endOf("day") })
|
|
||||||
});
|
|
||||||
|
|
||||||
const kaizenObject = {
|
const { jobs, bodyshops_by_pk } = await client.request(queries.KAIZEN_QUERY, {
|
||||||
DataFeed: {
|
bodyshopid: bodyshop.id,
|
||||||
ShopInfo: {
|
start: start ? moment(start).startOf("day") : moment().subtract(5, "days").startOf("day"),
|
||||||
ShopName: bodyshops_by_pk.shopname,
|
...(end && { end: moment(end).endOf("day") })
|
||||||
Jobs: jobs.map((j) =>
|
|
||||||
CreateRepairOrderTag({ ...j, bodyshop: bodyshops_by_pk }, function ({ job, error }) {
|
|
||||||
erroredJobs.push({ job: job, error: error.toString() });
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (erroredJobs.length > 0) {
|
|
||||||
logger.log("kaizen-failed-jobs", "ERROR", "api", bodyshop.id, {
|
|
||||||
count: erroredJobs.length,
|
|
||||||
jobs: JSON.stringify(erroredJobs.map((j) => j.job.ro_number))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var ret = builder
|
|
||||||
.create(
|
|
||||||
{
|
|
||||||
// version: "1.0",
|
|
||||||
// encoding: "UTF-8",
|
|
||||||
//keepNullNodes: true,
|
|
||||||
},
|
|
||||||
kaizenObject
|
|
||||||
)
|
|
||||||
.end({ allowEmptyTags: true });
|
|
||||||
|
|
||||||
allxmlsToUpload.push({
|
|
||||||
count: kaizenObject.DataFeed.ShopInfo.Jobs.length,
|
|
||||||
xml: ret,
|
|
||||||
filename: `${bodyshop.shopname}-${moment().format("YYYYMMDDTHHMMss")}.xml`
|
|
||||||
});
|
|
||||||
|
|
||||||
logger.log("kaizen-end-shop-extract", "DEBUG", "api", bodyshop.id, {
|
|
||||||
shopname: bodyshop.shopname
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
//Error at the shop level.
|
|
||||||
logger.log("kaizen-error-shop", "ERROR", "api", bodyshop.id, {
|
|
||||||
...error
|
|
||||||
});
|
|
||||||
|
|
||||||
allErrors.push({
|
|
||||||
bodyshopid: bodyshop.id,
|
|
||||||
imexshopid: bodyshop.imexshopid,
|
|
||||||
shopname: bodyshop.shopname,
|
|
||||||
fatal: true,
|
|
||||||
errors: [error.toString()]
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
allErrors.push({
|
|
||||||
bodyshopid: bodyshop.id,
|
|
||||||
imexshopid: bodyshop.imexshopid,
|
|
||||||
shopname: bodyshop.shopname,
|
|
||||||
errors: erroredJobs.map((ej) => ({
|
|
||||||
ro_number: ej.job?.ro_number,
|
|
||||||
jobid: ej.job?.id,
|
|
||||||
error: ej.error
|
|
||||||
}))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skipUpload) {
|
|
||||||
for (const xmlObj of allxmlsToUpload) {
|
|
||||||
fs.writeFileSync(`./logs/${xmlObj.filename}`, xmlObj.xml);
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(allxmlsToUpload);
|
|
||||||
sendServerEmail({
|
|
||||||
subject: `Kaizen Report ${moment().format("MM-DD-YY")}`,
|
|
||||||
text: `Errors: ${allErrors.map((e) => JSON.stringify(e, null, 2))}
|
|
||||||
Uploaded: ${JSON.stringify(
|
|
||||||
allxmlsToUpload.map((x) => ({ filename: x.filename, count: x.count })),
|
|
||||||
null,
|
|
||||||
2
|
|
||||||
)}
|
|
||||||
`
|
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let sftp = new Client();
|
const kaizenObject = {
|
||||||
sftp.on("error", (errors) =>
|
DataFeed: {
|
||||||
logger.log("kaizen-sftp-error", "ERROR", "api", null, {
|
ShopInfo: {
|
||||||
...errors
|
ShopName: bodyshops_by_pk.shopname,
|
||||||
})
|
Jobs: jobs.map((j) =>
|
||||||
);
|
CreateRepairOrderTag({ ...j, bodyshop: bodyshops_by_pk }, function ({ job, error }) {
|
||||||
try {
|
erroredJobs.push({ job: job, error: error.toString() });
|
||||||
//Connect to the FTP and upload all.
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
await sftp.connect(ftpSetup);
|
if (erroredJobs.length > 0) {
|
||||||
|
logger.log("kaizen-failed-jobs", "ERROR", "api", bodyshop.id, {
|
||||||
for (const xmlObj of allxmlsToUpload) {
|
count: erroredJobs.length,
|
||||||
logger.log("kaizen-sftp-upload", "DEBUG", "api", null, {
|
jobs: JSON.stringify(erroredJobs.map((j) => j.job.ro_number))
|
||||||
filename: xmlObj.filename
|
|
||||||
});
|
|
||||||
|
|
||||||
const uploadResult = await sftp.put(Buffer.from(xmlObj.xml), `/${xmlObj.filename}`);
|
|
||||||
logger.log("kaizen-sftp-upload-result", "DEBUG", "api", null, {
|
|
||||||
uploadResult
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//***TODO Change filing naming when creating the cron job. IM_ShopInternalName_DDMMYYYY_HHMMSS.xml
|
const ret = builder.create({}, kaizenObject).end({ allowEmptyTags: true });
|
||||||
|
|
||||||
|
allxmlsToUpload.push({
|
||||||
|
count: kaizenObject.DataFeed.ShopInfo.Jobs.length,
|
||||||
|
xml: ret,
|
||||||
|
filename: `${bodyshop.shopname}-${moment().format("YYYYMMDDTHHMMss")}.xml`
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.log("kaizen-end-shop-extract", "DEBUG", "api", bodyshop.id, {
|
||||||
|
shopname: bodyshop.shopname
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log("kaizen-sftp-error", "ERROR", "api", null, {
|
//Error at the shop level.
|
||||||
...error
|
logger.log("kaizen-error-shop", "ERROR", "api", bodyshop.id, { error: error.message, stack: error.stack });
|
||||||
|
|
||||||
|
allErrors.push({
|
||||||
|
bodyshopid: bodyshop.id,
|
||||||
|
imexshopid: bodyshop.imexshopid,
|
||||||
|
shopname: bodyshop.shopname,
|
||||||
|
fatal: true,
|
||||||
|
errors: [error.toString()]
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
sftp.end();
|
allErrors.push({
|
||||||
|
bodyshopid: bodyshop.id,
|
||||||
|
imexshopid: bodyshop.imexshopid,
|
||||||
|
shopname: bodyshop.shopname,
|
||||||
|
errors: erroredJobs.map((ej) => ({
|
||||||
|
ro_number: ej.job?.ro_number,
|
||||||
|
jobid: ej.job?.id,
|
||||||
|
error: ej.error
|
||||||
|
}))
|
||||||
|
});
|
||||||
}
|
}
|
||||||
sendServerEmail({
|
|
||||||
subject: `Kaizen Report ${moment().format("MM-DD-YY")}`,
|
|
||||||
text: `Errors: ${allErrors.map((e) => JSON.stringify(e, null, 2))}
|
|
||||||
Uploaded: ${JSON.stringify(
|
|
||||||
allxmlsToUpload.map((x) => ({ filename: x.filename, count: x.count })),
|
|
||||||
null,
|
|
||||||
2
|
|
||||||
)}
|
|
||||||
`
|
|
||||||
});
|
|
||||||
res.sendStatus(200);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(200).json(error);
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
async function uploadViaSFTP(allxmlsToUpload) {
|
||||||
|
const sftp = new Client();
|
||||||
|
sftp.on("error", (errors) =>
|
||||||
|
logger.log("kaizen-sftp-connection-error", "ERROR", "api", null, { error: errors.message, stack: errors.stack })
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
//Connect to the FTP and upload all.
|
||||||
|
await sftp.connect(ftpSetup);
|
||||||
|
|
||||||
|
for (const xmlObj of allxmlsToUpload) {
|
||||||
|
try {
|
||||||
|
xmlObj.result = await sftp.put(Buffer.from(xmlObj.xml), `${xmlObj.filename}`);
|
||||||
|
logger.log("kaizen-sftp-upload", "DEBUG", "api", null, {
|
||||||
|
filename: xmlObj.filename,
|
||||||
|
result: xmlObj.result
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("kaizen-sftp-upload-error", "ERROR", "api", null, {
|
||||||
|
filename: xmlObj.filename,
|
||||||
|
error: error.message,
|
||||||
|
stack: error.stack
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("kaizen-sftp-error", "ERROR", "api", null, { error: error.message, stack: error.stack });
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
sftp.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const CreateRepairOrderTag = (job, errorCallback) => {
|
const CreateRepairOrderTag = (job, errorCallback) => {
|
||||||
//Level 2
|
//Level 2
|
||||||
@@ -420,10 +427,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
|||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log("kaizen-job-calculate-error", "ERROR", "api", null, {
|
logger.log("kaizen-job-calculate-error", "ERROR", "api", null, { error: error.message, stack: error.stack });
|
||||||
error
|
|
||||||
});
|
|
||||||
|
|
||||||
errorCallback({ jobid: job.id, ro_number: job.ro_number, error });
|
errorCallback({ jobid: job.id, ro_number: job.ro_number, error });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -840,6 +840,7 @@ exports.CHATTER_QUERY = `query CHATTER_EXPORT($start: timestamptz, $bodyshopid:
|
|||||||
timezone
|
timezone
|
||||||
}
|
}
|
||||||
jobs(where: {_and: [{converted: {_eq: true}}, {actual_delivery: {_gt: $start}}, {actual_delivery: {_lte: $end}}, {shopid: {_eq: $bodyshopid}}, {_or: [{ownr_ph1: {_is_null: false}}, {ownr_ea: {_is_null: false}}]}]}) {
|
jobs(where: {_and: [{converted: {_eq: true}}, {actual_delivery: {_gt: $start}}, {actual_delivery: {_lte: $end}}, {shopid: {_eq: $bodyshopid}}, {_or: [{ownr_ph1: {_is_null: false}}, {ownr_ea: {_is_null: false}}]}]}) {
|
||||||
|
actual_delivery
|
||||||
id
|
id
|
||||||
created_at
|
created_at
|
||||||
ro_number
|
ro_number
|
||||||
|
|||||||
@@ -95,14 +95,14 @@ const createS3Client = () => {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
uploadFileToS3,
|
uploadFileToS3,
|
||||||
downloadFileFromS3,
|
downloadFileFromS3,
|
||||||
listFilesInS3Bucket,
|
listFilesInS3Bucket,
|
||||||
deleteFileFromS3,
|
deleteFileFromS3,
|
||||||
copyFileInS3,
|
copyFileInS3,
|
||||||
fileExistsInS3
|
fileExistsInS3,
|
||||||
|
...s3Client
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user