Compare commits

..

200 Commits

Author SHA1 Message Date
Allan Carr
44f2287b07 IO-2295 Individual Note Print File Name contained {{ro_number}} 2023-05-23 13:38:55 -07:00
Patrick Fic
8f91416623 Merged in release/2023-05-19 (pull request #796)
Release/2023 05 19
2023-05-19 17:17:47 +00:00
Allan Carr
a18dbbb6c4 Merged in feature/IO-2293-Autohouse-Job-Cost-Dinero-Type-Cast (pull request #794)
IO-2293 Autohouse & Job Costing Dinero Type Casting

Approved-by: Patrick Fic
2023-05-19 17:02:05 +00:00
Allan Carr
57d8ca5829 IO-2293 Autohouse & Job Costing Dinero Type Casting
All type cast to Dinero round to integer to prevent cast errors
2023-05-19 09:39:37 -07:00
Patrick Fic
4c6a2d6d63 Merged in release/2023-05-19 (pull request #793)
Release/2023 05 19
2023-05-18 22:05:08 +00:00
Patrick Fic
5861d0e9b6 IO-2289 Add betterment description to translation 2023-05-17 13:46:37 -07:00
Patrick Fic
e36904794b IO-2274 Add typing to notes. 2023-05-17 13:31:15 -07:00
Patrick Fic
1c89d12034 IO-2286 Resolve duplication of cost centers when sorting labor allocations. 2023-05-17 12:36:15 -07:00
Patrick Fic
5e36a4ae89 IO-2275 Remove PVRT and GST References in USA App. 2023-05-17 12:09:21 -07:00
Patrick Fic
f553307587 Added rounding to job costing for adjustments. 2023-05-17 10:11:27 -07:00
Patrick Fic
2c80c81197 Added tasks presets to database schema. 2023-05-17 07:39:23 -07:00
Patrick Fic
9d865cf130 Merged in release/2023-05-19 (pull request #789)
IO-2258 Scoreboard Chart
2023-05-16 18:34:13 +00:00
Allan Carr
8e119ce0dd Merged in feature/IO-2258-Scoreboard-Chart-Inconsistencies (pull request #788)
IO-2258 Scoreboard Chart

Approved-by: Patrick Fic
2023-05-16 18:33:34 +00:00
Allan Carr
fe49161718 IO-2258 Scoreboard Chart
Add in target paint and body to the overall calculation to bump the start value up to the target instead of zero.
2023-05-15 15:18:24 -07:00
Patrick Fic
040e366335 Merged in release/2023-05-12 (pull request #786)
Release/2023 05 12
2023-05-12 18:18:04 +00:00
Patrick Fic
4655663dd8 Merged in release/2023-05-12 (pull request #785)
Release/2023 05 12
2023-05-12 17:14:31 +00:00
Allan Carr
6e1fbda79b Merged in feature/IO-2261-opensearch-replacements (pull request #784)
IO-2261 Add missing fields to return querys

Approved-by: Patrick Fic
2023-05-12 17:14:04 +00:00
Allan Carr
b2f616f1eb IO-2261 Add missing fields to return querys
Customer info missing on return
2023-05-12 10:12:49 -07:00
Patrick Fic
76eec7bebc Merged in release/2023-05-12 (pull request #783)
IO-2261 Remove duplicate fields and add created_at into return querys
2023-05-12 16:32:51 +00:00
Allan Carr
aa5f405e1b Merged in feature/IO-2261-opensearch-replacements (pull request #782)
IO-2261 Remove duplicate fields and add created_at into return querys

Approved-by: Patrick Fic
2023-05-12 15:26:05 +00:00
Allan Carr
ca9752d119 IO-2261 Remove duplicate fields and add created_at into return querys 2023-05-12 08:23:16 -07:00
Patrick Fic
45b4af5225 Merged in release/2023-05-12 (pull request #781)
Release/2023 05 12
2023-05-11 23:39:04 +00:00
Allan Carr
d2d310cf57 Merged in feature/IO-2190-Autohouse (pull request #780)
IO-2190 Paint Costs for JC if Cost/Hr is 0

Approved-by: Patrick Fic
2023-05-11 23:38:42 +00:00
Allan Carr
5d1a7657a9 Merged in feature/IO-2265-Autohouse-Extract (pull request #779)
IO-2190 Allow for 0 in JC/Hr rate

Approved-by: Patrick Fic
2023-05-11 23:38:25 +00:00
Allan Carr
5cb17994cd IO-2190 Allow for 0 in JC/Hr rate 2023-05-11 16:09:30 -07:00
Allan Carr
dab78e3dc9 IO-2190 Paint Costs for JC if Cost/Hr is 0 2023-05-11 16:07:28 -07:00
Patrick Fic
1232f28b3d Merged in release/2023-05-12 (pull request #778)
IO-2261 Modify Opensearch Data after payment update
2023-05-11 21:42:57 +00:00
Allan Carr
8e8d40d4b0 Merged in feature/IO-2261-opensearch-replacements (pull request #777)
IO-2261 Modify Opensearch Data after payment update

Approved-by: Patrick Fic
2023-05-11 21:42:24 +00:00
Allan Carr
7fae408454 IO-2261 Modify Opensearch Data after payment update 2023-05-11 14:38:09 -07:00
Patrick Fic
1cdafaa2cc Merged in release/2023-05-12 (pull request #776)
Release/2023 05 12
2023-05-11 14:50:33 +00:00
Allan Carr
b9ca7ef2e3 Merged in feature/IO-2271-Country-Region (pull request #775)
Feature/IO-2271 Country Region

Approved-by: Patrick Fic
2023-05-11 14:50:07 +00:00
Allan Carr
60867ae4dc IO-2271 Country Region Print Center Modification
Allow items to be hidden by Country Code only from region
2023-05-10 18:03:42 -07:00
Allan Carr
b0ddb62ac0 Merged in feature/IO-2265-Autohouse-Extract (pull request #773)
IO-2265 Autohouse Extract Remove Customer Info

Approved-by: Patrick Fic
2023-05-10 15:24:27 +00:00
Allan Carr
39a4646339 IO-2271 Country Region for Print Center
Hide reports based on Country Code for Region
2023-05-09 18:11:06 -07:00
Allan Carr
584322819f IO-2265 Autohouse Extract Remove Customer Info 2023-05-09 16:51:55 -07:00
Patrick Fic
051ee347a9 Merged in release/2023-05-05 (pull request #768)
Release/2023 05 05
2023-05-05 22:51:16 +00:00
Patrick Fic
acf1b387de Merged in release/2023-05-05 (pull request #767)
Release/2023 05 05
2023-05-05 22:03:21 +00:00
John Allen Delos Reyes
d350515c90 Merged in feature/IO-1722-job-size-color (pull request #763)
Feature/IO-1722 job size color

Approved-by: Patrick Fic
2023-05-05 22:02:55 +00:00
Allan Carr
121e579388 Merged in feature/IO-2261-opensearch-replacements (pull request #766)
IO-2261 Missing loader handler for owner_owing, correct payment

Approved-by: Patrick Fic
2023-05-05 22:02:03 +00:00
Allan Carr
cf5ebb8130 IO-2261 Missing loader for owner_owing 2023-05-05 14:24:00 -07:00
Allan Carr
2dabf3c811 IO-2261 Missing loader handler for owner_owing, correct payment 2023-05-05 14:03:05 -07:00
swtmply
04509fa587 IO-1722 adjusted logic for card color 2023-05-06 04:56:03 +08:00
swtmply
56fef0f43c IO-1722 Added reset button 2023-05-06 04:55:21 +08:00
Patrick Fic
42702ef015 Merged in release/2023-05-05 (pull request #765)
Release/2023 05 05
2023-05-05 20:19:03 +00:00
Allan Carr
25bee3cfdf Merged in feature/IO-2261-opensearch-replacements (pull request #764)
Feature/IO-2261 opensearch replacements

Approved-by: Patrick Fic
2023-05-05 20:14:02 +00:00
Allan Carr
baf06fee6c Merge branch 'feature/IO-2261-opensearch-replacements' of https://bitbucket.org/snaptsoft/bodyshop into feature/IO-2261-opensearch-replacements 2023-05-05 13:10:39 -07:00
Allan Carr
a3557bbc86 IO-2261 Add Delete function, Correct Payment edit, add Totals to Bills handler 2023-05-05 13:10:07 -07:00
swtmply
3e00e7981d IO-1722 added placement to popover 2023-05-06 03:34:55 +08:00
swtmply
12fa270a1a IO-1722 adjusted background colors 2023-05-06 03:34:22 +08:00
Patrick Fic
de250b152a Change all open search events to trigger on all fields. 2023-05-05 12:20:25 -07:00
Patrick Fic
c45741257f Add export trigger for os_bills event. 2023-05-05 12:16:39 -07:00
swtmply
3988386c79 IO-1722 replaced hex to rgba 2023-05-06 02:56:02 +08:00
Patrick Fic
492032c1e2 Merged in release/2023-05-05 (pull request #762)
Release/2023 05 05
2023-05-05 17:56:36 +00:00
Allan Carr
8222e56485 Merged in feature/IO-2261-opensearch-replacements (pull request #761)
IO-2261 Add in missing field "date" for Payments

Approved-by: Patrick Fic
2023-05-05 17:56:14 +00:00
Patrick Fic
49a61e1564 Merge branch 'feature/IO-2261-opensearch-replacements' of https://bitbucket.org/snaptsoft/bodyshop into feature/IO-2261-opensearch-replacements 2023-05-05 10:55:59 -07:00
Patrick Fic
eed18aa1c5 Add event triggers on export fields 2023-05-05 10:55:42 -07:00
Allan Carr
2de3f8b022 IO-2261 Add in missing field "date" for Payments 2023-05-05 10:54:41 -07:00
Patrick Fic
91476c7ad3 Merged in release/2023-05-05 (pull request #760)
Release/2023 05 05
2023-05-05 17:44:50 +00:00
John Allen Delos Reyes
00eb7926f9 Merged in feature/IO-2266-duplicate-option (pull request #759)
IO-2266 fixed key issue causing option to duplicate

Approved-by: Patrick Fic
2023-05-05 17:44:19 +00:00
Patrick Fic
854ad21b20 Update autohouse header auth. 2023-05-05 10:16:41 -07:00
swtmply
3c3f9521f6 IO-2266 fixed key issue causing option to duplicate 2023-05-05 23:43:48 +08:00
Patrick Fic
561bcf10d9 Merged in release/2023-05-05 (pull request #758)
IO-2261 All Jobs, Bills, Payments
2023-05-05 14:49:55 +00:00
Allan Carr
75d9faa05b Merged in feature/IO-2261-opensearch-replacements (pull request #757)
IO-2261 All Jobs, Bills, Payments

Approved-by: Patrick Fic
2023-05-05 14:49:23 +00:00
Allan Carr
ac72177fbb IO-2261 All Jobs, Bills, Payments
Adjust Pagination settings and on clear delete search.page to reset. Adjust payments for bodyshopid as it was pointed at bill instead of payment
2023-05-04 18:27:47 -07:00
Allan Carr
088faf152c Merged in release/2023-05-05 (pull request #756)
Release/2023 05 05

Approved-by: Patrick Fic
2023-05-04 22:33:12 +00:00
Patrick Fic
90cba9ed24 Merge branch 'feature/IO-1722-job-size-color' into release/2023-05-05 2023-05-04 15:32:30 -07:00
Patrick Fic
a0702785c5 Revert "Revert "Merged in feature/IO-1722-job-size-color (pull request #746)""
This reverts commit 7dc3c00628.
2023-05-04 15:32:21 -07:00
Allan Carr
6898d609fe IO-2261 Add Loading effect 2023-05-04 15:17:37 -07:00
Allan Carr
d70893e2ba Merged in feature/IO-2261-opensearch-replacements (pull request #748)
Feature/IO-2261 opensearch replacements
2023-05-04 22:16:49 +00:00
Patrick Fic
6155b8bf24 Merged in release/2023-05-05 (pull request #754)
Add firebase auth to JSR call.
2023-05-04 21:04:16 +00:00
Patrick Fic
239dc5c62d Merged in release/2023-05-05 (pull request #753)
Release/2023 05 05
2023-05-04 20:36:18 +00:00
Patrick Fic
2586855f11 Add firebase auth to JSR call. 2023-05-04 13:33:16 -07:00
Patrick Fic
b3b3c4c737 Merged in release/2023-05-05 (pull request #752)
Resolve health check
2023-05-04 20:26:04 +00:00
Patrick Fic
abe5fadeea Resolve health check 2023-05-04 13:25:45 -07:00
swtmply
08e5543536 IO-1722 adjusted condition for text color 2023-05-05 04:00:44 +08:00
Patrick Fic
f1a10e0df4 Merged in release/2023-05-05 (pull request #750)
Release/2023 05 05
2023-05-04 19:57:22 +00:00
Patrick Fic
7dc3c00628 Revert "Merged in feature/IO-1722-job-size-color (pull request #746)"
This reverts commit 7594f53e88, reversing
changes made to b861957342.
2023-05-04 12:50:28 -07:00
Patrick Fic
1c5c403d65 Merged in release/2023-05-05 (pull request #749)
Release/2023 05 05
2023-05-04 19:34:56 +00:00
John Allen Delos Reyes
7594f53e88 Merged in feature/IO-1722-job-size-color (pull request #746)
Feature/IO-1722 job size color

Approved-by: Patrick Fic
2023-05-04 19:03:30 +00:00
Patrick Fic
b861957342 Additional security hardening. 2023-05-04 11:59:39 -07:00
swtmply
2bf24ff5a1 IO-1722 refactor color function 2023-05-04 23:00:37 +08:00
Allan Carr
6e5fcbfdbd IO-2267 Remove Sort for Linked Table fields 2023-05-03 16:30:48 -07:00
Allan Carr
759a8ac58c IO-2261 Opensearch for Payments, Bills and All Jobs 2023-05-03 16:29:01 -07:00
swtmply
833baca9cc Merge branch 'feature/IO-1722-job-size-color' of https://bitbucket.org/snaptsoft/bodyshop into feature/IO-1722-job-size-color 2023-05-04 01:27:24 +08:00
swtmply
889ef61185 IO-1722 fixed spacing on translations 2023-05-04 01:25:17 +08:00
swtmply
add1eddbc1 IO-1722 added translations 2023-05-04 01:18:16 +08:00
Allan Carr
1c63aa39c4 Merged in release/2023-05-05 (pull request #744)
Release/2023 05 05
2023-05-03 17:10:48 +00:00
swtmply
0cabd80b94 IO-1722 job size color in production card 2023-05-04 00:39:50 +08:00
Patrick Fic
7f756bab88 Merged in feature/IO-2190-Autohouse (pull request #743)
IO-2190 Autohouse & Job Costing
2023-05-02 21:53:40 +00:00
Allan Carr
99b847822f Merged in feature/IO-2190-Autohouse (pull request #742)
IO-2190 Autohouse & Job Costing

Approved-by: Patrick Fic
2023-05-02 21:52:50 +00:00
Allan Carr
f66d9b8c09 IO-2190 Autohouse & Job Costing
Insure that amount going into Dinero is Integer
2023-05-02 14:51:47 -07:00
Patrick Fic
5660de42af Add support email to server side emails. 2023-05-02 12:31:18 -07:00
Patrick Fic
ccbe92c275 Merged in feature/IO-2190-Autohouse (pull request #741)
IO-2190 Correct lookup location for MAPA Hrs
2023-05-02 17:06:12 +00:00
Allan Carr
b0ea8a71fb Merged in feature/IO-2190-Autohouse (pull request #738)
IO-2190 Correct lookup location for MAPA Hrs

Approved-by: Patrick Fic
2023-05-01 22:30:13 +00:00
Allan Carr
060871306f Merged in feature/IO-2257-PBS-EXPORT-CREDIT (pull request #737)
IO-2257 PBS Export of Credits

Approved-by: Patrick Fic
2023-05-01 22:30:00 +00:00
Allan Carr
2eb4e142ff IO-2190 Correct lookup location for MAPA Hrs 2023-05-01 13:48:18 -07:00
Patrick Fic
adf8cf9e8d Additional hasura indexes. 2023-05-01 13:05:59 -07:00
Patrick Fic
852fd9c388 IO-2261 Sample open search replacement. 2023-05-01 13:04:10 -07:00
Patrick Fic
e921f28105 Merged in release/2023-04-28 (pull request #736)
Additional database indexing.
2023-04-28 16:51:46 +00:00
Patrick Fic
6db68b76db Merged in release/2023-04-28 (pull request #735)
Additional database indexing.
2023-04-28 16:51:31 +00:00
Patrick Fic
51ebfd86e7 Additional database indexing. 2023-04-28 09:37:49 -07:00
Allan Carr
79a90bb9ee IO-2257 PBS Export of Credits
Amounts less then 0 (ie all credits) would not get pushed to transactionObject. Expand to be both sides of zero to allow for credits within transactionObject
2023-04-27 17:13:37 -07:00
Patrick Fic
1664f9c935 Merged in release/2023-04-28 (pull request #733)
Resolve Loader script issue.
2023-04-27 22:21:15 +00:00
Patrick Fic
23fcdd6375 Merged in release/2023-04-28 (pull request #732)
Release/2023 04 28
2023-04-27 22:21:03 +00:00
Patrick Fic
ea7c22daec Resolve Loader script issue. 2023-04-27 15:20:41 -07:00
Patrick Fic
10ffb33ec9 Merged in release/2023-04-28 (pull request #731)
Remove unneeded imports.
2023-04-27 21:33:39 +00:00
Patrick Fic
f9e023f922 Remove unneeded imports. 2023-04-27 14:19:27 -07:00
Patrick Fic
c7832bdd82 Merged in release/2023-04-28 (pull request #730)
Release/2023 04 28
2023-04-27 21:13:54 +00:00
Patrick Fic
329bdbe22d Merged in release/2023-04-28 (pull request #729)
Release/2023 04 28
2023-04-27 20:54:32 +00:00
Patrick Fic
2df046c39d IO-1053 Fix issues with scoreboard updates. 2023-04-27 13:52:01 -07:00
Patrick Fic
46065f1986 IO-1933 Resolve tech efficency component. 2023-04-27 13:13:16 -07:00
Allan Carr
66b3fb6988 Merged in release/2023-04-28 (pull request #728)
IO-2190 Factor Paint Costs from Scale over to Job Costing & Autohouse

Approved-by: Patrick Fic
2023-04-27 19:47:13 +00:00
swtmply
5eda224393 IO-1053 Added Job Total to graph 2023-04-28 01:42:22 +08:00
Patrick Fic
e387abcd14 IO-1741 IO-2147 IO-1933 Bug fixes for multiple tickets. 2023-04-27 10:20:46 -07:00
Allan Carr
4c2d4e20a6 IO-2190 Factor Paint Costs from Scale over to Job Costing & Autohouse
Add use_paint_scale_data to bodyshop query
2023-04-27 09:40:12 -07:00
Patrick Fic
3d26c2e94e Merged in release/2023-04-28 (pull request #727)
Release/2023 04 28
2023-04-27 16:32:43 +00:00
swtmply
d9e2ef9300 IO-1933 Added statistics on tech page 2023-04-27 22:19:32 +08:00
swtmply
b00fdadc1b IO-1741 Added touched property on calculate button 2023-04-27 22:19:00 +08:00
swtmply
4d5e06b9fc IO-2157 Added save to job notes button 2023-04-27 22:18:45 +08:00
Patrick Fic
ad42dd1295 Merged in release/2023-04-28 (pull request #726)
IO-2210 Remove unused state.
2023-04-26 23:52:34 +00:00
Patrick Fic
1f4c1c9e92 IO-2210 Remove unused state. 2023-04-26 16:51:53 -07:00
Patrick Fic
2938b9c94c Merged in release/2023-04-28 (pull request #725)
IO-2210 Search Improvements
2023-04-26 23:45:43 +00:00
Patrick Fic
2227acab3a IO-2210 Search Improvements 2023-04-26 16:45:20 -07:00
Patrick Fic
bde17446ad Merged in release/2023-04-28 (pull request #724)
Release/2023 04 28
2023-04-26 19:49:54 +00:00
Patrick Fic
081165b6f5 Resolve missing items from merge conflicts. 2023-04-26 12:46:41 -07:00
Allan Carr
7e717c0b1f Merge branch 'release/2023-04-28' of https://bitbucket.org/snaptsoft/bodyshop into release/2023-04-28
# Conflicts:
#	yarn.lock
2023-04-26 12:23:50 -07:00
Allan Carr
e242aaa9f5 IO-2190 Factor Paint Costs from Scale over to Job Costing & Autohouse
If Paint Scale Data exist in MixData then use the LiquidCost is use_paint_scale_data is set to true else fall back to cost calculations
2023-04-26 12:05:14 -07:00
Patrick Fic
fe60538acf Merged in release/2023-04-28 (pull request #723)
Resolve missing items from merge conflicts.
2023-04-26 17:21:20 +00:00
Patrick Fic
2db88f57df Resolve missing items from merge conflicts. 2023-04-26 10:20:24 -07:00
Patrick Fic
7461e58000 Merged in release/2023-04-28 (pull request #722)
Release/2023 04 28
2023-04-26 16:44:29 +00:00
Patrick Fic
cd0b7a4e56 Add additional indexes. 2023-04-26 09:42:43 -07:00
Allan Carr
2a3b4e89ab Merge branch 'release/2023-04-28' of https://bitbucket.org/snaptsoft/bodyshop into release/2023-04-28
# Conflicts:
#	hasura/metadata/tables.yaml
2023-04-26 09:13:34 -07:00
Allan Carr
1d77eda3e2 IO-2190 Add extra field in for this item 2023-04-26 09:02:36 -07:00
swtmply
490e1f696a IO-1741 Added touched property on calculate button 2023-04-26 22:33:30 +08:00
swtmply
b96c618f54 IO-2157 Added save to job notes button 2023-04-26 22:32:46 +08:00
Patrick Fic
1afda01d34 Merged in release/2023-04-28 (pull request #721)
Release/2023 04 28
2023-04-26 02:22:48 +00:00
Patrick Fic
b9d11580d4 IO-2210 Opensearch implementation. 2023-04-25 18:47:11 -07:00
Patrick Fic
27fadb9ae2 Additional payroll schema tracking. 2023-04-25 10:16:56 -07:00
Patrick Fic
4c5a2cefe9 Payroll schema updates. 2023-04-25 09:33:17 -07:00
Patrick Fic
175692559c Merged in release/2023-04-28 (pull request #720)
Release/2023 04 28
2023-04-24 21:45:57 +00:00
Patrick Fic
57b27f73c3 Added a search filter for greater than 3 characters. 2023-04-24 14:45:08 -07:00
Patrick Fic
7badb09ba1 Timeticket Approval Queue schema updates for payroll updates. 2023-04-24 13:39:59 -07:00
Patrick Fic
c39f1d824a Merged in release/2023-04-21 (pull request #719)
Release/2023 04 21
2023-04-21 20:18:25 +00:00
Patrick Fic
59f71d53cd Merged in release/2023-04-21 (pull request #718)
Release/2023 04 21
2023-04-21 18:42:34 +00:00
Allan Carr
0cad64ff6d Merged in release/2023-04-21 (pull request #717)
IO-2335 Exported GSR to Excel

Approved-by: Patrick Fic
2023-04-20 19:58:58 +00:00
Allan Carr
3a83160b33 Merged in release/2023-04-21 (pull request #716)
IO-2235 Exported GSR to Excel

Approved-by: Patrick Fic
2023-04-20 16:45:28 +00:00
Allan Carr
701c532e48 Merged in release/2023-04-21 (pull request #715)
Release/2023 04 21

Approved-by: Patrick Fic
2023-04-19 23:14:52 +00:00
Patrick Fic
7799d93f3d Merged in release/2023-04-21 (pull request #714)
Disable job status transition tracking.
2023-04-19 21:26:37 +00:00
Patrick Fic
54cc02068c Merged in release/2023-04-21 (pull request #713)
Release/2023 04 21
2023-04-19 21:11:45 +00:00
Patrick Fic
de44116940 Merged in release/2023-04-21 (pull request #712)
Resolve status transition error message.
2023-04-19 20:08:39 +00:00
Patrick Fic
14d6cc94dd Merged in release/2023-04-21 (pull request #711)
IO-2086 Resolve cloudinary based thumbnail retrieval.
2023-04-19 18:45:22 +00:00
Patrick Fic
c0d9bacf1d Merged in release/2023-04-21 (pull request #710)
Release/2023 04 21
2023-04-19 18:44:50 +00:00
Patrick Fic
357f40bdc2 Merged in release/2023-04-14 (pull request #706)
Release/2023 04 14
2023-04-14 20:03:58 +00:00
Patrick Fic
30689a8ca6 Merged in release/2023-04-14 (pull request #705)
Release/2023 04 14
2023-04-14 18:39:19 +00:00
Patrick Fic
554ec37ace Merged in release/2023-04-14 (pull request #704)
Release/2023 04 14
2023-04-13 16:36:16 +00:00
Patrick Fic
3fc7af9780 Merged in release/2023-04-07 (pull request #702)
Release/2023 04 07
2023-04-06 00:22:37 +00:00
John Allen Delos Reyes
a1b6ccc23d Merged in release/2023-04-07 (pull request #700)
Release/2023 04 07

Approved-by: Patrick Fic
2023-04-05 21:21:39 +00:00
Patrick Fic
dde6f17029 Merged in release/2023-03-17 (pull request #694)
Language updates & default for lost sale reason.
2023-03-17 18:43:52 +00:00
Allan Carr
1aceef9153 Merged in release/2023-03-17 (pull request #693)
IO-2193 Delete Owner & Vehicle

Approved-by: Patrick Fic
2023-03-17 01:06:10 +00:00
Patrick Fic
678892d134 Merged in release/2023-03-17 (pull request #692)
IO-2177 Add enforce category on conversion.
2023-03-16 21:51:01 +00:00
Allan Carr
dc187bbf24 Merged in release/2023-03-17 (pull request #691)
Release/2023 03 17

Approved-by: Patrick Fic
2023-03-16 18:51:11 +00:00
Patrick Fic
09aae78715 Merged in release/2023-03-17 (pull request #690)
Release/2023 03 17
2023-03-15 18:53:49 +00:00
Patrick Fic
c42276ab3a Merged in release/2023-03-10 (pull request #688)
Release/2023 03 10
2023-03-10 18:51:03 +00:00
Patrick Fic
41d25cbc52 Merged in release/2023-03-03 (pull request #686)
release/2023-03-03

Approved-by: Patrick Fic
2023-03-03 17:28:32 +00:00
Patrick Fic
085c27ad20 Merged in release/2023-03-03 (pull request #685)
release/2023-03-03

Approved-by: Patrick Fic
2023-03-03 17:08:45 +00:00
Patrick Fic
38e6b5010e Merged in release/2023-03-03 (pull request #684)
release/2023-03-03

Approved-by: Patrick Fic
2023-03-03 04:05:30 +00:00
Allan Carr
242c275e7d Merged in release/2023-02-24 (pull request #680)
Release/2023 02 24

Approved-by: Patrick Fic
2023-02-23 19:44:40 +00:00
Allan Carr
1dc6130fdf Merged in release/2023-02-17 (pull request #678)
Release/2023 02 17

Approved-by: Patrick Fic
2023-02-17 18:37:20 +00:00
Allan Carr
910afbf48d Merged in release/2023-02-17 (pull request #676)
Release/2023 02 17

Approved-by: Patrick Fic
2023-02-14 22:03:01 +00:00
Patrick Fic
9d9edfd674 Merged in release/2023-02-10 (pull request #674)
Improve display of job lines preset display.
2023-02-10 23:22:47 +00:00
Allan Carr
62a5b49836 Merged in release/2023-02-10 (pull request #673)
Release/2023 02 10

Approved-by: Patrick Fic
2023-02-09 17:56:24 +00:00
Patrick Fic
e93e138f78 Merged in release/2023-02-03 (pull request #671)
release/2023-02-03

Approved-by: Patrick Fic
2023-02-06 18:09:03 +00:00
Patrick Fic
4639e31e55 Merged in release/2023-02-03 (pull request #669)
release/2023-02-03

Approved-by: Patrick Fic
2023-02-04 01:19:46 +00:00
Patrick Fic
e8fde14f9b Merged in release/2023-02-03 (pull request #668)
release/2023-02-03

Approved-by: Patrick Fic
2023-02-03 22:58:21 +00:00
Patrick Fic
90e87adc34 Merged in release/2023-02-03 (pull request #667)
release/2023-02-03

Approved-by: Patrick Fic
2023-02-03 20:34:27 +00:00
Patrick Fic
81053b3cbf Merged in release/2023-02-03 (pull request #666)
release/2023-02-03

Approved-by: Patrick Fic
2023-02-02 21:47:46 +00:00
Patrick Fic
f4290bf20c Merged in release/2023-02-03 (pull request #665)
release/2023-02-03

Approved-by: Patrick Fic
2023-02-02 19:06:20 +00:00
Patrick Fic
5371657aa4 Merged in release/2023-02-03 (pull request #664)
release/2023-02-03

Approved-by: Patrick Fic
2023-02-02 18:42:40 +00:00
Patrick Fic
599f4e143c Merged in release/2023-02-03 (pull request #663)
release/2023-02-03

Approved-by: Patrick Fic
2023-02-02 18:10:12 +00:00
Patrick Fic
94440e5c48 Merged in master (pull request #662)
Merged in release/2023-01-27 (pull request #661)
2023-01-27 23:14:44 +00:00
Patrick Fic
aa5d6f2090 Merged in release/2023-01-27 (pull request #660)
IO-2156 Resolve AH detail line validation issue.
2023-01-27 21:21:21 +00:00
Patrick Fic
6bde1b1baf Merged in release/2023-01-27 (pull request #659)
Release/2023 01 27
2023-01-27 17:02:10 +00:00
Patrick Fic
fc404b1f3b Merged in release/2022-01-20 (pull request #655)
Release/2022 01 20
2023-01-19 21:11:58 +00:00
Patrick Fic
c6ba3fd8f0 Merged in release/2022-01-13 (pull request #653)
Release/2022 01 13
2023-01-09 17:36:25 +00:00
Patrick Fic
119904ca2b Merged in release/2023-01-06 (pull request #651)
Updates to Sentry & removal of Stripe.
2023-01-04 16:33:10 +00:00
Patrick Fic
f7e1b023df Merged in release/2023-01-06 (pull request #650)
Release/2023 01 06
2023-01-02 22:56:05 +00:00
Patrick Fic
5855569194 Merged in release/2022-12-30 (pull request #648)
IO-2133 Manual Line Highlighting
2022-12-28 18:05:20 +00:00
Patrick Fic
4f852e7493 Merged in release/2022-12-30 (pull request #647)
release/2022-12-30

Approved-by: Patrick Fic
2022-12-26 18:34:28 +00:00
Patrick Fic
deec40a89c Merged in release/2022-12-16 (pull request #642)
Remove unneeded import to fix CI.
2022-12-16 01:09:42 +00:00
Patrick Fic
145dd9bec6 Merged in release/2022-12-16 (pull request #641)
IO-2131 Resolve job search select filtering issue.
2022-12-16 01:02:45 +00:00
Patrick Fic
b8e5d4412f Merged in release/2022-12-16 (pull request #640)
Release/2022 12 16
2022-12-15 18:20:28 +00:00
Patrick Fic
277fb8f839 Merged in release/2022-12-09 (pull request #637)
IO-2123 Add cc inventory print.
2022-12-09 19:35:49 +00:00
Patrick Fic
d3d5485846 Merged in release/2022-12-09 (pull request #636)
Release/2022 12 09
2022-12-09 16:19:58 +00:00
Patrick Fic
55091d61d6 Merged in release/2022-12-02 (pull request #634)
Release/2022 12 02
2022-11-30 18:26:32 +00:00
Patrick Fic
5b5df8a3a1 Merged in release/2022-11-25 (pull request #630)
Release/2022 11 25
2022-11-25 16:42:19 +00:00
Patrick Fic
ccf48cfcf1 Merged in release/2022-11-10 (pull request #624)
release/2022-11-10

Approved-by: Patrick Fic
2022-11-10 18:47:48 +00:00
Patrick Fic
c89342b6ef Merge branch 'release/2022-11-10' into test
* release/2022-11-10:
  CI Test
2022-11-09 16:35:48 -08:00
Patrick Fic
e97ceb7cbe Merged in release/2022-11-10 (pull request #623)
CI Test
2022-11-10 00:30:20 +00:00
Patrick Fic
de34cbd937 Merged in release/2022-11-10 (pull request #622)
Release/2022 11 10
2022-11-10 00:23:10 +00:00
Patrick Fic
cf7a1b0168 Merged in release/2022-11-10 (pull request #621)
Add .circleci/config.yml
2022-11-08 19:10:04 +00:00
112 changed files with 5558 additions and 1237 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,4 @@
GENERATE_SOURCEMAP=false
REACT_APP_GRAPHQL_ENDPOINT=https://db.imex.online/v1/graphql
REACT_APP_GRAPHQL_ENDPOINT_WS=wss://db.imex.online/v1/graphql
REACT_APP_GA_CODE=231103507

View File

@@ -6,7 +6,7 @@ import { useTranslation } from "react-i18next";
import { DELETE_BILL } from "../../graphql/bills.queries";
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
export default function BillDeleteButton({ bill }) {
export default function BillDeleteButton({ bill, callback }) {
const [loading, setLoading] = useState(false);
const { t } = useTranslation();
const [deleteBill] = useMutation(DELETE_BILL);
@@ -36,6 +36,8 @@ export default function BillDeleteButton({ bill }) {
if (!!!result.errors) {
notification["success"]({ message: t("bills.successes.deleted") });
if (callback && typeof callback === "function") callback(bill.id);
} else {
//Check if it's an fkey violation.
const error = JSON.stringify(result.errors);

View File

@@ -7,7 +7,9 @@ import { createStructuredSelector } from "reselect";
import { selectBreadcrumbs } from "../../redux/application/application.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import GlobalSearch from "../global-search/global-search.component";
import GlobalSearchOs from "../global-search/global-search-os.component";
import "./breadcrumbs.styles.scss";
import { useTreatments } from "@splitsoftware/splitio-react";
const mapStateToProps = createStructuredSelector({
breadcrumbs: selectBreadcrumbs,
@@ -15,6 +17,12 @@ const mapStateToProps = createStructuredSelector({
});
export function BreadCrumbs({ breadcrumbs, bodyshop }) {
const { OpenSearch } = useTreatments(
["OpenSearch"],
{},
bodyshop && bodyshop.imexshopid
);
return (
<Row className="breadcrumb-container">
<Col xs={24} sm={24} md={16}>
@@ -38,7 +46,7 @@ export function BreadCrumbs({ breadcrumbs, bodyshop }) {
</Breadcrumb>
</Col>
<Col xs={24} sm={24} md={8}>
<GlobalSearch />
{OpenSearch.treatment === "on" ? <GlobalSearchOs /> : <GlobalSearch />}
</Col>
</Row>
);

View File

@@ -10,7 +10,10 @@ export default function CABCpvrtCalculator({ disabled, form }) {
const handleFinish = async (values) => {
logImEXEvent("job_ca_bc_pvrt_calculate");
form.setFieldsValue({ ca_bc_pvrt: ((values.rate||0) * (values.days||0)).toFixed(2) });
form.setFieldsValue({
ca_bc_pvrt: ((values.rate || 0) * (values.days || 0)).toFixed(2),
});
form.setFields([{ name: "ca_bc_pvrt", touched: true }]);
setVisibility(false);
};

View File

@@ -0,0 +1,216 @@
import { AutoComplete, Divider, Input, Space } from "antd";
import axios from "axios";
import _ from "lodash";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useHistory } from "react-router-dom";
import PhoneNumberFormatter from "../../utils/PhoneFormatter";
import OwnerNameDisplay, {
OwnerNameDisplayFunction,
} from "../owner-name-display/owner-name-display.component";
import VehicleVinDisplay from "../vehicle-vin-display/vehicle-vin-display.component";
export default function GlobalSearchOs() {
const { t } = useTranslation();
const history = useHistory();
const [loading, setLoading] = useState(false);
const [data, setData] = useState(false);
const executeSearch = async (v) => {
if (v && v && v !== "" && v.length >= 3) {
try {
setLoading(true);
const searchData = await axios.post("/search", {
search: v,
});
const resultsByType = {
payments: [],
jobs: [],
bills: [],
owners: [],
vehicles: [],
};
searchData.data.hits.hits.forEach((hit) => {
resultsByType[hit._index].push(hit._source);
});
setData([
{
label: renderTitle(t("menus.header.search.jobs")),
options: resultsByType.jobs.map((job) => {
return {
key: job.id,
value: job.ro_number || "N/A",
label: (
<Link to={`/manage/jobs/${job.id}`}>
<Space size="small" split={<Divider type="vertical" />}>
<strong>{job.ro_number || t("general.labels.na")}</strong>
<span>{`${job.status || ""}`}</span>
<span>
<OwnerNameDisplay ownerObject={job} />
</span>
<span>{`${job.v_model_yr || ""} ${
job.v_make_desc || ""
} ${job.v_model_desc || ""}`}</span>
<span>{`${job.clm_no || ""}`}</span>
</Space>
</Link>
),
};
}),
},
{
label: renderTitle(t("menus.header.search.owners")),
options: resultsByType.owners.map((owner) => {
return {
key: owner.id,
value: OwnerNameDisplayFunction(owner),
label: (
<Link to={`/manage/owners/${owner.id}`}>
<Space
size="small"
split={<Divider type="vertical" />}
wrap
>
<span>
<OwnerNameDisplay ownerObject={owner} />
</span>
<PhoneNumberFormatter>
{owner.ownr_ph1}
</PhoneNumberFormatter>
<PhoneNumberFormatter>
{owner.ownr_ph2}
</PhoneNumberFormatter>
</Space>
</Link>
),
};
}),
},
{
label: renderTitle(t("menus.header.search.vehicles")),
options: resultsByType.vehicles.map((vehicle) => {
return {
key: vehicle.id,
value: `${vehicle.v_model_yr || ""} ${
vehicle.v_make_desc || ""
} ${vehicle.v_model_desc || ""}`,
label: (
<Link to={`/manage/vehicles/${vehicle.id}`}>
<Space size="small" split={<Divider type="vertical" />}>
<span>
{`${vehicle.v_model_yr || ""} ${
vehicle.v_make_desc || ""
} ${vehicle.v_model_desc || ""}`}
</span>
<span>{vehicle.plate_no || ""}</span>
<span>
<VehicleVinDisplay>
{vehicle.v_vin || ""}
</VehicleVinDisplay>
</span>
</Space>
</Link>
),
};
}),
},
{
label: renderTitle(t("menus.header.search.payments")),
options: resultsByType.payments.map((payment) => {
return {
key: payment.id,
value: `${payment.job?.ro_number} ${payment.amount}`,
label: (
<Link to={`/manage/jobs/${payment.job?.id}`}>
<Space size="small" split={<Divider type="vertical" />}>
<span>{payment.paymentnum}</span>
<span>{payment.job?.ro_number}</span>
<span>{payment.memo || ""}</span>
<span>{payment.amount || ""}</span>
<span>{payment.transactionid || ""}</span>
</Space>
</Link>
),
};
}),
},
{
label: renderTitle(t("menus.header.search.bills")),
options: resultsByType.bills.map((bill) => {
return {
key: bill.id,
value: `${bill.invoice_number} - ${bill.vendor.name}`,
label: (
<Link to={`/manage/bills?billid=${bill.id}`}>
<Space size="small" split={<Divider type="vertical" />}>
<span>{bill.invoice_number}</span>
<span>{bill.vendor.name}</span>
<span>{bill.date}</span>
</Space>
</Link>
),
};
}),
},
// {
// label: renderTitle(t("menus.header.search.phonebook")),
// options: resultsByType.search_phonebook.map((pb) => {
// return {
// key: pb.id,
// value: `${pb.firstname || ""} ${pb.lastname || ""} ${
// pb.company || ""
// }`,
// label: (
// <Link to={`/manage/phonebook?phonebookentry=${pb.id}`}>
// <Space size="small" split={<Divider type="vertical" />}>
// <span>{`${pb.firstname || ""} ${pb.lastname || ""} ${
// pb.company || ""
// }`}</span>
// <PhoneNumberFormatter>{pb.phone1}</PhoneNumberFormatter>
// <span>{pb.email}</span>
// </Space>
// </Link>
// ),
// };
// }),
// },
]);
} catch (error) {
console.log("Error while fetching search results", error);
} finally {
setLoading(false);
}
}
};
const debouncedExecuteSearch = _.debounce(executeSearch, 750);
const handleSearch = (value) => {
debouncedExecuteSearch(value);
};
const renderTitle = (title) => {
return <span>{title}</span>;
};
return (
<AutoComplete
options={data}
onSearch={handleSearch}
defaultActiveFirstOption
onSelect={(val, opt) => {
history.push(opt.label.props.to);
}}
onClear={() => setData([])}
>
<Input.Search
size="large"
placeholder={t("general.labels.globalsearch")}
enterButton
allowClear
loading={loading}
/>
</AutoComplete>
);
}

View File

@@ -8,7 +8,7 @@ import { GLOBAL_SEARCH_QUERY } from "../../graphql/search.queries";
import PhoneNumberFormatter from "../../utils/PhoneFormatter";
import AlertComponent from "../alert/alert.component";
import OwnerNameDisplay, {
OwnerNameDisplayFunction
OwnerNameDisplayFunction,
} from "../owner-name-display/owner-name-display.component";
import VehicleVinDisplay from "../vehicle-vin-display/vehicle-vin-display.component";
export default function GlobalSearch() {
@@ -18,11 +18,18 @@ export default function GlobalSearch() {
useLazyQuery(GLOBAL_SEARCH_QUERY);
const executeSearch = (v) => {
if (v && v.variables.search && v.variables.search !== "") callSearch(v);
if (
v &&
v.variables.search &&
v.variables.search !== "" &&
v.variables.search.length >= 3
)
callSearch(v);
};
const debouncedExecuteSearch = _.debounce(executeSearch, 750);
const handleSearch = (value) => {
console.log("Handle Search");
debouncedExecuteSearch({ variables: { search: value } });
};
@@ -37,7 +44,7 @@ export default function GlobalSearch() {
options: data.search_jobs.map((job) => {
return {
key: job.id,
value: job.ro_number,
value: job.ro_number || "N/A",
label: (
<Link to={`/manage/jobs/${job.id}`}>
<Space size="small" split={<Divider type="vertical" />}>

View File

@@ -109,8 +109,8 @@ export function JobsConvertButton({
]}
>
<Select>
{bodyshop.md_ins_cos.map((s) => (
<Select.Option key={s.name} value={s.name}>
{bodyshop.md_ins_cos.map((s, i) => (
<Select.Option key={i} value={s.name}>
{s.name}
</Select.Option>
))}
@@ -219,13 +219,15 @@ export function JobsConvertButton({
</Select>
</Form.Item>
)}
<Form.Item
label={t("jobs.fields.ca_gst_registrant")}
name="ca_gst_registrant"
valuePropName="checked"
>
<Switch />
</Form.Item>
{bodyshop.region_config.toLowerCase().startsWith("ca") && (
<Form.Item
label={t("jobs.fields.ca_gst_registrant")}
name="ca_gst_registrant"
valuePropName="checked"
>
<Switch />
</Form.Item>
)}
<Form.Item
label={t("jobs.fields.driveable")}
name="driveable"

View File

@@ -224,13 +224,15 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) {
>
<CurrencyInput />
</Form.Item>
<Form.Item
label={t("jobs.fields.ca_gst_registrant")}
name="ca_gst_registrant"
valuePropName="checked"
>
<Switch />
</Form.Item>
{bodyshop.region_config.toLowerCase().startsWith("ca") && (
<Form.Item
label={t("jobs.fields.ca_gst_registrant")}
name="ca_gst_registrant"
valuePropName="checked"
>
<Switch />
</Form.Item>
)}
<Form.Item
label={t("jobs.fields.other_amount_payable")}
name="other_amount_payable"

View File

@@ -40,24 +40,26 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
>
<CurrencyInput disabled={jobRO} min={0} />
</Form.Item>
<Tooltip title={t("jobs.labels.ca_gst_all_if_null")}>
<Form.Item
label={t("jobs.fields.ca_customer_gst")}
name="ca_customer_gst"
>
<CurrencyInput
disabled={jobRO}
min={0}
max={
Math.round(
(job.job_totals &&
job.job_totals.totals.federal_tax.amount) ||
0
) / 100
}
/>
</Form.Item>
</Tooltip>
{bodyshop.region_config.toLowerCase().startsWith("ca") && (
<Tooltip title={t("jobs.labels.ca_gst_all_if_null")}>
<Form.Item
label={t("jobs.fields.ca_customer_gst")}
name="ca_customer_gst"
>
<CurrencyInput
disabled={jobRO}
min={0}
max={
Math.round(
(job.job_totals &&
job.job_totals.totals.federal_tax.amount) ||
0
) / 100
}
/>
</Form.Item>
</Tooltip>
)}
<Form.Item
label={t("jobs.fields.other_amount_payable")}
name="other_amount_payable"
@@ -82,12 +84,14 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
>
<CurrencyInput disabled={jobRO || bodyshop.cdk_dealerid} />
</Form.Item>
<Space align="end">
<Form.Item label={t("jobs.fields.ca_bc_pvrt")} name="ca_bc_pvrt">
<CurrencyInput disabled={jobRO} min={0} />
</Form.Item>
<CABCpvrtCalculator form={form} disabled={jobRO} />
</Space>
{bodyshop.region_config === "CA_BC" && (
<Space align="center">
<Form.Item label={t("jobs.fields.ca_bc_pvrt")} name="ca_bc_pvrt">
<CurrencyInput disabled={jobRO} min={0} />
</Form.Item>
<CABCpvrtCalculator form={form} disabled={jobRO} />
</Space>
)}
<Form.Item
label={t("jobs.fields.auto_add_ats")}
name="auto_add_ats"
@@ -141,13 +145,15 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
>
<InputNumber min={0} max={1} precision={2} disabled={jobRO} />
</Form.Item>
<Form.Item
label={t("jobs.fields.ca_gst_registrant")}
name="ca_gst_registrant"
valuePropName="checked"
>
<Switch disabled={jobRO} />
</Form.Item>
{bodyshop.region_config.toLowerCase().startsWith("ca") && (
<Form.Item
label={t("jobs.fields.ca_gst_registrant")}
name="ca_gst_registrant"
valuePropName="checked"
>
<Switch disabled={jobRO} />
</Form.Item>
)}
</FormRow>
<Divider
orientation="left"

View File

@@ -1,8 +1,9 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Card, Input, Space, Table, Typography } from "antd";
import axios from "axios";
import _ from "lodash";
import queryString from "query-string";
import React from "react";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link, useHistory, useLocation } from "react-router-dom";
@@ -21,6 +22,8 @@ const mapDispatchToProps = (dispatch) => ({
export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
const search = queryString.parse(useLocation().search);
const [openSearchResults, setOpenSearchResults] = useState([]);
const [searchLoading, setSearchLoading] = useState(false);
const { page, sortcolumn, sortorder } = search;
const history = useHistory();
@@ -193,6 +196,28 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
history.push({ search: queryString.stringify(search) });
};
useEffect(() => {
if (search.search && search.search.trim() !== "") {
searchJobs();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
async function searchJobs(value) {
try {
setSearchLoading(true);
const searchData = await axios.post("/search", {
search: value || search.search,
index: "jobs",
});
setOpenSearchResults(searchData.data.hits.hits.map((s) => s._source));
} catch (error) {
console.log("Error while fetching search results", error);
} finally {
setSearchLoading(false);
}
}
return (
<Card
extra={
@@ -205,6 +230,7 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
<Button
onClick={() => {
delete search.search;
delete search.page;
history.push({ search: queryString.stringify(search) });
}}
>
@@ -220,24 +246,32 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
onSearch={(value) => {
search.search = value;
history.push({ search: queryString.stringify(search) });
searchJobs(value);
}}
loading={loading || searchLoading}
enterButton
/>
</Space>
}
>
<Table
loading={loading}
pagination={{
position: "top",
pageSize: 25,
current: parseInt(page || 1),
total: total,
showSizeChanger: false,
}}
loading={loading || searchLoading}
pagination={
search?.search
? {
pageSize: 25,
showSizeChanger: false,
}
: {
pageSize: 25,
current: parseInt(page || 1),
total: total,
showSizeChanger: false,
}
}
columns={columns}
rowKey="id"
dataSource={jobs}
dataSource={search?.search ? openSearchResults : jobs}
onChange={handleTableChange}
/>
</Card>

View File

@@ -75,6 +75,27 @@ export function JobNotesComponent({
</span>
),
},
{
title: t("notes.fields.type"),
dataIndex: "type",
key: "type",
width: 120,
filteredValue: filter?.type || null,
filters: [
{ value: "general", text: t("notes.fields.types.general") },
{ value: "customer", text: t("notes.fields.types.customer") },
{ value: "shop", text: t("notes.fields.types.shop") },
{ value: "office", text: t("notes.fields.types.office") },
{ value: "parts", text: t("notes.fields.types.parts") },
{ value: "paint", text: t("notes.fields.types.paint") },
{
value: "supplement",
text: t("notes.fields.types.supplement"),
},
],
onFilter: (value, record) => value.includes(record.type),
render: (text, record) => t(`notes.fields.types.${record.type}`),
},
{
title: t("notes.fields.text"),
dataIndex: "text",
@@ -106,7 +127,7 @@ export function JobNotesComponent({
title: t("notes.actions.actions"),
dataIndex: "actions",
key: "actions",
width: 150,
width: 200,
render: (text, record) => (
<Space wrap>
<Button

View File

@@ -207,7 +207,7 @@ export function LaborAllocationsTable({
<Card title={t("jobs.labels.laborallocations")}>
<Table
columns={columns}
rowKey="cost_center"
rowKey={(record) => `${record.cost_center} ${record.mod_lbr_ty}`}
pagination={false}
onChange={handleTableChange}
dataSource={totals}

View File

@@ -1,4 +1,14 @@
import { Checkbox, Col, Form, Input, Row, Space, Switch, Tag } from "antd";
import {
Checkbox,
Col,
Form,
Input,
Row,
Select,
Space,
Switch,
Tag,
} from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -46,6 +56,28 @@ export function NoteUpsertModalComponent({ form, noteUpsertModal }) {
<Switch />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
label={t("notes.fields.type")}
name="type"
initialValue="general"
>
<Select
options={[
{ value: "general", label: t("notes.fields.types.general") },
{ value: "customer", label: t("notes.fields.types.customer") },
{ value: "shop", label: t("notes.fields.types.shop") },
{ value: "office", label: t("notes.fields.types.office") },
{ value: "parts", label: t("notes.fields.types.parts") },
{ value: "paint", label: t("notes.fields.types.paint") },
{
value: "supplement",
label: t("notes.fields.types.supplement"),
},
]}
/>
</Form.Item>
</Col>
<Col span={8}>
<NotesPresetButton form={form} />
</Col>

View File

@@ -34,7 +34,7 @@ export function NoteUpsertModalContainer({
const [updateNote] = useMutation(UPDATE_NOTE);
const { visible, context, actions } = noteUpsertModal;
const { jobId, existingNote } = context;
const { jobId, existingNote, text } = context;
const { refetch } = actions;
const [form] = Form.useForm();
@@ -45,8 +45,12 @@ export function NoteUpsertModalContainer({
form.setFieldsValue(existingNote);
} else if (!existingNote && visible) {
form.resetFields();
if (text) {
form.setFieldValue("text", text);
}
}
}, [existingNote, form, visible]);
}, [existingNote, form, visible, text]);
const handleFinish = async (formValues) => {
const { relatedros, ...values } = formValues;
@@ -82,6 +86,7 @@ export function NoteUpsertModalContainer({
{ ...values, jobid: jobId, created_by: currentUser.email },
],
},
refetchQueries: ["QUERY_NOTES_BY_JOB_PK"],
});
if (AdditionalNoteInserts.length > 0) {

View File

@@ -52,7 +52,7 @@ function PaymentModalContainer({
const { useStripe, sendby, ...paymentObj } = values;
setLoading(true);
let updatedPayment; //Moved up from if statement for greater scope.
try {
if (!context || (context && !context.id)) {
const newPayment = await insertPayment({
@@ -87,7 +87,7 @@ function PaymentModalContainer({
);
}
} else {
const updatedPayment = await updatePayment({
updatedPayment = await updatePayment({
variables: {
paymentId: context.id,
payment: paymentObj,
@@ -101,7 +101,11 @@ function PaymentModalContainer({
}
}
if (actions.refetch) actions.refetch();
if (actions.refetch)
actions.refetch(
updatedPayment && updatedPayment.data.update_payments.returning[0]
);
if (enterAgain) {
const prev = form.getFieldsValue(["date"]);

View File

@@ -1,20 +1,23 @@
import { EditFilled, SyncOutlined } from "@ant-design/icons";
import { useApolloClient } from "@apollo/client";
import { Button, Card, Input, Space, Table, Typography } from "antd";
import axios from "axios";
import queryString from "query-string";
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link, useHistory, useLocation } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { QUERY_PAYMENT_BY_ID } from "../../graphql/payments.queries";
import { setModalContext } from "../../redux/modals/modals.actions";
import { selectBodyshop } from "../../redux/user/user.selectors";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter";
import { alphaSort } from "../../utils/sorters";
import { TemplateList } from "../../utils/TemplateConstants";
import { alphaSort } from "../../utils/sorters";
import CaBcEtfTableModalContainer from "../ca-bc-etf-table-modal/ca-bc-etf-table-modal.container";
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
@@ -39,7 +42,10 @@ export function PaymentsListPaginated({
bodyshop,
}) {
const search = queryString.parse(useLocation().search);
const [openSearchResults, setOpenSearchResults] = useState([]);
const [searchLoading, setSearchLoading] = useState(false);
const { page, sortcolumn, sortorder } = search;
const client = useApolloClient();
const history = useHistory();
const [state, setState] = useState({
sortedInfo: {},
@@ -52,13 +58,17 @@ export function PaymentsListPaginated({
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
sortOrder: sortcolumn === "ro_number" && sortorder,
render: (text, record) => (
<Link to={"/manage/jobs/" + record.job.id}>
{record.job.ro_number || t("general.labels.na")}
</Link>
),
// sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
// sortOrder: sortcolumn === "ro_number" && sortorder,
render: (text, record) => {
return record.job ? (
<Link to={"/manage/jobs/" + record.job.id}>
{record.job.ro_number || t("general.labels.na")}
</Link>
) : (
<span>{t("general.labels.na")}</span>
);
},
},
{
title: t("payments.fields.paymentnum"),
@@ -72,16 +82,16 @@ export function PaymentsListPaginated({
dataIndex: "owner",
key: "owner",
ellipsis: true,
sorter: (a, b) => alphaSort(a.job.ownr_ln, b.job.ownr_ln),
sortOrder: sortcolumn === "owner" && sortorder,
// sorter: (a, b) => alphaSort(a.job.ownr_ln, b.job.ownr_ln),
// sortOrder: sortcolumn === "owner" && sortorder,
render: (text, record) => {
return record.job.owner ? (
<Link to={"/manage/owners/" + record.job.owner.id}>
<OwnerNameDisplay ownerObject={record} />
return record.job?.owner ? (
<Link to={"/manage/owners/" + record.job?.owner?.id}>
<OwnerNameDisplay ownerObject={record.job} />
</Link>
) : (
<span>
<OwnerNameDisplay ownerObject={record} />
<OwnerNameDisplay ownerObject={record.job} />
</span>
);
},
@@ -147,10 +157,33 @@ export function PaymentsListPaginated({
<Space>
<Button
disabled={record.exportedat}
onClick={() => {
onClick={async () => {
let apolloResults;
if (search.search) {
const { data } = await client.query({
query: QUERY_PAYMENT_BY_ID,
variables: {
paymentId: record.id,
},
});
apolloResults = data.payments_by_pk;
}
setPaymentContext({
actions: { refetch: refetch },
context: record,
actions: {
refetch: apolloResults
? (updatedRecord) => {
setOpenSearchResults((results) =>
results.map((result) => {
if (result.id !== record.id) {
return result;
}
return updatedRecord;
})
);
}
: refetch,
},
context: apolloResults ? apolloResults : record,
});
}}
>
@@ -177,6 +210,28 @@ export function PaymentsListPaginated({
history.push({ search: queryString.stringify(search) });
};
useEffect(() => {
if (search.search && search.search.trim() !== "") {
searchPayments();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
async function searchPayments(value) {
try {
setSearchLoading(true);
const searchData = await axios.post("/search", {
search: value || search.search,
index: "payments",
});
setOpenSearchResults(searchData.data.hits.hits.map((s) => s._source));
} catch (error) {
console.log("Error while fetching search results", error);
} finally {
setSearchLoading(false);
}
}
return (
<Card
extra={
@@ -189,6 +244,7 @@ export function PaymentsListPaginated({
<Button
onClick={() => {
delete search.search;
delete search.page;
history.push({ search: queryString.stringify(search) });
}}
>
@@ -212,24 +268,33 @@ export function PaymentsListPaginated({
onSearch={(value) => {
search.search = value;
history.push({ search: queryString.stringify(search) });
searchPayments(value);
}}
loading={loading || searchLoading}
enterButton
/>
</Space>
}
>
<Table
loading={loading}
loading={loading || searchLoading}
scroll={{ x: true }}
pagination={{
position: "top",
pageSize: 25,
current: parseInt(page || 1),
total: total,
}}
pagination={
search?.search
? {
pageSize: 25,
showSizeChanger: false,
}
: {
pageSize: 25,
current: parseInt(page || 1),
total: total,
showSizeChanger: false,
}
}
columns={columns}
rowKey="id"
dataSource={payments}
dataSource={search?.search ? openSearchResults : payments}
onChange={handleTableChange}
/>
</Card>

View File

@@ -29,7 +29,10 @@ export function PrintCenterJobsComponent({ printCenterModal, bodyshop }) {
})
.filter(
(temp) =>
!temp.regions || (temp.regions && temp.regions[bodyshop.region_config])
!temp.regions ||
(temp.regions && temp.regions[bodyshop.region_config]) ||
(temp.regions &&
bodyshop.region_config.includes(Object.keys(temp.regions)) === true)
);
const filteredJobsReportsList =

View File

@@ -0,0 +1,51 @@
import { Col, List, Space, Typography } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
const CardColorLegend = ({ bodyshop }) => {
const { t } = useTranslation();
const data = bodyshop.ssbuckets.map((bucket) => {
let color = { r: 255, g: 255, b: 255 };
if (bucket.color) {
color = bucket.color;
if (bucket.color.rgb) {
color = bucket.color.rgb;
}
}
return {
label: bucket.label,
color,
};
});
return (
<Col>
<Typography>{t("production.labels.legend")}</Typography>
<List
grid={{
gutter: 16,
}}
dataSource={data}
renderItem={(item) => (
<List.Item>
<Space>
<div
style={{
width: "1.5rem",
aspectRatio: "1/1",
backgroundColor: `rgba(${item.color.r},${item.color.g},${item.color.b},${item.color.a})`,
}}
></div>
<div>{item.label}</div>
</Space>
</List.Item>
)}
/>
</Col>
);
};
export default CardColorLegend;

View File

@@ -18,6 +18,31 @@ import moment from "moment";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import JobPartsQueueCount from "../job-parts-queue-count/job-parts-queue-count.component";
const cardColor = (ssbuckets, totalHrs) => {
const bucket = ssbuckets.filter(
(bucket) =>
bucket.gte <= totalHrs && (!!bucket.lt ? bucket.lt > totalHrs : true)
)[0];
let color = { r: 255, g: 255, b: 255 };
if (bucket && bucket.color) {
color = bucket.color;
if (bucket.color.rgb) {
color = bucket.color.rgb;
}
}
return color;
};
function getContrastYIQ(bgColor) {
const yiq = (bgColor.r * 299 + bgColor.g * 587 + bgColor.b * 114) / 1000;
return yiq >= 128 ? "black" : "white";
}
export default function ProductionBoardCard(
technician,
card,
@@ -54,10 +79,22 @@ export default function ProductionBoardCard(
.isSame(moment(card.scheduled_completion), "day") &&
"production-completion-soon"));
const totalHrs =
card.labhrs.aggregate.sum.mod_lb_hrs + card.larhrs.aggregate.sum.mod_lb_hrs;
const bgColor = cardColor(bodyshop.ssbuckets, totalHrs);
return (
<Card
className="react-kanban-card imex-kanban-card"
size="small"
style={{
backgroundColor:
cardSettings &&
cardSettings.cardcolor &&
`rgba(${bgColor.r},${bgColor.g},${bgColor.b},${bgColor.a})`,
color:
cardSettings && cardSettings.cardcolor && getContrastYIQ(bgColor),
}}
title={
<Space>
<ProductionAlert record={card} key="alert" />

View File

@@ -104,6 +104,13 @@ export default function ProductionBoardKanbanCardSettings({
>
<Switch />
</Form.Item>
<Form.Item
valuePropName="checked"
label={t("production.labels.cardcolor")}
name="cardcolor"
>
<Switch />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
@@ -166,7 +173,7 @@ export default function ProductionBoardKanbanCardSettings({
</div>
);
return (
<Popover content={overlay} visible={visible}>
<Popover content={overlay} visible={visible} placement="topRight">
<Button loading={loading} onClick={() => setVisible(true)}>
{t("production.labels.cardsettings")}
</Button>

View File

@@ -22,6 +22,7 @@ import ProductionBoardKanbanCardSettings from "./production-board-kanban.card-se
//import "@asseinfo/react-kanban/dist/styles.css";
import "./production-board-kanban.styles.scss";
import { createBoardData } from "./production-board-kanban.utils.js";
import CardColorLegend from "../production-board-kanban-card/production-board-kanban-card-color-legend.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
technician: selectTechnician,
@@ -221,6 +222,7 @@ export function ProductionBoardKanbanComponent({
employeeassignments: true,
scheduled_completion: true,
stickyheader: false,
cardcolor: false,
};
return (
@@ -256,6 +258,11 @@ export function ProductionBoardKanbanComponent({
</Space>
}
/>
{cardSettings.cardcolor && (
<CardColorLegend cardSettings={cardSettings} bodyshop={bodyshop} />
)}
<ProductionListDetailComponent jobs={data} />
<StickyContainer>
<Board

View File

@@ -1,12 +1,23 @@
import Icon from "@ant-design/icons";
import { useMutation } from "@apollo/client";
import { Button, Input, Popover } from "antd";
import { Button, Input, Popover, Space } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { FaRegStickyNote } from "react-icons/fa";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { UPDATE_JOB } from "../../graphql/jobs.queries";
export default function ProductionListColumnProductionNote({ record }) {
import { setModalContext } from "../../redux/modals/modals.actions";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
const mapStateToProps = createStructuredSelector({});
const mapDispatchToProps = (dispatch) => ({
setNoteUpsertContext: (context) =>
dispatch(setModalContext({ context: context, modal: "noteUpsert" })),
});
function ProductionListColumnProductionNote({ record, setNoteUpsertContext }) {
const { t } = useTranslation();
const [note, setNote] = useState(
@@ -60,12 +71,26 @@ export default function ProductionListColumnProductionNote({ record }) {
// onPressEnter={handleSaveNote}
autoFocus
allowClear
style={{ marginBottom: "1em" }}
/>
<div>
<Button onClick={handleSaveNote}>
<Space>
<Button onClick={handleSaveNote} type="primary">
{t("general.actions.save")}
</Button>
</div>
<Button
onClick={() => {
setVisible(false);
setNoteUpsertContext({
context: {
jobId: record.id,
text: note,
},
});
}}
>
{t("notes.actions.savetojobnotes")}
</Button>
</Space>
</div>
}
trigger={["click"]}
@@ -85,3 +110,8 @@ export default function ProductionListColumnProductionNote({ record }) {
</Popover>
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(ProductionListColumnProductionNote);

View File

@@ -0,0 +1,39 @@
import Dinero from "dinero.js";
const CustomTooltip = ({ active, payload, label }) => {
if (active && payload && payload.length) {
return (
<div
style={{
backgroundColor: "white",
border: "1px solid gray",
padding: "0.5rem",
}}
>
<p style={{ margin: "0" }}>{label}</p>
{payload.map((data, index) => {
if (data.dataKey === "sales" || data.dataKey === "accSales")
return (
<p
style={{ margin: "10px 0", color: data.color }}
key={index}
>{`${data.name} : ${Dinero({
amount: Math.round(data.value * 100),
}).toFormat()}`}</p>
);
return (
<p
style={{ margin: "10px 0", color: data.color }}
key={index}
>{`${data.name} : ${data.value}`}</p>
);
})}
</div>
);
}
return null;
};
export default CustomTooltip;

View File

@@ -1,4 +1,6 @@
import { Card } from "antd";
import Dinero from "dinero.js";
import _ from "lodash";
import moment from "moment";
import React from "react";
import { connect } from "react-redux";
@@ -17,7 +19,7 @@ import {
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import * as Utils from "../scoreboard-targets-table/scoreboard-targets-table.util";
import _ from "lodash";
import CustomTooltip from "./chart-custom-tooltip";
const graphProps = {
strokeWidth: 3,
@@ -44,14 +46,19 @@ export function ScoreboardChart({ sbEntriesByDate, bodyshop }) {
return {
bodyhrs: dayAcc.bodyhrs + dayVal.bodyhrs,
painthrs: dayAcc.painthrs + dayVal.painthrs,
sales:
dayAcc.painthrs +
dayVal.job.job_totals.totals.subtotal.amount / 100 +
2500,
};
},
{ bodyhrs: 0, painthrs: 0 }
{ bodyhrs: 0, painthrs: 0, sales: 0 }
);
} else {
dayhrs = {
bodyhrs: 0,
painthrs: 0,
sales: 0,
};
}
@@ -64,7 +71,9 @@ export function ScoreboardChart({ sbEntriesByDate, bodyshop }) {
bodyshop.scoreboard_target.dailyBodyTarget +
bodyshop.scoreboard_target.dailyPaintTarget,
val
),
) +
bodyshop.scoreboard_target.dailyBodyTarget +
bodyshop.scoreboard_target.dailyPaintTarget,
1
),
accHrs: _.round(
@@ -73,6 +82,13 @@ export function ScoreboardChart({ sbEntriesByDate, bodyshop }) {
: dayhrs.painthrs + dayhrs.bodyhrs,
1
),
sales: _.round(dayhrs.sales, 2),
accSales: _.round(
acc.length > 0
? acc[acc.length - 1].accSales + dayhrs.sales
: dayhrs.sales,
2
),
};
return [...acc, theValue];
@@ -87,22 +103,27 @@ export function ScoreboardChart({ sbEntriesByDate, bodyshop }) {
>
<CartesianGrid stroke="#f5f5f5" />
<XAxis dataKey="date" strokeWidth={graphProps.strokeWidth} />
<YAxis strokeWidth={graphProps.strokeWidth} />
<Tooltip />
<Legend />
<Area
type="monotone"
name="Accumulated Hours"
dataKey="accHrs"
fill="lightgreen"
stroke="green"
<YAxis
strokeWidth={graphProps.strokeWidth}
// allowDataOverflow
dataKey="sales"
yAxisId="right"
tickFormatter={(value) =>
Dinero({ amount: Math.round(value * 100) }).toFormat()
}
orientation="right"
/>
<YAxis yAxisId="left" strokeWidth={graphProps.strokeWidth} />
<Tooltip content={<CustomTooltip />} />
<Legend />
<Bar
name="Body Hours"
dataKey="bodyHrs"
stackId="day"
barSize={20}
fill="darkblue"
yAxisId="left"
/>
<Bar
name="Paint Hours"
@@ -110,12 +131,42 @@ export function ScoreboardChart({ sbEntriesByDate, bodyshop }) {
stackId="day"
barSize={20}
fill="darkred"
yAxisId="left"
/>
<Line
name="Target Hours"
type="monotone"
dataKey="accTargetHrs"
stroke="#ff7300"
yAxisId="left"
strokeWidth={graphProps.strokeWidth}
/>
<Area
type="monotone"
name="MTD Hours"
dataKey="accHrs"
fill="lightblue"
stroke="blue"
yAxisId="left"
/>
{
// <Area
// type="monotone"
// name="MTD Sales"
// dataKey="accSales"
// fill="lightgreen"
// stroke="green"
// yAxisId="right"
// />
}
<Bar
name="Sales"
dataKey="sales"
stackId="day"
barSize={20}
fill="darkgreen"
yAxisId="right"
strokeWidth={graphProps.strokeWidth}
/>
</ComposedChart>

View File

@@ -241,9 +241,11 @@ export default function ScoreboardTimeTickets() {
);
ret.totalEffieciencyOverPeriod =
(totalActualAndProductive.totalOverPeriod /
totalActualAndProductive.actualTotalOverPeriod) *
100;
totalActualAndProductive.actualTotalOverPeriod
? (totalActualAndProductive.totalOverPeriod /
totalActualAndProductive.actualTotalOverPeriod) *
100
: 0;
roundObject(ret);
roundObject(totals);

View File

@@ -116,7 +116,7 @@ export function ScoreboardTicketsStats({ data, bodyshop }) {
<Col span={12}>
<Statistic
title={t("scoreboard.labels.efficiencyoverperiod")}
value={`${data.totalEffieciencyOverPeriod}%`}
value={`${data.totalEffieciencyOverPeriod || 0}%`}
/>
</Col>
</Row>

View File

@@ -11,13 +11,13 @@ import {
} from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import FormItemEmail from "../form-items-formatted/email-form-item.component";
import PhoneFormItem, {
PhoneItemFormatterValidation,
} from "../form-items-formatted/phone-form-item.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import FormItemEmail from "../form-items-formatted/email-form-item.component";
import momentTZ from "moment-timezone";
const timeZonesList = momentTZ.tz.names();
@@ -551,6 +551,13 @@ export default function ShopInfoGeneral({ form }) {
>
<CurrencyInput />
</Form.Item>
<Form.Item
name={["use_paint_scale_data"]}
label={t("bodyshop.fields.use_paint_scale_data")}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
name={["attach_pdf_to_email"]}
label={t("bodyshop.fields.attach_pdf_to_email")}

View File

@@ -396,7 +396,7 @@ export function ShopInfoROStatusComponent({ bodyshop, form }) {
);
}
const ColorPicker = ({ value, onChange, style, ...restProps }) => {
export const ColorPicker = ({ value, onChange, style, ...restProps }) => {
const handleChange = (color) => {
if (onChange) onChange(color.rgb);
};

View File

@@ -15,6 +15,7 @@ import { useTranslation } from "react-i18next";
import ColorpickerFormItemComponent from "../form-items-formatted/colorpicker-form-item.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import { ColorPicker } from "./shop-info.rostatus.component";
export default function ShopInfoSchedulingComponent({ form }) {
const { t } = useTranslation();
@@ -277,17 +278,50 @@ export default function ShopInfoSchedulingComponent({ form }) {
>
<InputNumber />
</Form.Item>
<Space wrap>
<DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
<FormListMoveArrows
move={move}
index={index}
total={fields.length}
/>
<Space direction="horizontal">
<Form.Item
label={
<Space>
{t("bodyshop.fields.ssbuckets.color")}
<Button
size="small"
onClick={() => {
form.setFieldValue([
"ssbuckets",
field.name,
"color",
]);
form.setFields([
{
name: ["ssbuckets", field.name, "color"],
touched: true,
},
]);
}}
>
Reset
</Button>
</Space>
}
key={`${index}color`}
name={[field.name, "color"]}
>
<ColorPicker />
</Form.Item>
<Space wrap>
<DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
<FormListMoveArrows
move={move}
index={index}
total={fields.length}
/>
</Space>
</Space>
</LayoutFormRow>
</Form.Item>

View File

@@ -0,0 +1,131 @@
import { useQuery } from "@apollo/client";
import { Card, Col, Space, Statistic, Typography } from "antd";
import moment from "moment";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE } from "../../graphql/timetickets.queries";
import { selectTechnician } from "../../redux/tech/tech.selectors";
import AlertComponent from "../alert/alert.component";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
const { Title } = Typography;
const mapStateToProps = createStructuredSelector({
technician: selectTechnician,
});
const mapDispatchToProps = (dispatch) => ({});
const TechJobStatistics = ({ technician }) => {
const { t } = useTranslation();
const startDate = moment().startOf("week");
const endDate = moment().endOf("week");
const { loading, error, data } = useQuery(
QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE,
{
variables: {
start: startDate.format("YYYY-MM-DD"),
end: endDate.format("YYYY-MM-DD"),
fixedStart: moment().startOf("month").format("YYYY-MM-DD"),
fixedEnd: moment().endOf("month").format("YYYY-MM-DD"),
employeeid: technician.id,
},
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
}
);
const totals = useMemo(() => {
if (data && data.timetickets && data.fixedperiod) {
const week = data.timetickets.reduce(
(acc, val) => {
acc.productivehrs = acc.productivehrs + val.productivehrs;
acc.actualhrs = acc.actualhrs + val.actualhrs;
return acc;
},
{ productivehrs: 0, actualhrs: 0 }
);
const month = data.fixedperiod.reduce(
(acc, val) => {
acc.productivehrs = acc.productivehrs + val.productivehrs;
acc.actualhrs = acc.actualhrs + val.actualhrs;
return acc;
},
{ productivehrs: 0, actualhrs: 0 }
);
return {
week,
month,
};
}
return {
week: { productivehrs: 0, actualhrs: 0 },
month: { productivehrs: 0, actualhrs: 0 },
};
}, [data]);
if (loading) return <LoadingSpinner />;
if (error) return <AlertComponent message={error.message} type="error" />;
return (
<Card title={t("scoreboard.labels.productivestatistics")}>
<Space size={100}>
<Col>
<Title level={5}>{t("scoreboard.labels.thisweek")}</Title>
<Space size={20}>
<Statistic
title={t("timetickets.fields.productivehrs")}
value={totals.week.productivehrs.toFixed(2)}
/>
<Statistic
title={t("timetickets.fields.actualhrs")}
value={totals.week.actualhrs.toFixed(2)}
/>
<Statistic
title={t("timetickets.labels.efficiency")}
value={
totals.week.actualhrs
? `${(
(totals.week.productivehrs / totals.week.actualhrs) *
100
).toFixed(2)}%`
: "0%"
}
/>
</Space>
</Col>
<Col>
<Title level={5}>{t("scoreboard.labels.thismonth")}</Title>
<Space size={20}>
<Statistic
title={t("timetickets.fields.productivehrs")}
value={totals.month.productivehrs.toFixed(2)}
/>
<Statistic
title={t("timetickets.fields.actualhrs")}
value={totals.month.actualhrs.toFixed(2)}
/>
<Statistic
title={t("timetickets.labels.efficiency")}
value={
totals.month.actualhrs
? `${(
(totals.month.productivehrs / totals.month.actualhrs) *
100
).toFixed(2)}%`
: "0%"
}
/>
</Space>
</Col>
</Space>
</Card>
);
};
export default connect(mapStateToProps, mapDispatchToProps)(TechJobStatistics);

View File

@@ -20,13 +20,11 @@ export const DELETE_BILL = gql`
export const QUERY_ALL_BILLS_PAGINATED = gql`
query QUERY_ALL_BILLS_PAGINATED(
$search: String
$offset: Int
$limit: Int
$order: [bills_order_by!]!
) {
search_bills(
args: { search: $search }
bills(
offset: $offset
limit: $limit
order_by: $order
@@ -51,7 +49,7 @@ export const QUERY_ALL_BILLS_PAGINATED = gql`
ro_number
}
}
search_bills_aggregate(args: { search: $search }) {
bills_aggregate {
aggregate {
count(distinct: true)
}

View File

@@ -117,6 +117,7 @@ export const QUERY_BODYSHOP = gql`
md_parts_scan
enforce_conversion_category
tt_enforce_hours_for_tech_console
use_paint_scale_data
employees {
user_email
id

View File

@@ -1781,14 +1781,12 @@ export const QUERY_ALL_JOB_FIELDS = gql`
export const QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED = gql`
query QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED(
$search: String
$offset: Int
$limit: Int
$order: [jobs_order_by!]
$statusList: [String!]
) {
search_jobs(
args: { search: $search }
jobs(
offset: $offset
limit: $limit
order_by: $order
@@ -1819,10 +1817,7 @@ export const QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED = gql`
updated_at
ded_amt
}
search_jobs_aggregate(
args: { search: $search }
where: { status: { _in: $statusList } }
) {
jobs_aggregate(where: { status: { _in: $statusList } }) {
aggregate {
count(distinct: true)
}

View File

@@ -4,7 +4,16 @@ export const INSERT_NEW_NOTE = gql`
mutation INSERT_NEW_NOTE($noteInput: [notes_insert_input!]!) {
insert_notes(objects: $noteInput) {
returning {
created_at
created_by
critical
id
jobid
private
text
updated_at
audit
type
}
}
}
@@ -15,8 +24,8 @@ export const QUERY_NOTES_BY_JOB_PK = gql`
jobs_by_pk(id: $id) {
id
ro_number
vehicle{
jobs{
vehicle {
jobs {
id
ro_number
status
@@ -33,6 +42,7 @@ export const QUERY_NOTES_BY_JOB_PK = gql`
text
updated_at
audit
type
}
}
}
@@ -52,6 +62,7 @@ export const UPDATE_NOTE = gql`
text
updated_at
audit
type
}
}
}

View File

@@ -12,39 +12,39 @@ export const INSERT_NEW_PAYMENT = gql`
export const QUERY_ALL_PAYMENTS_PAGINATED = gql`
query QUERY_ALL_PAYMENTS_PAGINATED(
$search: String
$offset: Int
$limit: Int
$order: [payments_order_by!]!
) {
search_payments(
args: { search: $search }
offset: $offset
limit: $limit
order_by: $order
) {
payments(offset: $offset, limit: $limit, order_by: $order) {
id
amount
created_at
jobid
paymentnum
date
exportedat
jobid
job {
id
ro_number
ownerid
ownr_co_nm
ownr_fn
ownr_ln
ownr_co_nm
owner {
id
ownr_co_nm
ownr_fn
ownr_ln
}
ro_number
}
transactionid
memo
type
amount
stripeid
exportedat
stripeid
payer
paymentnum
stripeid
transactionid
type
}
search_payments_aggregate(args: { search: $search }) {
payments_aggregate {
aggregate {
count(distinct: true)
}
@@ -57,16 +57,31 @@ export const UPDATE_PAYMENT = gql`
update_payments(where: { id: { _eq: $paymentId } }, _set: $payment) {
returning {
id
transactionid
memo
type
amount
stripeid
created_at
date
exportedat
stripeid
jobid
job {
id
ownerid
ownr_co_nm
ownr_fn
ownr_ln
owner {
id
ownr_co_nm
ownr_fn
ownr_ln
}
ro_number
}
memo
payer
paymentnum
date
stripeid
transactionid
type
}
}
}
@@ -80,17 +95,31 @@ export const UPDATE_PAYMENTS = gql`
update_payments(where: { id: { _in: $paymentIdList } }, _set: $payment) {
returning {
id
exportedat
transactionid
memo
type
amount
stripeid
created_at
date
exportedat
stripeid
jobid
job {
id
ownerid
ownr_co_nm
ownr_fn
ownr_ln
owner {
id
ownr_co_nm
ownr_fn
ownr_ln
}
ro_number
}
memo
payer
paymentnum
date
stripeid
transactionid
type
}
}
}
@@ -109,3 +138,36 @@ export const QUERY_JOB_PAYMENT_TOTALS = gql`
}
}
`;
export const QUERY_PAYMENT_BY_ID = gql`
query QUERY_PAYMENT_BY_ID($paymentId: uuid!) {
payments_by_pk(id: $paymentId) {
id
amount
created_at
exportedat
date
jobid
job {
id
ownerid
ownr_co_nm
ownr_fn
ownr_ln
owner {
id
ownr_co_nm
ownr_fn
ownr_ln
}
ro_number
}
memo
payer
paymentnum
stripeid
transactionid
type
}
}
`;

View File

@@ -19,6 +19,7 @@ export const QUERY_SCOREBOARD = gql`
v_make_desc
v_model_desc
v_model_yr
job_totals
}
}
}

View File

@@ -59,6 +59,81 @@ export const QUERY_TIME_TICKETS_IN_RANGE = gql`
}
`;
export const QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE = gql`
query QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE(
$employeeid: uuid!
$start: date!
$end: date!
$fixedStart: date!
$fixedEnd: date!
) {
timetickets(
where: {
date: { _gte: $start, _lte: $end }
employeeid: { _eq: $employeeid }
}
order_by: { date: desc_nulls_first }
) {
actualhrs
ciecacode
clockoff
clockon
cost_center
created_at
date
id
rate
productivehrs
memo
jobid
flat_rate
job {
id
ro_number
}
employeeid
employee {
id
employee_number
first_name
last_name
}
}
fixedperiod: timetickets(
where: {
date: { _gte: $fixedStart, _lte: $fixedEnd }
employeeid: { _eq: $employeeid }
}
order_by: { date: desc_nulls_first }
) {
actualhrs
ciecacode
clockoff
clockon
cost_center
created_at
date
id
rate
productivehrs
memo
jobid
flat_rate
job {
id
ro_number
}
employeeid
employee {
id
employee_number
first_name
last_name
}
}
}
`;
export const QUERY_TIME_TICKETS_IN_RANGE_SB = gql`
query QUERY_TIME_TICKETS_IN_RANGE_SB(
$start: date!

View File

@@ -1,7 +1,8 @@
import { SyncOutlined, EditFilled } from "@ant-design/icons";
import { EditFilled, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Checkbox, Input, Space, Table, Typography } from "antd";
import axios from "axios";
import queryString from "query-string";
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link, useHistory, useLocation } from "react-router-dom";
@@ -11,8 +12,8 @@ import PrintWrapperComponent from "../../components/print-wrapper/print-wrapper.
import { setModalContext } from "../../redux/modals/modals.actions";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateFormatter } from "../../utils/DateFormatter";
import { alphaSort, dateSort } from "../../utils/sorters";
import { TemplateList } from "../../utils/TemplateConstants";
import { alphaSort, dateSort } from "../../utils/sorters";
const mapDispatchToProps = (dispatch) => ({
setPartsOrderContext: (context) =>
@@ -29,34 +30,36 @@ export function BillsListPage({
setPartsOrderContext,
setBillEnterContext,
}) {
const { t } = useTranslation();
const search = queryString.parse(useLocation().search);
const [openSearchResults, setOpenSearchResults] = useState([]);
const [searchLoading, setSearchLoading] = useState(false);
const { page } = search;
const history = useHistory();
const [state, setState] = useState({
sortedInfo: {},
filteredInfo: { text: "" },
});
const history = useHistory();
const search = queryString.parse(useLocation().search);
const { page } = search;
const Templates = TemplateList("bill");
const { t } = useTranslation();
const columns = [
{
title: t("bills.fields.vendorname"),
dataIndex: "vendorname",
key: "vendorname",
sortObject: (direction) => {
return {
vendor: {
name: direction
? direction === "descend"
? "desc"
: "asc"
: "desc",
},
};
},
sorter: (a, b) => alphaSort(a.vendor.name, b.vendor.name),
sortOrder:
state.sortedInfo.columnKey === "vendorname" && state.sortedInfo.order,
// sortObject: (direction) => {
// return {
// vendor: {
// name: direction
// ? direction === "descend"
// ? "desc"
// : "asc"
// : "desc",
// },
// };
// },
// sorter: (a, b) => alphaSort(a.vendor.name, b.vendor.name),
// sortOrder:
// state.sortedInfo.columnKey === "vendorname" && state.sortedInfo.order,
render: (text, record) => <span>{record.vendor.name}</span>,
},
{
@@ -72,20 +75,20 @@ export function BillsListPage({
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
sortObject: (direction) => {
return {
job: {
ro_number: direction
? direction === "descend"
? "desc"
: "asc"
: "desc",
},
};
},
sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
sortOrder:
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
// sortObject: (direction) => {
// return {
// job: {
// ro_number: direction
// ? direction === "descend"
// ? "desc"
// : "asc"
// : "desc",
// },
// };
// },
// sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
// sortOrder:
// state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
render: (text, record) =>
record.job && (
<Link to={`/manage/jobs/${record.job.id}`}>
@@ -174,7 +177,15 @@ export function BillsListPage({
// {t("bills.actions.return")}
// </Button>
}
<BillDeleteButton bill={record} />
<BillDeleteButton
bill={record}
callback={(deletedBillid) => {
//Filter out the state and set it again.
setOpenSearchResults((currentResults) =>
currentResults.filter((bill) => bill.id !== deletedBillid)
);
}}
/>
{record.isinhouse && (
<PrintWrapperComponent
templateObject={{
@@ -199,11 +210,32 @@ export function BillsListPage({
search.sortcolumn = sorter.order ? sorter.columnKey : null;
search.sortorder = sorter.order;
}
search.sort = JSON.stringify({ [sorter.columnKey]: sorter.order });
history.push({ search: queryString.stringify(search) });
};
useEffect(() => {
if (search.search && search.search.trim() !== "") {
searchBills();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
async function searchBills(value) {
try {
setSearchLoading(true);
const searchData = await axios.post("/search", {
search: value || search.search,
index: "bills",
});
setOpenSearchResults(searchData.data.hits.hits.map((s) => s._source));
} catch (error) {
console.log("Error while fetching search results", error);
} finally {
setSearchLoading(false);
}
}
return (
<Card
title={t("bills.labels.bills")}
@@ -217,6 +249,7 @@ export function BillsListPage({
<Button
onClick={() => {
delete search.search;
delete search.page;
history.push({ search: queryString.stringify(search) });
}}
>
@@ -243,7 +276,10 @@ export function BillsListPage({
onSearch={(value) => {
search.search = value;
history.push({ search: queryString.stringify(search) });
searchBills(value);
}}
loading={loading || searchLoading}
enterButton
/>
</Space>
}
@@ -251,19 +287,27 @@ export function BillsListPage({
<PartsOrderModalContainer />
<Table
loading={loading}
scroll={{
x: "50%", // y: "40rem"
}}
pagination={{
position: "top",
pageSize: 25,
current: parseInt(page || 1),
total: total,
}}
loading={loading || searchLoading}
// scroll={{
// x: "50%", // y: "40rem"
// }}
scroll={{ x: true }}
pagination={
search?.search
? {
pageSize: 25,
showSizeChanger: false,
}
: {
pageSize: 25,
current: parseInt(page || 1),
total: total,
showSizeChanger: false,
}
}
columns={columns}
rowKey="id"
dataSource={data}
dataSource={search?.search ? openSearchResults : data}
onChange={handleTableChange}
/>
</Card>

View File

@@ -1,6 +1,6 @@
import { useQuery } from "@apollo/client";
import queryString from "query-string";
import React, { useEffect } from "react";
import { useQuery } from "@apollo/client";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useLocation } from "react-router-dom";
@@ -22,7 +22,7 @@ const mapDispatchToProps = (dispatch) => ({
export function BillsPageContainer({ setBreadcrumbs, setSelectedHeader }) {
const { t } = useTranslation();
const searchParams = queryString.parse(useLocation().search);
const { page, sortcolumn, sortorder, search, searchObj } = searchParams;
const { page, sortcolumn, sortorder, searchObj } = searchParams;
useEffect(() => {
document.title = t("titles.bills-list");
@@ -38,7 +38,6 @@ export function BillsPageContainer({ setBreadcrumbs, setSelectedHeader }) {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
variables: {
search: search || "",
offset: page ? (page - 1) * 25 : 0,
limit: 25,
order: [
@@ -61,10 +60,10 @@ export function BillsPageContainer({ setBreadcrumbs, setSelectedHeader }) {
<RbacWrapper action="bills:list">
<div>
<BillsPageComponent
data={data ? data.search_bills : []}
data={data ? data.bills : []}
loading={loading}
refetch={refetch}
total={data ? data.search_bills_aggregate.aggregate.count : 0}
total={data ? data.bills_aggregate.aggregate.count : 0}
/>
<BillDetailEditContainer />

View File

@@ -25,7 +25,7 @@ const mapDispatchToProps = (dispatch) => ({
export function AllJobs({ setBreadcrumbs, setSelectedHeader }) {
const searchParams = queryString.parse(useLocation().search);
const { page, sortcolumn, sortorder, search, statusFilters } = searchParams;
const { page, sortcolumn, sortorder, statusFilters } = searchParams;
const { loading, error, data, refetch } = useQuery(
QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED,
@@ -33,13 +33,12 @@ export function AllJobs({ setBreadcrumbs, setSelectedHeader }) {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
variables: {
search: search || "",
offset: page ? (page - 1) * 25 : 0,
limit: 25,
...(statusFilters ? { statusList: JSON.parse(statusFilters) } : {}),
order: [
{
[sortcolumn || "created_at"]:
[sortcolumn || "ro_number"]:
sortorder && sortorder !== "false"
? sortorder === "descend"
? "desc"
@@ -67,8 +66,8 @@ export function AllJobs({ setBreadcrumbs, setSelectedHeader }) {
refetch={refetch}
loading={loading}
searchParams={searchParams}
total={data ? data.search_jobs_aggregate.aggregate.count : 0}
jobs={data ? data.search_jobs : []}
total={data ? data.jobs_aggregate.aggregate.count : 0}
jobs={data ? data.jobs : []}
/>
</RbacWrapper>
);

View File

@@ -52,6 +52,7 @@ import AuditTrailMapping from "../../utils/AuditTrailMappings";
import { insertAuditTrail } from "../../redux/application/application.actions";
import JobsDocumentsLocalGallery from "../../components/jobs-documents-local-gallery/jobs-documents-local-gallery.container";
import UndefinedToNull from "../../utils/undefinedtonull";
import NoteUpsertModalComponent from "../../components/note-upsert-modal/note-upsert-modal.container";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -97,7 +98,11 @@ export function JobsDetailPage({
variables: {
jobId: job.id,
job: {
...UndefinedToNull(values, ["alt_transport", "category", "referral_source"]),
...UndefinedToNull(values, [
"alt_transport",
"category",
"referral_source",
]),
parts_tax_rates: {
...job.parts_tax_rates,
...values.parts_tax_rates,
@@ -231,6 +236,7 @@ export function JobsDetailPage({
<ScheduleJobModalContainer />
<JobReconciliationModal />
<JobLineUpsertModalContainer />
<NoteUpsertModalComponent />
<Form
form={form}
name="JobDetailForm"

View File

@@ -26,7 +26,7 @@ const mapDispatchToProps = (dispatch) => ({
export function AllJobs({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
const searchParams = queryString.parse(useLocation().search);
const { page, sortcolumn, sortorder, search } = searchParams;
const { page, sortcolumn, sortorder, searchObj } = searchParams;
const { loading, error, data, refetch } = useQuery(
QUERY_ALL_PAYMENTS_PAGINATED,
@@ -34,11 +34,12 @@ export function AllJobs({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
variables: {
search: search || "",
offset: page ? (page - 1) * 25 : 0,
limit: 25,
order: [
{
searchObj
? JSON.parse(searchObj)
: {
[sortcolumn || "date"]: sortorder
? sortorder === "descend"
? "desc"
@@ -66,8 +67,8 @@ export function AllJobs({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
refetch={refetch}
loading={loading}
searchParams={searchParams}
total={data ? data.search_payments_aggregate.aggregate.count : 0}
payments={data ? data.search_payments : []}
total={data ? data.payments_aggregate.aggregate.count : 0}
payments={data ? data.payments : []}
/>
</RbacWrapper>
);

View File

@@ -2,10 +2,12 @@ import { Divider } from "antd";
import React from "react";
import TechClockInFormContainer from "../../components/tech-job-clock-in-form/tech-job-clock-in-form.container";
import TechClockedInList from "../../components/tech-job-clocked-in-list/tech-job-clocked-in-list.component";
import TechJobStatistics from "../../components/tech-job-statistics/tech-job-statistics.component";
export default function TechClockComponent() {
return (
<div>
<TechJobStatistics />
<TechClockInFormContainer />
<Divider />
<TechClockedInList />

View File

@@ -63,6 +63,7 @@
"scheduledfor": "Scheduled appointment for: ",
"severalerrorsfound": "Several jobs have issues which may prevent accurate smart scheduling. Click to expand.",
"smartscheduling": "Smart Scheduling",
"smspaymentreminder": "",
"suggesteddates": "Suggested Dates"
},
"successes": {
@@ -103,6 +104,7 @@
"admin_jobunvoid": "ADMIN: Job has been unvoided.",
"billposted": "Bill with invoice number {{invoice_number}} posted.",
"billupdated": "Bill with invoice number {{invoice_number}} updated.",
"failedpayment": "",
"jobassignmentchange": "Employee {{name}} assigned to {{operation}}",
"jobassignmentremoved": "Employee assignment removed for {{operation}}",
"jobchecklist": "Checklist type \"{{type}}\" completed. In production set to {{inproduction}}. Status set to {{status}}.",
@@ -227,6 +229,7 @@
},
"bodyshop": {
"actions": {
"add_task_preset": "",
"addapptcolor": "Add Appointment Color",
"addbucket": "Add Definition",
"addpartslocation": "Add Parts Location",
@@ -339,6 +342,12 @@
},
"md_payment_types": "Payment Types",
"md_referral_sources": "Referral Sources",
"md_tasks_presets": {
"hourstype": "",
"memo": "",
"name": "",
"percent": ""
},
"messaginglabel": "Messaging Preset Label",
"messagingtext": "Messaging Preset Text",
"noteslabel": "Note Label",
@@ -374,6 +383,9 @@
"export": "CSI -> Export",
"page": "CSI -> Page"
},
"employee_teams": {
"page": ""
},
"employees": {
"page": "Employees -> List"
},
@@ -432,10 +444,15 @@
},
"timetickets": {
"edit": "Time Tickets -> Edit",
"editcommitted": "",
"enter": "Time Tickets -> Enter",
"list": "Time Tickets -> List",
"shiftedit": "Time Tickets -> Shift Edit"
},
"ttapprovals": {
"approve": "",
"view": ""
},
"users": {
"editaccess": "Users -> Edit access"
}
@@ -453,6 +470,8 @@
"federal_tax": "Federal Tax",
"federal_tax_itc": "Federal Tax Credit",
"gst_override": "GST Override Account #",
"invoiceexemptcode": "",
"itemexemptcode": "",
"la1": "LA1",
"la2": "LA2",
"la3": "LA3",
@@ -504,6 +523,7 @@
"dailyhrslimit": "Daily Incoming Hours Limit"
},
"ssbuckets": {
"color": "Job Color",
"gte": "Greater Than/Equal to (hrs)",
"id": "ID",
"label": "Label",
@@ -543,6 +563,7 @@
"tt_allow_post_to_invoiced": "Allow Time Tickets to be posted to Invoiced & Exported Jobs",
"tt_enforce_hours_for_tech_console": "Restrict Claimable hours from Tech Console",
"use_fippa": "Use FIPPA for Names on Generated Documents?",
"use_paint_scale_data": "Use Paint Scale Data for Job Costing?",
"uselocalmediaserver": "Use Local Media Server?",
"website": "Website",
"zip_post": "Zip/Postal Code"
@@ -573,6 +594,7 @@
"title": "DMS"
},
"emaillater": "Email Later",
"employee_teams": "",
"employees": "Employees",
"estimators": "Estimators",
"filehandlers": "File Handlers",
@@ -581,6 +603,7 @@
"jobstatuses": "Job Statuses",
"laborrates": "Labor Rates",
"licensing": "Licensing",
"md_tasks_presets": "",
"md_to_emails": "Preset To Emails",
"md_to_emails_emails": "Emails",
"messagingpresets": "Messaging Presets",
@@ -607,6 +630,7 @@
"speedprint": "Speed Print Configuration",
"ssbuckets": "Job Size Definitions",
"systemsettings": "System Settings",
"task-presets": "",
"workingdays": "Working Days"
},
"successes": {
@@ -906,6 +930,18 @@
"sent": "Email sent successfully."
}
},
"employee_teams": {
"actions": {
"new": "",
"newmember": ""
},
"fields": {
"active": "",
"employeeid": "",
"name": "",
"percentage": ""
}
},
"employees": {
"actions": {
"addvacation": "Add Vacation",
@@ -1145,6 +1181,30 @@
"updated": "Inventory line updated."
}
},
"job_payments": {
"buttons": {
"goback": "",
"proceedtopayment": "",
"refundpayment": ""
},
"notifications": {
"error": {
"description": "",
"title": ""
}
},
"titles": {
"amount": "",
"dateOfPayment": "",
"descriptions": "",
"payer": "",
"payername": "",
"paymentid": "",
"paymenttype": "",
"refundamount": "",
"transactionid": ""
}
},
"joblines": {
"actions": {
"converttolabor": "Convert amount to Labor.",
@@ -1377,7 +1437,7 @@
"ded_amt": "Deductible",
"ded_note": "Deductible Note",
"ded_status": "Deductible Status",
"depreciation_taxes": "Depreciation/Taxes",
"depreciation_taxes": "Betterment/Depreciation/Taxes",
"dms": {
"address": "Customer Address",
"amount": "Amount",
@@ -1577,6 +1637,7 @@
"scheddates": "Schedule Dates"
},
"labels": {
"act_price_ppc": "",
"actual_completion_inferred": "$t(jobs.fields.actual_completion) inferred using $t(jobs.fields.scheduled_completion).",
"actual_delivery_inferred": "$t(jobs.fields.actual_delivery) inferred using $t(jobs.fields.scheduled_delivery).",
"actual_in_inferred": "$t(jobs.fields.actual_in) inferred using $t(jobs.fields.scheduled_in).",
@@ -1713,6 +1774,7 @@
"partstotal": "This is the total of all parts and sublet amounts on the vehicle (some of these may require an in-house invoice).<br/>\nItems such as shop and paint materials, labor online lines, etc. are not included in this total.",
"totalreturns": "The total <b>retail</b> amount of returns created for this job."
},
"ppc": "",
"profileadjustments": "",
"prt_dsmk_total": "Line Item Adjustment",
"rates": "Rates",
@@ -1853,6 +1915,7 @@
"customers": "Customers",
"dashboard": "Dashboard",
"enterbills": "Enter Bills",
"entercardpayment": "",
"enterpayment": "Enter Payments",
"entertimeticket": "Enter Time Tickets",
"export": "Export",
@@ -1864,6 +1927,7 @@
"newjob": "Create New Job",
"owners": "Owners",
"parts-queue": "Parts Queue",
"paymentremindersms": "",
"phonebook": "Phonebook",
"productionboard": "Production Board - Visual",
"productionlist": "Production Board - List",
@@ -1889,6 +1953,7 @@
"shop_vendors": "Vendors",
"temporarydocs": "Temporary Documents",
"timetickets": "Time Tickets",
"ttapprovals": "",
"vehicles": "Vehicles"
},
"jobsactions": {
@@ -1961,7 +2026,8 @@
"actions": "Actions",
"deletenote": "Delete Note",
"edit": "Edit Note",
"new": "New Note"
"new": "New Note",
"savetojobnotes": "Save to Job Notes"
},
"errors": {
"inserting": "Error inserting note. {{error}}"
@@ -1971,6 +2037,16 @@
"critical": "Critical",
"private": "Private",
"text": "Contents",
"type": "Type",
"types": {
"customer": "Customer",
"general": "General",
"office": "Office",
"paint": "Paint",
"parts": "Parts",
"shop": "Shop",
"supplement": "Supplement"
},
"updatedat": "Updated At"
},
"labels": {
@@ -2240,7 +2316,7 @@
"folder_label_multiple": "Folder Label - Multi",
"glass_express_checklist": "Glass Express Checklist",
"guarantee": "Repair Guarantee",
"individual_job_note": "Job Note RO # {{ro_number}}",
"individual_job_note": "RO Job Note",
"invoice_customer_payable": "Invoice (Customer Payable)",
"invoice_total_payable": "Invoice (Total Payable)",
"iou_form": "IOU Form",
@@ -2318,6 +2394,7 @@
},
"subjects": {
"jobs": {
"individual_job_note": "Job Note RO: {{ro_number}}",
"parts_order": "Parts Order PO: {{ro_number}} - {{name}}",
"sublet_order": "Sublet Order PO: {{ro_number}} - {{name}}"
}
@@ -2361,6 +2438,7 @@
"qbo_usa": "QBO USA"
}
},
"cardcolor": "Card Colors",
"cardsettings": "Card Settings",
"clm_no": "Claim Number",
"comment": "Comment",
@@ -2371,6 +2449,7 @@
"ins_co_nm": "Insurance Company Name",
"jobdetail": "Job Details",
"laborhrs": "Labor Hours",
"legend": "Legend:",
"note": "Production Note",
"ownr_nm": "Owner Name",
"paintpriority": "P/P",
@@ -2609,6 +2688,7 @@
},
"timetickets": {
"actions": {
"claimtasks": "",
"clockin": "Clock In",
"clockout": "Clock Out",
"enter": "Enter New Time Ticket",
@@ -2629,10 +2709,12 @@
"clockhours": "Clock Hours",
"clockoff": "Clock Off",
"clockon": "Clocked In",
"committed": "",
"cost_center": "Cost Center",
"date": "Ticket Date",
"efficiency": "Efficiency",
"employee": "Employee",
"employee_team": "",
"flat_rate": "Flat Rate?",
"memo": "Memo",
"productivehrs": "Productive Hours",
@@ -2719,6 +2801,7 @@
"shop-vendors": "Vendors",
"temporarydocs": "Temporary Documents",
"timetickets": "Time Tickets",
"ttapprovals": "",
"vehicle-details": "Vehicle: {{vehicle}}",
"vehicles": "Vehicles"
},
@@ -2764,9 +2847,15 @@
"shop_vendors": "Vendors | $t(titles.app)",
"temporarydocs": "Temporary Documents | $t(titles.app)",
"timetickets": "Time Tickets | $t(titles.app)",
"ttapprovals": "",
"vehicledetail": "Vehicle Details {{vehicle}} | $t(titles.app)",
"vehicles": "All Vehicles | $t(titles.app)"
},
"tt_approvals": {
"actions": {
"approveselected": ""
}
},
"user": {
"actions": {
"changepassword": "Change Password",

View File

@@ -63,6 +63,7 @@
"scheduledfor": "Cita programada para:",
"severalerrorsfound": "",
"smartscheduling": "",
"smspaymentreminder": "",
"suggesteddates": ""
},
"successes": {
@@ -103,6 +104,7 @@
"admin_jobunvoid": "",
"billposted": "",
"billupdated": "",
"failedpayment": "",
"jobassignmentchange": "",
"jobassignmentremoved": "",
"jobchecklist": "",
@@ -227,6 +229,7 @@
},
"bodyshop": {
"actions": {
"add_task_preset": "",
"addapptcolor": "",
"addbucket": "",
"addpartslocation": "",
@@ -339,6 +342,12 @@
},
"md_payment_types": "",
"md_referral_sources": "",
"md_tasks_presets": {
"hourstype": "",
"memo": "",
"name": "",
"percent": ""
},
"messaginglabel": "",
"messagingtext": "",
"noteslabel": "",
@@ -374,6 +383,9 @@
"export": "",
"page": ""
},
"employee_teams": {
"page": ""
},
"employees": {
"page": ""
},
@@ -432,10 +444,15 @@
},
"timetickets": {
"edit": "",
"editcommitted": "",
"enter": "",
"list": "",
"shiftedit": ""
},
"ttapprovals": {
"approve": "",
"view": ""
},
"users": {
"editaccess": ""
}
@@ -453,6 +470,8 @@
"federal_tax": "",
"federal_tax_itc": "",
"gst_override": "",
"invoiceexemptcode": "",
"itemexemptcode": "",
"la1": "",
"la2": "",
"la3": "",
@@ -504,6 +523,7 @@
"dailyhrslimit": ""
},
"ssbuckets": {
"color": "",
"gte": "",
"id": "",
"label": "",
@@ -543,6 +563,7 @@
"tt_allow_post_to_invoiced": "",
"tt_enforce_hours_for_tech_console": "",
"use_fippa": "",
"use_paint_scale_data": "",
"uselocalmediaserver": "",
"website": "",
"zip_post": ""
@@ -573,6 +594,7 @@
"title": ""
},
"emaillater": "",
"employee_teams": "",
"employees": "",
"estimators": "",
"filehandlers": "",
@@ -581,6 +603,7 @@
"jobstatuses": "",
"laborrates": "",
"licensing": "",
"md_tasks_presets": "",
"md_to_emails": "",
"md_to_emails_emails": "",
"messagingpresets": "",
@@ -607,6 +630,7 @@
"speedprint": "",
"ssbuckets": "",
"systemsettings": "",
"task-presets": "",
"workingdays": ""
},
"successes": {
@@ -906,6 +930,18 @@
"sent": "Correo electrónico enviado con éxito."
}
},
"employee_teams": {
"actions": {
"new": "",
"newmember": ""
},
"fields": {
"active": "",
"employeeid": "",
"name": "",
"percentage": ""
}
},
"employees": {
"actions": {
"addvacation": "",
@@ -1145,6 +1181,30 @@
"updated": ""
}
},
"job_payments": {
"buttons": {
"goback": "",
"proceedtopayment": "",
"refundpayment": ""
},
"notifications": {
"error": {
"description": "",
"title": ""
}
},
"titles": {
"amount": "",
"dateOfPayment": "",
"descriptions": "",
"payer": "",
"payername": "",
"paymentid": "",
"paymenttype": "",
"refundamount": "",
"transactionid": ""
}
},
"joblines": {
"actions": {
"converttolabor": "",
@@ -1577,6 +1637,7 @@
"scheddates": ""
},
"labels": {
"act_price_ppc": "",
"actual_completion_inferred": "",
"actual_delivery_inferred": "",
"actual_in_inferred": "",
@@ -1713,6 +1774,7 @@
"partstotal": "",
"totalreturns": ""
},
"ppc": "",
"profileadjustments": "",
"prt_dsmk_total": "",
"rates": "Tarifas",
@@ -1853,6 +1915,7 @@
"customers": "Clientes",
"dashboard": "",
"enterbills": "",
"entercardpayment": "",
"enterpayment": "",
"entertimeticket": "",
"export": "",
@@ -1864,6 +1927,7 @@
"newjob": "",
"owners": "propietarios",
"parts-queue": "",
"paymentremindersms": "",
"phonebook": "",
"productionboard": "",
"productionlist": "",
@@ -1889,6 +1953,7 @@
"shop_vendors": "Vendedores",
"temporarydocs": "",
"timetickets": "",
"ttapprovals": "",
"vehicles": "Vehículos"
},
"jobsactions": {
@@ -1961,7 +2026,8 @@
"actions": "Comportamiento",
"deletenote": "Borrar nota",
"edit": "Editar nota",
"new": "Nueva nota"
"new": "Nueva nota",
"savetojobnotes": ""
},
"errors": {
"inserting": ""
@@ -1971,6 +2037,16 @@
"critical": "Crítico",
"private": "Privado",
"text": "Contenido",
"type": "",
"types": {
"customer": "",
"general": "",
"office": "",
"paint": "",
"parts": "",
"shop": "",
"supplement": ""
},
"updatedat": "Actualizado en"
},
"labels": {
@@ -2318,6 +2394,7 @@
},
"subjects": {
"jobs": {
"individual_job_note": "",
"parts_order": "",
"sublet_order": ""
}
@@ -2361,6 +2438,7 @@
"qbo_usa": ""
}
},
"cardcolor": "",
"cardsettings": "",
"clm_no": "",
"comment": "",
@@ -2371,6 +2449,7 @@
"ins_co_nm": "",
"jobdetail": "",
"laborhrs": "",
"legend": "",
"note": "",
"ownr_nm": "",
"paintpriority": "",
@@ -2609,6 +2688,7 @@
},
"timetickets": {
"actions": {
"claimtasks": "",
"clockin": "",
"clockout": "",
"enter": "",
@@ -2629,10 +2709,12 @@
"clockhours": "",
"clockoff": "",
"clockon": "",
"committed": "",
"cost_center": "",
"date": "",
"efficiency": "",
"employee": "",
"employee_team": "",
"flat_rate": "",
"memo": "",
"productivehrs": "",
@@ -2719,6 +2801,7 @@
"shop-vendors": "",
"temporarydocs": "",
"timetickets": "",
"ttapprovals": "",
"vehicle-details": "",
"vehicles": ""
},
@@ -2764,9 +2847,15 @@
"shop_vendors": "Vendedores | $t(titles.app)",
"temporarydocs": "",
"timetickets": "",
"ttapprovals": "",
"vehicledetail": "Detalles del vehículo {{vehicle}} | $t(titles.app)",
"vehicles": "Todos los vehiculos | $t(titles.app)"
},
"tt_approvals": {
"actions": {
"approveselected": ""
}
},
"user": {
"actions": {
"changepassword": "",

View File

@@ -63,6 +63,7 @@
"scheduledfor": "Rendez-vous prévu pour:",
"severalerrorsfound": "",
"smartscheduling": "",
"smspaymentreminder": "",
"suggesteddates": ""
},
"successes": {
@@ -103,6 +104,7 @@
"admin_jobunvoid": "",
"billposted": "",
"billupdated": "",
"failedpayment": "",
"jobassignmentchange": "",
"jobassignmentremoved": "",
"jobchecklist": "",
@@ -227,6 +229,7 @@
},
"bodyshop": {
"actions": {
"add_task_preset": "",
"addapptcolor": "",
"addbucket": "",
"addpartslocation": "",
@@ -339,6 +342,12 @@
},
"md_payment_types": "",
"md_referral_sources": "",
"md_tasks_presets": {
"hourstype": "",
"memo": "",
"name": "",
"percent": ""
},
"messaginglabel": "",
"messagingtext": "",
"noteslabel": "",
@@ -374,6 +383,9 @@
"export": "",
"page": ""
},
"employee_teams": {
"page": ""
},
"employees": {
"page": ""
},
@@ -432,10 +444,15 @@
},
"timetickets": {
"edit": "",
"editcommitted": "",
"enter": "",
"list": "",
"shiftedit": ""
},
"ttapprovals": {
"approve": "",
"view": ""
},
"users": {
"editaccess": ""
}
@@ -453,6 +470,8 @@
"federal_tax": "",
"federal_tax_itc": "",
"gst_override": "",
"invoiceexemptcode": "",
"itemexemptcode": "",
"la1": "",
"la2": "",
"la3": "",
@@ -504,6 +523,7 @@
"dailyhrslimit": ""
},
"ssbuckets": {
"color": "",
"gte": "",
"id": "",
"label": "",
@@ -543,6 +563,7 @@
"tt_allow_post_to_invoiced": "",
"tt_enforce_hours_for_tech_console": "",
"use_fippa": "",
"use_paint_scale_data": "",
"uselocalmediaserver": "",
"website": "",
"zip_post": ""
@@ -573,6 +594,7 @@
"title": ""
},
"emaillater": "",
"employee_teams": "",
"employees": "",
"estimators": "",
"filehandlers": "",
@@ -581,6 +603,7 @@
"jobstatuses": "",
"laborrates": "",
"licensing": "",
"md_tasks_presets": "",
"md_to_emails": "",
"md_to_emails_emails": "",
"messagingpresets": "",
@@ -607,6 +630,7 @@
"speedprint": "",
"ssbuckets": "",
"systemsettings": "",
"task-presets": "",
"workingdays": ""
},
"successes": {
@@ -906,6 +930,18 @@
"sent": "E-mail envoyé avec succès."
}
},
"employee_teams": {
"actions": {
"new": "",
"newmember": ""
},
"fields": {
"active": "",
"employeeid": "",
"name": "",
"percentage": ""
}
},
"employees": {
"actions": {
"addvacation": "",
@@ -1145,6 +1181,30 @@
"updated": ""
}
},
"job_payments": {
"buttons": {
"goback": "",
"proceedtopayment": "",
"refundpayment": ""
},
"notifications": {
"error": {
"description": "",
"title": ""
}
},
"titles": {
"amount": "",
"dateOfPayment": "",
"descriptions": "",
"payer": "",
"payername": "",
"paymentid": "",
"paymenttype": "",
"refundamount": "",
"transactionid": ""
}
},
"joblines": {
"actions": {
"converttolabor": "",
@@ -1577,6 +1637,7 @@
"scheddates": ""
},
"labels": {
"act_price_ppc": "",
"actual_completion_inferred": "",
"actual_delivery_inferred": "",
"actual_in_inferred": "",
@@ -1713,6 +1774,7 @@
"partstotal": "",
"totalreturns": ""
},
"ppc": "",
"profileadjustments": "",
"prt_dsmk_total": "",
"rates": "Les taux",
@@ -1853,6 +1915,7 @@
"customers": "Les clients",
"dashboard": "",
"enterbills": "",
"entercardpayment": "",
"enterpayment": "",
"entertimeticket": "",
"export": "",
@@ -1864,6 +1927,7 @@
"newjob": "",
"owners": "Propriétaires",
"parts-queue": "",
"paymentremindersms": "",
"phonebook": "",
"productionboard": "",
"productionlist": "",
@@ -1889,6 +1953,7 @@
"shop_vendors": "Vendeurs",
"temporarydocs": "",
"timetickets": "",
"ttapprovals": "",
"vehicles": "Véhicules"
},
"jobsactions": {
@@ -1961,7 +2026,8 @@
"actions": "actes",
"deletenote": "Supprimer la note",
"edit": "Note éditée",
"new": "Nouvelle note"
"new": "Nouvelle note",
"savetojobnotes": ""
},
"errors": {
"inserting": ""
@@ -1971,6 +2037,16 @@
"critical": "Critique",
"private": "privé",
"text": "Contenu",
"type": "",
"types": {
"customer": "",
"general": "",
"office": "",
"paint": "",
"parts": "",
"shop": "",
"supplement": ""
},
"updatedat": "Mis à jour à"
},
"labels": {
@@ -2318,6 +2394,7 @@
},
"subjects": {
"jobs": {
"individual_job_note": "",
"parts_order": "",
"sublet_order": ""
}
@@ -2361,6 +2438,7 @@
"qbo_usa": ""
}
},
"cardcolor": "",
"cardsettings": "",
"clm_no": "",
"comment": "",
@@ -2371,6 +2449,7 @@
"ins_co_nm": "",
"jobdetail": "",
"laborhrs": "",
"legend": "",
"note": "",
"ownr_nm": "",
"paintpriority": "",
@@ -2609,6 +2688,7 @@
},
"timetickets": {
"actions": {
"claimtasks": "",
"clockin": "",
"clockout": "",
"enter": "",
@@ -2629,10 +2709,12 @@
"clockhours": "",
"clockoff": "",
"clockon": "",
"committed": "",
"cost_center": "",
"date": "",
"efficiency": "",
"employee": "",
"employee_team": "",
"flat_rate": "",
"memo": "",
"productivehrs": "",
@@ -2719,6 +2801,7 @@
"shop-vendors": "",
"temporarydocs": "",
"timetickets": "",
"ttapprovals": "",
"vehicle-details": "",
"vehicles": ""
},
@@ -2764,9 +2847,15 @@
"shop_vendors": "Vendeurs | $t(titles.app)",
"temporarydocs": "",
"timetickets": "",
"ttapprovals": "",
"vehicledetail": "Détails du véhicule {{vehicle} | $t(titles.app)",
"vehicles": "Tous les véhicules | $t(titles.app)"
},
"tt_approvals": {
"actions": {
"approveselected": ""
}
},
"user": {
"actions": {
"changepassword": "",

View File

@@ -1,6 +1,5 @@
import { gql } from "@apollo/client";
import { notification } from "antd";
import axios from "axios";
import jsreport from "@jsreport/browser-client";
import _ from "lodash";
import moment from "moment";
@@ -9,7 +8,8 @@ import { setEmailOptions } from "../redux/email/email.actions";
import { store } from "../redux/store";
import client from "../utils/GraphQLClient";
import { TemplateList } from "./TemplateConstants";
import cleanAxios from "./CleanAxios";
import axios from "axios";
const server = process.env.REACT_APP_REPORTS_SERVER_URL;
jsreport.serverUrl = server;
@@ -26,10 +26,14 @@ export default async function RenderTemplate(
if (window.jsr3) {
jsreport.serverUrl = "https://reports3.test.imex.online/";
}
const jsrAuth = (await axios.post("/utils/jsr")).data;
jsreport.headers["Authorization"] = jsrAuth;
//Query assets that match the template name. Must be in format <<templateName>>.query
let { contextData, useShopSpecificTemplate } = await fetchContextData(
templateObject
templateObject,
jsrAuth
);
const { ignoreCustomMargins } = Templates[templateObject.name];
@@ -137,11 +141,15 @@ export async function RenderTemplates(
//Query assets that match the template name. Must be in format <<templateName>>.query
let unsortedTemplatesAndData = [];
let proms = [];
const jsrAuth = (await axios.post("/utils/jsr")).data;
jsreport.headers["Authorization"] = jsrAuth;
templateObjects.forEach((template) => {
proms.push(
(async () => {
let { contextData, useShopSpecificTemplate } = await fetchContextData(
template
template,
jsrAuth
);
unsortedTemplatesAndData.push({
templateObject: template,
@@ -298,19 +306,22 @@ export const GenerateDocuments = async (templates) => {
await RenderTemplates(templates, bodyshop);
};
const fetchContextData = async (templateObject) => {
const fetchContextData = async (templateObject, jsrAuth) => {
const bodyshop = store.getState().user.bodyshop;
jsreport.headers["Authorization"] =
jsreport.headers["FirebaseAuthorization"] =
"Bearer " + (await auth.currentUser.getIdToken());
const folders = await axios.get(`${server}/odata/folders`);
const folders = await cleanAxios.get(`${server}/odata/folders`, {
headers: { Authorization: jsrAuth },
});
const shopSpecificFolder = folders.data.value.find(
(f) => f.name === bodyshop.imexshopid
);
const jsReportQueries = await axios.get(
`${server}/odata/assets?$filter=name eq '${templateObject.name}.query'`
const jsReportQueries = await cleanAxios.get(
`${server}/odata/assets?$filter=name eq '${templateObject.name}.query'`,
{ headers: { Authorization: jsrAuth } }
);
let templateQueryToExecute;

View File

@@ -7,22 +7,24 @@ export const EmailSettings = {
export const TemplateList = (type, context) => {
//const { bodyshop } = store.getState().user;
return {
//If there's no type or the type is job, send it back.
...(!type || type === "job"
? {
casl_authorization: {
title: i18n.t("printcenter.jobs.casl_authorization"),
description: "CASL Authorization",
description: "",
subject: i18n.t("printcenter.jobs.casl_authorization"),
key: "casl_authorization",
disabled: false,
group: "authorization",
regions: {
CA: true,
},
},
fippa_authorization: {
title: i18n.t("printcenter.jobs.fippa_authorization"),
description: "CASL Authorization",
description: "",
subject: i18n.t("printcenter.jobs.fippa_authorization"),
key: "fippa_authorization",
disabled: false,
@@ -30,7 +32,7 @@ export const TemplateList = (type, context) => {
},
diagnostic_authorization: {
title: i18n.t("printcenter.jobs.diagnostic_authorization"),
description: "Diagnostic Authorization",
description: "",
subject: i18n.t("printcenter.jobs.diagnostic_authorization"),
key: "diagnostic_authorization",
disabled: false,
@@ -38,7 +40,7 @@ export const TemplateList = (type, context) => {
},
mechanical_authorization: {
title: i18n.t("printcenter.jobs.mechanical_authorization"),
description: "Diagnostic Authorization",
description: "",
subject: i18n.t("printcenter.jobs.mechanical_authorization"),
key: "mechanical_authorization",
disabled: false,
@@ -46,7 +48,7 @@ export const TemplateList = (type, context) => {
},
appointment_reminder: {
title: i18n.t("printcenter.jobs.appointment_reminder"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.appointment_reminder"),
key: "appointment_reminder",
disabled: false,
@@ -54,7 +56,7 @@ export const TemplateList = (type, context) => {
},
estimate_followup: {
title: i18n.t("printcenter.jobs.estimate_followup"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.estimate_followup"),
key: "estimate_followup",
disabled: false,
@@ -62,7 +64,7 @@ export const TemplateList = (type, context) => {
},
express_repair_checklist: {
title: i18n.t("printcenter.jobs.express_repair_checklist"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.express_repair_checklist"),
key: "express_repair_checklist",
disabled: false,
@@ -70,7 +72,7 @@ export const TemplateList = (type, context) => {
},
glass_express_checklist: {
title: i18n.t("printcenter.jobs.glass_express_checklist"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.glass_express_checklist"),
key: "glass_express_checklist",
disabled: false,
@@ -78,7 +80,7 @@ export const TemplateList = (type, context) => {
},
stolen_recovery_checklist: {
title: i18n.t("printcenter.jobs.stolen_recovery_checklist"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.stolen_recovery_checklist"),
key: "stolen_recovery_checklist",
disabled: false,
@@ -86,7 +88,7 @@ export const TemplateList = (type, context) => {
},
vehicle_check_in: {
title: i18n.t("printcenter.jobs.vehicle_check_in"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.vehicle_check_in"),
key: "vehicle_check_in",
disabled: false,
@@ -94,7 +96,7 @@ export const TemplateList = (type, context) => {
},
parts_order_history: {
title: i18n.t("printcenter.jobs.parts_order_history"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.parts_order_history"),
key: "parts_order_history",
disabled: false,
@@ -102,7 +104,7 @@ export const TemplateList = (type, context) => {
},
job_notes: {
title: i18n.t("printcenter.jobs.job_notes"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.job_notes"),
key: "job_notes",
disabled: false,
@@ -110,7 +112,7 @@ export const TemplateList = (type, context) => {
},
ro_with_description: {
title: i18n.t("printcenter.jobs.ro_with_description"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.ro_with_description"),
key: "ro_with_description",
disabled: false,
@@ -118,7 +120,7 @@ export const TemplateList = (type, context) => {
},
window_tag: {
title: i18n.t("printcenter.jobs.window_tag"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.window_tag"),
key: "window_tag",
disabled: false,
@@ -126,7 +128,7 @@ export const TemplateList = (type, context) => {
},
supplement_request: {
title: i18n.t("printcenter.jobs.supplement_request"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.supplement_request"),
key: "supplement_request",
disabled: false,
@@ -134,7 +136,7 @@ export const TemplateList = (type, context) => {
},
estimate: {
title: i18n.t("printcenter.jobs.estimate"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.estimate"),
key: "estimate",
disabled: false,
@@ -142,7 +144,7 @@ export const TemplateList = (type, context) => {
},
parts_list: {
title: i18n.t("printcenter.jobs.parts_list"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.parts_list"),
key: "parts_list",
disabled: false,
@@ -150,7 +152,7 @@ export const TemplateList = (type, context) => {
},
coversheet_portrait: {
title: i18n.t("printcenter.jobs.coversheet_portrait"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.coversheet_portrait"),
key: "coversheet_portrait",
disabled: false,
@@ -158,7 +160,7 @@ export const TemplateList = (type, context) => {
},
coversheet_landscape: {
title: i18n.t("printcenter.jobs.coversheet_landscape"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.coversheet_landscape"),
key: "coversheet_landscape",
disabled: false,
@@ -166,7 +168,7 @@ export const TemplateList = (type, context) => {
},
key_tag: {
title: i18n.t("printcenter.jobs.key_tag"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.key_tag"),
key: "key_tag",
disabled: false,
@@ -174,7 +176,7 @@ export const TemplateList = (type, context) => {
},
paint_grid: {
title: i18n.t("printcenter.jobs.paint_grid"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.paint_grid"),
key: "paint_grid",
disabled: false,
@@ -182,7 +184,7 @@ export const TemplateList = (type, context) => {
},
worksheet_by_line_number: {
title: i18n.t("printcenter.jobs.worksheet_by_line_number"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.worksheet_by_line_number"),
key: "worksheet_by_line_number",
disabled: false,
@@ -192,7 +194,7 @@ export const TemplateList = (type, context) => {
title: i18n.t(
"printcenter.jobs.worksheet_sorted_by_operation_type"
),
description: "All Jobs Notes",
description: "",
subject: i18n.t(
"printcenter.jobs.worksheet_sorted_by_operation_type"
),
@@ -202,7 +204,7 @@ export const TemplateList = (type, context) => {
},
worksheet_sorted_by_operation: {
title: i18n.t("printcenter.jobs.worksheet_sorted_by_operation"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.worksheet_sorted_by_operation"),
key: "worksheet_sorted_by_operation",
disabled: false,
@@ -212,7 +214,7 @@ export const TemplateList = (type, context) => {
title: i18n.t(
"printcenter.jobs.worksheet_sorted_by_operation_no_hours"
),
description: "All Jobs Notes",
description: "",
subject: i18n.t(
"printcenter.jobs.worksheet_sorted_by_operation_no_hours"
),
@@ -224,7 +226,7 @@ export const TemplateList = (type, context) => {
title: i18n.t(
"printcenter.jobs.worksheet_sorted_by_operation_part_type"
),
description: "All Jobs Notes",
description: "",
subject: i18n.t(
"printcenter.jobs.worksheet_sorted_by_operation_part_type"
),
@@ -234,7 +236,7 @@ export const TemplateList = (type, context) => {
},
payments_by_job: {
title: i18n.t("printcenter.jobs.payments_by_job"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.payments_by_job"),
key: "payments_by_job",
disabled: false,
@@ -242,7 +244,7 @@ export const TemplateList = (type, context) => {
},
final_invoice: {
title: i18n.t("printcenter.jobs.final_invoice"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.final_invoice"),
key: "final_invoice",
disabled: false,
@@ -250,7 +252,7 @@ export const TemplateList = (type, context) => {
},
payment_request: {
title: i18n.t("printcenter.jobs.payment_request"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.payment_request"),
key: "payment_request",
disabled: false,
@@ -258,7 +260,7 @@ export const TemplateList = (type, context) => {
},
invoice_total_payable: {
title: i18n.t("printcenter.jobs.invoice_total_payable"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.invoice_total_payable"),
key: "invoice_total_payable",
disabled: false,
@@ -266,7 +268,7 @@ export const TemplateList = (type, context) => {
},
invoice_customer_payable: {
title: i18n.t("printcenter.jobs.invoice_customer_payable"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.invoice_customer_payable"),
key: "invoice_customer_payable",
disabled: false,
@@ -274,7 +276,7 @@ export const TemplateList = (type, context) => {
},
ro_totals: {
title: i18n.t("printcenter.jobs.ro_totals"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.ro_totals"),
key: "ro_totals",
disabled: false,
@@ -282,7 +284,7 @@ export const TemplateList = (type, context) => {
},
job_costing_ro: {
title: i18n.t("printcenter.jobs.job_costing_ro"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.job_costing_ro"),
key: "job_costing_ro",
disabled: false,
@@ -290,7 +292,7 @@ export const TemplateList = (type, context) => {
},
purchases_by_ro_detail: {
title: i18n.t("printcenter.jobs.purchases_by_ro_detail"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.purchases_by_ro_detail"),
key: "purchases_by_ro_detail",
disabled: false,
@@ -298,7 +300,7 @@ export const TemplateList = (type, context) => {
},
purchases_by_ro_summary: {
title: i18n.t("printcenter.jobs.purchases_by_ro_summary"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.purchases_by_ro_summary"),
key: "purchases_by_ro_summary",
disabled: false,
@@ -306,7 +308,7 @@ export const TemplateList = (type, context) => {
},
filing_coversheet_portrait: {
title: i18n.t("printcenter.jobs.filing_coversheet_portrait"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.filing_coversheet_portrait"),
key: "filing_coversheet_portrait",
disabled: false,
@@ -314,7 +316,7 @@ export const TemplateList = (type, context) => {
},
filing_coversheet_landscape: {
title: i18n.t("printcenter.jobs.filing_coversheet_landscape"),
description: "CASL Authorization",
description: "",
subject: i18n.t("printcenter.jobs.filing_coversheet_landscape"),
key: "filing_coversheet_landscape",
disabled: false,
@@ -322,7 +324,7 @@ export const TemplateList = (type, context) => {
},
qc_sheet: {
title: i18n.t("printcenter.jobs.qc_sheet"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.qc_sheet"),
key: "qc_sheet",
disabled: false,
@@ -330,7 +332,7 @@ export const TemplateList = (type, context) => {
},
vehicle_delivery_check: {
title: i18n.t("printcenter.jobs.vehicle_delivery_check"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.vehicle_delivery_check"),
key: "vehicle_delivery_check",
disabled: false,
@@ -338,7 +340,7 @@ export const TemplateList = (type, context) => {
},
guarantee: {
title: i18n.t("printcenter.jobs.guarantee"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.guarantee"),
key: "guarantee",
disabled: false,
@@ -346,7 +348,7 @@ export const TemplateList = (type, context) => {
},
csi_invitation: {
title: i18n.t("printcenter.jobs.csi_invitation"),
description: "CSI invite",
description: "",
key: "csi_invitation",
subject: i18n.t("printcenter.jobs.csi_invitation"),
disabled: false,
@@ -354,7 +356,7 @@ export const TemplateList = (type, context) => {
},
window_tag_sublet: {
title: i18n.t("printcenter.jobs.window_tag_sublet"),
description: "Window Tag Sublet",
description: "",
key: "window_tag_sublet",
subject: i18n.t("printcenter.jobs.window_tag_sublet"),
disabled: false,
@@ -362,7 +364,7 @@ export const TemplateList = (type, context) => {
},
thank_you_ro: {
title: i18n.t("printcenter.jobs.thank_you_ro"),
description: "Thank You Letter by RO",
description: "",
key: "thank_you_ro",
subject: i18n.t("printcenter.jobs.thank_you_ro"),
disabled: false,
@@ -370,7 +372,7 @@ export const TemplateList = (type, context) => {
},
parts_label_single: {
title: i18n.t("printcenter.jobs.parts_label_single"),
description: "Thank You Letter by RO",
description: "",
key: "parts_label_single",
subject: i18n.t("printcenter.jobs.parts_label_single"),
disabled: false,
@@ -379,7 +381,7 @@ export const TemplateList = (type, context) => {
},
envelope_return_address: {
title: i18n.t("printcenter.jobs.envelope_return_address"),
description: "All Jobs Notes",
description: "",
subject: i18n.t("printcenter.jobs.envelope_return_address"),
key: "envelope_return_address",
disabled: false,
@@ -388,7 +390,7 @@ export const TemplateList = (type, context) => {
},
sgi_certificate_of_repairs: {
title: i18n.t("printcenter.jobs.sgi_certificate_of_repairs"),
description: "Thank You Letter by RO",
description: "",
key: "sgi_certificate_of_repairs",
subject: i18n.t("printcenter.jobs.sgi_certificate_of_repairs"),
disabled: false,
@@ -399,7 +401,7 @@ export const TemplateList = (type, context) => {
},
sgi_windshield_auth: {
title: i18n.t("printcenter.jobs.sgi_windshield_auth"),
description: "Thank You Letter by RO",
description: "",
key: "sgi_windshield_auth",
subject: i18n.t("printcenter.jobs.sgi_windshield_auth"),
disabled: false,
@@ -410,7 +412,7 @@ export const TemplateList = (type, context) => {
},
mpi_final_acct_sheet: {
title: i18n.t("printcenter.jobs.mpi_final_acct_sheet"),
description: "Thank You Letter by RO",
description: "",
key: "mpi_final_acct_sheet",
subject: i18n.t("printcenter.jobs.mpi_final_acct_sheet"),
disabled: false,
@@ -421,7 +423,7 @@ export const TemplateList = (type, context) => {
},
mpi_eglass_auth: {
title: i18n.t("printcenter.jobs.mpi_eglass_auth"),
description: "Thank You Letter by RO",
description: "",
key: "mpi_eglass_auth",
subject: i18n.t("printcenter.jobs.mpi_eglass_auth"),
disabled: false,
@@ -432,7 +434,7 @@ export const TemplateList = (type, context) => {
},
mpi_animal_checklist: {
title: i18n.t("printcenter.jobs.mpi_animal_checklist"),
description: "Thank You Letter by RO",
description: "",
key: "mpi_animal_checklist",
subject: i18n.t("printcenter.jobs.mpi_animal_checklist"),
disabled: false,
@@ -443,7 +445,7 @@ export const TemplateList = (type, context) => {
},
ab_proof_of_loss: {
title: i18n.t("printcenter.jobs.ab_proof_of_loss"),
description: "Thank You Letter by RO",
description: "",
key: "ab_proof_of_loss",
subject: i18n.t("printcenter.jobs.ab_proof_of_loss"),
disabled: false,
@@ -454,7 +456,7 @@ export const TemplateList = (type, context) => {
},
// parts_label_multi: {
// title: i18n.t("printcenter.jobs.parts_label_multi"),
// description: "Thank You Letter by RO",
// description: "",
// key: "parts_label_multi",
// subject: i18n.t("printcenter.jobs.parts_label_multi"),
// disabled: false,
@@ -462,7 +464,7 @@ export const TemplateList = (type, context) => {
// },
iou_form: {
title: i18n.t("printcenter.jobs.iou_form"),
description: "CASL Authorization",
description: "",
subject: i18n.t("printcenter.jobs.iou_form"),
key: "iou_form",
disabled: false,
@@ -470,7 +472,7 @@ export const TemplateList = (type, context) => {
},
lag_time_ro: {
title: i18n.t("printcenter.jobs.lag_time_ro"),
description: "CASL Authorization",
description: "",
subject: i18n.t("printcenter.jobs.lag_time_ro"),
key: "lag_time_ro",
disabled: false,
@@ -478,7 +480,7 @@ export const TemplateList = (type, context) => {
},
rental_reservation: {
title: i18n.t("printcenter.jobs.rental_reservation"),
description: "CASL Authorization",
description: "",
subject: i18n.t("printcenter.jobs.rental_reservation"),
key: "rental_reservation",
disabled: false,
@@ -486,7 +488,7 @@ export const TemplateList = (type, context) => {
},
timetickets_ro: {
title: i18n.t("printcenter.jobs.timetickets_ro"),
description: "CASL Authorization",
description: "",
subject: i18n.t("printcenter.jobs.timetickets_ro"),
key: "timetickets_ro",
disabled: false,
@@ -494,7 +496,7 @@ export const TemplateList = (type, context) => {
},
dms_posting_sheet: {
title: i18n.t("printcenter.jobs.dms_posting_sheet"),
description: "DMS Posting Sheet",
description: "",
subject: i18n.t("printcenter.jobs.dms_posting_sheet"),
key: "dms_posting_sheet",
disabled: false,
@@ -506,41 +508,41 @@ export const TemplateList = (type, context) => {
? {
special_thirdpartypayer: {
title: i18n.t("printcenter.jobs.thirdpartypayer"),
description: "CSI invite",
description: "",
key: "special_thirdpartypayer",
disabled: false,
},
folder_label_multiple: {
title: i18n.t("printcenter.jobs.folder_label_multiple"),
description: "Folder Label Multiple",
description: "",
key: "folder_label_multiple",
disabled: false,
},
parts_label_multiple: {
title: i18n.t("printcenter.jobs.parts_label_multiple"),
description: "Parts Label Multiple",
description: "",
key: "parts_label_multiple",
disabled: false,
},
parts_invoice_label_single: {
title: i18n.t("printcenter.jobs.parts_invoice_label_single"),
description: "Parts Label Multiple",
description: "",
key: "parts_invoice_label_single",
disabled: false,
ignoreCustomMargins: true,
},
csi_invitation_action: {
title: i18n.t("printcenter.jobs.csi_invitation_action"),
description: "CSI invite",
description: "",
key: "csi_invitation_action",
subject: i18n.t("printcenter.jobs.csi_invitation_action"),
disabled: false,
},
individual_job_note: {
title: i18n.t("printcenter.jobs.individual_job_note"),
description: "CSI invite",
description: "",
key: "individual_job_note",
subject: i18n.t("printcenter.jobs.individual_job_note", {
subject: i18n.t("printcenter.subjects.jobs.individual_job_note", {
ro_number: (context && context.ro_number) || "",
}),
disabled: false,
@@ -551,7 +553,7 @@ export const TemplateList = (type, context) => {
? {
appointment_confirmation: {
title: i18n.t("printcenter.appointments.appointment_confirmation"),
description: "Appointment Confirmation",
description: "",
subject: i18n.t(
"printcenter.appointments.appointment_confirmation"
),
@@ -564,7 +566,7 @@ export const TemplateList = (type, context) => {
? {
parts_order: {
title: i18n.t("printcenter.jobs.parts_order"),
description: "Parts Order",
description: "",
key: "parts_order",
subject: i18n.t("printcenter.subjects.jobs.parts_order", {
ro_number: context && context.job && context.job.ro_number,
@@ -578,7 +580,7 @@ export const TemplateList = (type, context) => {
},
sublet_order: {
title: i18n.t("printcenter.jobs.sublet_order"),
description: "Parts Order",
description: "",
key: "sublet_order",
subject: i18n.t("printcenter.subjects.jobs.sublet_order", {
ro_number: context && context.job && context.job.ro_number,
@@ -593,7 +595,7 @@ export const TemplateList = (type, context) => {
parts_return_slip: {
title: i18n.t("printcenter.jobs.parts_return_slip"),
subject: i18n.t("printcenter.jobs.parts_return_slip"),
description: "Parts Return",
description: "",
key: "parts_return_slip",
disabled: false,
},
@@ -603,7 +605,7 @@ export const TemplateList = (type, context) => {
? {
payment_receipt: {
title: i18n.t("printcenter.jobs.payment_receipt"),
description: "Payment Receipt",
description: "",
subject: i18n.t("printcenter.jobs.payment_receipt"),
key: "payment_receipt",
disabled: false,
@@ -1891,7 +1893,7 @@ export const TemplateList = (type, context) => {
title: i18n.t(
"printcenter.courtesycarcontract.courtesy_car_contract"
),
description: "Est Detail",
description: "",
subject: i18n.t(
"printcenter.courtesycarcontract.courtesy_car_contract"
),
@@ -1900,7 +1902,7 @@ export const TemplateList = (type, context) => {
},
courtesy_car_terms: {
title: i18n.t("printcenter.courtesycarcontract.courtesy_car_terms"),
description: "Est Detail",
description: "",
subject: i18n.t(
"printcenter.courtesycarcontract.courtesy_car_terms"
),
@@ -1911,7 +1913,7 @@ export const TemplateList = (type, context) => {
title: i18n.t(
"printcenter.courtesycarcontract.courtesy_car_impound"
),
description: "Est Detail",
description: "",
subject: i18n.t(
"printcenter.courtesycarcontract.courtesy_car_impound"
),
@@ -1926,7 +1928,7 @@ export const TemplateList = (type, context) => {
title: i18n.t(
"printcenter.courtesycarcontract.courtesy_car_inventory"
),
description: "Est Detail",
description: "",
subject: i18n.t(
"printcenter.courtesycarcontract.courtesy_car_inventory"
),
@@ -1939,7 +1941,7 @@ export const TemplateList = (type, context) => {
? {
inhouse_invoice: {
title: i18n.t("printcenter.bills.inhouse_invoice"),
description: "Est Detail",
description: "",
subject: i18n.t("printcenter.bills.inhouse_invoice"),
key: "inhouse_invoice",
disabled: false,
@@ -1950,7 +1952,7 @@ export const TemplateList = (type, context) => {
? {
// timetickets: {
// title: i18n.t("printcenter.timetickets.timetickets"),
// description: "Est Detail",
// description: "",
// subject: `${i18n.t("printcenter.timetickets.timetickets")} - ${
// context && context.job && context.job.ro_number
// }`,
@@ -1963,14 +1965,14 @@ export const TemplateList = (type, context) => {
? {
purchases_by_vendor_detailed: {
title: i18n.t("printcenter.vendors.purchases_by_vendor_detailed"),
description: "Est Detail",
description: "",
subject: i18n.t("printcenter.vendors.purchases_by_vendor_detailed"),
key: "purchases_by_vendor_detailed",
disabled: false,
},
purchases_by_vendor_summary: {
title: i18n.t("printcenter.vendors.purchases_by_vendor_summary"),
description: "Est Detail",
description: "",
subject: i18n.t("printcenter.vendors.purchases_by_vendor_summary"),
key: "purchases_by_vendor_summary",
disabled: false,
@@ -2043,21 +2045,21 @@ export const TemplateList = (type, context) => {
? {
ca_bc_etf_table: {
title: i18n.t("printcenter.payments.ca_bc_etf_table"),
description: "Est Detail",
description: "",
subject: i18n.t("printcenter.payments.ca_bc_etf_table"),
key: "ca_bc_etf_table",
disabled: false,
},
exported_payroll: {
title: i18n.t("printcenter.payments.exported_payroll"),
description: "Est Detail",
description: "",
subject: i18n.t("printcenter.payments.exported_payroll"),
key: "exported_payroll",
disabled: false,
},
attendance_detail_csv: {
title: i18n.t("printcenter.special.attendance_detail_csv"),
description: "Est Detail",
description: "",
subject: i18n.t("printcenter.special.attendance_detail_csv"),
key: "attendance_detail_csv",
disabled: false,

View File

@@ -673,6 +673,30 @@
_eq: true
- exported:
_eq: false
event_triggers:
- name: os_bills
definition:
delete:
columns: '*'
enable_manual: false
insert:
columns: '*'
update:
columns: '*'
retry_conf:
interval_sec: 10
num_retries: 3
timeout_sec: 60
webhook_from_env: HASURA_API_URL
headers:
- name: event-secret
value_from_env: EVENT_SECRET
request_transform:
method: POST
query_params: {}
template_engine: Kriti
url: '{{$base_url}}/opensearch'
version: 2
- table:
name: bodyshops
schema: public
@@ -917,6 +941,7 @@
- md_referral_sources
- md_responsibility_centers
- md_ro_statuses
- md_tasks_presets
- md_to_emails
- messagingservicesid
- pbs_configuration
@@ -945,6 +970,7 @@
- tt_enforce_hours_for_tech_console
- updated_at
- use_fippa
- use_paint_scale_data
- uselocalmediaserver
- website
- workingdays
@@ -1013,6 +1039,7 @@
- md_referral_sources
- md_responsibility_centers
- md_ro_statuses
- md_tasks_presets
- md_to_emails
- pbs_configuration
- phone
@@ -1034,6 +1061,7 @@
- tt_enforce_hours_for_tech_console
- updated_at
- use_fippa
- use_paint_scale_data
- uselocalmediaserver
- website
- workingdays
@@ -4054,6 +4082,29 @@
template_engine: Kriti
url: '{{$base_url}}/record-handler/arms'
version: 2
- name: os_jobs
definition:
delete:
columns: '*'
enable_manual: false
insert:
columns: '*'
update:
columns: '*'
retry_conf:
interval_sec: 10
num_retries: 3
timeout_sec: 60
webhook_from_env: HASURA_API_URL
headers:
- name: event-secret
value_from_env: EVENT_SECRET
request_transform:
method: POST
query_params: {}
template_engine: Kriti
url: '{{$base_url}}/opensearch'
version: 2
- table:
name: masterdata
schema: public
@@ -4282,6 +4333,7 @@
- jobid
- private
- text
- type
- updated_at
select_permissions:
- role: user
@@ -4295,6 +4347,7 @@
- jobid
- private
- text
- type
- updated_at
filter:
job:
@@ -4318,6 +4371,7 @@
- jobid
- private
- text
- type
- updated_at
filter:
job:
@@ -4478,6 +4532,30 @@
_eq: X-Hasura-User-Id
- active:
_eq: true
event_triggers:
- name: os_owners
definition:
delete:
columns: '*'
enable_manual: false
insert:
columns: '*'
update:
columns: '*'
retry_conf:
interval_sec: 10
num_retries: 3
timeout_sec: 60
webhook_from_env: HASURA_API_URL
headers:
- name: event-secret
value_from_env: EVENT_SECRET
request_transform:
method: POST
query_params: {}
template_engine: Kriti
url: '{{$base_url}}/opensearch'
version: 2
- table:
name: parts_order_lines
schema: public
@@ -4901,6 +4979,30 @@
_eq: X-Hasura-User-Id
- active:
_eq: true
event_triggers:
- name: os_payments
definition:
delete:
columns: '*'
enable_manual: false
insert:
columns: '*'
update:
columns: '*'
retry_conf:
interval_sec: 10
num_retries: 3
timeout_sec: 60
webhook_from_env: HASURA_API_URL
headers:
- name: event-secret
value_from_env: EVENT_SECRET
request_transform:
method: POST
query_params: {}
template_engine: Kriti
url: '{{$base_url}}/opensearch'
version: 2
- table:
name: phonebook
schema: public
@@ -5231,14 +5333,12 @@
- name: job
using:
foreign_key_constraint_on: jobid
array_relationships:
- name: tt_approval_queues
- name: tt_approval_queue
using:
foreign_key_constraint_on:
column: timeticketid
table:
name: tt_approval_queue
schema: public
foreign_key_constraint_on: ttapprovalqueueid
- name: user
using:
foreign_key_constraint_on: commited_by
insert_permissions:
- role: user
permission:
@@ -5257,6 +5357,7 @@
- ciecacode
- clockoff
- clockon
- commited_by
- committed_at
- cost_center
- created_at
@@ -5268,6 +5369,7 @@
- memo
- productivehrs
- rate
- ttapprovalqueueid
- updated_at
select_permissions:
- role: user
@@ -5278,6 +5380,7 @@
- ciecacode
- clockoff
- clockon
- commited_by
- committed_at
- cost_center
- created_at
@@ -5289,6 +5392,7 @@
- memo
- productivehrs
- rate
- ttapprovalqueueid
- updated_at
filter:
bodyshop:
@@ -5308,6 +5412,7 @@
- ciecacode
- clockoff
- clockon
- commited_by
- committed_at
- cost_center
- created_at
@@ -5319,6 +5424,7 @@
- memo
- productivehrs
- rate
- ttapprovalqueueid
- updated_at
filter:
bodyshop:
@@ -5442,12 +5548,17 @@
- name: job
using:
foreign_key_constraint_on: jobid
- name: timeticket
using:
foreign_key_constraint_on: timeticketid
- name: user
using:
foreign_key_constraint_on: approved_by
array_relationships:
- name: timetickets
using:
foreign_key_constraint_on:
column: ttapprovalqueueid
table:
name: timetickets
schema: public
insert_permissions:
- role: user
permission:
@@ -5461,44 +5572,42 @@
authid:
_eq: X-Hasura-User-Id
columns:
- id
- created_at
- updated_at
- bodyshopid
- jobid
- employeeid
- timeticketid
- approved_by
- approved_at
- actualhrs
- productivehrs
- rate
- flat_rate
- approved_at
- approved_by
- bodyshopid
- ciecacode
- cost_center
- created_at
- date
- employeeid
- flat_rate
- id
- jobid
- memo
- productivehrs
- rate
- updated_at
select_permissions:
- role: user
permission:
columns:
- flat_rate
- date
- actualhrs
- productivehrs
- rate
- approved_at
- approved_by
- bodyshopid
- ciecacode
- cost_center
- memo
- approved_at
- created_at
- updated_at
- bodyshopid
- date
- employeeid
- flat_rate
- id
- jobid
- timeticketid
- memo
- productivehrs
- rate
- updated_at
filter:
bodyshop:
associations:
@@ -5513,23 +5622,22 @@
- role: user
permission:
columns:
- flat_rate
- date
- actualhrs
- productivehrs
- rate
- approved_at
- approved_by
- bodyshopid
- ciecacode
- cost_center
- memo
- approved_at
- created_at
- updated_at
- bodyshopid
- date
- employeeid
- flat_rate
- id
- jobid
- timeticketid
- memo
- productivehrs
- rate
- updated_at
filter:
bodyshop:
associations:
@@ -5610,6 +5718,13 @@
table:
name: parts_orders
schema: public
- name: timetickets
using:
foreign_key_constraint_on:
column: commited_by
table:
name: timetickets
schema: public
- name: tt_approval_queues
using:
foreign_key_constraint_on:
@@ -5802,6 +5917,30 @@
_eq: X-Hasura-User-Id
- active:
_eq: true
event_triggers:
- name: os_vehicles
definition:
delete:
columns: '*'
enable_manual: false
insert:
columns: '*'
update:
columns: '*'
retry_conf:
interval_sec: 10
num_retries: 3
timeout_sec: 60
webhook_from_env: HASURA_API_URL
headers:
- name: event-secret
value_from_env: EVENT_SECRET
request_transform:
method: POST
query_params: {}
template_engine: Kriti
url: '{{$base_url}}/opensearch'
version: 2
- table:
name: vendors
schema: public

View File

@@ -0,0 +1,5 @@
alter table "public"."tt_approval_queue"
add constraint "tt_approval_queue_timeticketid_fkey"
foreign key ("timeticketid")
references "public"."timetickets"
("id") on update cascade on delete cascade;

View File

@@ -0,0 +1 @@
alter table "public"."tt_approval_queue" drop constraint "tt_approval_queue_timeticketid_fkey";

View File

@@ -0,0 +1,2 @@
alter table "public"."tt_approval_queue" alter column "timeticketid" drop not null;
alter table "public"."tt_approval_queue" add column "timeticketid" uuid;

View File

@@ -0,0 +1 @@
alter table "public"."tt_approval_queue" drop column "timeticketid" cascade;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."timetickets" add column "ttapprovalqueueid" uuid
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."timetickets" add column "ttapprovalqueueid" uuid
null;

View File

@@ -0,0 +1 @@
alter table "public"."timetickets" drop constraint "timetickets_ttapprovalqueueid_fkey";

View File

@@ -0,0 +1,5 @@
alter table "public"."timetickets"
add constraint "timetickets_ttapprovalqueueid_fkey"
foreign key ("ttapprovalqueueid")
references "public"."tt_approval_queue"
("id") on update cascade on delete set null;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."timetickets" add column "commited_by" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."timetickets" add column "commited_by" text
null;

View File

@@ -0,0 +1 @@
alter table "public"."timetickets" drop constraint "timetickets_commited_by_fkey";

View File

@@ -0,0 +1,5 @@
alter table "public"."timetickets"
add constraint "timetickets_commited_by_fkey"
foreign key ("commited_by")
references "public"."users"
("email") on update restrict on delete restrict;

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."bodyshops" add column "use_paint_scale_data" boolean
-- not null default 'false';

View File

@@ -0,0 +1,2 @@
alter table "public"."bodyshops" add column "use_paint_scale_data" boolean
not null default 'false';

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."jobs_idx_status_hash";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "jobs_idx_status_hash" on
"public"."jobs" using hash ("status");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_jobs_ronumber_btree";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_jobs_ronumber_btree" on
"public"."jobs" using btree ("ro_number");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."job_conversations_jobid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "job_conversations_jobid" on
"public"."job_conversations" using btree ("jobid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."job_conversations_conversationid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "job_conversations_conversationid" on
"public"."job_conversations" using btree ("conversationid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."job_conversations_job_and_conversation_id";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "job_conversations_job_and_conversation_id" on
"public"."job_conversations" using btree ("conversationid", "jobid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_payments_jobid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_payments_jobid" on
"public"."payments" using btree ("jobid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_mixdata_jobid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_mixdata_jobid" on
"public"."mixdata" using btree ("jobid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_notes_jobid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_notes_jobid" on
"public"."notes" using btree ("jobid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_users_authid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_users_authid" on
"public"."users" using btree ("authid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_employees_shopid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_employees_shopid" on
"public"."employees" using btree ("shopid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_employee_vacation_employeeid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_employee_vacation_employeeid" on
"public"."employee_vacation" using btree ("employeeid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_counters_shopid_type";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_counters_shopid_type" on
"public"."counters" using btree ("shopid", "countertype");

View File

@@ -0,0 +1,3 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- CREATE INDEX idx_jobs_inproduction_true ON jobs(inproduction) WHERE inproduction = true;

View File

@@ -0,0 +1 @@
CREATE INDEX idx_jobs_inproduction_true ON jobs(inproduction) WHERE inproduction = true;

View File

@@ -0,0 +1,3 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- CREATE INDEX idx_associations_active_true ON associations(active) WHERE active = true;

View File

@@ -0,0 +1 @@
CREATE INDEX idx_associations_active_true ON associations(active) WHERE active = true;

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_associations_shopid_user";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_associations_shopid_user" on
"public"."associations" using btree ("shopid", "useremail", "active");

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."bodyshops" add column "md_tasks_presets" jsonb
-- not null default jsonb_build_object();

View File

@@ -0,0 +1,2 @@
alter table "public"."bodyshops" add column "md_tasks_presets" jsonb
not null default jsonb_build_object();

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."notes" add column "type" text
-- not null default 'general';

View File

@@ -0,0 +1,2 @@
alter table "public"."notes" add column "type" text
not null default 'general';

260
os-loader.js Normal file
View File

@@ -0,0 +1,260 @@
const Dinero = require("dinero.js");
//const client = require("../graphql-client/graphql-client").client;
const _ = require("lodash");
const GraphQLClient = require("graphql-request").GraphQLClient;
const logger = require("./server/utils/logger");
const path = require("path");
const client = require("./server/graphql-client/graphql-client").client;
require("dotenv").config({
path: path.resolve(
process.cwd(),
`.env.${process.env.NODE_ENV || "development"}`
),
});
const { Client, Connection } = require("@opensearch-project/opensearch");
const { defaultProvider } = require("@aws-sdk/credential-provider-node");
const aws4 = require("aws4");
const { gql } = require("graphql-request");
const gqlclient = require("./server/graphql-client/graphql-client").client;
// const osClient = new Client({
// node: `https://imex:Wl0d8k@!@search-imexonline-search-ixp2stfvwp6qocjsowzjzyreoy.ca-central-1.es.amazonaws.com/`,
// });
var host = process.env.OPEN_SEARCH_HOST; // e.g. https://my-domain.region.es.amazonaws.com
const createAwsConnector = (credentials, region) => {
class AmazonConnection extends Connection {
buildRequestObject(params) {
const request = super.buildRequestObject(params);
request.service = "es";
request.region = region;
request.headers = request.headers || {};
request.headers["host"] = request.hostname;
return aws4.sign(request, credentials);
}
}
return {
Connection: AmazonConnection,
};
};
const getClient = async () => {
const credentials = await defaultProvider()();
return new Client({
...createAwsConnector(credentials, "ca-central-1"),
node: host,
});
};
async function OpenSearchUpdateHandler(req, res) {
try {
var osClient = await getClient();
// const osClient = new Client({
// node: `https://imex:password@search-imexonline-search-ixp2stfvwp6qocjsowzjzyreoy.ca-central-1.es.amazonaws.com`,
// });
//Clear out all current documents
// const deleteResult = await osClient.deleteByQuery({
// index: ["*"], // ["jobs", "payments", "bills", "vehicles", "owners"],
// body: {
// query: {
// match_all: {},
// },
// },
// });
// return;
var batchSize = 1000;
var promiseQueue = [];
//Jobs Load.
const jobsData = await gqlclient.request(`query{jobs{
id
bodyshopid:shopid
clm_no
clm_total
comment
ins_co_nm
owner_owing
ownr_co_nm
ownr_fn
ownr_ln
ownr_ph1
ownr_ph2
plate_no
ro_number
status
v_model_yr
v_make_desc
v_model_desc
}}`);
for (let i = 0; i <= jobsData.jobs.length / batchSize; i++) {
const slicedArray = jobsData.jobs.slice(
i * batchSize,
i * batchSize + batchSize
);
const bulkOperation = [];
slicedArray.forEach((job) => {
bulkOperation.push({ index: { _index: "jobs", _id: job.id } });
bulkOperation.push(job);
});
promiseQueue.push(bulkOperation);
}
//Owner Load
const ownersData = await gqlclient.request(`{
owners {
id
bodyshopid: shopid
ownr_fn
ownr_ln
ownr_co_nm
ownr_ph1
ownr_ph2
}
}
`);
for (let i = 0; i <= ownersData.owners.length / batchSize; i++) {
const slicedArray = ownersData.owners.slice(
i * batchSize,
i * batchSize + batchSize
);
const bulkOperation = [];
slicedArray.forEach((owner) => {
bulkOperation.push({ index: { _index: "owners", _id: owner.id } });
bulkOperation.push(owner);
});
promiseQueue.push(bulkOperation);
}
//Vehicles
const vehiclesData = await gqlclient.request(`{
vehicles {
id
bodyshopid: shopid
plate_no
v_model_yr
v_model_desc
v_make_desc
v_color
v_vin
}
}
`);
for (let i = 0; i <= vehiclesData.vehicles.length / batchSize; i++) {
const slicedArray = vehiclesData.vehicles.slice(
i * batchSize,
i * batchSize + batchSize
);
const bulkOperation = [];
slicedArray.forEach((vehicle) => {
bulkOperation.push({ index: { _index: "vehicles", _id: vehicle.id } });
bulkOperation.push(vehicle);
});
promiseQueue.push(bulkOperation);
}
//payments
const paymentsData = await gqlclient.request(`{
payments {
id
amount
created_at
date
exportedat
memo
payer
paymentnum
transactionid
type
job {
id
ownerid
ownr_co_nm
ownr_fn
ownr_ln
owner {
id
ownr_co_nm
ownr_fn
ownr_ln
}
ro_number
bodyshopid: shopid
}
}
}
`);
for (let i = 0; i <= paymentsData.payments.length / batchSize; i++) {
const slicedArray = paymentsData.payments.slice(
i * batchSize,
i * batchSize + batchSize
);
const bulkOperation = [];
slicedArray.forEach((payment) => {
bulkOperation.push({ index: { _index: "payments", _id: payment.id } });
bulkOperation.push({
..._.omit(payment, ["job"]),
bodyshopid: payment.job.bodyshopid,
});
});
promiseQueue.push(bulkOperation);
}
//bills
const billsData = await gqlclient.request(`{
bills {
id
date
exported
exported_at
invoice_number
is_credit_memo
total
vendor {
name
id
}
job {
ro_number
id
bodyshopid: shopid
}
}
}`);
for (let i = 0; i <= billsData.bills.length / batchSize; i++) {
const slicedArray = billsData.bills.slice(
i * batchSize,
i * batchSize + batchSize
);
const bulkOperation = [];
slicedArray.forEach((bill) => {
bulkOperation.push({ index: { _index: "bills", _id: bill.id } });
bulkOperation.push({
..._.omit(bill, ["job"]),
bodyshopid: bill.job.bodyshopid,
});
});
promiseQueue.push(bulkOperation);
}
//Load the entire queue.
for (const queueItem of promiseQueue) {
const insertJobsBulk = await osClient.bulk({ body: queueItem });
console.log(
` ${insertJobsBulk.body.items.length} Records inserted in ${insertJobsBulk.body.took}.`
);
if (insertJobsBulk.body.errors)
console.error("*** Error while inserting.");
}
} catch (error) {
console.log(error);
}
}
OpenSearchUpdateHandler();

52
package-lock.json generated
View File

@@ -9,6 +9,7 @@
"version": "0.0.1",
"license": "UNLICENSED",
"dependencies": {
"@opensearch-project/opensearch": "^2.2.1",
"aws-sdk": "^2.1326.0",
"axios": "^0.27.2",
"bluebird": "^3.7.2",
@@ -362,6 +363,22 @@
"node": ">=8.0"
}
},
"node_modules/@opensearch-project/opensearch": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@opensearch-project/opensearch/-/opensearch-2.2.1.tgz",
"integrity": "sha512-8zfQX1acL9eWG+ohIc9nJVT9LSqXCdbVEJs0rCPRtji3XF6ahzsiKmGNTeWLxCPDxWCjAIWq9t95xP3Y5Egi6Q==",
"dependencies": {
"aws4": "^1.11.0",
"debug": "^4.3.1",
"hpagent": "^1.2.0",
"ms": "^2.1.3",
"secure-json-parse": "^2.4.0"
},
"engines": {
"node": ">=10",
"yarn": "^1.22.10"
}
},
"node_modules/@protobufjs/aspromise": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
@@ -3066,6 +3083,14 @@
"node": ">=8"
}
},
"node_modules/hpagent": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz",
"integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==",
"engines": {
"node": ">=14"
}
},
"node_modules/href-content": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/href-content/-/href-content-2.0.2.tgz",
@@ -4972,6 +4997,11 @@
"integrity": "sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q==",
"license": "BSD-3-Clause"
},
"node_modules/secure-json-parse": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz",
"integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw=="
},
"node_modules/semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
@@ -6580,6 +6610,18 @@
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.8.tgz",
"integrity": "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ=="
},
"@opensearch-project/opensearch": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@opensearch-project/opensearch/-/opensearch-2.2.1.tgz",
"integrity": "sha512-8zfQX1acL9eWG+ohIc9nJVT9LSqXCdbVEJs0rCPRtji3XF6ahzsiKmGNTeWLxCPDxWCjAIWq9t95xP3Y5Egi6Q==",
"requires": {
"aws4": "^1.11.0",
"debug": "^4.3.1",
"hpagent": "^1.2.0",
"ms": "^2.1.3",
"secure-json-parse": "^2.4.0"
}
},
"@protobufjs/aspromise": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
@@ -8622,6 +8664,11 @@
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
"integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g=="
},
"hpagent": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz",
"integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA=="
},
"href-content": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/href-content/-/href-content-2.0.2.tgz",
@@ -10042,6 +10089,11 @@
"resolved": "https://registry.npmjs.org/scmp/-/scmp-2.1.0.tgz",
"integrity": "sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q=="
},
"secure-json-parse": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz",
"integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw=="
},
"semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",

Some files were not shown because too many files have changed in this diff Show More