Compare commits

...

535 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
132cf98a37 IO-2086 Resolve local media server pulling full size image for thumbnail. 2023-04-21 12:21:28 -07: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
Patrick Fic
f4b3a990d7 Additional schema changes for payroll. 2023-04-21 08:42:47 -07:00
swtmply
20371ea00d Merge branch 'release/2023-04-21' of https://bitbucket.org/snaptsoft/bodyshop into release/2023-04-21 2023-04-21 22:28:00 +08:00
swtmply
3086a654a1 IO-1461 made the sider sticky 2023-04-21 22:27:48 +08:00
Patrick Fic
60768c8847 Timeticket approval queue aggregation permissions. 2023-04-20 15:28:14 -07:00
Patrick Fic
a68f8d6880 Payroll schema changes. 2023-04-20 15:05:23 -07: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
522665256e IO-2335 Exported GSR to Excel
Change idtype to reporttype to prevent issues later on down the road if we extend more reports to excel format
2023-04-20 12:43:06 -07:00
swtmply
d3fe2c9d06 IO-2011 removed column background color 2023-04-21 03:37:36 +08:00
swtmply
f080e84985 IO-2242 added email on vendor query 2023-04-21 02:56:11 +08:00
Allan Carr
2a0ad46eea IO-2235
Changes in Prettier
2023-04-20 09:46:21 -07: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
7725080a11 IO-2235 Exported GSR to Excel
For Morrey Body Shop
2023-04-20 09:33:22 -07: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
Allan Carr
1932795f55 Merge branch 'release/2023-04-21' of https://bitbucket.org/snaptsoft/bodyshop into release/2023-04-21 2023-04-19 15:44:41 -07:00
Allan Carr
cc7bd1c792 IO-2243 DMS Posting Sheet Report
Requested by Morrey Auto Body
2023-04-19 15:44:09 -07: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
a7cf36d5f8 Disable job status transition tracking. 2023-04-19 14:26:12 -07: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
f575870685 Added missed limit on global search. 2023-04-19 14:10:33 -07:00
Patrick Fic
171b61b92f Included a limit on global search query to limit performance impact. 2023-04-19 14:08:57 -07: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
3c0a883326 Resolve status transition error message. 2023-04-19 13:08:18 -07: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
d787821345 IO-2086 Resolve cloudinary based thumbnail retrieval. 2023-04-19 11:43:24 -07:00
Patrick Fic
ed6eab4c38 Merged in release/2023-04-14 (pull request #708)
Remove erroneous console log.
2023-04-14 20:05:43 +00:00
Patrick Fic
b12c9407d9 Remove erroneous console log. 2023-04-14 13:05:09 -07:00
Patrick Fic
300aee5b02 Merged in release/2023-04-14 (pull request #707)
Release/2023 04 14
2023-04-14 20:04:15 +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
0a93551db4 Merge branch 'release/2023-04-14' of https://bitbucket.org/snaptsoft/bodyshop into release/2023-04-14
# Conflicts:
#	client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx
2023-04-14 12:30:22 -07:00
Patrick Fic
8602ccbb8a IO-2240 Resolve efficiency calculation issue. 2023-04-14 12:29:11 -07:00
swtmply
d7b0e3046b IO-2240 Adjusted calculation for total efficiency 2023-04-15 03:26:56 +08: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
swtmply
0e06b449cb IO-2240 Adjusted the location of the calculation 2023-04-15 01:18:29 +08:00
swtmply
8e8208dd9a IO-2240 Moved the calculation within the function 2023-04-15 01:11:44 +08:00
swtmply
79e2fecb24 IO-2239 Removed total title 2023-04-14 23:33:14 +08:00
swtmply
86e909e4e9 Merge branch 'release/2023-04-14' of https://bitbucket.org/snaptsoft/bodyshop into release/2023-04-14 2023-04-14 02:53:14 +08:00
swtmply
c7ff893397 IO-1412 Fixed column resize drag speed 2023-04-14 02:53:04 +08:00
Patrick Fic
3981b8684c IO-2244 Round difference calculation to 1 decimal point for productive hours claiming enforcement. 2023-04-13 10:11:15 -07:00
swtmply
1fb856f95f Merge branch 'release/2023-04-14' of https://bitbucket.org/snaptsoft/bodyshop into release/2023-04-14 2023-04-14 00:41:00 +08:00
swtmply
c62c3fa938 IO-2240 total for productive hours in summary 2023-04-14 00:40:50 +08: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
be4feca990 Clean up unneeded import. 2023-04-13 09:26:24 -07:00
Patrick Fic
ec45454b3d IO-2244 Restrict claimable productive hours based on remaining hours 2023-04-13 09:25:52 -07:00
swtmply
0e78cb47f9 Merge branch 'release/2023-04-14' of https://bitbucket.org/snaptsoft/bodyshop into release/2023-04-14 2023-04-13 22:04:01 +08:00
Patrick Fic
e5b8d003ec IO-2137 Adjust PBS company name logic for posting. 2023-04-13 22:03:35 +08:00
Patrick Fic
2eb81dde37 Add ppc field to job lines. 2023-04-13 22:03:35 +08:00
Patrick Fic
614549a545 Include employee team changes from Payroll Based Changes. 2023-04-13 22:03:35 +08:00
Patrick Fic
5717727d2a IO-2243 Capture successful CDK posting details. 2023-04-13 22:03:35 +08:00
swtmply
f3714cea1e IO-2239 Added totals on cards in job scoreboards 2023-04-13 22:03:35 +08:00
swtmply
a3375e6152 IO-2238 Changed vehicle column to be a hyperlink 2023-04-13 22:03:24 +08:00
Patrick Fic
f48fb7130e IO-2137 Adjust PBS company name logic for posting. 2023-04-12 13:16:18 -07:00
Patrick Fic
1460fa6fd7 Add ppc field to job lines. 2023-04-12 13:13:51 -07:00
Patrick Fic
3d9a07bd39 Include employee team changes from Payroll Based Changes. 2023-04-12 13:08:39 -07:00
Patrick Fic
bd4aa4027a IO-2243 Capture successful CDK posting details. 2023-04-12 13:02:45 -07:00
swtmply
9fa995f002 IO-2239 Added totals on cards in job scoreboards 2023-04-12 03:13:19 +08:00
swtmply
3ed48b26f1 IO-2338 Changed vehicle column to be a hyperlink 2023-04-12 01:44:45 +08:00
swtmply
d585cacdfc IO-1412 Fixed column resize 2023-04-12 00:57:13 +08:00
Patrick Fic
55ddaca328 Merged in release/2023-04-07 (pull request #703)
Release/2023 04 07
2023-04-06 00:22:52 +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
Patrick Fic
146bf95e51 IO-2086 Resolve additional gallery import issue & tech login issue. 2023-04-05 17:22:18 -07:00
Patrick Fic
58defad2ea IO-2086 Resolve imports for additional classes with gallery. 2023-04-05 17:21:47 -07:00
Patrick Fic
9c40a03a06 Merged in release/2023-04-07 (pull request #701)
Release/2023 04 07
2023-04-05 22:09:28 +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
9b4247d6f6 Revert "fixed column resize"
This reverts commit 6e7d1abd70.
2023-04-05 14:20:15 -07:00
Patrick Fic
8a6d94f193 Resolve time ticket posting issue. 2023-04-05 14:02:34 -07:00
swtmply
6e7d1abd70 fixed column resize 2023-04-05 02:35:07 +08:00
swtmply
6bd74aae87 document galleries 2023-04-01 03:26:08 +08:00
Patrick Fic
f21caa10fc Merged in release/2023-03-21 (pull request #697)
IO-2213 Resolve issue with filtering on schedule screen.
2023-03-21 16:10:03 +00:00
Patrick Fic
3d164eb070 IO-2213 Resolve issue with filtering on schedule screen. 2023-03-21 09:09:03 -07:00
Patrick Fic
88ab3a21e2 Merged in release/2023-03-17 (pull request #695)
Release/2023 03 17
2023-03-17 18:44:06 +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
Patrick Fic
45bc1893a0 Language updates & default for lost sale reason. 2023-03-17 11:23:29 -07: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
Allan Carr
d053e682d7 IO-2193 Delete Owner & Vehicle
Pass error message on deleting to translation
2023-03-16 17:58:12 -07:00
Allan Carr
984a4a4cf6 IO-2193 Delete Owner & Vehicle 2023-03-16 16:44:12 -07: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
Patrick Fic
9438ef9683 IO-2177 Add enforce category on conversion. 2023-03-16 14:15:29 -07: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
Allan Carr
10a354e479 IO-2220 Customer List Report
Customer List report for Loewen Body Shop
2023-03-16 11:04:12 -07:00
Patrick Fic
31092c20a9 Updated hasura metadata 2023-03-16 07:59:40 -07: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
86beaf049c IO-2219 Resolve employees not needing job to post time ticket. 2023-03-14 14:41:14 -07:00
Patrick Fic
3bc0653230 IO-2215 Critical Parts scanning.
IO-2215 Critical Parts Scanning

IO-2215 critical parts scanning
2023-03-14 12:30:55 -07:00
Patrick Fic
b950b3f825 IO-2215 Critical Parts Scanning 2023-03-14 08:41:35 -07:00
Patrick Fic
3891fbefdf IO-2215 Critical parts scanning 2023-03-14 08:41:26 -07:00
Patrick Fic
73bcc72fc3 IO-2213 Add Ins Co filtering to several pages. 2023-03-13 14:37:05 -07:00
Patrick Fic
f3911859c7 IO-2214 Add lost sale reason tracking. 2023-03-13 12:07:25 -07:00
Patrick Fic
12e3d61cfb Merged in release/2023-03-10 (pull request #689)
Release/2023 03 10
2023-03-10 22:55:07 +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
4cba91e097 IO-2203 Resolve RO staying after payment modal close. 2023-03-09 11:23:46 -08:00
Patrick Fic
c695aea12e Autohouse change to respect flat rate employees 2023-03-09 11:08:47 -08:00
Patrick Fic
111f554dea IO-9 Remove license decode button. 2023-03-08 16:26:47 -08:00
Patrick Fic
fe2a731b5f Merged in release/2023-03-03 (pull request #687)
Release/2023 03 03
2023-03-06 19:48:13 +00:00
Patrick Fic
61e6511547 Add missing field to query. 2023-03-06 11:42:58 -08:00
Patrick Fic
85346e203b Update to env file. 2023-03-06 11:41:00 -08: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
c565e2199d IO-2195 Add additional check for conversation query. 2023-03-03 09:28:10 -08: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
8fa0946cfa IO-2195 Conversation query performance improvements. 2023-03-03 09:00:44 -08:00
Patrick Fic
a1ab254d6f Update hasura metadata. 2023-03-02 20:38:10 -08: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
Patrick Fic
99d3943955 Improve changing active shop profile methods to avoid multiple queries. 2023-03-02 20:04:54 -08:00
Patrick Fic
2415b4c2b4 IO-2194 Static control numbers for CDK. 2023-03-02 19:39:24 -08:00
Patrick Fic
99c7ba1fbc Disable ARMS on server side. 2023-03-02 19:38:37 -08:00
Patrick Fic
36e593f806 Io-2192 Add predefined vehicles list. 2023-03-02 19:06:08 -08:00
Patrick Fic
d825c04850 Package update modifications & IO-2192 Add ability to preselect make and model when creating a job. 2023-03-02 08:50:05 -08:00
Patrick Fic
ca7dfacec4 Package updates. 2023-03-01 13:01:48 -08:00
Patrick Fic
1138540518 Merged in release/2023-02-24 (pull request #682)
Release/2023 02 24
2023-02-27 18:11:31 +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
59db305cb8 IO-2186 Production Over Time
Add new report requested by Loewen Body Shop
2023-02-23 11:14:00 -08:00
Patrick Fic
fea69fe3a5 Add payment response object. 2023-02-22 08:15:58 -08:00
Patrick Fic
43e4ff911e Merged in release/2023-02-17 (pull request #679)
Release/2023 02 17
2023-02-17 23:39:24 +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
ae4cff98e7 IO-2175 Category Dropdown Clear
Allow for clear and correct for Select allowClear sending undefined and convert that to null. Overload UndefinedtoNull to have an array of keys
2023-02-16 17:26:57 -08:00
Allan Carr
3650cacb51 IO-2173 Job Line Discount
Correct for when new line is added with no part
2023-02-16 17:23:09 -08:00
Patrick Fic
c2bf6841e1 Documentation updates. 2023-02-14 15:05:09 -08: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
Allan Carr
f41b94d16d Merge branch 'release/2023-02-17' of https://bitbucket.org/snaptsoft/bodyshop into release/2023-02-17 2023-02-14 11:32:21 -08:00
Allan Carr
24da0207e5 IO-2173 Client Fusion - Job Line Discount not allowed
Adjust client job-line-upsert-modal to allow for discounts as markups were only allowed before. Convert prt_dsmk_p over to prt_dsmk_m on save of modal for both markup/discount for handling and viewing
2023-02-14 11:30:09 -08:00
Patrick Fic
bf34765e6b Additional Hasura Indexes. 2023-02-13 11:21:59 -08:00
Patrick Fic
4c98a347f5 Additional indexes for performance improvements. 2023-02-13 10:37:10 -08:00
Patrick Fic
840e760619 Merged in release/2023-02-10 (pull request #675)
Release/2023 02 10
2023-02-10 23:34:55 +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
Patrick Fic
739265ee6a Improve display of job lines preset display. 2023-02-10 09:08:39 -08: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
Allan Carr
038aaf249e IO-2160 Purchase & Return Ratio by Vendor Reports 2023-02-08 18:37:10 -08:00
Patrick Fic
e0eb4657d2 Resolve null displays of vehicle names. 2023-02-06 12:45:19 -08:00
Patrick Fic
02a6ccd481 Add indexes to export logs. 2023-02-06 10:39:47 -08:00
Patrick Fic
79e75a5e73 Merged in release/2023-02-03 (pull request #672)
IO-2162 Resolve display issues on scheduling modal .

Approved-by: Patrick Fic
2023-02-06 18:09:14 +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
8d22248f4b IO-2162 Resolve display issues on scheduling modal . 2023-02-06 09:02:33 -08:00
Patrick Fic
bb8024ba9c Merged in release/2023-02-03 (pull request #670)
release/2023-02-03

Approved-by: Patrick Fic
2023-02-04 01:20:00 +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
a960963e36 IO-2162 Smart Scheduling updates. 2023-02-03 17:19:30 -08: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
3be50b5067 IO-2162 Improved UI for scheduled problem jobs. 2023-02-03 13:48:49 -08: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
563c1d2402 IO-2162 Resolve smart scheduling issues. 2023-02-03 11:48:07 -08: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
2108a4e96c IO-2163 Revise report key. 2023-02-02 13:47:28 -08: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
c04a690dc3 IO-2162 Update smart scheduling server side. 2023-02-02 11:06:05 -08: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
20e84668a5 IO-2162 remove unnecessary conditions. 2023-02-02 10:42:16 -08: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
2e40583d31 IO-2164 IO-2163 Additional GSR reports. 2023-02-02 10:08:55 -08:00
Patrick Fic
07c307e17b IO-2162 Updated smart schedule graph logic. 2023-02-02 10:04:11 -08: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
176774a888 Merged in release/2023-01-27 (pull request #661)
Release/2023 01 27
2023-01-27 22:29:51 +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
7b3dcf295e IO-2156 Resolve AH detail line validation issue. 2023-01-27 13:20:53 -08: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
380dbd8b96 IO-2150 Additional report. 2023-01-27 09:00:44 -08:00
Patrick Fic
a34c2a5bc2 IO-2155 IO-2149 Add report templates. 2023-01-27 08:54:55 -08:00
Patrick Fic
d8ba40979e IO-2154 Add expected jobsin production count. 2023-01-27 08:35:45 -08:00
Patrick Fic
5cd0527e16 Improved global search. 2023-01-27 08:00:54 -08:00
Patrick Fic
25513ae5b5 IO-2151 Resolve issue removing CSR on conversion. 2023-01-26 11:24:53 -08:00
Patrick Fic
d89acbd49d Remove log statement. 2023-01-26 11:12:21 -08:00
Patrick Fic
a54862a309 Add cost center to employee time tickets summary. 2023-01-26 11:07:08 -08:00
Patrick Fic
423157dfcc Add misc labor cost for autohouse. 2023-01-26 08:32:43 -08:00
Patrick Fic
6607c80aca IO-2146 Remove Sublet from jobline status db view. 2023-01-24 09:31:25 -08:00
Patrick Fic
162aeca7c8 Merged in release/2022-01-20 (pull request #657)
Release/2022 01 20
2023-01-20 21:49:59 +00:00
Patrick Fic
1583ed2d61 IO-2143 Add truncation for long vehicle notes. 2023-01-20 13:46:20 -08:00
Patrick Fic
c78b13baa3 Update label for consistency. 2023-01-20 13:46:09 -08: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
6528a0c700 Update missed in last commit. 2023-01-19 13:06:43 -08:00
Patrick Fic
79f032ecaf Profile page improvements. 2023-01-19 13:05:00 -08:00
Patrick Fic
42b4534d21 IO-2141 Add detail only line for autohous exports. 2023-01-19 11:04:40 -08:00
Patrick Fic
32de0ddeb6 Merged in release/2022-01-13 (pull request #654)
Remove sentry tracing.
2023-01-09 17:46:42 +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
76025b5db1 Remove sentry tracing. 2023-01-09 09:36:00 -08:00
Patrick Fic
ea27fcd476 Merged in release/2023-01-06 (pull request #652)
Release/2023 01 06
2023-01-06 19:26:18 +00:00
Patrick Fic
968816b4a6 IO-2134 Add option to choose CSR on job conversion. 2023-01-06 10:12:07 -08:00
Patrick Fic
9de076f060 IO-2132 Updated approach to ATS summary. 2023-01-06 09:56:23 -08:00
Patrick Fic
08d334e93a Resolve rounding for QBO Receivables Multi Payer. 2023-01-05 17:06:47 -08: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
af009a0bb3 Updates to Sentry & removal of Stripe. 2023-01-03 12:23:25 -08: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
f8e74d9bad IO-2089 Incorporate Lbr Adjustments into scoreboard. 2023-01-02 14:48:10 -08:00
Patrick Fic
f6bf1ce793 IO-2109 Resolve label printing validation issue. 2023-01-02 14:15:59 -08:00
Patrick Fic
9413bc60cf IO-2134 Add CSR to conversion. 2023-01-02 13:56:35 -08:00
Patrick Fic
34f5fad365 IO-2132 Add Weekly ATS Summary 2023-01-02 11:46:23 -08:00
Patrick Fic
d69ce2d2a9 Merged in release/2022-12-30 (pull request #649)
Release/2022 12 30
2022-12-30 19:30:25 +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
b0755a0cde IO-2133 Manual Line Highlighting 2022-12-27 13:32:24 -08: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
a551258895 IO-2129 Add reports to report center. 2022-12-26 10:33:47 -08:00
Patrick Fic
8a0281fb43 Merged in release/2022-12-16 (pull request #643)
Release/2022 12 16
2022-12-16 18:59:41 +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
1df023fd15 Remove unneeded import to fix CI. 2022-12-15 17:09:05 -08: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
54277e4548 IO-2131 Resolve job search select filtering issue. 2022-12-15 16:39:47 -08: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
cffa1e2172 IO-2121 Add custom label to conversation. 2022-12-15 10:13:30 -08:00
Patrick Fic
6a25dff32d Merged in release/2022-12-16 (pull request #639)
Resolve scheduling loading issue.
2022-12-14 16:59:04 +00:00
Patrick Fic
ecfc365926 Resolve scheduling loading issue. 2022-12-14 08:30:16 -08:00
Patrick Fic
2f0bb4539e Merged in release/2022-12-09 (pull request #638)
Release/2022 12 09
2022-12-10 01:32:06 +00:00
Patrick Fic
2ac7f9b678 Add ownr_co_nm to search own query. 2022-12-09 14:07:27 -08: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
e192a63575 IO-2123 Add cc inventory print. 2022-12-09 11:35:13 -08: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
4c42522f3a IO-2122 Add time ticket report. 2022-12-09 08:09:53 -08:00
Patrick Fic
dad3dc9e42 Autohouse based updates. 2022-12-08 14:47:51 -08:00
Patrick Fic
b2b754bee0 IO-2118 Add expected production hours to scheduling. 2022-12-05 15:20:37 -08:00
Patrick Fic
8f9f80e8ee IO-2084 Add actualr epair start date. 2022-12-05 14:38:36 -08:00
Patrick Fic
0cf677abbf Merged in release/2022-12-02 (pull request #635)
IO-2116 Add account number to control types for DMS.
2022-12-03 03:16:53 +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
bc3238aba2 IO-2116 Add account number to control types for DMS. 2022-11-30 08:47:20 -08:00
Patrick Fic
df8c94cda2 Merged in release/2022-11-25 (pull request #632)
IO-2114 Resolve issue with unfound payer.
2022-11-26 00:01:25 +00:00
Patrick Fic
6a2fefc573 IO-2114 Resolve issue with unfound payer. 2022-11-25 15:59:55 -08:00
Patrick Fic
e1dc257279 Merged in release/2022-11-25 (pull request #631)
Release/2022 11 25
2022-11-25 20:57:01 +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
94e8dc7456 IO-2106 Add payment Ref to QBO export. 2022-11-25 08:40:40 -08:00
Patrick Fic
d6c6e5245d IO-2114 Resolve missing translation on DMS form when no control tpye set. 2022-11-25 08:27:56 -08:00
Patrick Fic
a64f9d8213 IO-2112 Update size of note preset field. 2022-11-25 08:23:02 -08:00
Patrick Fic
e8c727a393 Resolve bounced email tracking. 2022-11-23 14:31:25 -08:00
Patrick Fic
37cef75fef IO-2098 Fix vin search bug on job import. 2022-11-23 12:27:11 -08:00
Patrick Fic
7301d9da85 IO-2098 Remove page size on all jobs. 2022-11-23 11:05:27 -08:00
Patrick Fic
beb7daec5f Remove packages no longer controled by this repo. 2022-11-23 10:53:39 -08:00
Patrick Fic
311da0c028 Merged in revert-pr-628 (pull request #629)
Revert "Release/2022 11 25 (pull request #628)"
2022-11-22 01:31:33 +00:00
Patrick Fic
f9a5e8485b Revert "Release/2022 11 25 (pull request #628)" 2022-11-22 01:31:09 +00:00
Patrick Fic
0fdb663d50 Merged in release/2022-11-25 (pull request #628)
Release/2022 11 25
2022-11-21 23:52:30 +00:00
Patrick Fic
d528a4b730 Resynced lock files. 2022-11-21 15:50:34 -08:00
Patrick Fic
e4692c2965 Remove uneeded package. 2022-11-21 15:00:48 -08:00
Patrick Fic
a600bd446c Merged in release/2022-11-10 (pull request #625)
Release/2022 11 10
2022-11-10 20:04:14 +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
9f28b80a5a IO-1532 Status Transition Tracking. 2022-11-10 09:42:03 -08: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
77e865c5c4 CI Test 2022-11-09 16:34:30 -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
d01a1aa0a0 CI Test 2022-11-09 16:29:32 -08: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
77bfa90b59 IO-2062 Update handling of negative EFT amounts for ICBC. 2022-11-09 09:28:56 -08:00
Patrick Fic
b8d3c5e36c IO-2097 Update query on job card details to include remove = true filter. 2022-11-09 09:18:20 -08:00
Patrick Fic
abac60a316 IO-2100 Update label for updated date range picker. 2022-11-09 08:59:51 -08:00
Patrick Fic
83626d83de IO-2100 Add last 3 months to date range picker. 2022-11-09 08:16:44 -08:00
Patrick Fic
928673691b Updated header to remove language selector. 2022-11-08 14:22:03 -08:00
Patrick Fic
818e0679d9 Update AP posting form validation. 2022-11-08 13:36:54 -08: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
Patrick Fic
18f56a93d0 Merged in circleci-editor/847/test (pull request #620)
Add .circleci/config.yml
2022-11-08 19:08:56 +00:00
Patrick Fic
d4a6c528d0 Add .circleci/config.yml 2022-11-08 19:06:22 +00:00
Patrick Fic
6410f868db Merged in release/2022-11-10 (pull request #619)
release/2022-11-10

Approved-by: Patrick Fic
2022-11-08 18:51:55 +00:00
Patrick Fic
058cd31784 CI file updates. 2022-11-08 10:51:20 -08:00
Patrick Fic
9a04c63f72 Merged in release/2022-11-10 (pull request #618)
release/2022-11-10

Approved-by: Patrick Fic
2022-11-08 18:35:58 +00:00
Patrick Fic
3fa38822f3 IO-2096 Fix grouping for CT report. 2022-11-08 10:35:26 -08:00
Patrick Fic
8d84ed8e00 Updated CI 2022-11-08 10:13:04 -08:00
Patrick Fic
60fa40f738 Merged in release/2022-11-10 (pull request #617)
Updated git ignore for updated CI.

Approved-by: Patrick Fic
2022-11-08 18:10:27 +00:00
Patrick Fic
22d075c89a Updated git ignore for updated CI. 2022-11-08 10:08:58 -08:00
Patrick Fic
ac1eead695 Merged in release/2022-11-10 (pull request #616)
release/2022-11-10

Approved-by: Patrick Fic
2022-11-08 18:02:10 +00:00
Patrick Fic
5a12738da5 IO-2096 Add Cycle Time Analysis report 2022-11-08 10:01:40 -08:00
Patrick Fic
480cdb9b28 updated GIT and circle CI messages. 2022-11-07 15:58:30 -08:00
Patrick Fic
f389dfdd94 Merged in release/2022-11-10 (pull request #615)
PBS AP: skip posting of bills/wip for AR
2022-11-07 22:23:14 +00:00
Patrick Fic
fb20cceebc Merged in release/2022-11-10 (pull request #614)
PBS AP: skip posting of bills/wip for AR
2022-11-07 22:05:40 +00:00
Patrick Fic
b549f45cde PBS AP: skip posting of bills/wip for AR 2022-11-07 13:24:54 -08:00
Patrick Fic
a4fc26c139 Merged in release/2022-11-04 (pull request #613)
Release/2022 11 04
2022-11-04 17:32:17 +00:00
Patrick Fic
8f9cecd6bf Merged in release/2022-11-04 (pull request #612)
Add title to email overlay to prevent close button overlap.
2022-11-04 17:31:07 +00:00
Patrick Fic
ee05f59bd3 Merged in release/2022-11-04 (pull request #611)
release/2022-11-04

Approved-by: Patrick Fic
2022-11-03 18:45:28 +00:00
Patrick Fic
3a5508fc95 Merged in release/2022-11-04 (pull request #610)
Release/2022 11 04
2022-11-03 17:15:37 +00:00
Patrick Fic
00ae2cda5d Merged in release/2022-11-04 (pull request #609)
Release/2022 11 04
2022-11-03 17:02:46 +00:00
Patrick Fic
821bc850db Merged in release/2022-10-28 (pull request #606)
Release/2022 10 28
2022-10-27 18:15:08 +00:00
Patrick Fic
3e8af5fec7 Merged in release/2022-10-28 (pull request #604)
release/2022-10-28

Approved-by: Patrick Fic
2022-10-26 16:27:23 +00:00
Patrick Fic
07dce11341 Merged in release/2022-10-28 (pull request #602)
release/2022-10-28

Approved-by: Patrick Fic
2022-10-24 20:50:20 +00:00
Patrick Fic
ab242955f1 Merged in release/2022-10-28 (pull request #601)
IO-2086 Improved local media image display.
2022-10-24 19:52:10 +00:00
Patrick Fic
2c1bd448e7 Merged in release/2022-10-21 (pull request #599)
Release/2022 10 21
2022-10-18 17:46:18 +00:00
Patrick Fic
dc21c25c95 Merged in release/2022-10-21 (pull request #598)
IO-2072 Update template for parts label.
2022-10-18 00:40:49 +00:00
Patrick Fic
24c62f4905 Merged in release/2022-10-21 (pull request #597)
Release/2022 10 21
2022-10-18 00:07:33 +00:00
Patrick Fic
f23868bbde Merged in release/2022-10-14 (pull request #595)
release/2022-10-14

Approved-by: Patrick Fic
2022-10-14 15:47:18 +00:00
Patrick Fic
7d84dcacee Merged in release/2022-10-14 (pull request #594)
release/2022-10-14

Approved-by: Patrick Fic
2022-10-13 20:22:18 +00:00
Patrick Fic
6aeeac15b6 Merged in release/2022-09-30 (pull request #591)
IO-223 Use NA for owner company name.
2022-09-28 19:45:32 +00:00
Patrick Fic
e69a218392 Merged in release/2022-09-30 (pull request #590)
Release/2022 09 30
2022-09-28 19:07:50 +00:00
Patrick Fic
477c7bb006 Merged in release/2022-09-30 (pull request #589)
IO-2054 Bug fix for payments.
2022-09-28 00:08:15 +00:00
Patrick Fic
0f75ca555d Merged in release/2022-09-30 (pull request #588)
Release/2022 09 30
2022-09-27 22:25:54 +00:00
Patrick Fic
e9c83e567a Merged in release/2022-09-30 (pull request #587)
Release/2022 09 30
2022-09-27 19:20:01 +00:00
Patrick Fic
5ed8cef2f5 Merged in release/2022-09-23 (pull request #581)
Release/2022 09 23
2022-09-22 23:22:55 +00:00
Patrick Fic
ff149c4464 Merged in release/2022-09-23 (pull request #580)
IO-233 Logging & Credentials
2022-09-19 18:00:44 +00:00
Patrick Fic
195e4a05db Merged in release/2022-09-23 (pull request #579)
IO-233 Update ARMS trigger & error logging.
2022-09-19 17:54:24 +00:00
Patrick Fic
7194d2bba0 Merged in release/2022-09-16 (pull request #577)
Release/2022 09 16
2022-09-14 17:12:08 +00:00
Patrick Fic
9b92f83e52 Merged in release/2022-09-09 (pull request #575)
Release/2022 09 09
2022-09-08 17:04:23 +00:00
Patrick Fic
88a9ec1d3c Merged in releaase/2022-09-02 (pull request #573)
releaase/2022-09-02

Approved-by: Patrick Fic
2022-09-01 23:49:36 +00:00
Patrick Fic
2e2e9ad7a9 Merged in releaase/2022-09-02 (pull request #572)
Releaase/2022 09 02
2022-09-01 15:54:46 +00:00
Patrick Fic
eb52ccbc9d Merged in releaase/2022-09-02 (pull request #571)
Releaase/2022 09 02
2022-08-31 21:10:18 +00:00
Patrick Fic
8f44b61a16 Merged in release/2022-08-26 (pull request #569)
release/2022-08-26

Approved-by: Patrick Fic
2022-08-29 23:22:05 +00:00
Patrick Fic
7104af82d7 Merged in release/2022-08-26 (pull request #567)
release/2022-08-26

Approved-by: Patrick Fic
2022-08-29 15:13:31 +00:00
Patrick Fic
511b7693c7 Merged in release/2022-08-26 (pull request #565)
release/2022-08-26

Approved-by: Patrick Fic
2022-08-26 21:06:12 +00:00
Patrick Fic
cdacc2befa Merged in release/2022-08-26 (pull request #564)
release/2022-08-26

Approved-by: Patrick Fic
2022-08-25 22:48:17 +00:00
Patrick Fic
93cdbea17c Merged in release/2022-08-19 (pull request #561)
Release/2022 08 19
2022-08-18 21:47:16 +00:00
Patrick Fic
18c182e573 Merged in release/2022-08-19 (pull request #560)
Release/2022 08 19
2022-08-17 16:30:52 +00:00
Patrick Fic
c2058bcec6 Merged in release/2022-08-05 (pull request #558)
Release/2022 08 05
2022-08-04 15:28:08 +00:00
Patrick Fic
6031255d61 Merged in release/2022-07-29 (pull request #551)
release/2022-07-29

Approved-by: Patrick Fic
2022-07-29 18:08:36 +00:00
Patrick Fic
e9c229f307 Merged in release/2022-07-29 (pull request #550)
release/2022-07-29

Approved-by: Patrick Fic
2022-07-29 17:39:51 +00:00
Patrick Fic
26f6f63782 Merged in release/2022-07-29 (pull request #549)
IO-2000 Add parts_not_recieved_vendor to report center.

Approved-by: Patrick Fic
2022-07-26 21:30:26 +00:00
Patrick Fic
3eaf199322 Merged in release/2022-07-29 (pull request #548)
release/2022-07-29

Approved-by: Patrick Fic
2022-07-26 18:40:50 +00:00
Patrick Fic
9ded2fd5ba Merged in release/2022-07-29 (pull request #547)
release/2022-07-29

Approved-by: Patrick Fic
2022-07-25 20:05:51 +00:00
Patrick Fic
a1e35a137e Merged in release/2022-07-22 (pull request #544)
Remove logging statement.
2022-07-22 17:56:10 +00:00
Patrick Fic
fa9731369b Merged in release/2022-07-22 (pull request #543)
Release/2022 07 22
2022-07-22 15:34:30 +00:00
Patrick Fic
616f326a88 Merged in release/2022-07-22 (pull request #542)
release/2022-07-22

Approved-by: Patrick Fic
2022-07-20 22:19:46 +00:00
Patrick Fic
60950be9d5 Merged in release/2022-07-22 (pull request #541)
Release/2022 07 22
2022-07-19 21:53:12 +00:00
Patrick Fic
f479aeda54 Merged in release/2022-07-15 (pull request #539)
Release/2022 07 15
2022-07-15 22:40:04 +00:00
Patrick Fic
98bf700d1c Merged in release/2022-07-15 (pull request #538)
IO-1536 Add VIN Highlighting.
2022-07-15 17:51:21 +00:00
Patrick Fic
2a9609b917 Merged in release/2022-07-15 (pull request #537)
release/2022-07-15

Approved-by: Patrick Fic
2022-07-14 16:10:05 +00:00
Patrick Fic
423df9f9aa Merged in release/2022-07-08 (pull request #535)
release/2022-07-08

Approved-by: Patrick Fic
2022-07-07 16:30:17 +00:00
Patrick Fic
184ea58ec2 Merged in release/2022-06-30 (pull request #533)
release/2022-06-30

Approved-by: Patrick Fic
2022-06-30 21:17:08 +00:00
Patrick Fic
f9b6920eba Merged in release/2022-06-30 (pull request #532)
release/2022-06-30

Approved-by: Patrick Fic
2022-06-30 16:59:17 +00:00
Patrick Fic
9d8550e040 Merged in release/2022-06-30 (pull request #531)
release/2022-06-30

Approved-by: Patrick Fic
2022-06-30 16:04:37 +00:00
Patrick Fic
930321c885 Merged in release/2022-06-30 (pull request #530)
release/2022-06-30

Approved-by: Patrick Fic
2022-06-29 23:20:00 +00:00
Patrick Fic
5ff660d83d Merged in release/2022-06-30 (pull request #529)
release/2022-06-30

Approved-by: Patrick Fic
2022-06-29 22:20:53 +00:00
Patrick Fic
4b923acdf3 Merged in release/2022-06-30 (pull request #528)
release/2022-06-30

Approved-by: Patrick Fic
2022-06-29 22:05:24 +00:00
Patrick Fic
6337a961e9 Merged in release/2022-06-30 (pull request #525)
Release/2022 06 30
2022-06-28 22:50:16 +00:00
Patrick Fic
fb04742e5b Merged in release/2022-06-24 (pull request #522)
Add job reconciliation & autohouse filtering.

Approved-by: Patrick Fic
2022-06-24 16:48:05 +00:00
Patrick Fic
50f5be3174 Merged in release/2022-06-24 (pull request #520)
release/2022-06-24

Approved-by: Patrick Fic
2022-06-20 22:19:15 +00:00
Patrick Fic
63106487b9 Merged in release/2022-06-17 (pull request #518)
release/2022-06-17

Approved-by: Patrick Fic
2022-06-20 17:48:16 +00:00
Patrick Fic
a3a48c1b29 Merged in release/2022-06-10 (pull request #512)
release/2022-06-10

Approved-by: Patrick Fic
2022-06-10 22:37:40 +00:00
Patrick Fic
72d0a990ec Merged in release/2022-06-10 (pull request #511)
release/2022-06-10

Approved-by: Patrick Fic
2022-06-10 17:07:01 +00:00
Patrick Fic
e8d6871a20 Merged in release/2022-06-10 (pull request #510)
release/2022-06-10

Approved-by: Patrick Fic
2022-06-09 22:55:25 +00:00
Patrick Fic
5d4b2f308d Merged in release/2022-06-10 (pull request #509)
Resolved issues for job search select & updated packages.

Approved-by: Patrick Fic
2022-06-09 19:01:39 +00:00
Patrick Fic
84b274d0a5 Merged in release/2022-06-10 (pull request #508)
release/2022-06-10

Approved-by: Patrick Fic
2022-06-09 17:46:36 +00:00
Patrick Fic
271b2286ae Merged in release/2022-06-10 (pull request #507)
release/2022-06-10

Approved-by: Patrick Fic
2022-06-09 17:24:20 +00:00
Patrick Fic
660f851ee6 Merged in release/2022-06-10 (pull request #506)
Revert "Server Side CORS Updates."

Approved-by: Patrick Fic
2022-06-09 16:56:28 +00:00
Patrick Fic
5367e96aad Merged in release/2022-06-10 (pull request #505)
release/2022-06-10

Approved-by: Patrick Fic
2022-06-09 00:46:53 +00:00
Patrick Fic
9ac262fec2 Merged in release/2022-06-10 (pull request #504)
Resolve email PDFs not generating header.

Approved-by: Patrick Fic
2022-06-08 17:01:40 +00:00
Patrick Fic
62e044fbb2 Merged in release/2022-06-10 (pull request #503)
release/2022-06-10

Approved-by: Patrick Fic
2022-06-07 21:36:19 +00:00
Patrick Fic
d71155f350 Merged in release/2022-06-10 (pull request #502)
release/2022-06-10

Approved-by: Patrick Fic
2022-06-07 19:40:36 +00:00
Patrick Fic
c105c56acf Merged in release/2022-06-10 (pull request #501)
release/2022-06-10

Approved-by: Patrick Fic
2022-06-06 21:34:08 +00:00
Patrick Fic
9c7f2a6080 Merged in hotfix/2022-06-03 (pull request #497)
hotfix/2022-06-03

Approved-by: Patrick Fic
2022-06-03 17:15:51 +00:00
Patrick Fic
bcd6cc006f Merged in release/2022-05-27 (pull request #494)
release/2022-05-27

Approved-by: Patrick Fic
2022-05-27 21:44:45 +00:00
Patrick Fic
b2e14ed03b Merged in release/2022-05-27 (pull request #493)
release/2022-05-27

Approved-by: Patrick Fic
2022-05-27 21:34:31 +00:00
Patrick Fic
1d21dc3ee4 Merged in release/2022-05-27 (pull request #492)
release/2022-05-27

Approved-by: Patrick Fic
2022-05-26 22:21:32 +00:00
Patrick Fic
3c355a8227 Merged in release/2022-05-27 (pull request #491)
release/2022-05-27

Approved-by: Patrick Fic
2022-05-26 19:25:41 +00:00
Patrick Fic
546208d249 Merged in release/2022-05-20 (pull request #489)
Release/2022 05 20
2022-05-20 17:32:31 +00:00
Patrick Fic
012d59e5b7 Merged in release/2022-05-20 (pull request #488)
release/2022-05-20

Approved-by: Patrick Fic
2022-05-20 16:20:12 +00:00
Patrick Fic
8da2205a14 Merged in release/2022-05-20 (pull request #487)
release/2022-05-20

Approved-by: Patrick Fic
2022-05-20 15:54:17 +00:00
Patrick Fic
ad2bae00de Merged in release/2022-05-20 (pull request #486)
release/2022-05-20

Approved-by: Patrick Fic
2022-05-19 18:26:10 +00:00
Patrick Fic
8a21c24a5b Merged in release/2022-05-13 (pull request #480)
Updated CI config.

Approved-by: Patrick Fic
2022-05-13 23:40:32 +00:00
Patrick Fic
4004856cd6 Merged in release/2022-05-13 (pull request #479)
Local media server bugfixes.

Approved-by: Patrick Fic
2022-05-13 16:35:47 +00:00
Patrick Fic
23ace9f7be Merged in release/2022-05-13 (pull request #478)
IO-1875 Add CNR by Vendor
2022-05-12 23:59:10 +00:00
Patrick Fic
64f188dbdc Merged in release/2022-05-13 (pull request #476)
release/2022-05-13

Approved-by: Patrick Fic
2022-05-12 23:04:31 +00:00
Patrick Fic
ce15216764 Merged in release/2022-05-13 (pull request #475)
Release/2022 05 13
2022-05-12 19:41:19 +00:00
Patrick Fic
01253361b5 Merged in release/2022-05-13 (pull request #473)
Added IMS token changes.

Approved-by: Patrick Fic
2022-05-11 23:32:04 +00:00
Patrick Fic
fad667f2a4 Merged in release/2022-05-13 (pull request #471)
release/2022-05-13

Approved-by: Patrick Fic
2022-05-10 21:45:17 +00:00
Patrick Fic
00b982becc Merged in release/2022-05-13 (pull request #465)
Release/2022 05 13
2022-05-10 20:31:43 +00:00
Patrick Fic
c8fb685cb0 Merged in release/2022-05-06 (pull request #462)
release/2022-05-06

Approved-by: Patrick Fic
2022-05-06 22:50:44 +00:00
Patrick Fic
6a7b616037 Merged in release/2022-05-06 (pull request #461)
release/2022-05-06

Approved-by: Patrick Fic
2022-05-06 21:30:47 +00:00
Patrick Fic
6607258777 Merged in release/2022-05-06 (pull request #460)
release/2022-05-06

Approved-by: Patrick Fic
2022-05-06 17:20:13 +00:00
Patrick Fic
4ad9ccec47 Merged in release/2022-05-06 (pull request #458)
Add backwards compatibility for log generation.
2022-05-03 18:08:45 +00:00
Patrick Fic
896d82202b Merged in release/2022-05-06 (pull request #457)
Release/2022 05 06
2022-05-03 16:55:47 +00:00
Patrick Fic
2ad4035294 Merged in release/2022-04-29 (pull request #455)
release/2022-04-29

Approved-by: Patrick Fic
2022-04-28 20:41:34 +00:00
Patrick Fic
e65101b4a9 Merged in release/2022-04-22 (pull request #453)
Release/2022 04 22
2022-04-22 22:14:52 +00:00
Patrick Fic
cd25f079b5 Merged in release/2022-04-22 (pull request #452)
Release/2022 04 22
2022-04-22 19:04:11 +00:00
Patrick Fic
427c2b762b Merged in release/2022-04-22 (pull request #451)
release/2022-04-22

Approved-by: Patrick Fic
2022-04-21 19:39:36 +00:00
Patrick Fic
f50b7ccaee Merged in release/2022-04-22 (pull request #450)
release/2022-04-22

Approved-by: Patrick Fic
2022-04-21 19:12:03 +00:00
Patrick Fic
c67bcd2098 Merged in release/2022-04-22 (pull request #449)
release/2022-04-22

Approved-by: Patrick Fic
2022-04-21 17:05:20 +00:00
Patrick Fic
6c6cce7da7 Merged in release/2022-04-15 (pull request #447)
Resolve third party payer template issue.
2022-04-14 17:48:23 +00:00
Patrick Fic
e273481a25 Merged in release/2022-04-15 (pull request #446)
release/2022-04-15

Approved-by: Patrick Fic
2022-04-14 00:30:22 +00:00
Patrick Fic
4b34cd2a2e Merged in release/2022-04-15 (pull request #445)
release/2022-04-15

Approved-by: Patrick Fic
2022-04-13 22:13:29 +00:00
Patrick Fic
f54883164c Merged in release/2022-04-15 (pull request #444)
Release/2022 04 15
2022-04-12 22:51:22 +00:00
Patrick Fic
82e7e5d910 Merged in release/2022-04-08 (pull request #442)
release/2022-04-08

Approved-by: Patrick Fic
2022-04-08 00:40:14 +00:00
Patrick Fic
6831184e33 Merged in release/2022-04-02 (pull request #438)
release/2022-04-02

Approved-by: Patrick Fic
2022-03-31 21:44:14 +00:00
Patrick Fic
a39a79102d Merged in release/2022-04-02 (pull request #437)
release/2022-04-02

Approved-by: Patrick Fic
2022-03-31 21:26:41 +00:00
Patrick Fic
95fff2acc4 Merged in release/2022-04-02 (pull request #436)
Release/2022 04 02
2022-03-31 19:51:22 +00:00
Patrick Fic
64d1c87dbd Merged in release/2022-04-02 (pull request #435)
release/2022-04-02

Approved-by: Patrick Fic
2022-03-25 21:42:50 +00:00
Patrick Fic
47dc00ff6e Merged in release/2022-03-25 (pull request #432)
release/2022-03-25

Approved-by: Patrick Fic
2022-03-24 21:40:43 +00:00
Patrick Fic
a2fbdd6a32 Merged in release/2022-03-25 (pull request #431)
release/2022-03-25

Approved-by: Patrick Fic
2022-03-24 21:18:15 +00:00
Patrick Fic
e46240f543 Merged in release/2022-03-25 (pull request #430)
release/2022-03-25

Approved-by: Patrick Fic
2022-03-22 19:41:39 +00:00
Patrick Fic
8882481006 Merged in release/2022-03-25 (pull request #429)
release/2022-03-25

Approved-by: Patrick Fic
2022-03-22 17:12:08 +00:00
Patrick Fic
79f66294d9 Merged in release/2022-03-25 (pull request #428)
release/2022-03-25

Approved-by: Patrick Fic
2022-03-21 17:53:26 +00:00
Patrick Fic
f9f1dbaf24 Merged in release/2022-03-18 (pull request #425)
Release/2022 03 18
2022-03-17 22:48:36 +00:00
Patrick Fic
ac8ae34e1d Merged in release/2022-03-18 (pull request #423)
Release/2022 03 18
2022-03-16 21:01:48 +00:00
Patrick Fic
e72925e34e Merged in release/2022-03-18 (pull request #422)
Release/2022 03 18
2022-03-16 20:54:13 +00:00
Patrick Fic
9a6be8a71e Merged in release/2022-03-18 (pull request #421)
Release/2022 03 18
2022-03-14 20:49:42 +00:00
Patrick Fic
11b20c54c2 Merged in release/2022-03-11 (pull request #419)
IO-1776 Mechanical authorization added to print center.

Approved-by: Patrick Fic
2022-03-11 16:53:26 +00:00
Patrick Fic
ac7dcdd6a9 Merged in release/2022-03-11 (pull request #418)
release/2022-03-11

Approved-by: Patrick Fic
2022-03-10 19:02:58 +00:00
Patrick Fic
20abda83f3 Merged in release/2022-03-11 (pull request #414)
release/2022-03-11

Approved-by: Patrick Fic
2022-03-07 22:47:56 +00:00
Patrick Fic
826a57c012 Merged in release/2022-03-04 (pull request #412)
release/2022-03-04

Approved-by: Patrick Fic
2022-03-04 18:13:33 +00:00
Patrick Fic
1a0c5c44ba Merged in release/2022-03-04 (pull request #411)
release/2022-03-04

Approved-by: Patrick Fic
2022-03-03 20:39:40 +00:00
Patrick Fic
9e8eb35792 Merged in release/2022-03-04 (pull request #409)
release/2022-03-04

Approved-by: Patrick Fic
2022-03-03 17:07:03 +00:00
Patrick Fic
49618ac6ef Merged in release/2022-03-04 (pull request #408)
release/2022-03-04

Approved-by: Patrick Fic
2022-03-02 21:00:10 +00:00
Patrick Fic
ad8c13f346 Merged in release/2022-03-04 (pull request #406)
release/2022-03-04

Approved-by: Patrick Fic
2022-03-02 01:27:33 +00:00
Patrick Fic
e2f3d6ef83 Merged in release/2022-02-18 (pull request #404)
Updated task scheduler.

Approved-by: Patrick Fic
2022-02-18 20:59:32 +00:00
Patrick Fic
a859990110 Merged in release/2022-02-18 (pull request #403)
release/2022-02-18

Approved-by: Patrick Fic
2022-02-18 01:14:54 +00:00
Patrick Fic
1286b72f2c Merged in release/2022-02-18 (pull request #402)
release/2022-02-18

Approved-by: Patrick Fic
2022-02-18 01:08:43 +00:00
Patrick Fic
5a42cafe8a Merged in release/2022-02-18 (pull request #401)
release/2022-02-18

Approved-by: Patrick Fic
2022-02-18 00:30:33 +00:00
Patrick Fic
1fd9bfc34c Merged in release/2022-02-18 (pull request #400)
CI Fix.
2022-02-17 01:12:36 +00:00
Patrick Fic
8e470376fd Merged in release/2022-02-18 (pull request #399)
IO-1738 PVRT Update
2022-02-17 00:46:15 +00:00
Patrick Fic
171e11c9f0 Merged in release/2022-02-18 (pull request #398)
Release/2022 02 18
2022-02-16 23:31:51 +00:00
Patrick Fic
e56664bbc6 Merge branch 'release/2022-02-18' into test 2022-02-15 16:03:52 -08:00
Patrick Fic
0f16f616d4 Merged in release/2022-02-18 (pull request #396)
Release/2022 02 18
2022-02-15 21:47:22 +00:00
Patrick Fic
2fc2e0f02e Merged in release/2022-02-18 (pull request #394)
Resolve Date Picker Issues.
2022-02-15 17:31:05 +00:00
Patrick Fic
3cd2445098 Merged in release/2022-02-18 (pull request #391)
Release/2022 02 18
2022-02-15 03:35:19 +00:00
Patrick Fic
1742f66312 Merged in hotfix/2022-02-14 (pull request #387)
Resolve bill update error.
2022-02-14 21:03:44 +00:00
393 changed files with 22182 additions and 108693 deletions

180
.circleci/config.yml Normal file
View File

@@ -0,0 +1,180 @@
version: 2.1
orbs:
#snyk: snyk/snyk@0.0.8
#cypress: cypress-io/cypress@1.23.0
aws-s3: circleci/aws-s3@2.0.0
eb: circleci/aws-elastic-beanstalk@1.0.2
jira: circleci/jira@1.3.1
jobs:
api-deploy:
docker:
- image: "cimg/base:stable"
steps:
- checkout
- eb/setup
- run:
command: |
eb init imex-online-production-api -r ca-central-1 -p "Node.js 16 running on 64bit Amazon Linux 2"
eb status --verbose
eb deploy
eb status
- jira/notify
hasura-migrate:
docker:
- image: cimg/node:16.15.0
parameters:
secret:
type: string
default: $HASURA_PROD_SECRET
working_directory: ~/repo/hasura
steps:
- checkout:
path: ~/repo
- run:
name: Execute migration
command: |
npm install hasura-cli -g
hasura migrate apply --endpoint https://db.imex.online/ --admin-secret << parameters.secret >>
hasura metadata apply --endpoint https://db.imex.online/ --admin-secret << parameters.secret >>
hasura metadata reload --endpoint https://db.imex.online/ --admin-secret << parameters.secret >>
app-build:
docker:
- image: cimg/node:16.15.0
working_directory: ~/repo/client
steps:
- checkout:
path: ~/repo
- restore_cache:
name: Restore Yarn Package Cache
keys:
- yarn-packages-{{ checksum "yarn.lock" }}
- run:
name: Install Dependencies
command: yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
- save_cache:
name: Save Yarn Package Cache
key: yarn-packages-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn
- run: yarn run build
- aws-s3/sync:
from: build
to: "s3://imex-online-production/"
- jira/notify
test-hasura-migrate:
docker:
- image: cimg/node:16.15.0
parameters:
secret:
type: string
default: $HASURA_TEST_SECRET
working_directory: ~/repo/hasura
steps:
- checkout:
path: ~/repo
- run:
name: Execute migration
command: |
npm install hasura-cli -g
echo ${HASURA_TEST_SECRET}
hasura migrate apply --endpoint https://db.test.bodyshop.app/ --admin-secret << parameters.secret >>
hasura metadata apply --endpoint https://db.test.bodyshop.app/ --admin-secret << parameters.secret >>
hasura metadata reload --endpoint https://db.test.bodyshop.app/ --admin-secret << parameters.secret >>
test-app-build:
docker:
- image: cimg/node:16.15.0
working_directory: ~/repo/client
steps:
- checkout:
path: ~/repo
- restore_cache:
name: Restore Yarn Package Cache
keys:
- yarn-packages-{{ checksum "yarn.lock" }}
- run:
name: Install Dependencies
command: yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
- save_cache:
name: Save Yarn Package Cache
key: yarn-packages-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn
- run: yarn run build:test
- aws-s3/sync:
from: build
to: "s3://imex-online-test/"
- jira/notify
admin-app-build:
docker:
- image: cimg/node:16.15.0
working_directory: ~/repo/admin
steps:
- checkout:
path: ~/repo
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run: npm i
- save_cache:
paths:
- node_modules
- ~/.npm
- ~/.cache
key: v1-dependencies-{{ checksum "package.json" }}
- run: npm run build
- aws-s3/sync:
from: build
to: "s3://adm.imex.online/"
workflows:
deploy_and_build:
jobs:
- api-deploy:
filters:
branches:
only: master
- app-build:
filters:
branches:
only: master
- hasura-migrate:
secret: ${HASURA_PROD_SECRET}
filters:
branches:
only: master
- test-app-build:
filters:
branches:
only: test
- test-hasura-migrate:
secret: ${HASURA_TEST_SECRET}
filters:
branches:
only: test
#- admin-app-build:
#filters:
#branches:
#only: master

View File

@@ -17,5 +17,4 @@
"no-console": "off"
},
"settings": {}
//"plugins": ["cypress"]
}

4
.gitignore vendored
View File

@@ -115,4 +115,6 @@ firebase/.env
logs/oAuthClient-log.log
.node-persist/**
.node-persist/**
/*.env.*

View File

@@ -1,14 +1,3 @@
Yarn Dependency Management:
To force upgrades for some packages:
yarn upgrade-interactive --latest
To Start Hasura CLI:
npx hasura console
Migrating to Staging:
npx hasura migrate apply --endpoint https://db.imex.online/ --admin-secret 'Production-ImEXOnline!@#'
npx hasura migrate apply --endpoint https://db.test.bodyshop.app/ --admin-secret 'Test-ImEXOnlineBySnaptSoftware!'
NGROK TEsting:
./ngrok.exe http http://localhost:4000 -host-header="localhost:4000"
@@ -21,4 +10,4 @@ hasura migrate apply --version "1620771761757" --skip-execution --endpoint https
hasura migrate status --endpoint https://db.imex.online/ --admin-secret 'Production-ImEXOnline!@#'
Generate the license file:
$ generate-license-file --input package.json --output third-party-licenses.txt --overwrite
$ generate-license-file --input package.json --output third-party-licenses.txt --overwrite

View File

@@ -1,68 +0,0 @@
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## Available Scripts
In the project directory, you can run:
### `yarn start`
Runs the app in the development mode.<br />
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
The page will reload if you make edits.<br />
You will also see any lint errors in the console.
### `yarn test`
Launches the test runner in the interactive watch mode.<br />
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `yarn build`
Builds the app for production to the `build` folder.<br />
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.<br />
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `yarn eject`
**Note: this is a one-way operation. Once you `eject`, you cant go back!**
If you arent satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point youre on your own.
You dont have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldnt feel obligated to use this feature. However we understand that this tool wouldnt be useful if you couldnt customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
### Analyzing the Bundle Size
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
### Making a Progressive Web App
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
### Advanced Configuration
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
### Deployment
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
### `yarn build` fails to minify
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify

18103
admin/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,47 +0,0 @@
{
"name": "admin",
"version": "0.1.0",
"private": true,
"dependencies": {
"@apollo/client": "^3.3.15",
"@testing-library/jest-dom": "^5.11.10",
"@testing-library/react": "^11.2.6",
"@testing-library/user-event": "^13.1.5",
"@types/prop-types": "^15.7.3",
"apollo-boost": "^0.4.9",
"apollo-link-context": "^1.0.20",
"apollo-link-logger": "^2.0.0",
"dotenv": "^8.2.0",
"firebase": "^8.4.1",
"graphql": "^15.4.0",
"prop-types": "^15.7.2",
"ra-data-hasura-graphql": "^0.1.13",
"react": "^17.0.1",
"react-admin": "^3.14.4",
"react-dom": "^17.0.1",
"react-icons": "^4.2.0",
"react-scripts": "4.0.3",
"sass": "^1.32.10"
},
"scripts": {
"start": "set PORT=3001 && react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1,43 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>ImEX Online - ADMIN</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -1,25 +0,0 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@@ -1,3 +0,0 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@@ -1,38 +0,0 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@@ -1,12 +0,0 @@
import React from "react";
import AdminRoot from "../components/admin-root/admin-root.component";
import "./App.css";
function App() {
return (
<div className="App">
<AdminRoot />
</div>
);
}
export default App;

View File

@@ -1,9 +0,0 @@
import React from 'react';
import { render } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
const { getByText } = render(<App />);
const linkElement = getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
<g fill="#61DAFB">
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
<circle cx="420.9" cy="296.5" r="45.7"/>
<path d="M520.5 78.1z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -1,283 +0,0 @@
import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client";
import { ApolloLink } from "apollo-boost";
import { setContext } from "apollo-link-context";
import { HttpLink } from "apollo-link-http";
import apolloLogger from "apollo-link-logger";
import buildHasuraProvider from "ra-data-hasura-graphql";
import React, { Component } from "react";
import {
Admin,
EditGuesser,
ListGuesser,
Resource,
ShowGuesser,
} from "react-admin";
import { FaFileInvoiceDollar } from "react-icons/fa";
import CircularProgress from "@material-ui/core/CircularProgress";
import { auth } from "../../firebase/admin-firebase-utils";
import authProvider from "../auth-provider/auth-provider";
import JoblinesCreate from "../joblines/joblines.create";
import JoblinesEdit from "../joblines/joblines.edit";
import JoblinesList from "../joblines/joblines.list";
import JoblinesShow from "../joblines/joblines.show";
import JobsCreate from "../jobs/jobs.create";
import JobsEdit from "../jobs/jobs.edit";
import JobsList from "../jobs/jobs.list";
import JobsShow from "../jobs/jobs.show";
const httpLink = new HttpLink({
uri: process.env.REACT_APP_GRAPHQL_ENDPOINT,
headers: {
"x-hasura-admin-secret": `Dev-BodyShopApp!`,
// 'Authorization': `Bearer xxxx`,
},
});
const authLink = setContext((_, { headers }) => {
return (
auth.currentUser &&
auth.currentUser.getIdToken().then((token) => {
if (token) {
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
},
};
} else {
return { headers };
}
})
);
});
const middlewares = [];
if (process.env.NODE_ENV === "development") {
middlewares.push(apolloLogger);
}
middlewares.push(authLink.concat(httpLink));
const client = new ApolloClient({
link: ApolloLink.from(middlewares),
cache: new InMemoryCache(),
});
// const client = new ApolloClient({
// uri: process.env.REACT_APP_GRAPHQL_ENDPOINT,
// cache: new InMemoryCache(),
// headers: {
// "x-hasura-admin-secret": `Dev-BodyShopApp!`,
// // 'Authorization': `Bearer xxxx`,
// },
// });
class AdminRoot extends Component {
constructor() {
super();
this.state = { dataProvider: null };
}
componentDidMount() {
buildHasuraProvider({
client,
}).then((dataProvider) => this.setState({ dataProvider }));
}
render() {
const { dataProvider } = this.state;
if (!dataProvider) {
return (
<div>
<CircularProgress />
</div>
);
}
return (
<ApolloProvider client={client}>
<Admin dataProvider={dataProvider} authProvider={authProvider}>
<Resource
icon={FaFileInvoiceDollar}
name="jobs"
list={JobsList}
edit={JobsEdit}
create={JobsCreate}
show={JobsShow}
/>
<Resource
name="joblines"
list={JoblinesList}
edit={JoblinesEdit}
create={JoblinesCreate}
show={JoblinesShow}
/>
<Resource
name="bodyshops"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="owners"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="vehicles"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="appointments"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="available_jobs"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="cccontracts"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="conversations"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="counters"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="courtesycars"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="csi"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="csiquestions"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="documents"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="employees"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="invoicelines"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="invoices"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="job_conversations"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="masterdata"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="messages"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="notes"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="parts_order_lines"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="parts_orders"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="payments"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="scoreboard"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="templates"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="timetickets"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="users"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="vendors"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
</Admin>
</ApolloProvider>
);
}
}
export default AdminRoot;

View File

@@ -1,39 +0,0 @@
import { auth, getCurrentUser } from "../../firebase/admin-firebase-utils";
const authProvider = {
login: async ({ username, password }) => {
console.log(username, password);
try {
const { user } = await auth.signInWithEmailAndPassword(
username,
password
);
const token = await user.getIdToken();
localStorage.setItem("token", token);
return Promise.resolve();
} catch (error) {
console.log("error", error);
return Promise.reject();
}
},
logout: async (params) => {
await auth.signOut();
localStorage.removeItem("token");
return Promise.resolve();
},
checkAuth: async (params) => {
const user = await getCurrentUser();
if (!!user) {
return Promise.resolve();
} else {
return Promise.reject();
}
},
checkError: (error) => {
return Promise.resolve();
},
getPermissions: (params) => {
return Promise.resolve();
},
};
export default authProvider;

View File

@@ -1,26 +0,0 @@
import React from "react";
import {
Create,
NumberInput, SimpleForm,
TextInput
} from "react-admin";
const JoblinesCreate = (props) => (
<Create {...props}>
<SimpleForm>
<TextInput source="line_ref" />
<TextInput source="line_ind" />
<NumberInput source="db_price" />
<NumberInput source="act_price" />
<NumberInput source="part_qty" />
<NumberInput source="mod_lb_hrs" />
<TextInput source="mod_lbr_type" />
<TextInput source="lbr_op" />
</SimpleForm>
</Create>
);
export default JoblinesCreate;

View File

@@ -1,70 +0,0 @@
import React from "react";
import {
BooleanInput,
DateField,
Edit,
NumberInput,
SimpleForm,
TextInput,
} from "react-admin";
const JoblinesEdit = (props) => (
<Edit {...props}>
<SimpleForm>
<TextInput source="id" />
<DateField showTime source="created_at" />
<DateField showTime source="updated_at" />
<TextInput source="jobid" />
<NumberInput source="unq_seq" />
<NumberInput source="line_ind" />
<TextInput source="line_desc" />
<TextInput source="part_type" />
<TextInput source="oem_partno" />
<TextInput source="est_seq" />
<TextInput source="db_ref" />
<TextInput source="line_ref" />
<BooleanInput source="tax_part" />
<NumberInput source="db_price" />
<NumberInput source="act_price" />
<NumberInput source="part_qty" />
<TextInput source="alt_partno" />
<TextInput source="mod_lbr_ty" />
<NumberInput source="db_hrs" />
<NumberInput source="mod_lb_hrs" />
<TextInput source="lbr_op" />
<NumberInput source="lbr_amt" />
<BooleanInput source="glass_flag" />
<TextInput source="price_inc" />
<TextInput source="alt_part_i" />
<TextInput source="price_j" />
<TextInput source="cert_part" />
<TextInput source="alt_co_id" />
<TextInput source="alt_overrd" />
<TextInput source="alt_partm" />
<TextInput source="prt_dsmk_p" />
<TextInput source="prt_dsmk_m" />
<TextInput source="lbr_inc" />
<TextInput source="lbr_hrs_j" />
<TextInput source="lbr_typ_j" />
<TextInput source="lbr_op_j" />
<TextInput source="paint_stg" />
<TextInput source="paint_tone" />
<TextInput source="lbr_tax" />
<NumberInput source="misc_amt" />
<TextInput source="misc_sublt" />
<TextInput source="misc_tax" />
<TextInput source="bett_type" />
<NumberInput source="bett_pctg" />
<NumberInput source="bett_amt" />
<TextInput source="bett_tax" />
<TextInput source="op_code_desc" />
<TextInput source="status" />
<TextInput source="removed" />
<NumberInput source="line_no" />
<TextInput source="notes" />
<TextInput source='"location"' />
</SimpleForm>
</Edit>
);
export default JoblinesEdit;

View File

@@ -1,29 +0,0 @@
import React from "react";
import {
Datagrid, List,
NumberField,
ReferenceField, TextField
} from "react-admin";
const JoblinesList = (props) => (
<List {...props}>
<Datagrid rowClick="edit">
<ReferenceField source="jobid" reference="jobs">
<TextField source="ro_number" />
</ReferenceField>
<TextField source="line_ref" />
<TextField source="line_ind" />
<NumberField source="db_price" />
<NumberField source="act_price" />
<NumberField source="part_qty" />
<NumberField source="mod_lb_hrs" />
<TextField source="mod_lbr_type" />
<TextField source="lbr_op" />
</Datagrid>
</List>
);
export default JoblinesList;

View File

@@ -1,24 +0,0 @@
import React from "react";
import {
NumberInput, Show,
SimpleShowLayout,
TextInput
} from "react-admin";
const JoblinesShow = (props) => (
<Show {...props}>
<SimpleShowLayout>
<TextInput source="line_ref" />
<TextInput source="line_ind" />
<NumberInput source="db_price" />
<NumberInput source="act_price" />
<NumberInput source="part_qty" />
<NumberInput source="mod_lb_hrs" />
<TextInput source="mod_lbr_type" />
<TextInput source="lbr_op" />
</SimpleShowLayout>
</Show>
);
export default JoblinesShow;

View File

@@ -1,17 +0,0 @@
import React from "react";
import { Create, EmailField, SimpleForm, TextInput } from "react-admin";
const JobsCreate = (props) => (
<Create {...props}>
<SimpleForm>
<TextInput source="ro_number" />
<TextInput source="ownr_fn" />
<TextInput source="ownr_ln" />
<TextInput source="converted" />
<EmailField source="ownr_ea" />
</SimpleForm>
</Create>
);
export default JobsCreate;

View File

@@ -1,316 +0,0 @@
import React from "react";
//@ts-ignore
import {
AutocompleteInput,
BooleanInput,
Edit,
FormTab,
NumberInput,
ReferenceInput,
SelectInput,
SimpleForm,
TabbedForm,
TextInput,
} from "react-admin";
const JobsEdit = (props) => (
<Edit {...props}>
<TabbedForm>
<FormTab label="Job Info">
<SimpleForm>
<ReferenceInput label="Shopid" source="shopid" reference="bodyshops">
<SelectInput disabled optionText="shopname" />
</ReferenceInput>
<TextInput source="ro_number" />
<ReferenceInput label="Owner ID" source="ownerid" reference="owners">
<AutocompleteInput
matchSuggestion={(filter, choice) =>
choice.ownr_fn &&
choice.ownr_fn.toLowerCase().includes(filter.toLowerCase())
}
optionText={(record) =>
`${record.ownr_fn || ""} ${record.ownr_ln || ""} ${
record.ownr_co_nm || ""
} (${record.ownr_ph1 || ""})`
}
/>
</ReferenceInput>
<ReferenceInput
label="Vehicle Id"
source="vehicleid"
reference="vehicles"
>
<SelectInput optionText="v_vin" />
</ReferenceInput>
<ReferenceInput label="Shopid" source="shopid" reference="bodyshops">
<SelectInput disabled optionText="shopname" />
</ReferenceInput>
<TextInput source="ro_number" />
<ReferenceInput label="Owner ID" source="ownerid" reference="owners">
<AutocompleteInput
matchSuggestion={(filter, choice) =>
choice.ownr_fn &&
choice.ownr_fn.toLowerCase().includes(filter.toLowerCase())
}
optionText={(record) =>
`${record.ownr_fn || ""} ${record.ownr_ln || ""} ${
record.ownr_co_nm || ""
} (${record.ownr_ph1 || ""})`
}
/>
</ReferenceInput>
<ReferenceInput
label="Vehicle Id"
source="vehicleid"
reference="vehicles"
>
<SelectInput optionText="v_vin" />
</ReferenceInput>
<BooleanInput source="inproduction" />
<BooleanInput source="converted" />
<TextInput disabled source="id" />
<TextInput disabled source="created_at" />
<TextInput disabled source="updated_at" />
</SimpleForm>
</FormTab>
<FormTab label="Labor Rates">
<NumberInput source="labor_rate_id" />
<NumberInput source="labor_rate_desc" />
<NumberInput source="rate_lab" />
<NumberInput source="rate_lad" />
<NumberInput source="rate_lae" />
<NumberInput source="rate_lar" />
<NumberInput source="rate_las" />
<NumberInput source="rate_laf" />
<NumberInput source="rate_lam" />
<NumberInput source="rate_lag" />
<NumberInput source="rate_atp" />
<NumberInput source="rate_lau" />
<NumberInput source="rate_la1" />
<NumberInput source="rate_la2" />
<NumberInput source="rate_la3" />
<NumberInput source="rate_la4" />
<NumberInput source="rate_mapa" />
<NumberInput source="rate_mash" />
<NumberInput source="rate_mahw" />
<NumberInput source="rate_ma2s" />
<NumberInput source="rate_ma3s" />
<NumberInput source="rate_ma2t" />
<NumberInput source="rate_mabl" />
<NumberInput source="rate_macs" />
<NumberInput source="rate_matd" />
<NumberInput source="federal_tax_rate" />
<NumberInput source="state_tax_rate" />
<NumberInput source="local_tax_rate" />
</FormTab>
<FormTab label="Dates">
<TextInput source="scheduled_in" />
<TextInput source="actual_in" />
<TextInput source="scheduled_completion" />
<TextInput source="actual_completion" />
<TextInput source="scheduled_delivery" />
<TextInput source="actual_delivery" />
<TextInput source="invoice_date" />
<TextInput source="date_estimated" />
<TextInput source="date_open" />
<TextInput source="date_scheduled" />
<TextInput source="date_invoiced" />
<TextInput source="date_exported" />
</FormTab>
<FormTab label="Insurance info">
<TextInput source="est_co_nm" />
<TextInput source="est_addr1" />
<TextInput source="est_addr2" />
<TextInput source="est_city" />
<TextInput source="est_st" />
<TextInput source="est_zip" />
<TextInput source="est_ctry" />
<TextInput source="est_ph1" />
<TextInput source="est_ea" />
<TextInput source="est_ct_ln" />
<TextInput source="est_ct_fn" />
<TextInput source="regie_number" />
<TextInput source="statusid" />
<TextInput source="ins_co_id" />
<TextInput source="ins_co_nm" />
<TextInput source="ins_addr1" />
<TextInput source="ins_addr2" />
<TextInput source="ins_city" />
<TextInput source="ins_st" />
<TextInput source="ins_zip" />
<TextInput source="ins_ctry" />
<TextInput source="ins_ph1" />
<TextInput source="ins_ph1x" />
<TextInput source="ins_ph2" />
<TextInput source="ins_ph2x" />
<TextInput source="ins_fax" />
<TextInput source="ins_faxx" />
<TextInput source="ins_ct_ln" />
<TextInput source="ins_ct_fn" />
<TextInput source="ins_title" />
<TextInput source="ins_ct_ph" />
<TextInput source="ins_ct_phx" />
<TextInput source="ins_ea" />
<TextInput source="ins_memo" />
<TextInput source="policy_no" />
<TextInput source="ded_amt" />
<TextInput source="ded_status" />
<TextInput source="asgn_no" />
<TextInput source="asgn_date" />
<TextInput source="asgn_type" />
<TextInput source="clm_no" />
<TextInput source="clm_ofc_id" />
<TextInput source="agt_co_id" />
<TextInput source="agt_co_nm" />
<TextInput source="agt_addr1" />
<TextInput source="agt_addr2" />
<TextInput source="agt_city" />
<TextInput source="agt_st" />
<TextInput source="agt_zip" />
<TextInput source="agt_ctry" />
<TextInput source="agt_ph1" />
<TextInput source="agt_ph1x" />
<TextInput source="agt_ph2" />
<TextInput source="agt_ph2x" />
<TextInput source="agt_fax" />
<TextInput source="agt_faxx" />
<TextInput source="agt_ct_ln" />
<TextInput source="agt_ct_fn" />
<TextInput source="agt_ct_ph" />
<TextInput source="agt_ct_phx" />
<TextInput source="agt_ea" />
<TextInput source="agt_lic_no" />
<TextInput source="loss_type" />
<TextInput source="loss_desc" />
<TextInput source="theft_ind" />
<TextInput source="cat_no" />
<TextInput source="tlos_ind" />
<TextInput source="ciecaid" />
<TextInput source="loss_date" />
<TextInput source="clm_ofc_nm" />
<TextInput source="clm_addr1" />
<TextInput source="clm_addr2" />
<TextInput source="clm_city" />
<TextInput source="clm_st" />
<TextInput source="clm_zip" />
<TextInput source="clm_ctry" />
<TextInput source="clm_ph1" />
<TextInput source="clm_ph1x" />
<TextInput source="clm_ph2" />
<TextInput source="clm_ph2x" />
<TextInput source="clm_fax" />
<TextInput source="clm_faxx" />
<TextInput source="clm_ct_ln" />
<TextInput source="clm_ct_fn" />
<TextInput source="clm_title" />
<TextInput source="clm_ct_ph" />
<TextInput source="clm_ct_phx" />
<TextInput source="clm_ea" />
<TextInput source="payee_nms" />
<TextInput source="pay_type" />
<TextInput source="pay_date" />
<TextInput source="pay_chknm" />
<TextInput source="pay_amt" />
</FormTab>
<FormTab label="Owner Data on Job">
<TextInput source="cust_pr" />
<TextInput source="insd_ln" />
<TextInput source="insd_fn" />
<TextInput source="insd_title" />
<TextInput source="insd_co_nm" />
<TextInput source="insd_addr1" />
<TextInput source="insd_addr2" />
<TextInput source="insd_city" />
<TextInput source="insd_st" />
<TextInput source="insd_zip" />
<TextInput source="insd_ctry" />
<TextInput source="insd_ph1" />
<TextInput source="insd_ph1x" />
<TextInput source="insd_ph2" />
<TextInput source="insd_ph2x" />
<TextInput source="insd_fax" />
<TextInput source="insd_faxx" />
<TextInput source="insd_ea" />
<TextInput source="ownr_ln" />
<TextInput source="ownr_fn" />
<TextInput source="ownr_title" />
<TextInput source="ownr_co_nm" />
<TextInput source="ownr_addr1" />
<TextInput source="ownr_addr2" />
<TextInput source="ownr_city" />
<TextInput source="ownr_st" />
<TextInput source="ownr_zip" />
<TextInput source="ownr_ctry" />
<TextInput source="ownr_ph1" />
<TextInput source="ownr_ph1x" />
<TextInput source="ownr_ph2" />
<TextInput source="ownr_ph2x" />
<TextInput source="ownr_fax" />
<TextInput source="ownr_faxx" />
<TextInput source="ownr_ea" />
</FormTab>
<FormTab label="Financial">
<TextInput source="clm_total" />
<TextInput source="owner_owing" />
</FormTab>
<FormTab label="Other">
<TextInput source="area_of_damage" />
<TextInput source="loss_cat" />
<TextInput source="special_coverage_policy" />
<TextInput source="csr" />
<TextInput source="po_number" />
<TextInput source="unit_number" />
<TextInput source="kmin" />
<TextInput source="kmout" />
<TextInput source="referral_source" />
<TextInput source="selling_dealer" />
<TextInput source="servicing_dealer" />
<TextInput source="servicing_dealer_contact" />
<TextInput source="selling_dealer_contact" />
<TextInput source="depreciation_taxes" />
<TextInput source="federal_tax_payable" />
<TextInput source="other_amount_payable" />
<TextInput source="towing_payable" />
<TextInput source="storage_payable" />
<TextInput source="adjustment_bottom_line" />
<TextInput source="tax_pstthr" />
<TextInput source="tax_tow_rt" />
<TextInput source="tax_sub_rt" />
<TextInput source="tax_paint_mat_rt" />
<TextInput source="tax_levies_rt" />
<TextInput source="tax_prethr" />
<TextInput source="tax_thramt" />
<TextInput source="tax_str_rt" />
<TextInput source="tax_lbr_rt" />
<TextInput source="adj_g_disc" />
<TextInput source="adj_towdis" />
<TextInput source="adj_strdis" />
<TextInput source="tax_predis" />
<TextInput source="rate_laa" />
<TextInput source="status" />
<TextInput source="cieca_stl" />
<TextInput source="g_bett_amt" />
<TextInput source="cieca_ttl" />
<TextInput source="plate_no" />
<TextInput source="plate_st" />
<TextInput source="v_vin" />
<TextInput source="v_model_yr" />
<TextInput source="v_model_desc" />
<TextInput source="v_make_desc" />
<TextInput source="v_color" />
<TextInput source="parts_tax_rates" />
<TextInput source="job_totals" />
<TextInput source="production_vars" />
<TextInput source="intakechecklist" />
<TextInput source="invoice_allocation" />
<TextInput source="kanbanparent" />
<TextInput source="employee_body" />
<TextInput source="employee_refinish" />
<TextInput source="employee_prep" />
</FormTab>
</TabbedForm>
</Edit>
);
export default JobsEdit;

View File

@@ -1,69 +0,0 @@
import { useQuery } from "@apollo/client";
import CircularProgress from "@material-ui/core/CircularProgress";
import React from "react";
import {
Datagrid,
Filter,
List,
ReferenceField,
SelectInput,
TextField,
TextInput,
} from "react-admin";
import { QUERY_ALL_SHOPS } from "../../graphql/admin.shop.queries";
const JobsList = (props) => (
<List filters={<JobsFilter />} {...props}>
<Datagrid rowClick="edit">
<TextField source="id" label="Job ID" />
<ReferenceField source="shopid" reference="bodyshops" label="Shop Name">
<TextField source="shopname" />
</ReferenceField>
<TextField source="ro_number" label="RO Number" />
<TextField source="ownr_fn" label="Owner FN" />
<TextField source="ownr_ln" label="Owner LN" />
<TextField source="ownr_co_nm" label="Owner CO" />
<ReferenceField source="ownerid" reference="owners" label="Owner Record">
<TextField source="id" />
</ReferenceField>
<TextField source="v_model_yr" label="Year" />
<TextField source="v_make_desc" label="Make" />
<TextField source="v_model_desc" label="Model" />
<ReferenceField
source="vehicleid"
reference="vehicles"
label="Vehicle ID"
>
<TextField source="id" />
</ReferenceField>
</Datagrid>
</List>
);
const JobsFilter = (props) => {
const { loading, error, data } = useQuery(QUERY_ALL_SHOPS, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
});
if (loading) return <CircularProgress />;
if (error) return JSON.stringify(error);
return (
<Filter {...props}>
<TextInput label="RO Number" source="ro_number" />
<TextInput label="Job ID" source="id" />
<SelectInput
source="shopid"
label="Bodyshop"
choices={data.bodyshops.map((b) => {
return { id: b.id, name: b.shopname };
})}
/>
</Filter>
);
};
export default JobsList;

View File

@@ -1,280 +0,0 @@
import React from "react";
import {
Datagrid,
EditButton,
NumberField,
ReferenceManyField,
Show,
Tab,
TabbedShowLayout,
TextField,
} from "react-admin";
const JobsShow = (props) => (
<Show {...props}>
<TabbedShowLayout>
<Tab label="summary">
<TextField source="id" />
<TextField source="created_at" />
<TextField source="updated_at" />
<TextField source="shopid" />
<TextField source="ro_number" />
<TextField source="ownerid" />
<TextField source="vehicleid" />
</Tab>
<Tab label="Job Lines">
<ReferenceManyField
reference="joblines"
target="jobid"
label="Job Lines"
>
<Datagrid>
<TextField source="id" />
<TextField source="line_ref" />
<TextField source="line_desc" />
<TextField source="line_ind" />
<NumberField source="db_price" />
<NumberField source="act_price" />
<NumberField source="part_qty" />
<NumberField source="mod_lb_hrs" />
<TextField source="mod_lbr_type" />
<TextField source="lbr_op" />
<EditButton />
</Datagrid>
</ReferenceManyField>
</Tab>
<Tab label="other">
<TextField source="labor_rate_id" />
<TextField source="labor_rate_desc" />
<TextField source="rate_lab" />
<TextField source="rate_lad" />
<TextField source="rate_lae" />
<TextField source="rate_lar" />
<TextField source="rate_las" />
<TextField source="rate_laf" />
<TextField source="rate_lam" />
<TextField source="rate_lag" />
<TextField source="rate_atp" />
<TextField source="rate_lau" />
<TextField source="rate_la1" />
<TextField source="rate_la2" />
<TextField source="rate_la3" />
<TextField source="rate_la4" />
<TextField source="rate_mapa" />
<TextField source="rate_mash" />
<TextField source="rate_mahw" />
<TextField source="rate_ma2s" />
<TextField source="rate_ma3s" />
<TextField source="rate_ma2t" />
<TextField source="rate_mabl" />
<TextField source="rate_macs" />
<TextField source="rate_matd" />
<TextField source="federal_tax_rate" />
<TextField source="state_tax_rate" />
<TextField source="local_tax_rate" />
<TextField source="est_co_nm" />
<TextField source="est_addr1" />
<TextField source="est_addr2" />
<TextField source="est_city" />
<TextField source="est_st" />
<TextField source="est_zip" />
<TextField source="est_ctry" />
<TextField source="est_ph1" />
<TextField source="est_ea" />
<TextField source="est_ct_ln" />
<TextField source="est_ct_fn" />
<TextField source="scheduled_in" />
<TextField source="actual_in" />
<TextField source="scheduled_completion" />
<TextField source="actual_completion" />
<TextField source="scheduled_delivery" />
<TextField source="actual_delivery" />
<TextField source="regie_number" />
<TextField source="invoice_date" />
<TextField source="inproduction" />
<TextField source="statusid" />
<TextField source="ins_co_id" />
<TextField source="ins_co_nm" />
<TextField source="ins_addr1" />
<TextField source="ins_addr2" />
<TextField source="ins_city" />
<TextField source="ins_st" />
<TextField source="ins_zip" />
<TextField source="ins_ctry" />
<TextField source="ins_ph1" />
<TextField source="ins_ph1x" />
<TextField source="ins_ph2" />
<TextField source="ins_ph2x" />
<TextField source="ins_fax" />
<TextField source="ins_faxx" />
<TextField source="ins_ct_ln" />
<TextField source="ins_ct_fn" />
<TextField source="ins_title" />
<TextField source="ins_ct_ph" />
<TextField source="ins_ct_phx" />
<TextField source="ins_ea" />
<TextField source="ins_memo" />
<TextField source="policy_no" />
<TextField source="ded_amt" />
<TextField source="ded_status" />
<TextField source="asgn_no" />
<TextField source="asgn_date" />
<TextField source="asgn_type" />
<TextField source="clm_no" />
<TextField source="clm_ofc_id" />
<TextField source="date_estimated" />
<TextField source="date_open" />
<TextField source="date_scheduled" />
<TextField source="date_invoiced" />
<TextField source="date_exported" />
<TextField source="clm_total" />
<TextField source="owner_owing" />
<TextField source="converted" />
<TextField source="ciecaid" />
<TextField source="loss_date" />
<TextField source="clm_ofc_nm" />
<TextField source="clm_addr1" />
<TextField source="clm_addr2" />
<TextField source="clm_city" />
<TextField source="clm_st" />
<TextField source="clm_zip" />
<TextField source="clm_ctry" />
<TextField source="clm_ph1" />
<TextField source="clm_ph1x" />
<TextField source="clm_ph2" />
<TextField source="clm_ph2x" />
<TextField source="clm_fax" />
<TextField source="clm_faxx" />
<TextField source="clm_ct_ln" />
<TextField source="clm_ct_fn" />
<TextField source="clm_title" />
<TextField source="clm_ct_ph" />
<TextField source="clm_ct_phx" />
<TextField source="clm_ea" />
<TextField source="payee_nms" />
<TextField source="pay_type" />
<TextField source="pay_date" />
<TextField source="pay_chknm" />
<TextField source="pay_amt" />
<TextField source="agt_co_id" />
<TextField source="agt_co_nm" />
<TextField source="agt_addr1" />
<TextField source="agt_addr2" />
<TextField source="agt_city" />
<TextField source="agt_st" />
<TextField source="agt_zip" />
<TextField source="agt_ctry" />
<TextField source="agt_ph1" />
<TextField source="agt_ph1x" />
<TextField source="agt_ph2" />
<TextField source="agt_ph2x" />
<TextField source="agt_fax" />
<TextField source="agt_faxx" />
<TextField source="agt_ct_ln" />
<TextField source="agt_ct_fn" />
<TextField source="agt_ct_ph" />
<TextField source="agt_ct_phx" />
<TextField source="agt_ea" />
<TextField source="agt_lic_no" />
<TextField source="loss_type" />
<TextField source="loss_desc" />
<TextField source="theft_ind" />
<TextField source="cat_no" />
<TextField source="tlos_ind" />
<TextField source="cust_pr" />
<TextField source="insd_ln" />
<TextField source="insd_fn" />
<TextField source="insd_title" />
<TextField source="insd_co_nm" />
<TextField source="insd_addr1" />
<TextField source="insd_addr2" />
<TextField source="insd_city" />
<TextField source="insd_st" />
<TextField source="insd_zip" />
<TextField source="insd_ctry" />
<TextField source="insd_ph1" />
<TextField source="insd_ph1x" />
<TextField source="insd_ph2" />
<TextField source="insd_ph2x" />
<TextField source="insd_fax" />
<TextField source="insd_faxx" />
<TextField source="insd_ea" />
<TextField source="ownr_ln" />
<TextField source="ownr_fn" />
<TextField source="ownr_title" />
<TextField source="ownr_co_nm" />
<TextField source="ownr_addr1" />
<TextField source="ownr_addr2" />
<TextField source="ownr_city" />
<TextField source="ownr_st" />
<TextField source="ownr_zip" />
<TextField source="ownr_ctry" />
<TextField source="ownr_ph1" />
<TextField source="ownr_ph1x" />
<TextField source="ownr_ph2" />
<TextField source="ownr_ph2x" />
<TextField source="ownr_fax" />
<TextField source="ownr_faxx" />
<TextField source="ownr_ea" />
<TextField source="area_of_damage" />
<TextField source="loss_cat" />
<TextField source="special_coverage_policy" />
<TextField source="csr" />
<TextField source="po_number" />
<TextField source="unit_number" />
<TextField source="kmin" />
<TextField source="kmout" />
<TextField source="referral_source" />
<TextField source="selling_dealer" />
<TextField source="servicing_dealer" />
<TextField source="servicing_dealer_contact" />
<TextField source="selling_dealer_contact" />
<TextField source="depreciation_taxes" />
<TextField source="federal_tax_payable" />
<TextField source="other_amount_payable" />
<TextField source="towing_payable" />
<TextField source="storage_payable" />
<TextField source="adjustment_bottom_line" />
<TextField source="tax_pstthr" />
<TextField source="tax_tow_rt" />
<TextField source="tax_sub_rt" />
<TextField source="tax_paint_mat_rt" />
<TextField source="tax_levies_rt" />
<TextField source="tax_prethr" />
<TextField source="tax_thramt" />
<TextField source="tax_str_rt" />
<TextField source="tax_lbr_rt" />
<TextField source="adj_g_disc" />
<TextField source="adj_towdis" />
<TextField source="adj_strdis" />
<TextField source="tax_predis" />
<TextField source="rate_laa" />
<TextField source="status" />
<TextField source="cieca_stl" />
<TextField source="g_bett_amt" />
<TextField source="cieca_ttl" />
<TextField source="plate_no" />
<TextField source="plate_st" />
<TextField source="v_vin" />
<TextField source="v_model_yr" />
<TextField source="v_model_desc" />
<TextField source="v_make_desc" />
<TextField source="v_color" />
<TextField source="parts_tax_rates" />
<TextField source="job_totals" />
<TextField source="production_vars" />
<TextField source="intakechecklist" />
<TextField source="invoice_allocation" />
<TextField source="kanbanparent" />
<TextField source="employee_body" />
<TextField source="employee_refinish" />
<TextField source="employee_prep" />
</Tab>
</TabbedShowLayout>
</Show>
);
export default JobsShow;

View File

@@ -1,31 +0,0 @@
import firebase from "firebase/app";
import "firebase/firestore";
import "firebase/auth";
const config = JSON.parse(process.env.REACT_APP_FIREBASE_CONFIG);
firebase.initializeApp(config);
export const auth = firebase.auth();
export const firestore = firebase.firestore();
export default firebase;
export const getCurrentUser = () => {
return new Promise((resolve, reject) => {
const unsubscribe = auth.onAuthStateChanged((userAuth) => {
unsubscribe();
resolve(userAuth);
}, reject);
});
};
export const updateCurrentUser = (userDetails) => {
return new Promise((resolve, reject) => {
const unsubscribe = auth.onAuthStateChanged((userAuth) => {
userAuth.updateProfile(userDetails).then((r) => {
unsubscribe();
resolve(userAuth);
});
}, reject);
});
};

View File

@@ -1,10 +0,0 @@
import { gql } from "@apollo/client";
export const QUERY_ALL_SHOPS = gql`
query QUERY_ALL_SHOPS {
bodyshops {
id
shopname
}
}
`;

View File

@@ -1,13 +0,0 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

View File

@@ -1,17 +0,0 @@
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App/App";
import * as serviceWorker from "./serviceWorker";
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

View File

@@ -1,141 +0,0 @@
// This optional code is used to register a service worker.
// register() is not called by default.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on subsequent visits to a page, after all the
// existing tabs open on the page have been closed, since previously cached
// resources are updated in the background.
// To learn more about the benefits of this model and instructions on how to
// opt-in, read https://bit.ly/CRA-PWA
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.0/8 are considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export function register(config) {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Let's check if a service worker still exists or not.
checkValidServiceWorker(swUrl, config);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://bit.ly/CRA-PWA'
);
});
} else {
// Is not localhost. Just register service worker
registerValidSW(swUrl, config);
}
});
}
}
function registerValidSW(swUrl, config) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker == null) {
return;
}
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the updated precached content has been fetched,
// but the previous service worker will still serve the older
// content until all client tabs are closed.
console.log(
'New content is available and will be used when all ' +
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
);
// Execute callback
if (config && config.onUpdate) {
config.onUpdate(registration);
}
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
// Execute callback
if (config && config.onSuccess) {
config.onSuccess(registration);
}
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl, config) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl, {
headers: { 'Service-Worker': 'script' },
})
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
const contentType = response.headers.get('content-type');
if (
response.status === 404 ||
(contentType != null && contentType.indexOf('javascript') === -1)
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl, config);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready
.then(registration => {
registration.unregister();
})
.catch(error => {
console.error(error.message);
});
}
}

View File

@@ -1,5 +0,0 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom/extend-expect';

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

13
client/.env.development Normal file
View File

@@ -0,0 +1,13 @@
REACT_APP_GRAPHQL_ENDPOINT=https://db.dev.bodyshop.app/v1/graphql
REACT_APP_GRAPHQL_ENDPOINT_WS=wss://db.dev.bodyshop.app/v1/graphql
REACT_APP_GA_CODE=231099835
REACT_APP_FIREBASE_CONFIG={"apiKey":"AIzaSyDPLT8GiDHDR1R4nI66Qi0BY1aYviDPioc","authDomain":"imex-dev.firebaseapp.com","databaseURL":"https://imex-dev.firebaseio.com","projectId":"imex-dev","storageBucket":"imex-dev.appspot.com","messagingSenderId":"759548147434","appId":"1:759548147434:web:e8239868a48ceb36700993","measurementId":"G-K5XRBVVB4S"}
REACT_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/io-test
REACT_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/io-test
REACT_APP_CLOUDINARY_API_KEY=957865933348715
REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
REACT_APP_FIREBASE_PUBLIC_VAPID_KEY='BG3tzU7L2BXlGZ_3VLK4PNaRceoEXEnmHfxcVbRMF5o5g05ejslhVPki9kBM9cBBT-08Ad9kN3HSpS6JmrWD6h4'
REACT_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
REACT_APP_AXIOS_BASE_API_URL=http://localhost:4000
REACT_APP_REPORTS_SERVER_URL=https://reports3.test.imex.online
REACT_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc

14
client/.env.production Normal file
View File

@@ -0,0 +1,14 @@
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
REACT_APP_FIREBASE_CONFIG={"apiKey":"AIzaSyDSezy-jGJreo7ulgpLdlpOwAOrgcaEkhU","authDomain":"imex-prod.firebaseapp.com","databaseURL":"https://imex-prod.firebaseio.com","projectId":"imex-prod","storageBucket":"imex-prod.appspot.com","messagingSenderId":"253497221485","appId":"1:253497221485:web:3c81c483b94db84b227a64","measurementId":"G-NTWBKG2L0M"}
REACT_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/bodyshop
REACT_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/bodyshop
REACT_APP_CLOUDINARY_API_KEY=473322739956866
REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
REACT_APP_FIREBASE_PUBLIC_VAPID_KEY='BMgZT1NZztW2DsJl8Mg2L04hgY9FzAg6b8fbzgNAfww2VDzH3VE63Ot9EaP_U7KWS2JT-7HPHaw0T_Tw_5vkZc8'
REACT_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
REACT_APP_AXIOS_BASE_API_URL=https://api.imex.online/
REACT_APP_REPORTS_SERVER_URL=https://reports.imex.online
REACT_APP_SPLIT_API=et9pjkik6bn67he5evpmpr1agoo7gactphgk

14
client/.env.test Normal file
View File

@@ -0,0 +1,14 @@
REACT_APP_GRAPHQL_ENDPOINT=https://db.test.bodyshop.app/v1/graphql
REACT_APP_GRAPHQL_ENDPOINT_WS=wss://db.test.bodyshop.app/v1/graphql
REACT_APP_GA_CODE=231099835
REACT_APP_FIREBASE_CONFIG={ "apiKey":"AIzaSyBw7_GTy7GtQyfkIRPVrWHEGKfcqeyXw0c", "authDomain":"imex-test.firebaseapp.com", "projectId":"imex-test", "storageBucket":"imex-test.appspot.com", "messagingSenderId":"991923618608", "appId":"1:991923618608:web:633437569cdad78299bef5", "measurementId":"G-TW0XLZEH18"}
REACT_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/bodyshop
REACT_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/bodyshop
REACT_APP_CLOUDINARY_API_KEY=473322739956866
REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
REACT_APP_FIREBASE_PUBLIC_VAPID_KEY='BN2GcDPjipR5MTEosO5dT4CfQ3cmrdBIsI4juoOQrRijn_5aRiHlwj1mlq0W145mOusx6xynEKl_tvYJhpCc9lo'
REACT_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
REACT_APP_AXIOS_BASE_API_URL=https://api.test.imex.online/
REACT_APP_REPORTS_SERVER_URL=https://reports3.test.imex.online
REACT_APP_IS_TEST=true
REACT_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc

View File

@@ -4,71 +4,70 @@
"private": true,
"proxy": "http://localhost:4000",
"dependencies": {
"@apollo/client": "^3.6.9",
"@apollo/client": "^3.7.9",
"@asseinfo/react-kanban": "^2.2.0",
"@craco/craco": "^6.4.5",
"@craco/craco": "^7.0.0",
"@fingerprintjs/fingerprintjs": "^3.3.3",
"@jsreport/browser-client": "^3.1.0",
"@sentry/react": "^7.7.0",
"@sentry/tracing": "^7.7.0",
"@splitsoftware/splitio-react": "^1.6.0",
"@stripe/react-stripe-js": "^1.9.0",
"@stripe/stripe-js": "^1.32.0",
"@sentry/react": "^7.40.0",
"@sentry/tracing": "^7.40.0",
"@splitsoftware/splitio-react": "^1.8.1",
"@tanem/react-nprogress": "^5.0.8",
"antd": "^4.22.3",
"apollo-link-logger": "^2.0.0",
"axios": "^0.27.2",
"craco-less": "^1.20.0",
"antd": "^4.24.8",
"apollo-link-logger": "^2.0.1",
"axios": "^1.3.4",
"craco-less": "^2.0.0",
"dinero.js": "^1.9.1",
"dotenv": "^16.0.1",
"enquire-js": "^0.2.1",
"env-cmd": "^10.1.0",
"exifr": "^7.1.3",
"firebase": "^9.9.1",
"graphql": "^16.5.0",
"i18next": "^21.8.14",
"i18next-browser-languagedetector": "^6.1.4",
"firebase": "^9.17.1",
"graphql": "^16.6.0",
"i18next": "^22.4.10",
"i18next-browser-languagedetector": "^7.0.1",
"jsoneditor": "^9.9.0",
"jsreport-browser-client-dist": "^1.3.0",
"libphonenumber-js": "^1.10.9",
"libphonenumber-js": "^1.10.21",
"logrocket": "^3.0.1",
"markerjs2": "^2.22.0",
"markerjs2": "^2.28.1",
"moment-business-days": "^1.2.0",
"moment-timezone": "^0.5.34",
"normalize-url": "^7.0.3",
"phone": "^3.1.23",
"moment-timezone": "^0.5.41",
"normalize-url": "^8.0.0",
"phone": "^3.1.35",
"preval.macro": "^5.0.0",
"prop-types": "^15.8.1",
"query-string": "^7.1.1",
"query-string": "^7.1.3",
"rc-queue-anim": "^2.0.0",
"rc-scroll-anim": "^2.7.6",
"react": "^17.0.2",
"react-big-calendar": "^1.5.0",
"react-big-calendar": "^1.6.8",
"react-color": "^2.19.3",
"react-cookie": "^4.1.1",
"react-dom": "^17.0.2",
"react-drag-listview": "^0.2.1",
"react-grid-gallery": "^0.5.5",
"react-grid-gallery": "^1.0.0",
"react-grid-layout": "^1.3.4",
"react-i18next": "^11.18.1",
"react-icons": "^4.4.0",
"react-number-format": "^4.9.3",
"react-redux": "^7.2.8",
"react-i18next": "^12.2.0",
"react-icons": "^4.7.1",
"react-image-lightbox": "^5.1.4",
"react-number-format": "^5.1.3",
"react-redux": "^8.0.5",
"react-resizable": "^3.0.4",
"react-router-dom": "^5.3.0",
"react-scripts": "^4.0.3",
"react-scripts": "^5.0.1",
"react-sticky": "^6.0.3",
"react-sublime-video": "^0.2.5",
"react-virtualized": "^9.22.3",
"recharts": "^2.1.12",
"redux": "^4.2.0",
"recharts": "^2.4.3",
"redux": "^4.2.1",
"redux-persist": "^6.0.0",
"redux-saga": "^1.1.3",
"redux-saga": "^1.2.2",
"redux-state-sync": "^3.1.4",
"reselect": "^4.1.6",
"sass": "^1.54.0",
"socket.io-client": "^4.5.1",
"styled-components": "^5.3.5",
"reselect": "^4.1.7",
"sass": "^1.58.3",
"socket.io-client": "^4.6.1",
"styled-components": "^5.3.6",
"subscriptions-transport-ws": "^0.11.0",
"web-vitals": "^2.1.4",
"workbox-background-sync": "^6.5.3",
@@ -119,7 +118,7 @@
"react-error-overlay": "6.0.9"
},
"devDependencies": {
"@sentry/webpack-plugin": "^1.19.0",
"@sentry/webpack-plugin": "^1.20.0",
"@testing-library/cypress": "^8.0.3",
"cypress": "^10.3.1",
"eslint-plugin-cypress": "^2.12.1",

View File

@@ -143,8 +143,16 @@
}
}
//Update row highlighting on production board.
//Update row highlighting on production board.
.ant-table-tbody > tr.ant-table-row:hover > td {
background: #eaeaea !important;
}
}
.job-line-manual {
color: tomato;
font-style: italic;
}
td.ant-table-column-sort {
background-color: transparent;
}

View File

@@ -1,8 +1,4 @@
import {
PaymentRequestButtonElement,
useStripe,
} from "@stripe/react-stripe-js";
import React, { useEffect, useState } from "react";
import React from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
@@ -19,49 +15,6 @@ const mapDispatchToProps = (dispatch) => ({
});
function Test({ bodyshop, setEmailOptions }) {
const stripe = useStripe();
const [paymentRequest, setPaymentRequest] = useState(null);
useEffect(() => {
if (stripe) {
const pr = stripe.paymentRequest({
country: "CA",
displayItems: [{ label: "Deductible", amount: 1099 }],
currency: "cad",
total: {
label: "Demo total",
amount: 1099,
},
requestPayerName: true,
requestPayerEmail: true,
});
// Check the availability of the Payment Request API.
pr.canMakePayment().then((result) => {
if (result) {
setPaymentRequest(pr);
} else {
// var details = {
// total: { label: "", amount: { currency: "CAD", value: "0.00" } },
// };
new PaymentRequest(
[{ supportedMethods: ["basic-card"] }],
{}
// details
).show();
}
});
}
}, [stripe]);
if (paymentRequest) {
return (
<div style={{ height: "300px" }}>
<PaymentRequestButtonElement options={{ paymentRequest }} />
</div>
);
}
return (
<div>
<button

View File

@@ -107,11 +107,6 @@ export function AccountingPayablesTableComponent({
dataIndex: "transactionid",
key: "transactionid",
},
{
title: t("payments.fields.stripeid"),
dataIndex: "stripeid",
key: "stripeid",
},
{
title: t("payments.fields.created_at"),
dataIndex: "created_at",

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

@@ -39,7 +39,13 @@ export function ContractsFindModalContainer({
if (!claim || !shortclaim) return;
const trimmedShortClaim = shortclaim.trim();
// const trimmedClaim = claim.trim();
claimNumbers.push({ claim: trimmedShortClaim, amount });
if (amount.slice(-1) === "-") {
}
claimNumbers.push({
claim: trimmedShortClaim,
amount: amount.slice(-1) === "-" ? parseFloat(amount) * -1 : amount,
});
});
await GenerateDocument(

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

@@ -6,8 +6,8 @@ import { setSelectedConversation } from "../../redux/messaging/messaging.actions
import { selectSelectedConversation } from "../../redux/messaging/messaging.selectors";
import { TimeAgoFormatter } from "../../utils/DateFormatter";
import PhoneFormatter from "../../utils/PhoneFormatter";
import "./chat-conversation-list.styles.scss";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import "./chat-conversation-list.styles.scss";
const mapStateToProps = createStructuredSelector({
selectedConversation: selectSelectedConversation,
@@ -38,17 +38,20 @@ export function ChatConversationListComponent({
: null
}`}
>
{item.job_conversations.length > 0 ? (
<div className="chat-name">
{item.job_conversations.map((j, idx) => (
<div key={idx}>
<OwnerNameDisplay ownerObject={j.job} />
</div>
))}
</div>
) : (
<PhoneFormatter>{item.phone_num}</PhoneFormatter>
)}
<div sryle={{ display: "inline-block" }}>
{item.label && <div className="chat-name">{item.label}</div>}
{item.job_conversations.length > 0 ? (
<div className="chat-name">
{item.job_conversations.map((j, idx) => (
<div key={idx}>
<OwnerNameDisplay ownerObject={j.job} />
</div>
))}
</div>
) : (
<PhoneFormatter>{item.phone_num}</PhoneFormatter>
)}
</div>
<div sryle={{ display: "inline-block" }}>
<div>
{item.job_conversations.length > 0

View File

@@ -3,6 +3,7 @@ import React from "react";
import PhoneNumberFormatter from "../../utils/PhoneFormatter";
import ChatArchiveButton from "../chat-archive-button/chat-archive-button.component";
import ChatConversationTitleTags from "../chat-conversation-title-tags/chat-conversation-title-tags.component";
import ChatLabelComponent from "../chat-label/chat-label.component";
import ChatTagRoContainer from "../chat-tag-ro/chat-tag-ro.container";
export default function ChatConversationTitle({ conversation }) {
@@ -11,6 +12,7 @@ export default function ChatConversationTitle({ conversation }) {
<PhoneNumberFormatter>
{conversation && conversation.phone_num}
</PhoneNumberFormatter>
<ChatLabelComponent conversation={conversation} />
<ChatConversationTitleTags
jobConversations={
(conversation && conversation.job_conversations) || []

View File

@@ -42,6 +42,7 @@ export function ChatConversationContainer({ bodyshop, selectedConversation }) {
MARK_MESSAGES_AS_READ_BY_CONVERSATION,
{
variables: { conversationId: selectedConversation },
refetchQueries: ["UNREAD_CONVERSATION_COUNT"],
update(cache) {
cache.modify({
id: cache.identify({

View File

@@ -0,0 +1,67 @@
import { PlusOutlined } from "@ant-design/icons";
import { useMutation } from "@apollo/client";
import { Input, notification, Spin, Tag, Tooltip } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { UPDATE_CONVERSATION_LABEL } from "../../graphql/conversations.queries";
export default function ChatLabel({ conversation }) {
const [loading, setLoading] = useState(false);
const [editing, setEditing] = useState(false);
const [value, setValue] = useState(conversation.label);
const { t } = useTranslation();
const [updateLabel] = useMutation(UPDATE_CONVERSATION_LABEL);
const handleSave = async () => {
setLoading(true);
try {
const response = await updateLabel({
variables: { id: conversation.id, label: value },
});
if (response.errors) {
notification["error"]({
message: t("messages.errors.updatinglabel", {
error: JSON.stringify(response.errors),
}),
});
} else {
setEditing(false);
}
} catch (error) {
notification["error"]({
message: t("messages.errors.updatinglabel", {
error: JSON.stringify(error),
}),
});
} finally {
setLoading(false);
}
};
if (editing) {
return (
<div>
<Input
autoFocus
value={value}
onChange={(e) => setValue(e.target.value)}
onBlur={handleSave}
allowClear
/>
{loading && <Spin size="small" />}
</div>
);
} else {
return conversation.label && conversation.label.trim() !== "" ? (
<Tag style={{ cursor: "pointer" }} onClick={() => setEditing(true)}>
{conversation.label}
</Tag>
) : (
<Tooltip title={t("messaging.labels.addlabel")}>
<PlusOutlined
style={{ cursor: "pointer" }}
onClick={() => setEditing(true)}
/>
</Tooltip>
);
}
}

View File

@@ -10,7 +10,10 @@ import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { CONVERSATION_LIST_QUERY } from "../../graphql/conversations.queries";
import {
CONVERSATION_LIST_QUERY,
UNREAD_CONVERSATION_COUNT,
} from "../../graphql/conversations.queries";
import { toggleChatVisible } from "../../redux/messaging/messaging.actions";
import {
selectChatVisible,
@@ -37,9 +40,17 @@ export function ChatPopupComponent({
}) {
const { t } = useTranslation();
const [pollInterval, setpollInterval] = useState(0);
const { data: unreadData } = useQuery(UNREAD_CONVERSATION_COUNT, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
...(pollInterval > 0 ? { pollInterval } : {}),
});
const { loading, data, refetch, called } = useQuery(CONVERSATION_LIST_QUERY, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
skip: !chatVisible,
...(pollInterval > 0 ? { pollInterval } : {}),
});
@@ -57,12 +68,14 @@ export function ChatPopupComponent({
if (called && chatVisible) refetch();
}, [chatVisible, called, refetch]);
const unreadCount = data
? data.conversations.reduce(
(acc, val) => val.messages_aggregate.aggregate.count + acc,
0
)
: 0;
// const unreadCount = data
// ? data.conversations.reduce(
// (acc, val) => val.messages_aggregate.aggregate.count + acc,
// 0
// )
// : 0;
const unreadCount = unreadData?.messages_aggregate.aggregate.count || 0;
return (
<Badge count={unreadCount}>

View File

@@ -4,7 +4,7 @@ import moment from "moment";
import React from "react";
import { useTranslation } from "react-i18next";
import { DateFormatter } from "../../utils/DateFormatter";
import ContractLicenseDecodeButton from "../contract-license-decode-button/contract-license-decode-button.component";
//import ContractLicenseDecodeButton from "../contract-license-decode-button/contract-license-decode-button.component";
import ContractStatusSelector from "../contract-status-select/contract-status-select.component";
import ContractsRatesChangeButton from "../contracts-rates-change-button/contracts-rates-change-button.component";
import CourtesyCarFuelSlider from "../courtesy-car-fuel-select/courtesy-car-fuel-select.component";
@@ -165,7 +165,9 @@ export default function ContractFormComponent({
/>
</div>
)}
<ContractLicenseDecodeButton form={form} />
{
//<ContractLicenseDecodeButton form={form} />
}
</Space>
</div>
<LayoutFormRow header={t("contracts.labels.driverinformation")}>

View File

@@ -1,5 +1,14 @@
import { SyncOutlined, WarningFilled } from "@ant-design/icons";
import { Button, Card, Input, Space, Table, Tooltip } from "antd";
import {
Button,
Card,
Dropdown,
Input,
Menu,
Space,
Table,
Tooltip,
} from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
@@ -7,6 +16,8 @@ import { DateTimeFormatter } from "../../utils/DateFormatter";
import { alphaSort } from "../../utils/sorters";
import { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
import moment from "moment";
import { GenerateDocument } from "../../utils/RenderTemplate";
import { TemplateList } from "../../utils/TemplateConstants";
export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
const [state, setState] = useState({
sortedInfo: {},
@@ -166,6 +177,32 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
<Button onClick={() => refetch()}>
<SyncOutlined />
</Button>
<Dropdown
trigger="click"
overlay={
<Menu>
<Menu.Item
onClick={() =>
GenerateDocument(
{
name: TemplateList("courtesycar").courtesy_car_inventory
.key,
variables: {
//id: contract.id
},
},
{},
"p"
)
}
>
{t("printcenter.courtesycarcontract.courtesy_car_inventory")}
</Menu.Item>
</Menu>
}
>
<Button>{t("general.labels.print")}</Button>
</Dropdown>
<Link to={`/manage/courtesycars/new`}>
<Button>{t("courtesycars.actions.new")}</Button>
</Link>

View File

@@ -8,6 +8,8 @@ export default function DataLabel({
vertical,
visible = true,
valueStyle = {},
valueClassName,
onValueClick,
...props
}) {
if (!visible || (hideIfNull && !!!children)) return null;
@@ -28,7 +30,10 @@ export default function DataLabel({
marginLeft: ".3rem",
fontWeight: "bolder",
wordWrap: "break-word",
cursor: onValueClick !== undefined ? "pointer" : "",
}}
className={valueClassName}
onClick={onValueClick}
>
{typeof children === "string" ? (
<Typography.Text style={valueStyle}>{children}</Typography.Text>

View File

@@ -140,7 +140,10 @@ export function DmsAllocationsSummaryAp({ socket, bodyshop, billids, title }) {
>
<Input />
</Form.Item>
<Button disabled={!socket.allocationsSummary} htmlType="submit">
<Button
disabled={!allocationsSummary || allocationsSummary.length === 0}
htmlType="submit"
>
{t("jobs.actions.dms.post")}
</Button>
</Form>

View File

@@ -1,4 +1,4 @@
import { Button, Card, Table, Typography } from "antd";
import { Alert, Button, Card, Table, Typography } from "antd";
import React, { useState, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -90,6 +90,9 @@ export function DmsAllocationsSummary({ socket, bodyshop, jobId, title }) {
</Button>
}
>
{bodyshop.pbs_configuration?.disablebillwip && (
<Alert type="warning" message={t("jobs.labels.dms.disablebillwip")} />
)}
<Table
pagination={{ position: "top", defaultPageSize: 50 }}
columns={columns}

View File

@@ -21,6 +21,7 @@ import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { determineDmsType } from "../../pages/dms/dms.container";
import { selectBodyshop } from "../../redux/user/user.selectors";
import i18n from "../../translations/i18n";
import DmsCdkMakes from "../dms-cdk-makes/dms-cdk-makes.component";
import DmsCdkMakesRefetch from "../dms-cdk-makes/dms-cdk-makes.refetch.component";
import FormDatePicker from "../form-date-picker/form-date-picker.component";
@@ -335,13 +336,31 @@ export function DmsPostForm({ bodyshop, socket, job, logsRef }) {
bodyshop.cdk_configuration.payers.find(
(i) => i && row && i.name === row.name
);
return (
<div>
{cdkPayer &&
t(`jobs.fields.${cdkPayer.control_type}`)}
</div>
);
if (
i18n.exists(`jobs.fields.${cdkPayer?.control_type}`)
)
return (
<div>
{cdkPayer &&
t(`jobs.fields.${cdkPayer?.control_type}`)}
</div>
);
else if (
i18n.exists(
`jobs.fields.dms.control_type.${cdkPayer?.control_type}`
)
) {
return (
<div>
{cdkPayer &&
t(
`jobs.fields.dms.control_type.${cdkPayer?.control_type}`
)}
</div>
);
} else {
return null;
}
}}
</Form.Item>

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

@@ -1,6 +1,5 @@
import { useLazyQuery } from "@apollo/client";
import { LoadingOutlined } from "@ant-design/icons";
import { AutoComplete, Divider, Space } from "antd";
import { AutoComplete, Divider, Input, Space } from "antd";
import _ from "lodash";
import React from "react";
import { useTranslation } from "react-i18next";
@@ -19,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 } });
};
@@ -38,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" />}>
@@ -178,13 +184,18 @@ export default function GlobalSearch() {
<AutoComplete
options={options}
onSearch={handleSearch}
suffixIcon={loading && <LoadingOutlined spin />}
defaultActiveFirstOption
placeholder={t("general.labels.globalsearch")}
allowClear
onSelect={(val, opt) => {
history.push(opt.label.props.to);
}}
></AutoComplete>
>
<Input.Search
size="large"
placeholder={t("general.labels.globalsearch")}
enterButton
allowClear
loading={loading}
/>
</AutoComplete>
);
}

View File

@@ -12,7 +12,7 @@ import Icon, {
FileAddFilled,
FileAddOutlined,
FileFilled,
GlobalOutlined,
//GlobalOutlined,
HomeFilled,
ImportOutlined,
LineChartOutlined,
@@ -374,25 +374,27 @@ function Header({
<Menu.Item key="profile">
<Link to="/manage/profile">{t("menus.currentuser.profile")}</Link>
</Menu.Item>
<Menu.SubMenu
key="langselecter"
title={
<span>
<GlobalOutlined />
<span>{t("menus.currentuser.languageselector")}</span>
</span>
}
>
<Menu.Item actiontype="lang-select" key="en-US">
{t("general.languages.english")}
</Menu.Item>
<Menu.Item actiontype="lang-select" key="fr-CA">
{t("general.languages.french")}
</Menu.Item>
<Menu.Item actiontype="lang-select" key="es-MX">
{t("general.languages.spanish")}
</Menu.Item>
</Menu.SubMenu>
{
// <Menu.SubMenu
// key="langselecter"
// title={
// <span>
// <GlobalOutlined />
// <span>{t("menus.currentuser.languageselector")}</span>
// </span>
// }
// >
// <Menu.Item actiontype="lang-select" key="en-US">
// {t("general.languages.english")}
// </Menu.Item>
// <Menu.Item actiontype="lang-select" key="fr-CA">
// {t("general.languages.french")}
// </Menu.Item>
// <Menu.Item actiontype="lang-select" key="es-MX">
// {t("general.languages.spanish")}
// </Menu.Item>
// </Menu.SubMenu>
}
</Menu.SubMenu>
<Menu.SubMenu key="recent" title={<ClockCircleFilled />}>
{recentItems.map((i, idx) => (

View File

@@ -3,9 +3,11 @@ import {
Button,
Divider,
Dropdown,
Form,
Menu,
notification,
Popover,
Select,
Space,
} from "antd";
import parsePhoneNumber from "libphonenumber-js";
@@ -59,7 +61,10 @@ export function ScheduleEventComponent({
const blockContent = (
<div>
<Button onClick={() => handleCancel(event.id)} disabled={event.arrived}>
<Button
onClick={() => handleCancel({ id: event.id })}
disabled={event.arrived}
>
{t("appointments.actions.cancel")}
</Button>
</div>
@@ -203,10 +208,46 @@ export function ScheduleEventComponent({
<Button>{t("appointments.actions.sendreminder")}</Button>
</Dropdown>
) : null}
<Button onClick={() => handleCancel(event.id)} disabled={event.arrived}>
{t("appointments.actions.cancel")}
</Button>
<Popover
trigger="click"
disabled={event.arrived}
content={
<Form
layout="vertical"
onFinish={({ lost_sale_reason }) => {
handleCancel({ id: event.id, lost_sale_reason });
}}
>
<Form.Item
name="lost_sale_reason"
label={t("jobs.fields.lost_sale_reason")}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Select
options={bodyshop.md_lost_sale_reasons.map((lsr) => ({
label: lsr,
value: lsr,
}))}
/>
</Form.Item>
<Button htmlType="submit">
{t("appointments.actions.cancel")}
</Button>
</Form>
}
>
<Button
// onClick={() => handleCancel(event.id)}
disabled={event.arrived}
>
{t("appointments.actions.cancel")}
</Button>
</Popover>
{event.isintake ? (
<Button
disabled={event.arrived}
@@ -249,7 +290,7 @@ export function ScheduleEventComponent({
const RegularEvent = event.isintake ? (
<Space
wrap
size='small'
size="small"
style={{
backgroundColor:
event.color && event.color.hex ? event.color.hex : event.color,

View File

@@ -11,7 +11,7 @@ export default function ScheduleEventContainer({ bodyshop, event, refetch }) {
const { t } = useTranslation();
const [cancelAppointment] = useMutation(CANCEL_APPOINTMENT_BY_ID);
const [updateJob] = useMutation(UPDATE_JOB);
const handleCancel = async (id) => {
const handleCancel = async ({ id, lost_sale_reason }) => {
logImEXEvent("schedule_cancel_appt");
const cancelAppt = await cancelAppointment({
@@ -38,7 +38,8 @@ export default function ScheduleEventContainer({ bodyshop, event, refetch }) {
job: {
date_scheduled: null,
scheduled_in: null,
scheduled_completion:null,
scheduled_completion: null,
lost_sale_reason,
status: bodyshop.md_ro_statuses.default_imported,
},
},

View File

@@ -59,14 +59,18 @@ export default function JobDetailCardsDatesComponent({ loading, data }) {
<DateTimeFormatter>{data.scheduled_in}</DateTimeFormatter>
</Timeline.Item>
) : null}
{data.actual_in ? (
<Timeline.Item>
<label>{t("jobs.fields.actual_in")}: </label>
<DateTimeFormatter>{data.actual_in}</DateTimeFormatter>
</Timeline.Item>
) : null}
{data.date_repairstarted ? (
<Timeline.Item>
<label>{t("jobs.fields.date_repairstarted")}: </label>
<DateTimeFormatter>{data.date_repairstarted}</DateTimeFormatter>
</Timeline.Item>
) : null}
{data.scheduled_completion ? (
<Timeline.Item>
<label>{t("jobs.fields.scheduled_completion")}: </label>

View File

@@ -103,6 +103,12 @@ export function JobLinesComponent({
fixed: "left",
key: "line_desc",
sorter: (a, b) => alphaSort(a.line_desc, b.line_desc),
onCell: (record) => ({
className: record.manual_line && "job-line-manual",
style: {
...(record.critical ? { boxShadow: " -.5em 0 0 #FFC107" } : {}),
},
}),
sortOrder:
state.sortedInfo.columnKey === "line_desc" && state.sortedInfo.order,
ellipsis: true,
@@ -342,7 +348,7 @@ export function JobLinesComponent({
onClick={() => {
setJobLineEditContext({
actions: { refetch: refetch, submit: form && form.submit },
context: record,
context: { ...record, jobid: job.id },
});
}}
>

View File

@@ -22,9 +22,20 @@ export function JoblinePresetButton({ bodyshop, form }) {
};
const menu = (
<Menu>
<Menu
style={{
columnCount: Math.max(
Math.floor(bodyshop.md_jobline_presets.length / 15),
1
),
}}
>
{bodyshop.md_jobline_presets.map((i, idx) => (
<Menu.Item onClick={() => handleSelect(i)} key={idx}>
<Menu.Item
onClick={() => handleSelect(i)}
key={idx}
style={{ breakInside: "avoid" }}
>
{i.label}
</Menu.Item>
))}

View File

@@ -40,6 +40,11 @@ export function JobLinesUpsertModalComponent({
{},
bodyshop.imexshopid
);
const { Autohouse_Detail_line } = useTreatments(
["Autohouse_Detail_line"],
{},
bodyshop.imexshopid
);
return (
<Modal
@@ -155,6 +160,40 @@ export function JobLinesUpsertModalComponent({
>
<InputNumber precision={1} />
</Form.Item>
{Autohouse_Detail_line.treatment === "on" && (
<Form.Item
label={t("joblines.fields.ah_detail_line")}
name="ah_detail_line"
valuePropName="checked"
dependencies={["mod_lbr_ty"]}
initialValue={false}
rules={[
({ getFieldValue }) => ({
validator(rule, value) {
if (
value === false ||
value === undefined ||
value === null
)
return Promise.resolve();
if (
value === true &&
["LA1", "LA2", "LA3", "LA4", "LAU"].includes(
getFieldValue("mod_lbr_ty")
)
) {
return Promise.resolve();
}
return Promise.reject(
t("joblines.validations.ahdetailonlyonuserdefinedtypes")
);
},
}),
]}
>
<Switch />
</Form.Item>
)}
</LayoutFormRow>
<LayoutFormRow>
<Form.Item label={t("joblines.fields.part_type")} name="part_type">
@@ -218,7 +257,6 @@ export function JobLinesUpsertModalComponent({
rules={[
({ getFieldValue }) => ({
validator(rule, value) {
console.log(value);
if (!value || getFieldValue("part_type") !== "PAE") {
return Promise.resolve();
}
@@ -229,7 +267,6 @@ export function JobLinesUpsertModalComponent({
}),
({ getFieldValue }) => ({
validator(rule, value) {
console.log(value, !!value);
if (
!!getFieldValue("part_type") === (!!value || value === 0)
) {
@@ -252,7 +289,7 @@ export function JobLinesUpsertModalComponent({
name="prt_dsmk_p"
initialValue={0}
>
<InputNumber precision={0} min={0} max={100} />
<InputNumber precision={0} min={-100} max={100} />
</Form.Item>
<Form.Item
label={t("joblines.fields.tax_part")}

View File

@@ -13,8 +13,13 @@ import { selectJobLineEditModal } from "../../redux/modals/modals.selectors";
import UndefinedToNull from "../../utils/undefinedtonull";
import JobLinesUpdsertModal from "./job-lines-upsert-modal.component";
import Axios from "axios";
import Dinero from "dinero.js";
import CriticalPartsScan from "../../utils/criticalPartsScan";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { useTreatments } from "@splitsoftware/splitio-react";
const mapStateToProps = createStructuredSelector({
jobLineEditModal: selectJobLineEditModal,
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
toggleModalVisible: () => dispatch(toggleModalVisible("jobLineEdit")),
@@ -23,7 +28,13 @@ const mapDispatchToProps = (dispatch) => ({
function JobLinesUpsertModalContainer({
jobLineEditModal,
toggleModalVisible,
bodyshop,
}) {
const { CriticalPartsScanning } = useTreatments(
["CriticalPartsScanning"],
{},
bodyshop.imexshopid
);
const { t } = useTranslation();
const [insertJobLine] = useMutation(INSERT_NEW_JOB_LINE);
const [updateJobLine] = useMutation(UPDATE_JOB_LINE);
@@ -40,7 +51,15 @@ function JobLinesUpsertModalContainer({
manual_line: !(
jobLineEditModal.context && jobLineEditModal.context.id
),
...UndefinedToNull(values),
...UndefinedToNull({
...values,
prt_dsmk_m: Dinero({
amount: Math.round((values.act_price || 0) * 100),
})
.percentage(Math.abs(values.prt_dsmk_p || 0))
.multiply(values.prt_dsmk_p >= 0 ? 1 : -1)
.toFormat(0.0),
}),
},
],
},
@@ -68,7 +87,15 @@ function JobLinesUpsertModalContainer({
const r = await updateJobLine({
variables: {
lineId: jobLineEditModal.context.id,
line: values,
line: {
...values,
prt_dsmk_m: Dinero({
amount: Math.round(values.act_price * 100),
})
.percentage(Math.abs(values.prt_dsmk_p || 0))
.multiply(values.prt_dsmk_p >= 0 ? 1 : -1)
.toFormat(0.0),
},
},
refetchQueries: ["GET_LINE_TICKET_BY_PK"],
});
@@ -92,6 +119,9 @@ function JobLinesUpsertModalContainer({
}
toggleModalVisible();
}
if (CriticalPartsScanning.treatment === "on") {
CriticalPartsScan(jobLineEditModal.context.jobid);
}
setLoading(false);
};

View File

@@ -25,8 +25,6 @@ const mapDispatchToProps = (dispatch) => ({
dispatch(setModalContext({ context: context, modal: "payment" })),
});
const stripeTestEnv = process.env.REACT_APP_STRIPE_PUBLIC_KEY; //.includes("test");
export function JobPayments({
job,
jobRO,
@@ -94,23 +92,6 @@ export function JobPayments({
state.sortedInfo.columnKey === "transactionid" &&
state.sortedInfo.order,
},
{
title: t("payments.fields.stripeid"),
dataIndex: "stripeid",
key: "stripeid",
render: (text, record) =>
record.stripeid ? (
<a
href={
stripeTestEnv
? `https://dashboard.stripe.com/${bodyshop.stripe_acct_id}/test/payments/${record.stripeid}`
: `https://dashboard.stripe.com/${bodyshop.stripe_acct_id}/payments/${record.stripeid}`
}
>
{record.stripeid}
</a>
) : null,
},
{
title: t("general.labels.actions"),
dataIndex: "actions",

View File

@@ -166,6 +166,16 @@ export default function ScoreboardAddButton({
painthrs: 0,
}
);
//Add Labor Adjustments
v.painthrs = v.painthrs + (job.lbr_adjustments.LAR || 0);
v.bodyhrs =
v.bodyhrs +
Object.keys(job.lbr_adjustments)
.filter((key) => key !== "LAR")
.reduce((acc, val) => {
return acc + job.lbr_adjustments[val];
}, 0);
form.setFieldsValue({
date: new moment(),
bodyhrs: Math.round(v.bodyhrs * 10) / 10,

View File

@@ -43,11 +43,9 @@ const JobSearchSelect = (
search: value,
...(convertedOnly || notExported
? {
variables: {
...(convertedOnly ? { isConverted: true } : {}),
...(notExported ? { notExported: true } : {}),
...(notInvoiced ? { notInvoiced: true } : {}),
},
...(convertedOnly ? { isConverted: true } : {}),
...(notExported ? { notExported: true } : {}),
...(notInvoiced ? { notInvoiced: true } : {}),
}
: {}),
},
@@ -79,6 +77,7 @@ const JobSearchSelect = (
disabled={disabled}
showSearch
autoFocus
allowClear
style={{
width: "100%",
}}

View File

@@ -126,6 +126,9 @@ export function JobsAdminDatesChange({ insertAuditTrail, job }) {
<Form.Item label={t("jobs.fields.actual_in")} name="actual_in">
<DateTimePicker />
</Form.Item>
<Form.Item label={t("jobs.fields.date_repairstarted")} name="date_repairstarted">
<DateTimePicker />
</Form.Item>
<Form.Item
label={t("jobs.fields.date_last_contacted")}
name="date_last_contacted"

View File

@@ -3,8 +3,9 @@ import {
useApolloClient,
useLazyQuery,
useMutation,
useQuery,
useQuery
} from "@apollo/client";
import { useTreatments } from "@splitsoftware/splitio-react";
import { Col, notification, Row } from "antd";
import Axios from "axios";
import Dinero from "dinero.js";
@@ -19,7 +20,7 @@ import { logImEXEvent } from "../../firebase/firebase.utils";
import {
DELETE_AVAILABLE_JOB,
QUERY_AVAILABLE_JOBS,
QUERY_AVAILABLE_NEW_JOBS_EST_DATA_BY_PK,
QUERY_AVAILABLE_NEW_JOBS_EST_DATA_BY_PK
} from "../../graphql/available-jobs.queries";
import { INSERT_NEW_JOB, UPDATE_JOB } from "../../graphql/jobs.queries";
import { INSERT_NEW_NOTE } from "../../graphql/notes.queries";
@@ -27,10 +28,11 @@ import { SEARCH_VEHICLE_BY_VIN } from "../../graphql/vehicles.queries";
import { insertAuditTrail } from "../../redux/application/application.actions";
import {
selectBodyshop,
selectCurrentUser,
selectCurrentUser
} from "../../redux/user/user.selectors";
import confirmDialog from "../../utils/asyncConfirm";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
import CriticalPartsScan from "../../utils/criticalPartsScan";
import AlertComponent from "../alert/alert.component";
import JobsAvailableScan from "../jobs-available-scan/jobs-available-scan.component";
import JobsFindModalContainer from "../jobs-find-modal/jobs-find-modal.container";
@@ -53,6 +55,11 @@ export function JobsAvailableContainer({
currentUser,
insertAuditTrail,
}) {
const { CriticalPartsScanning } = useTreatments(
["CriticalPartsScanning"],
{},
bodyshop.imexshopid
);
const { loading, error, data, refetch } = useQuery(QUERY_AVAILABLE_JOBS, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
@@ -112,12 +119,12 @@ export function JobsAvailableContainer({
).data;
let existingVehicles;
if (estData.est_data.vehicle && estData.est_data.vin) {
if (estData.est_data.v_vin) {
//There's vehicle data, need to double check the VIN.
existingVehicles = await client.query({
query: SEARCH_VEHICLE_BY_VIN,
variables: {
vin: estData.est_data.vehicle.data.v_vin,
vin: estData.est_data.v_vin || estData.est_data.vehicle.data.v_vin,
},
});
}
@@ -155,6 +162,9 @@ export function JobsAvailableContainer({
},
})
.then((r) => {
if (CriticalPartsScanning.treatment === "on") {
CriticalPartsScan(r.data.insert_jobs.returning[0].id);
}
notification["success"]({
message: t("jobs.successes.created"),
onClick: () => {
@@ -241,7 +251,9 @@ export function JobsAvailableContainer({
},
},
});
if (CriticalPartsScanning.treatment === "on") {
CriticalPartsScan(updateResult.data.update_jobs.returning[0].id);
}
if (updateResult.errors) {
//error while inserting
notification["error"]({

View File

@@ -9,6 +9,7 @@ import {
Space,
Switch,
} from "antd";
import axios from "axios";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -18,7 +19,6 @@ import { insertAuditTrail } from "../../redux/application/application.actions";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
import axios from "axios";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
bodyshop: selectBodyshop,
@@ -43,14 +43,22 @@ export function JobsConvertButton({
const { t } = useTranslation();
const [form] = Form.useForm();
const handleConvert = async (values) => {
const handleConvert = async ({ employee_csr, category, ...values }) => {
if (parentFormIsFieldsTouched()) {
alert(t("jobs.labels.savebeforeconversion"));
return;
}
setLoading(true);
const res = await mutationConvertJob({
variables: { jobId: job.id, ...values },
variables: {
jobId: job.id,
job: {
converted: true,
...(bodyshop.enforce_conversion_csr ? { employee_csr } : {}),
...(bodyshop.enforce_conversion_category ? { category } : {}),
...values,
},
},
});
if (values.ca_gst_registrant) {
@@ -83,7 +91,12 @@ export function JobsConvertButton({
layout="vertical"
form={form}
onFinish={handleConvert}
initialValues={{ driveable: true, towin: false }}
initialValues={{
driveable: true,
towin: false,
employee_csr: job.employee_csr,
category: job.category,
}}
>
<Form.Item
name={["ins_co_nm"]}
@@ -96,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>
))}
@@ -151,13 +164,70 @@ export function JobsConvertButton({
</Form.Item>
</>
)}
<Form.Item
label={t("jobs.fields.ca_gst_registrant")}
name="ca_gst_registrant"
valuePropName="checked"
>
<Switch />
</Form.Item>
{bodyshop.enforce_conversion_csr && (
<Form.Item
name={"employee_csr"}
label={t("jobs.fields.employee_csr")}
rules={[
{
required: bodyshop.enforce_conversion_csr,
//message: t("general.validation.required"),
},
]}
>
<Select
showSearch
style={{ width: 200 }}
optionFilterProp="children"
filterOption={(input, option) =>
option.props.children
.toLowerCase()
.indexOf(input.toLowerCase()) >= 0
}
>
{bodyshop.employees
.filter((emp) => emp.active)
.map((emp) => (
<Select.Option
value={emp.id}
key={emp.id}
name={`${emp.first_name} ${emp.last_name}`}
>
{`${emp.first_name} ${emp.last_name}`}
</Select.Option>
))}
</Select>
</Form.Item>
)}
{bodyshop.enforce_conversion_category && (
<Form.Item
name={"category"}
label={t("jobs.fields.category")}
rules={[
{
required: bodyshop.enforce_conversion_category,
//message: t("general.validation.required"),
},
]}
>
<Select allowClear>
{bodyshop.md_categories.map((s) => (
<Select.Option key={s} value={s}>
{s}
</Select.Option>
))}
</Select>
</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"
@@ -194,7 +264,14 @@ export function JobsConvertButton({
// style={{ display: job.converted ? "none" : "" }}
disabled={job.converted || jobRO}
loading={loading}
onClick={() => setVisible(true)}
onClick={() => {
setVisible(true);
form.setFieldsValue({
driveable: true,
towin: false,
employee_csr: job.employee_csr,
});
}}
>
{t("jobs.actions.convert")}
</Button>

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

@@ -9,7 +9,11 @@ const colSpan = {
lg: { span: 12 },
};
export default function JobsCreateVehicleInfoComponent({ loading, vehicles }) {
export default function JobsCreateVehicleInfoComponent({
loading,
vehicles,
form,
}) {
const [state, setState] = useContext(JobCreateContext);
const { t } = useTranslation();
return (
@@ -58,7 +62,7 @@ export default function JobsCreateVehicleInfoComponent({ loading, vehicles }) {
/>
</Col>
<Col {...colSpan}>
<JobsCreateVehicleInfoNewComponent />
<JobsCreateVehicleInfoNewComponent form={form}/>
</Col>
</Row>
</div>

View File

@@ -20,6 +20,7 @@ export default function JobsCreateVehicleInfoContainer({ form }) {
<JobsCreateVehicleInfoComponent
loading={loading}
vehicles={data ? data.search_vehicles : null}
form={form}
/>
);
}

View File

@@ -4,8 +4,9 @@ import { useTranslation } from "react-i18next";
import JobCreateContext from "../../pages/jobs-create/jobs-create.context";
import FormDatePicker from "../form-date-picker/form-date-picker.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import JobsCreateVehicleInfoPredefined from "./jobs-create-vehicle-info.predefined.component";
export default function JobsCreateVehicleInfoNewComponent() {
export default function JobsCreateVehicleInfoNewComponent({ form }) {
const [state] = useContext(JobCreateContext);
const { t } = useTranslation();
@@ -25,7 +26,7 @@ export default function JobsCreateVehicleInfoNewComponent() {
<Input disabled={!state.vehicle.new} />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow grow>
<LayoutFormRow grow noDivider>
<Form.Item
label={t("vehicles.fields.v_color")}
name={["vehicle", "data", "v_color"]}
@@ -52,8 +53,9 @@ export default function JobsCreateVehicleInfoNewComponent() {
</Form.Item>
</LayoutFormRow>
<LayoutFormRow grow>
<LayoutFormRow grow noDivider>
<Form.Item
span={10}
label={t("vehicles.fields.v_make_desc")}
name={["vehicle", "data", "v_make_desc"]}
rules={[
@@ -66,6 +68,7 @@ export default function JobsCreateVehicleInfoNewComponent() {
<Input disabled={!state.vehicle.new} />
</Form.Item>
<Form.Item
span={11}
label={t("vehicles.fields.v_model_desc")}
name={["vehicle", "data", "v_model_desc"]}
rules={[
@@ -77,6 +80,11 @@ export default function JobsCreateVehicleInfoNewComponent() {
>
<Input disabled={!state.vehicle.new} />
</Form.Item>
<JobsCreateVehicleInfoPredefined
disabled={!state.vehicle.new}
form={form}
span={1}
/>
</LayoutFormRow>
<LayoutFormRow header={t("vehicles.forms.registration")} grow>

View File

@@ -0,0 +1,81 @@
import { PlusOutlined, SearchOutlined } from "@ant-design/icons";
import { Button, Input, Popover, Table } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import PredefinedVehicles from "./predefined-vehicles.js";
export default function JobsCreateVehicleInfoPredefined({ disabled, form }) {
const [open, setOpen] = useState(false);
const [search, setSearch] = useState("");
const { t } = useTranslation();
const handleOpenChange = (newOpen) => {
setOpen(newOpen);
setSearch("");
};
const filteredPredefinedVehicles =
search === ""
? PredefinedVehicles
: PredefinedVehicles.filter(
(v) =>
v.make.toLowerCase().includes(search.toLowerCase()) ||
v.model.toLowerCase().includes(search.toLowerCase())
);
const popContent = () => (
<div>
<Table
size="small"
title={() => <Input.Search onSearch={(value) => setSearch(value)} />}
dataSource={filteredPredefinedVehicles}
columns={[
{
dataIndex: "make",
key: "make",
title: t("vehicles.fields.v_make_desc"),
},
{
dataIndex: "model",
key: "model",
title: t("vehicles.fields.v_model_desc"),
},
{
dataIndex: "select",
key: "select",
title: t("general.labels.actions"),
render: (value, record) => (
<Button
disabled={disabled}
onClick={() => {
form.setFieldsValue({
vehicle: {
data: {
v_make_desc: record.make,
v_model_desc: record.model,
},
},
});
setOpen(false);
setSearch("");
}}
>
<PlusOutlined />
</Button>
),
},
]}
/>
</div>
);
return (
<Popover
content={popContent}
trigger="click"
open={open}
placement="left"
onOpenChange={handleOpenChange}
destroyTooltipOnHide
>
<SearchOutlined style={{ cursor: "pointer" }} />
</Popover>
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -42,7 +42,10 @@ export function JobsDetailDatesComponent({ jobRO, job, bodyshop }) {
<Form.Item label={t("jobs.fields.date_towin")} name="date_towin">
<DateTimePicker disabled={jobRO} />
</Form.Item>
<Form.Item label={t("jobs.fields.date_rentalresp")} name="date_rentalresp">
<Form.Item
label={t("jobs.fields.date_rentalresp")}
name="date_rentalresp"
>
<DateTimePicker disabled={jobRO} />
</Form.Item>
</FormRow>
@@ -73,6 +76,12 @@ export function JobsDetailDatesComponent({ jobRO, job, bodyshop }) {
title={t("jobs.labels.calc_repair_days")}
/>
</Tooltip>
<Form.Item
label={t("jobs.fields.date_repairstarted")}
name="date_repairstarted"
>
<DateTimePicker disabled={jobRO} />
</Form.Item>
</FormRow>
<FormRow header={t("jobs.forms.repairdates")}>
<Form.Item

View File

@@ -256,7 +256,7 @@ export function JobsDetailGeneral({ bodyshop, jobRO, job, form }) {
</FormRow>
<FormRow header={t("jobs.forms.other")}>
<Form.Item label={t("jobs.fields.category")} name="category">
<Select disabled={jobRO}>
<Select disabled={jobRO} allowClear>
{bodyshop.md_categories.map((s) => (
<Select.Option key={s} value={s}>
{s}
@@ -289,6 +289,12 @@ export function JobsDetailGeneral({ bodyshop, jobRO, job, form }) {
>
<Input disabled={jobRO} />
</Form.Item>
<Form.Item
label={t("jobs.fields.lost_sale_reason")}
name="lost_sale_reason"
>
<Input disabled={jobRO} allowClear />
</Form.Item>
</FormRow>
</div>
);

View File

@@ -1,6 +1,15 @@
import { DownCircleFilled } from "@ant-design/icons";
import { useApolloClient, useMutation } from "@apollo/client";
import { Button, Dropdown, Menu, notification, Popconfirm } from "antd";
import {
Button,
Dropdown,
Form,
Menu,
notification,
Popconfirm,
Popover,
Select,
} from "antd";
import React, { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -127,35 +136,63 @@ export function JobsDetailHeaderActions({
<Menu.Item
disabled={job.status !== bodyshop.md_ro_statuses.default_scheduled}
>
<Popconfirm
title={t("general.labels.areyousure")}
okText="Yes"
cancelText="No"
onClick={(e) => e.stopPropagation()}
<Popover
trigger="click"
disabled={job.status !== bodyshop.md_ro_statuses.default_scheduled}
onConfirm={async () => {
const jobUpdate = await cancelAllAppointments({
variables: {
jobid: job.id,
job: {
date_scheduled: null,
scheduled_in: null,
scheduled_completion: null,
status: bodyshop.md_ro_statuses.default_imported,
},
},
});
if (!jobUpdate.errors) {
notification["success"]({
message: t("appointments.successes.canceled"),
});
return;
}
}}
getPopupContainer={(trigger) => trigger.parentNode}
content={
<Form
layout="vertical"
onFinish={async ({ lost_sale_reason }) => {
const jobUpdate = await cancelAllAppointments({
variables: {
jobid: job.id,
job: {
date_scheduled: null,
scheduled_in: null,
scheduled_completion: null,
lost_sale_reason,
status: bodyshop.md_ro_statuses.default_imported,
},
},
});
if (!jobUpdate.errors) {
notification["success"]({
message: t("appointments.successes.canceled"),
});
return;
}
}}
>
<Form.Item
name="lost_sale_reason"
label={t("jobs.fields.lost_sale_reason")}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Select
options={bodyshop.md_lost_sale_reasons.map((lsr) => ({
label: lsr,
value: lsr,
}))}
/>
</Form.Item>
<Button
htmlType="submit"
disabled={
job.status !== bodyshop.md_ro_statuses.default_scheduled
}
>
{t("appointments.actions.cancel")}
</Button>
</Form>
}
>
{t("menus.jobsactions.cancelallappointments")}
</Popconfirm>
</Popover>
</Menu.Item>
<Menu.Item
disabled={

View File

@@ -5,7 +5,7 @@ import {
BranchesOutlined,
} from "@ant-design/icons";
import { Card, Col, Row, Space, Tag, Tooltip } from "antd";
import React from "react";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
@@ -56,7 +56,7 @@ const colSpan = {
export function JobsDetailHeader({ job, bodyshop, disabled }) {
const { t } = useTranslation();
const [notesClamped, setNotesClamped] = useState(true);
const vehicleTitle = `${job.v_model_yr || ""} ${job.v_color || ""}
${job.v_make_desc || ""}
${job.v_model_desc || ""}`.trim();
@@ -229,6 +229,8 @@ export function JobsDetailHeader({ job, bodyshop, disabled }) {
<DataLabel
label={t("vehicles.fields.notes")}
valueStyle={{ whiteSpace: "pre-wrap" }}
valueClassName={notesClamped ? "clamp" : ""}
onValueClick={() => setNotesClamped(!notesClamped)}
>
{job.vehicle.notes}
</DataLabel>

View File

@@ -6,3 +6,12 @@
display: flex;
flex-wrap: wrap;
}
.clamp {
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
overflow-wrap: break-word;
}

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

@@ -5,7 +5,7 @@ import { useTranslation } from "react-i18next";
import { logImEXEvent } from "../../firebase/firebase.utils";
import cleanAxios from "../../utils/CleanAxios";
import formatBytes from "../../utils/formatbytes";
import yauzl from "yauzl";
//import yauzl from "yauzl";
import { useTreatments } from "@splitsoftware/splitio-react";
import { connect } from "react-redux";
@@ -69,44 +69,44 @@ export function JobsDocumentsDownloadButton({
setDownload(null);
if (Direct_Media_Download.treatment === "on") {
try {
const parentDir = await window.showDirectoryPicker({
id: "media",
startIn: "downloads",
});
// const parentDir = await window.showDirectoryPicker({
// id: "media",
// startIn: "downloads",
// });
const directory = await parentDir.getDirectoryHandle(identifier, {
create: true,
});
// const directory = await parentDir.getDirectoryHandle(identifier, {
// create: true,
// });
yauzl.fromBuffer(
Buffer.from(theDownloadedZip.data),
{},
(err, zipFile) => {
if (err) throw err;
zipFile.on("entry", (entry) => {
zipFile.openReadStream(entry, async (readErr, readStream) => {
if (readErr) {
zipFile.close();
throw readErr;
}
if (err) throw err;
let fileSystemHandle = await directory.getFileHandle(
entry.fileName,
{
create: true,
}
);
const writable = await fileSystemHandle.createWritable();
readStream.on("data", async function (chunk) {
await writable.write(chunk);
});
readStream.on("end", async function () {
await writable.close();
});
});
});
}
);
// yauzl.fromBuffer(
// Buffer.from(theDownloadedZip.data),
// {},
// (err, zipFile) => {
// if (err) throw err;
// zipFile.on("entry", (entry) => {
// zipFile.openReadStream(entry, async (readErr, readStream) => {
// if (readErr) {
// zipFile.close();
// throw readErr;
// }
// if (err) throw err;
// let fileSystemHandle = await directory.getFileHandle(
// entry.fileName,
// {
// create: true,
// }
// );
// const writable = await fileSystemHandle.createWritable();
// readStream.on("data", async function (chunk) {
// await writable.write(chunk);
// });
// readStream.on("end", async function () {
// await writable.close();
// });
// });
// });
// }
// );
} catch (e) {
console.log(e);
standardMediaDownload(theDownloadedZip.data);

View File

@@ -1,7 +1,7 @@
import { EditFilled, FileExcelFilled, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Col, Row, Space } from "antd";
import React, { useEffect, useState } from "react";
import Gallery from "react-grid-gallery";
import { Gallery } from "react-grid-gallery";
import { useTranslation } from "react-i18next";
import DocumentsUploadComponent from "../documents-upload/documents-upload.component";
import { DetermineFileType } from "../documents-upload/documents-upload.utility";
@@ -11,6 +11,9 @@ import JobsDocumentsGalleryReassign from "./jobs-document-gallery.reassign.compo
import JobsDocumentsDeleteButton from "./jobs-documents-gallery.delete.component";
import JobsDocumentsGallerySelectAllComponent from "./jobs-documents-gallery.selectall.component";
import Lightbox from "react-image-lightbox";
import "react-image-lightbox/style.css";
function JobsDocumentsComponent({
data,
jobId,
@@ -23,11 +26,7 @@ function JobsDocumentsComponent({
}) {
const [galleryImages, setgalleryImages] = useState({ images: [], other: [] });
const { t } = useTranslation();
const [index, setIndex] = useState(0);
const onCurrentImageChange = (index) => {
setIndex(index);
};
const [modalState, setModalState] = useState({ open: false, index: 0 });
useEffect(() => {
let documents = data.reduce(
@@ -35,14 +34,16 @@ function JobsDocumentsComponent({
const fileType = DetermineFileType(value.type);
if (value.type.startsWith("image")) {
acc.images.push({
src: GenerateSrcUrl(value),
thumbnail: GenerateThumbUrl(value),
thumbnailHeight: 225,
thumbnailWidth: 225,
// src: GenerateSrcUrl(value),
src: GenerateThumbUrl(value),
// src: GenerateSrcUrl(value),
// thumbnail: GenerateThumbUrl(value),
fullsize: GenerateSrcUrl(value),
height: 225,
width: 225,
isSelected: false,
key: value.key,
extension: value.extension,
id: value.id,
type: value.type,
size: value.size,
@@ -62,7 +63,7 @@ function JobsDocumentsComponent({
const fileName = value.key.split("/").pop();
acc.other.push({
source: GenerateSrcUrl(value),
src: "",
src: thumb,
thumbnail: thumb,
tags: [
{
@@ -85,10 +86,9 @@ function JobsDocumentsComponent({
]
: []),
],
thumbnailHeight: 225,
thumbnailWidth: 225,
height: 225,
width: 225,
isSelected: false,
extension: value.extension,
key: value.key,
id: value.id,
@@ -148,35 +148,15 @@ function JobsDocumentsComponent({
<Card title={t("jobs.labels.documents-images")}>
<Gallery
images={galleryImages.images}
backdropClosesModal={true}
currentImageWillChange={onCurrentImageChange}
customControls={[
<Button
key="edit-button"
style={{
float: "right",
zIndex: "5",
}}
onClick={() => {
const newWindow = window.open(
`${window.location.protocol}//${window.location.host}/edit?documentId=${galleryImages.images[index].id}`,
"_blank",
"noopener,noreferrer"
);
if (newWindow) newWindow.opener = null;
}}
>
<EditFilled />
</Button>,
]}
onClickImage={(props) => {
window.open(
props.target.src,
"_blank",
"toolbar=0,location=0,menubar=0"
);
onClick={(index, item) => {
setModalState({ open: true, index: index });
// window.open(
// item.fullsize,
// "_blank",
// "toolbar=0,location=0,menubar=0"
// );
}}
onSelectImage={(index, image) => {
onSelect={(index, image) => {
setgalleryImages({
...galleryImages,
images: galleryImages.images.map((g, idx) =>
@@ -191,8 +171,6 @@ function JobsDocumentsComponent({
<Card title={t("jobs.labels.documents-other")}>
<Gallery
images={galleryImages.other}
backdropClosesModal={true}
enableLightbox={false}
thumbnailStyle={() => {
return {
backgroundImage: <FileExcelFilled />,
@@ -201,14 +179,14 @@ function JobsDocumentsComponent({
cursor: "pointer",
};
}}
onClickThumbnail={(index) => {
onClick={(index) => {
window.open(
galleryImages.other[index].source,
"_blank",
"toolbar=0,location=0,menubar=0"
);
}}
onSelectImage={(index) => {
onSelect={(index) => {
setgalleryImages({
...galleryImages,
other: galleryImages.other.map((g, idx) =>
@@ -219,6 +197,53 @@ function JobsDocumentsComponent({
/>
</Card>
</Col>
{modalState.open && (
<Lightbox
toolbarButtons={[
<EditFilled
onClick={() => {
const newWindow = window.open(
`${window.location.protocol}//${
window.location.host
}/edit?documentId=${
galleryImages.images[modalState.index].id
}`,
"_blank",
"noopener,noreferrer"
);
if (newWindow) newWindow.opener = null;
}}
/>,
]}
mainSrc={galleryImages.images[modalState.index].fullsize}
nextSrc={
galleryImages.images[
(modalState.index + 1) % galleryImages.images.length
].fullsize
}
prevSrc={
galleryImages.images[
(modalState.index + galleryImages.images.length - 1) %
galleryImages.images.length
].fullsize
}
onCloseRequest={() => setModalState({ open: false, index: 0 })}
onMovePrevRequest={() =>
setModalState({
...modalState,
index:
(modalState.index + galleryImages.images.length - 1) %
galleryImages.images.length,
})
}
onMoveNextRequest={() =>
setModalState({
...modalState,
index: (modalState.index + 1) % galleryImages.images.length,
})
}
/>
)}
</Row>
</div>
);

View File

@@ -1,7 +1,7 @@
import React, { useEffect } from "react";
import Gallery from "react-grid-gallery";
import { Gallery } from "react-grid-gallery";
import { useTranslation } from "react-i18next";
import { GenerateSrcUrl, GenerateThumbUrl } from "./job-documents.utility";
import { GenerateThumbUrl } from "./job-documents.utility";
function JobsDocumentGalleryExternal({
data,
@@ -15,8 +15,8 @@ function JobsDocumentGalleryExternal({
let documents = data.reduce((acc, value) => {
if (value.type.startsWith("image")) {
acc.push({
src: GenerateSrcUrl(value),
thumbnail: GenerateThumbUrl(value),
//src: GenerateSrcUrl(value),
src: GenerateThumbUrl(value),
thumbnailHeight: 225,
thumbnailWidth: 225,
isSelected: false,
@@ -39,7 +39,7 @@ function JobsDocumentGalleryExternal({
<Gallery
images={galleryImages}
backdropClosesModal={true}
onSelectImage={(index, image) => {
onSelect={(index, image) => {
setgalleryImages(
galleryImages.map((g, idx) =>
index === idx ? { ...g, isSelected: !g.isSelected } : g

View File

@@ -1,7 +1,7 @@
import { SyncOutlined, FileExcelFilled } from "@ant-design/icons";
import { Alert, Button, Card, Space } from "antd";
import React, { useEffect } from "react";
import Gallery from "react-grid-gallery";
import React, { useEffect, useState } from "react";
import { Gallery } from "react-grid-gallery";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -19,6 +19,9 @@ import JobsLocalGalleryDownloadButton from "./jobs-documents-local-gallery.downl
import JobsDocumentsLocalGalleryReassign from "./jobs-documents-local-gallery.reassign.component";
import JobsDocumentsLocalGallerySelectAllComponent from "./jobs-documents-local-gallery.selectall.component";
import Lightbox from "react-image-lightbox";
import "react-image-lightbox/style.css";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
allMedia: selectAllMedia,
@@ -49,6 +52,7 @@ export function JobsDocumentsLocalGallery({
vendorid,
}) {
const { t } = useTranslation();
const [modalState, setModalState] = useState({ open: false, index: 0 });
useEffect(() => {
if (job) {
if (invoice_number) {
@@ -70,12 +74,20 @@ export function JobsDocumentsLocalGallery({
) {
acc.images.push({
...val,
fullsize: val.src,
src: val.thumbnail,
height: val.thumbnailHeight,
width: val.thumbnailWidth,
...(val.optimized && { src: val.optimized, fullsize: val.src }),
});
if (val.optimized) optimized = true;
} else {
acc.other.push({
...val,
fullsize: val.src,
src: val.thumbnail,
height: val.thumbnailHeight,
width: val.thumbnailWidth,
tags: [{ value: val.filename, title: val.filename }],
});
}
@@ -120,8 +132,7 @@ export function JobsDocumentsLocalGallery({
<Card title={t("jobs.labels.documents-images")}>
<Gallery
images={jobMedia.images}
backdropClosesModal={true}
onSelectImage={(index, image) => {
onSelect={(index, image) => {
toggleMediaSelected({ jobid: job.id, filename: image.filename });
}}
{...(optimized && {
@@ -133,24 +144,23 @@ export function JobsDocumentsLocalGallery({
/>,
],
})}
onClickImage={(props) => {
const media = allMedia[job.id].find(
(m) => m.optimized === props.target.src
);
onClick={(index) => {
setModalState({ open: true, index: index });
// const media = allMedia[job.id].find(
// (m) => m.optimized === item.src
// );
window.open(
media ? media.src : props.target.src,
"_blank",
"toolbar=0,location=0,menubar=0"
);
// window.open(
// media ? media.fullsize : item.fullsize,
// "_blank",
// "toolbar=0,location=0,menubar=0"
// );
}}
/>
</Card>
<Card title={t("jobs.labels.documents-other")}>
<Gallery
images={jobMedia.other}
backdropClosesModal={true}
enableLightbox={false}
thumbnailStyle={() => {
return {
backgroundImage: <FileExcelFilled />,
@@ -159,18 +169,48 @@ export function JobsDocumentsLocalGallery({
cursor: "pointer",
};
}}
onClickThumbnail={(index) => {
onClick={(index) => {
window.open(
jobMedia.other[index].src,
jobMedia.other[index].fullsize,
"_blank",
"toolbar=0,location=0,menubar=0"
);
}}
onSelectImage={(index, image) => {
onSelect={(index, image) => {
toggleMediaSelected({ jobid: job.id, filename: image.filename });
}}
/>
</Card>
{modalState.open && (
<Lightbox
mainSrc={jobMedia.images[modalState.index].fullsize}
nextSrc={
jobMedia.images[(modalState.index + 1) % jobMedia.images.length]
.fullsize
}
prevSrc={
jobMedia.images[
(modalState.index + jobMedia.images.length - 1) %
jobMedia.images.length
].fullsize
}
onCloseRequest={() => setModalState({ open: false, index: 0 })}
onMovePrevRequest={() =>
setModalState({
...modalState,
index:
(modalState.index + jobMedia.images.length - 1) %
jobMedia.images.length,
})
}
onMoveNextRequest={() =>
setModalState({
...modalState,
index: (modalState.index + 1) % jobMedia.images.length,
})
}
/>
)}
</div>
);
}

View File

@@ -1,5 +1,5 @@
import React, { useEffect } from "react";
import Gallery from "react-grid-gallery";
import { Gallery } from "react-grid-gallery";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -38,7 +38,7 @@ function JobDocumentsLocalGalleryExternal({
const { t } = useTranslation();
useEffect(() => {
if ( jobId) {
if (jobId) {
getJobMedia(jobId);
}
}, [jobId, getJobMedia]);
@@ -52,11 +52,15 @@ function JobDocumentsLocalGalleryExternal({
val.type.mime &&
val.type.mime.startsWith("image")
) {
acc.push(val);
acc.push({ ...val, src: val.thumbnail });
}
return acc;
}, [])
: [];
console.log(
"🚀 ~ file: jobs-documents-local-gallery.external.component.jsx:48 ~ useEffect ~ documents:",
documents
);
setgalleryImages(documents);
}, [allMedia, jobId, setgalleryImages, t]);
@@ -65,8 +69,7 @@ function JobDocumentsLocalGalleryExternal({
<div className="clearfix">
<Gallery
images={galleryImages}
backdropClosesModal={true}
onSelectImage={(index, image) => {
onSelect={(index, image) => {
setgalleryImages(
galleryImages.map((g, idx) =>
index === idx ? { ...g, isSelected: !g.isSelected } : g

View File

@@ -182,7 +182,7 @@ export function JobsExportAllButton({
return (
<Button onClick={handleQbxml} loading={loading} disabled={disabled}>
{t("jobs.actions.export")}
{t("jobs.actions.exportselected")}
</Button>
);
}

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,23 +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,
}}
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

@@ -260,6 +260,19 @@ export function JobsList({ bodyshop }) {
dataIndex: "ins_co_nm",
key: "ins_co_nm",
ellipsis: true,
filters:
(jobs &&
jobs
.map((j) => j.ins_co_nm)
.filter(onlyUnique)
.map((s) => {
return {
text: s,
value: [s],
};
})) ||
[],
onFilter: (value, record) => value.includes(record.ins_co_nm),
responsive: ["md"],
},
{

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

@@ -272,6 +272,19 @@ export function JobsReadyList({ bodyshop }) {
dataIndex: "ins_co_nm",
key: "ins_co_nm",
ellipsis: true,
filters:
(jobs &&
jobs
.map((j) => j.ins_co_nm)
.filter(onlyUnique)
.map((s) => {
return {
text: s,
value: [s],
};
})) ||
[],
onFilter: (value, record) => value.includes(record.ins_co_nm),
responsive: ["md"],
},
{

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

@@ -6,10 +6,6 @@ export const CalculateAllocationsTotals = (
timetickets,
adjustments = []
) => {
console.log(
"🚀 ~ file: labor-allocations-table.utility.js ~ line 9 ~ adjustments",
adjustments
);
const responsibilitycenters = bodyshop.md_responsibility_centers;
const jobCodes = joblines.map((item) => item.mod_lbr_ty);
//.filter((value, index, self) => self.indexOf(value) === index && !!value);

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

@@ -1,15 +1,40 @@
import { Button, Form, notification, PageHeader } from "antd";
import { Button, Form, notification, PageHeader, Popconfirm } from "antd";
import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import { useMutation } from "@apollo/client";
import { useTranslation } from "react-i18next";
import { UPDATE_OWNER } from "../../graphql/owners.queries";
import { DELETE_OWNER, UPDATE_OWNER } from "../../graphql/owners.queries";
import OwnerDetailFormComponent from "./owner-detail-form.component";
function OwnerDetailFormContainer({ owner, refetch }) {
const { t } = useTranslation();
const [form] = Form.useForm();
const history = useHistory();
const [loading, setLoading] = useState(false);
const [updateOwner] = useMutation(UPDATE_OWNER);
const [deleteOwner] = useMutation(DELETE_OWNER);
const handleDelete = async () => {
setLoading(true);
const result = await deleteOwner({
variables: { id: owner.id },
});
console.log(result);
if (result.errors) {
notification["error"]({
message: t("owners.errors.deleting", {
error: JSON.stringify(result.errors),
}),
});
setLoading(false);
} else {
notification["success"]({
message: t("owners.successes.delete"),
});
setLoading(false);
history.push(`/manage/owners`);
}
};
const handleFinish = async (values) => {
setLoading(true);
@@ -41,15 +66,29 @@ function OwnerDetailFormContainer({ owner, refetch }) {
<>
<PageHeader
title={t("menus.header.owners")}
extra={
extra={[
<Popconfirm
trigger="click"
onConfirm={handleDelete}
disabled={owner.jobs.length !== 0}
title={t("owners.labels.deleteconfirm")}
>
<Button
type="danger"
loading={loading}
disabled={owner.jobs.length !== 0}
>
{t("general.actions.delete")}
</Button>
</Popconfirm>,
<Button
type="primary"
loading={loading}
onClick={() => form.submit()}
>
{t("general.actions.save")}
</Button>
}
</Button>,
]}
/>
<Form
form={form}

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