Compare commits

...

227 Commits

Author SHA1 Message Date
Patrick Fic
7b3dcf295e IO-2156 Resolve AH detail line validation issue. 2023-01-27 13:20:53 -08: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
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
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
af009a0bb3 Updates to Sentry & removal of Stripe. 2023-01-03 12:23:25 -08: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
b0755a0cde IO-2133 Manual Line Highlighting 2022-12-27 13:32:24 -08: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
1df023fd15 Remove unneeded import to fix CI. 2022-12-15 17:09:05 -08:00
Patrick Fic
54277e4548 IO-2131 Resolve job search select filtering issue. 2022-12-15 16:39:47 -08: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
e192a63575 IO-2123 Add cc inventory print. 2022-12-09 11:35:13 -08: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
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
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
9f28b80a5a IO-1532 Status Transition Tracking. 2022-11-10 09:42:03 -08:00
Patrick Fic
77e865c5c4 CI Test 2022-11-09 16:34:30 -08:00
Patrick Fic
d01a1aa0a0 CI Test 2022-11-09 16:29:32 -08: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
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
6c5d684218 Add title to email overlay to prevent close button overlap. 2022-11-03 16:37:09 -07: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
a62796b12f ARMS Update 2022-11-03 11:44:37 -07: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
6a49457382 CI fix. 2022-11-03 10:12:46 -07:00
Patrick Fic
24d71413c1 Revert "IO-2086 Use new grid gallery and lightbox for performance."
This reverts commit 089fc0b0f7.
2022-11-03 10:12:15 -07: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
3354afe380 Merge branch 'feature/pbs-ap' into release/2022-11-04
* feature/pbs-ap:
  Minor bug fixes.
  Add notification of complete export.
  AP changes based on validation testing.
  WIP PBS AP.
  WIP PBS AP.
2022-11-03 10:01:39 -07:00
Patrick Fic
089fc0b0f7 IO-2086 Use new grid gallery and lightbox for performance. 2022-11-01 09:04:41 -07:00
Patrick Fic
33dea8638c Merged in release/2022-10-31 (pull request #608)
Improved LR tracking.
2022-10-31 18:31:03 +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
157 changed files with 2173 additions and 97224 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,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

View File

@@ -1,4 +1,4 @@
<babeledit_project version="1.2" be_version="2.7.1">
<babeledit_project be_version="2.7.1" version="1.2">
<!--
BabelEdit project file
@@ -736,6 +736,48 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>expectedjobs</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>expectedprodhrs</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>history</name>
<definition_loaded>false</definition_loaded>
@@ -4213,6 +4255,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>disablebillwip</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>disablecontactvehiclecreation</name>
<definition_loaded>false</definition_loaded>
@@ -4381,6 +4444,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>sendmaterialscosting</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>srcco</name>
<definition_loaded>false</definition_loaded>
@@ -4446,6 +4530,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>enforce_conversion_csr</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>enforce_referral</name>
<definition_loaded>false</definition_loaded>
@@ -14191,6 +14296,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>emailpreview</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>generatingemail</name>
<definition_loaded>false</definition_loaded>
@@ -18235,6 +18361,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>ah_detail_line</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>db_price</name>
<definition_loaded>false</definition_loaded>
@@ -19562,6 +19709,27 @@
<folder_node>
<name>validations</name>
<children>
<concept_node>
<name>ahdetailonlyonuserdefinedtypes</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>hrsrequirediflbrtyp</name>
<definition_loaded>false</definition_loaded>
@@ -22222,6 +22390,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>date_repairstarted</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>date_scheduled</name>
<definition_loaded>false</definition_loaded>
@@ -22414,6 +22603,32 @@
</translation>
</translations>
</concept_node>
<folder_node>
<name>control_type</name>
<children>
<concept_node>
<name>account_number</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children>
</folder_node>
<concept_node>
<name>cost</name>
<definition_loaded>false</definition_loaded>
@@ -27535,6 +27750,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>disablebillwip</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>invoicedatefuture</name>
<definition_loaded>false</definition_loaded>
@@ -28760,6 +28996,27 @@
</concept_node>
</children>
</folder_node>
<concept_node>
<name>profileadjustments</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>prt_dsmk_total</name>
<definition_loaded>false</definition_loaded>
@@ -32518,11 +32775,53 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>updatinglabel</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children>
</folder_node>
<folder_node>
<name>labels</name>
<children>
<concept_node>
<name>addlabel</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>archive</name>
<definition_loaded>false</definition_loaded>
@@ -36367,6 +36666,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>courtesy_car_inventory</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>courtesy_car_terms</name>
<definition_loaded>false</definition_loaded>
@@ -38025,6 +38345,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>timetickets_ro</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>vehicle_check_in</name>
<definition_loaded>false</definition_loaded>
@@ -40392,6 +40733,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>cycle_time_analysis</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>estimates_written_converted</name>
<definition_loaded>false</definition_loaded>
@@ -41148,6 +41510,48 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>jobs_completed_not_invoiced</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>jobs_invoiced_not_exported</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>jobs_reconcile</name>
<definition_loaded>false</definition_loaded>
@@ -41274,6 +41678,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>open_orders_specific_csr</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>open_orders_status</name>
<definition_loaded>false</definition_loaded>
@@ -41820,6 +42245,48 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>returns_grouped_by_vendor_detailed</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>returns_grouped_by_vendor_summary</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>schedule</name>
<definition_loaded>false</definition_loaded>
@@ -41841,6 +42308,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>scheduled_parts_list</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>scoreboard_detail</name>
<definition_loaded>false</definition_loaded>
@@ -42082,6 +42570,27 @@
<folder_node>
<name>labels</name>
<children>
<concept_node>
<name>atssummary</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>employeevacation</name>
<definition_loaded>false</definition_loaded>
@@ -46223,6 +46732,48 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>changepassword</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>profileinfo</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children>
</folder_node>
<folder_node>

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=https://api.imex.online/
REACT_APP_REPORTS_SERVER_URL=https://reports3.test.imex.online
REACT_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc

13
client/.env.production Normal file
View File

@@ -0,0 +1,13 @@
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

@@ -9,11 +9,9 @@
"@craco/craco": "^6.4.5",
"@fingerprintjs/fingerprintjs": "^3.3.3",
"@jsreport/browser-client": "^3.1.0",
"@sentry/react": "^7.7.0",
"@sentry/tracing": "^7.7.0",
"@sentry/react": "^7.28.1",
"@sentry/tracing": "^7.28.1",
"@splitsoftware/splitio-react": "^1.6.0",
"@stripe/react-stripe-js": "^1.9.0",
"@stripe/stripe-js": "^1.32.0",
"@tanem/react-nprogress": "^5.0.8",
"antd": "^4.22.3",
"apollo-link-logger": "^2.0.0",
@@ -119,7 +117,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

@@ -147,4 +147,9 @@
//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;
}

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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -1,6 +1,5 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Card, Form, Input, Table } from "antd";
import Dinero from "dinero.js";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -141,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

@@ -178,6 +178,7 @@ export function EmailOverlayContainer({
maskClosable={false}
width={"80%"}
onOk={() => form.submit()}
title={t("emails.labels.emailpreview")}
onCancel={() => {
toggleEmailOverlayVisible();
}}
@@ -198,7 +199,7 @@ export function EmailOverlayContainer({
<div>
<div
style={{
marginTop: "1rem",
// marginTop: "3rem",
display: "flex",
justifyContent: "flex-end",
}}

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";
@@ -9,7 +8,7 @@ import { GLOBAL_SEARCH_QUERY } from "../../graphql/search.queries";
import PhoneNumberFormatter from "../../utils/PhoneFormatter";
import AlertComponent from "../alert/alert.component";
import OwnerNameDisplay, {
OwnerNameDisplayFunction,
OwnerNameDisplayFunction
} from "../owner-name-display/owner-name-display.component";
import VehicleVinDisplay from "../vehicle-vin-display/vehicle-vin-display.component";
export default function GlobalSearch() {
@@ -178,13 +177,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

@@ -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,7 @@ 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" }),
sortOrder:
state.sortedInfo.columnKey === "line_desc" && state.sortedInfo.order,
ellipsis: true,

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)
) {

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

@@ -112,12 +112,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,
},
});
}

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,21 @@ export function JobsConvertButton({
const { t } = useTranslation();
const [form] = Form.useForm();
const handleConvert = async (values) => {
const handleConvert = async ({ employee_csr, ...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 } : {}),
...values,
},
},
});
if (values.ca_gst_registrant) {
@@ -83,7 +90,11 @@ export function JobsConvertButton({
layout="vertical"
form={form}
onFinish={handleConvert}
initialValues={{ driveable: true, towin: false }}
initialValues={{
driveable: true,
towin: false,
employee_csr: job.employee_csr,
}}
>
<Form.Item
name={["ins_co_nm"]}
@@ -151,6 +162,41 @@ export function JobsConvertButton({
</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>
)}
<Form.Item
label={t("jobs.fields.ca_gst_registrant")}
name="ca_gst_registrant"
@@ -194,7 +240,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

@@ -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

@@ -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

@@ -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

@@ -233,6 +233,7 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
pageSize: 25,
current: parseInt(page || 1),
total: total,
showSizeChanger: false,
}}
columns={columns}
rowKey="id"

View File

@@ -159,7 +159,7 @@ export function PayableExportAll({
} else {
notification["error"]({
message: t("bills.errors.exporting", {
error: JSON.stringify(billUpdateResponse.error),
error: JSON.stringify(billUpdateResponse.errors),
}),
});
}

View File

@@ -1,12 +1,10 @@
import { useTreatments } from "@splitsoftware/splitio-react";
import { CardElement } from "@stripe/react-stripe-js";
import { Checkbox, Form, Input, Radio, Select } from "antd";
import { Form, Input, Radio, Select } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import Alert from "../alert/alert.component";
import DatePickerFormItem from "../form-date-picker/form-date-picker.component";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import JobSearchSelect from "../job-search-select/job-search-select.component";
@@ -19,11 +17,9 @@ const mapStateToProps = createStructuredSelector({
export function PaymentFormComponent({
form,
stripeStateArr,
bodyshop,
disabled,
}) {
const [stripeState, setStripeState] = stripeStateArr;
const { Qb_Multi_Ar } = useTreatments(
["Qb_Multi_Ar"],
{},
@@ -31,9 +27,6 @@ export function PaymentFormComponent({
);
const { t } = useTranslation();
const handleStripeChange = (e) => {
setStripeState({ error: e.error, cardComplete: e.complete });
};
return (
<div>
@@ -150,57 +143,6 @@ export function PaymentFormComponent({
</Form.Item>
</LayoutFormRow>
<LayoutFormRow grow>
<div>
<Form.Item
label={t("payments.labels.electronicpayment")}
name="useStripe"
valuePropName="checked"
>
<Checkbox
defaultChecked={!!bodyshop.stripe_acct_id}
disabled={!!!bodyshop.stripe_acct_id || disabled}
/>
</Form.Item>
{!bodyshop.stripe_acct_id ? (
<div style={{ fontStyle: "italic" }}>
{t("payments.labels.signup")}
</div>
) : null}
<Form.Item shouldUpdate>
{() => {
if (form.getFieldValue("useStripe"))
return (
<CardElement
options={{
style: {
base: {
color: "#32325d",
//fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: "antialiased",
//fontSize: "16px",
"::placeholder": {
color: "#aab7c4",
},
},
invalid: {
color: "#fa755a",
iconColor: "#fa755a",
},
},
}}
onChange={handleStripeChange}
/>
);
return null;
}}
</Form.Item>
{stripeState.error ? (
<Alert type="error" message={stripeState.error.message} />
) : null}
</div>
<Form.Item
label={t("general.labels.sendby")}
name="sendby"

View File

@@ -1,23 +1,20 @@
import { useApolloClient, useMutation } from "@apollo/client";
import { CardElement, useElements, useStripe } from "@stripe/react-stripe-js";
import { useMutation } from "@apollo/client";
import { Button, Form, Modal, notification } from "antd";
import axios from "axios";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { GET_JOB_INFO_FOR_STRIPE } from "../../graphql/jobs.queries";
import {
INSERT_NEW_PAYMENT,
UPDATE_PAYMENT,
UPDATE_PAYMENT
} from "../../graphql/payments.queries";
import { setEmailOptions } from "../../redux/email/email.actions";
import { toggleModalVisible } from "../../redux/modals/modals.actions";
import { selectPayment } from "../../redux/modals/modals.selectors";
import {
selectBodyshop,
selectCurrentUser,
selectCurrentUser
} from "../../redux/user/user.selectors";
import { GenerateDocument } from "../../utils/RenderTemplate";
import { TemplateList } from "../../utils/TemplateConstants";
@@ -45,82 +42,23 @@ function PaymentModalContainer({
const [enterAgain, setEnterAgain] = useState(false);
const [insertPayment] = useMutation(INSERT_NEW_PAYMENT);
const [updatePayment] = useMutation(UPDATE_PAYMENT);
const client = useApolloClient();
const stripe = useStripe();
const elements = useElements();
const { t } = useTranslation();
const { context, actions, visible } = paymentModal;
const [loading, setLoading] = useState(false);
const stripeStateArr = useState({
error: null,
cardComplete: false,
});
const stripeState = stripeStateArr[0];
const cardValid = !!!stripeState.error && stripeState.cardComplete;
const handleFinish = async (values) => {
const { useStripe, sendby, ...paymentObj } = values;
if (useStripe && !cardValid) return;
if ((useStripe && !stripe) || !elements) {
// Stripe.js has not yet loaded.
// Make sure to disable form submission until Stripe.js has loaded.
return;
}
setLoading(true);
try {
let stripePayment;
if (useStripe && bodyshop.stripe_acct_id) {
logImEXEvent("payment_stripe_attempt");
const secretKey = await axios.post("/stripe/payment", {
amount: Math.round(values.amount * 100),
stripe_acct_id: bodyshop.stripe_acct_id,
});
const { data } = await client.query({
query: GET_JOB_INFO_FOR_STRIPE,
variables: { jobid: values.jobid },
});
stripePayment = await stripe.confirmCardPayment(
secretKey.data.clientSecret,
{
payment_method: {
card: elements.getElement(CardElement),
billing_details: {
name: `${data.jobs_by_pk.ownr_fn || ""} ${
data.jobs_by_pk.ownr_ln || ""
} ${data.jobs_by_pk.ownr_co_nm || ""}`,
email: data.jobs_by_pk.ownr_ea,
phone: data.jobs_by_pk.ownr_ph1,
},
},
}
);
if (stripePayment.paymentIntent.status === "succeeded") {
notification["success"]({ message: t("payments.successes.stripe") });
} else {
notification["error"]({ message: t("payments.errors.stripe") });
throw new Error();
}
}
logImEXEvent("payment_insert");
if (!context || (context && !context.id)) {
const newPayment = await insertPayment({
variables: {
paymentInput: {
...paymentObj,
stripeid:
stripePayment &&
stripePayment.paymentIntent &&
stripePayment.paymentIntent.id,
},
},
});
@@ -236,11 +174,7 @@ function PaymentModalContainer({
layout="vertical"
initialValues={context || {}}
>
<PaymentForm
form={form}
stripeStateArr={stripeStateArr}
disabled={context && context.stripeid}
/>
<PaymentForm form={form} />
</Form>
</Modal>
);
@@ -250,15 +184,3 @@ export default connect(
mapStateToProps,
mapDispatchToProps
)(PaymentModalContainer);
// const pr = stripe.paymentRequest({
// country: "CA",
// currency: "CAD",
// total: {
// label: "Demo total",
// amount: 1099,
// },
// requestPayerName: true,
// requestPayerEmail: true,
// });
// console.log("handleFinish -> pr", pr);

View File

@@ -16,8 +16,6 @@ import CaBcEtfTableModalContainer from "../ca-bc-etf-table-modal/ca-bc-etf-table
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
const stripeTestEnv = process.env.REACT_APP_STRIPE_PUBLIC_KEY; //.includes("test");
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
bodyshop: selectBodyshop,
@@ -125,23 +123,6 @@ export function PaymentsListPaginated({
dataIndex: "transactionid",
key: "transactionid",
},
{
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("payments.fields.created_at"),
dataIndex: "created_at",

View File

@@ -1,4 +1,12 @@
import { Button, Card, Form, InputNumber, Popover, Radio } from "antd";
import {
Button,
Card,
Form,
InputNumber,
notification,
Popover,
Radio,
} from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -27,7 +35,6 @@ export function PrintCenterJobsLabels({ bodyshop, jobId }) {
const handleOk = (e) => {
e.stopPropagation();
form.submit();
setIsModalVisible(false);
};
const handleCancel = () => {
@@ -37,18 +44,24 @@ export function PrintCenterJobsLabels({ bodyshop, jobId }) {
const handleFinish = async ({ template, ...values }) => {
const { sendtype, ...restVals } = values;
setLoading(true);
await GenerateDocument(
{
name: TemplateList("job_special")[template].key,
variables: { id: jobId },
context: restVals,
},
{},
"p",
jobId
);
setLoading(false);
setIsModalVisible(false);
try {
await GenerateDocument(
{
name: TemplateList("job_special")[template].key,
variables: { id: jobId },
context: restVals,
},
{},
"p",
jobId
);
setIsModalVisible(false);
} catch (error) {
notification.open({ type: "error", message: JSON.stringify(error) });
} finally {
setLoading(false);
}
form.resetFields();
};
@@ -60,7 +73,15 @@ export function PrintCenterJobsLabels({ bodyshop, jobId }) {
layout="vertical"
form={form}
>
<Form.Item required name="template">
<Form.Item
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
name="template"
>
<Radio.Group>
<Radio.Button value="parts_label_multiple">
{t("printcenter.jobs.parts_label_multiple")}
@@ -71,14 +92,24 @@ export function PrintCenterJobsLabels({ bodyshop, jobId }) {
</Radio.Group>
</Form.Item>
<Form.Item
required
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
label={t("printcenter.jobs.labels.position")}
name="position"
>
<InputNumber min={1} precision={0} />
</Form.Item>
<Form.Item
required
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
label={t("printcenter.jobs.labels.count")}
name="count"
>

View File

@@ -534,6 +534,7 @@ const r = ({ technician, state, activeStatuses, bodyshop }) => {
<JobPartsQueueCount parts={record.joblines_status} record={record} />
),
},
//Added as a place holder for St Claude. Not implemented as it requires another join for a field used by only 1 client.
// {
// title: i18n.t("vehicles.fields.v_paint_codes", { number: "" }),
@@ -555,6 +556,29 @@ const r = ({ technician, state, activeStatuses, bodyshop }) => {
// </span>
// ) : null,
// },
{
title: i18n.t("jobs.fields.date_repairstarted"),
dataIndex: "date_repairstarted",
key: "date_repairstarted",
ellipsis: true,
sorter: (a, b) => dateSort(a.date_repairstarted, b.date_repairstarted),
sortOrder:
state.sortedInfo.columnKey === "date_repairstarted" &&
state.sortedInfo.order,
render: (text, record) => (
<ProductionListDate record={record} field="date_repairstarted" time />
),
},
{
title: i18n.t("jobs.fields.date_repairstarted") + " (HH:MM)",
dataIndex: "date_repairstarted_time",
key: "date_repairstarted_time",
ellipsis: true,
render: (text, record) => (
<TimeFormatter>{record.date_repairstarted}</TimeFormatter>
),
},
];
};
export default r;

View File

@@ -1,4 +1,4 @@
import { Button, Form, Input, notification } from "antd";
import { Button, Card, Col, Form, Input, notification } from "antd";
import { LockOutlined } from "@ant-design/icons";
import React from "react";
import { useTranslation } from "react-i18next";
@@ -48,81 +48,99 @@ export default connect(
};
return (
<div>
<Form
onFinish={handleFinish}
autoComplete={"no"}
initialValues={currentUser}
layout="vertical"
>
<LayoutFormRow>
<Form.Item
label={t("user.fields.displayname")}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
name="displayName"
<>
<Col span={24}>
<Form
onFinish={handleFinish}
autoComplete={"no"}
initialValues={currentUser}
layout="vertical"
>
<Card
title={t("user.labels.profileinfo")}
extra={
<Button type="primary" key="submit" htmlType="submit">
{t("user.actions.updateprofile")}
</Button>
}
>
<Input />
</Form.Item>
<Form.Item label={t("user.fields.photourl")} name="photoURL">
<Input />
</Form.Item>
</LayoutFormRow>
<Button type="primary" key="submit" htmlType="submit">
{t("user.actions.updateprofile")}
</Button>
</Form>
<Form
onFinish={handleChangePassword}
autoComplete={"no"}
initialValues={currentUser}
layout="vertical"
>
<LayoutFormRow>
<Form.Item label={t("general.labels.newpassword")} name="password">
<Input
prefix={<LockOutlined />}
type="password"
placeholder={t("general.labels.password")}
/>
</Form.Item>
<Form.Item
label={t("general.labels.confirmpassword")}
name="password-confirm"
dependencies={["password"]}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
({ getFieldValue }) => ({
validator(rule, value) {
if (!value || getFieldValue("password") === value) {
return Promise.resolve();
}
return Promise.reject(
t("general.labels.passwordsdonotmatch")
);
},
}),
]}
<LayoutFormRow noDivider>
<Form.Item
label={t("user.fields.displayname")}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
name="displayName"
>
<Input />
</Form.Item>
<Form.Item label={t("user.fields.photourl")} name="photoURL">
<Input />
</Form.Item>
</LayoutFormRow>
</Card>
</Form>
</Col>
<Col span={24}>
<Form
onFinish={handleChangePassword}
autoComplete={"no"}
initialValues={currentUser}
layout="vertical"
>
<Card
title={t("user.labels.changepassword")}
extra={
<Button type="primary" key="submit" htmlType="submit">
{t("user.actions.changepassword")}
</Button>
}
>
<Input
prefix={<LockOutlined />}
type="password"
placeholder={t("general.labels.password")}
/>
</Form.Item>
</LayoutFormRow>
<Button type="primary" key="submit" htmlType="submit">
{t("user.actions.changepassword")}
</Button>
</Form>
</div>
<LayoutFormRow>
<Form.Item
label={t("general.labels.newpassword")}
name="password"
>
<Input
prefix={<LockOutlined />}
type="password"
placeholder={t("general.labels.password")}
/>
</Form.Item>
<Form.Item
label={t("general.labels.confirmpassword")}
name="password-confirm"
dependencies={["password"]}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
({ getFieldValue }) => ({
validator(rule, value) {
if (!value || getFieldValue("password") === value) {
return Promise.resolve();
}
return Promise.reject(
t("general.labels.passwordsdonotmatch")
);
},
}),
]}
>
<Input
prefix={<LockOutlined />}
type="password"
placeholder={t("general.labels.password")}
/>
</Form.Item>
</LayoutFormRow>
</Card>
</Form>
</Col>
</>
);
});

View File

@@ -1,13 +1,13 @@
import React from "react";
import { Button, Card, Col, Input, Table, Typography } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { Table, Button, Typography } from "antd";
export default function ProfileShopsComponent({
loading,
data,
updateActiveShop,
}) {
const { t } = useTranslation();
const [search, setSearch] = useState("");
const columns = [
{
title: t("associations.fields.shopname"),
@@ -39,18 +39,39 @@ export default function ProfileShopsComponent({
),
},
];
console.log("🚀 ~ file: profile-shops.component.jsx:45 ~ data", data);
const filteredData =
search === ""
? data
: data.filter((d) =>
d.bodyshop.shopname.toLowerCase().includes(search.toLowerCase())
);
return (
<Table
title={() => (
<Typography.Title level={4}>
{t("profile.labels.activeshop")}
</Typography.Title>
)}
loading={loading}
columns={columns}
rowKey="id"
dataSource={data}
/>
<Col span={24}>
<Card
title={
<Typography.Title level={4}>
{t("profile.labels.activeshop")}
</Typography.Title>
}
extra={
<Input.Search
value={search}
onChange={(e) => setSearch(e.target.value)}
allowClear
placeholder={t("general.labels.search")}
/>
}
>
<Table
pagination={false}
loading={loading}
columns={columns}
rowKey="id"
dataSource={filteredData}
/>
</Card>
</Col>
);
}

View File

@@ -0,0 +1,48 @@
import { Space } from "antd";
import React, { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectScheduleLoad } from "../../redux/application/application.selectors";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
scheduleLoad: selectScheduleLoad,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export function ScheduleAtsSummary({ scheduleLoad, appointments }) {
const { t } = useTranslation();
const atsSummary = useMemo(() => {
let atsSummary = {};
if (!appointments || appointments.length === 0) {
return {};
}
appointments
.filter((a) => a.isintake)
.forEach((a) => {
if (!a.job.alt_transport) return;
if (!atsSummary[a.job.alt_transport]) {
atsSummary[a.job.alt_transport] = 1;
} else {
atsSummary[a.job.alt_transport] = atsSummary[a.job.alt_transport] + 1;
}
});
return atsSummary;
}, [appointments]);
if (Object.keys(atsSummary).length > 0)
return (
<Space wrap>
{t("schedule.labels.atssummary")}
{Object.keys(atsSummary).map((key) => (
<span key={key}>{`${key}: ${atsSummary[key]}`}</span>
))}
</Space>
);
return null;
}
export default connect(mapStateToProps, mapDispatchToProps)(ScheduleAtsSummary);

View File

@@ -1,19 +1,19 @@
import { Popover } from "antd";
import { RadarChartOutlined } from "@ant-design/icons";
import { Popover, Space } from "antd";
import React, { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import {
Legend,
PolarAngleAxis,
PolarGrid,
PolarRadiusAxis,
Radar,
Legend,
RadarChart,
Tooltip,
} from "recharts";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { RadarChartOutlined } from "@ant-design/icons";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
});
@@ -22,8 +22,12 @@ const mapDispatchToProps = (dispatch) => ({
});
export function ScheduleCalendarHeaderGraph({ bodyshop, loadData }) {
console.log(
"🚀 ~ file: schedule-calendar-header-graph.component.js:23 ~ ScheduleCalendarHeaderGraph ~ loadData",
loadData
);
const { ssbuckets } = bodyshop;
const { t } = useTranslation();
const data = useMemo(() => {
return (
(loadData &&
@@ -43,6 +47,12 @@ export function ScheduleCalendarHeaderGraph({ bodyshop, loadData }) {
const popContent = (
<div>
<Space>
{t("appointments.labels.expectedprodhrs")}
<strong>{loadData?.expectedHours?.toFixed(1)}</strong>
{t("appointments.labels.expectedjobs")}
<strong>{loadData?.expectedJobCount}</strong>
</Space>
<RadarChart
// cx={300}
// cy={250}

View File

@@ -3,6 +3,7 @@ import { Button, Card, Checkbox, Col, PageHeader, Row, Space } from "antd";
import { t } from "i18next";
import React, { useMemo } from "react";
import useLocalStorage from "../../utils/useLocalStorage";
import ScheduleAtsSummary from "../schedule-ats-summary/schedule-ats-summary.component";
import ScheduleCalendarWrapperComponent from "../schedule-calendar-wrapper/scheduler-calendar-wrapper.component";
import ScheduleModal from "../schedule-job-modal/schedule-job-modal.container";
import ScheduleManualEvent from "../schedule-manual-event/schedule-manual-event.component";
@@ -35,6 +36,7 @@ export default function ScheduleCalendarComponent({ data, refetch }) {
<PageHeader
extra={
<Space wrap>
<ScheduleAtsSummary appointments={filteredData} />
<Checkbox
checked={filter?.intake}
onChange={(e) => {

View File

@@ -466,6 +466,13 @@ export default function ShopInfoGeneral({ form }) {
>
<Switch />
</Form.Item>
<Form.Item
name={["enforce_conversion_csr"]}
label={t("bodyshop.fields.enforce_conversion_csr")}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
name={["target_touchtime"]}
label={t("bodyshop.fields.target_touchtime")}
@@ -659,7 +666,7 @@ export default function ShopInfoGeneral({ form }) {
},
]}
>
<Input />
<Input.TextArea rows={3} />
</Form.Item>
<Space wrap>
<DeleteFilled
@@ -1337,7 +1344,14 @@ export default function ShopInfoGeneral({ form }) {
>
<InputNumber precision={0} min={0} max={100} />
</Form.Item>
<Form.Item
label={t("joblines.fields.ah_detail_line")}
key={`${index}ah_detail_line`}
name={[field.name, "ah_detail_line"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Space wrap>
<DeleteFilled
onClick={() => {

View File

@@ -139,6 +139,12 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.dms.sendmaterialscosting")}
name={["cdk_configuration", "sendmaterialscosting"]}
>
<InputNumber min={0} max={100} />
</Form.Item>
{bodyshop.pbs_serialnumber && (
<Form.Item
label={t("bodyshop.fields.dms.disablecontactvehiclecreation")}
@@ -148,6 +154,15 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
<Switch />
</Form.Item>
)}
{bodyshop.pbs_serialnumber && (
<Form.Item
label={t("bodyshop.fields.dms.disablebillwip")}
valuePropName="checked"
name={["pbs_configuration", "disablebillwip"]}
>
<Switch />
</Form.Item>
)}
</LayoutFormRow>
<LayoutFormRow header={t("bodyshop.labels.dms.cdk.payers")}>
<Form.List name={["cdk_configuration", "payers"]}>
@@ -191,7 +206,7 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
// },
// ]}
>
<Select showSearch>
<Select allowClear showSearch>
<Select.Option value="ro_number">
{t("jobs.fields.ro_number")}
</Select.Option>
@@ -201,6 +216,9 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
<Select.Option value="po_number">
{t("jobs.fields.ponumber")}
</Select.Option>
<Select.Option value="account_number">
{t("jobs.fields.dms.control_type.account_number")}
</Select.Option>
</Select>
</Form.Item>

View File

@@ -85,7 +85,7 @@ export function TimeTicketList({
text: (() => {
const emp = bodyshop.employees.find((e) => e.id === s);
return `${emp.first_name} ${emp.last_name}`;
return `${emp?.first_name} ${emp?.last_name}`;
})(), //
value: [s],
};

View File

@@ -131,6 +131,7 @@ const JobRelatedTicketsTable = ({
return {
id: `${item.jobKey}${costCenter}`,
costCenter,
item,
actHrs: actHrs.toFixed(1),
prodHrs: prodHrs.toFixed(1),
@@ -151,7 +152,9 @@ const JobRelatedTicketsTable = ({
sortOrder:
state.sortedInfo.columnKey === "empname" && state.sortedInfo.order,
render: (text, record) =>
`${record.item.employee.first_name} ${record.item.employee.last_name}`,
`${record.item.employee.first_name} ${record.item.employee.last_name} ${
record.costCenter ? `(${record.costCenter})` : ""
}`.trim(),
},
{
title: t("timetickets.fields.actualhrs"),

View File

@@ -364,6 +364,7 @@ export const QUERY_SCHEDULE_LOAD_DATA = gql`
ownr_fn
ownr_ln
ownr_co_nm
alt_transport
labhrs: joblines_aggregate(
where: { mod_lbr_ty: { _neq: "LAR" }, removed: { _eq: false } }
) {

View File

@@ -111,6 +111,7 @@ export const QUERY_BODYSHOP = gql`
localmediaserverhttp
localmediaservernetwork
localmediatoken
enforce_conversion_csr
employees {
user_email
id
@@ -220,6 +221,7 @@ export const UPDATE_SHOP = gql`
localmediaserverhttp
localmediaservernetwork
localmediatoken
enforce_conversion_csr
employees {
id
first_name

View File

@@ -43,6 +43,7 @@ export const CONVERSATION_LIST_QUERY = gql`
updated_at
unreadcnt
archived
label
messages_aggregate(
where: { read: { _eq: false }, isoutbound: { _eq: false } }
) {
@@ -88,6 +89,7 @@ export const GET_CONVERSATION_DETAILS = gql`
id
phone_num
archived
label
job_conversations {
jobid
conversationid
@@ -136,3 +138,15 @@ export const TOGGLE_CONVERSATION_ARCHIVE = gql`
}
}
`;
export const UPDATE_CONVERSATION_LABEL = gql`
mutation UPDATE_CONVERSATION_LABEL($id: uuid!, $label: String) {
update_conversations_by_pk(
pk_columns: { id: $id }
_set: { label: $label }
) {
label
id
}
}
`;

View File

@@ -142,6 +142,7 @@ export const QUERY_EXACT_JOB_IN_PRODUCTION = gql`
employee_refinish
employee_prep
employee_csr
date_repairstarted
joblines_status {
part_type
status
@@ -221,6 +222,7 @@ export const QUERY_EXACT_JOBS_IN_PRODUCTION = gql`
employee_refinish
employee_prep
employee_csr
date_repairstarted
joblines_status {
part_type
status
@@ -302,6 +304,7 @@ export const QUERY_JOBS_IN_PRODUCTION = gql`
employee_prep
employee_csr
suspended
date_repairstarted
joblines_status {
part_type
status
@@ -498,6 +501,10 @@ export const GET_JOB_BY_PK = gql`
first_name
last_name
}
employee_csr
employee_prep
employee_refinish
employee_body
alt_transport
intakechecklist
invoice_final_note
@@ -672,6 +679,7 @@ export const GET_JOB_BY_PK = gql`
date_towin
date_rentalresp
date_exported
date_repairstarted
status
owner_owing
tax_registration_number
@@ -712,6 +720,7 @@ export const GET_JOB_BY_PK = gql`
prt_dsmk_m
ioucreated
convertedtolbr
ah_detail_line
billlines(limit: 1, order_by: { bill: { date: desc } }) {
id
quantity
@@ -847,6 +856,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
owner_owing
special_coverage_policy
suspended
lbr_adjustments
available_jobs {
id
}
@@ -855,7 +865,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
count
status
}
joblines {
joblines(where: { removed: { _eq: false } }) {
id
mod_lbr_ty
mod_lb_hrs
@@ -917,7 +927,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
date_next_contact
date_open
date_exported
date_repairstarted
date_scheduled
date_estimated
employee_body_rel {
@@ -1092,6 +1102,9 @@ export const UPDATE_JOB_ASSIGNMENTS = gql`
first_name
last_name
}
employee_csr
employee_body
employee_prep
}
}
}
@@ -1140,29 +1153,8 @@ export const UPDATE_JOBS = gql`
`;
export const CONVERT_JOB_TO_RO = gql`
mutation CONVERT_JOB_TO_RO(
$jobId: uuid!
$class: String
$ins_co_nm: String!
$ca_gst_registrant: Boolean
$driveable: Boolean
$towin: Boolean
$referral_source: String
$referral_source_extra: String
) {
update_jobs(
where: { id: { _eq: $jobId } }
_set: {
converted: true
ins_co_nm: $ins_co_nm
class: $class
ca_gst_registrant: $ca_gst_registrant
towin: $towin
driveable: $driveable
referral_source: $referral_source
referral_source_extra: $referral_source_extra
}
) {
mutation CONVERT_JOB_TO_RO($jobId: uuid!, $job: jobs_set_input!) {
update_jobs(where: { id: { _eq: $jobId } }, _set: $job) {
returning {
id
ro_number
@@ -1171,6 +1163,10 @@ export const CONVERT_JOB_TO_RO = gql`
ins_co_nm
referral_source
referral_source_extra
employee_csr
employee_csr_rel {
id
}
}
}
}
@@ -1896,6 +1892,7 @@ export const QUERY_JOB_CLOSE_DETAILS = gql`
kmin
kmout
qb_multiple_payers
lbr_adjustments
joblines(where: { removed: { _eq: false } }, order_by: { line_no: asc }) {
id
removed

View File

@@ -5,6 +5,7 @@ export const QUERY_SEARCH_OWNER_BY_IDX = gql`
search_owners(args: { search: $search }, limit: 100) {
ownr_fn
ownr_ln
ownr_co_nm
ownr_ph1
ownr_ph2
ownr_addr1

View File

@@ -14,7 +14,7 @@ import { persistor, store } from "./redux/store";
import reportWebVitals from "./reportWebVitals";
import "./translations/i18n";
import "./utils/CleanAxios";
require("dotenv").config();
//import { BrowserTracing } from "@sentry/tracing";
// Dinero.defaultCurrency = "CAD";
// Dinero.globalLocale = "en-CA";
@@ -29,10 +29,18 @@ if (process.env.NODE_ENV !== "development") {
"Module specifier, 'zlib' does not start with",
],
integrations: [
// new Integrations.BrowserTracing(),
// new BrowserTracing(),
// new Sentry.Integrations.Breadcrumbs({ console: true }),
// new Sentry.Replay(),
],
// This sets the sample rate to be 10%. You may want this to be 100% while
// in development and sample at a lower rate in production
// replaysSessionSampleRate: 0.1,
// // If the entire session is not sampled, use the below sample rate to sample
// // sessions when an error occurs.
// replaysOnErrorSampleRate: 1.0,
environment: process.env.NODE_ENV,
// tracesSampleRate: 0.2,
// We recommend adjusting this value in production, or using tracesSampler
// for finer control
// tracesSampleRate: 0.5,

View File

@@ -1,5 +1,3 @@
import { Elements } from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";
import { BackTop, Layout } from "antd";
import preval from "preval.macro";
import React, { lazy, Suspense, useEffect } from "react";
@@ -170,18 +168,6 @@ const DmsPayables = lazy(() =>
const { Content, Footer } = Layout;
const stripePromise = new Promise((resolve, reject) => {
// client.query({ query: QUERY_STRIPE_ID }).then((resp) => {
// if (resp.data.bodyshops[0])
resolve(
loadStripe(process.env.REACT_APP_STRIPE_PUBLIC_KEY, {
stripeAccount: "No Stripe Id Resolve",
})
);
// reject();
// });
});
const mapStateToProps = createStructuredSelector({
conflict: selectInstanceConflict,
bodyshop: selectBodyshop,
@@ -207,9 +193,9 @@ export function Manage({ match, conflict, bodyshop }) {
<Suspense
fallback={<LoadingSpinner message={t("general.labels.loadingapp")} />}
>
<Elements stripe={stripePromise}>
<PaymentModalContainer />
</Elements>
<BreadCrumbs />
<BillEnterModalContainer />
<JobCostingModal />

View File

@@ -1,81 +1,81 @@
import {
PaymentRequestButtonElement,
useStripe,
} from "@stripe/react-stripe-js";
import React, { useEffect, useState } from "react";
// import {
// PaymentRequestButtonElement,
// useStripe,
// } from "@stripe/react-stripe-js";
// import React, { useEffect, useState } from "react";
export default function MobilePaymentComponent() {
const stripe = useStripe();
// export default function MobilePaymentComponent() {
// const stripe = useStripe();
const [paymentRequest, setPaymentRequest] = useState(null);
useEffect(() => {
if (stripe) {
const pr = stripe.paymentRequest({
country: "CA",
displayItems: [{ label: "Deductible", amount: 1 }],
currency: "cad",
total: {
label: "Demo total",
amount: 1,
},
requestPayerName: true,
requestPayerEmail: true,
});
// const [paymentRequest, setPaymentRequest] = useState(null);
// useEffect(() => {
// if (stripe) {
// const pr = stripe.paymentRequest({
// country: "CA",
// displayItems: [{ label: "Deductible", amount: 1 }],
// currency: "cad",
// total: {
// label: "Demo total",
// amount: 1,
// },
// 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]);
// // 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) {
paymentRequest.on("paymentmethod", async (ev) => {
//Call server side to get the client secret
// Confirm the PaymentIntent without handling potential next actions (yet).
const { error: confirmError } = await stripe.confirmCardPayment(
"clientSecret",
{ payment_method: ev.paymentMethod.id },
{ handleActions: false }
);
// if (paymentRequest) {
// paymentRequest.on("paymentmethod", async (ev) => {
// //Call server side to get the client secret
// // Confirm the PaymentIntent without handling potential next actions (yet).
// const { error: confirmError } = await stripe.confirmCardPayment(
// "clientSecret",
// { payment_method: ev.paymentMethod.id },
// { handleActions: false }
// );
if (confirmError) {
// Report to the browser that the payment failed, prompting it to
// re-show the payment interface, or show an error message and close
// the payment interface.
ev.complete("fail");
} else {
// Report to the browser that the confirmation was successful, prompting
// it to close the browser payment method collection interface.
ev.complete("success");
// Let Stripe.js handle the rest of the payment flow.
const {
error, //paymentIntent
} = await stripe.confirmCardPayment("clientSecret");
if (error) {
// The payment failed -- ask your customer for a new payment method.
} else {
// The payment has succeeded.
}
}
});
return (
<div style={{ height: "300px" }}>
<PaymentRequestButtonElement options={{ paymentRequest }} />
</div>
);
}
// if (confirmError) {
// // Report to the browser that the payment failed, prompting it to
// // re-show the payment interface, or show an error message and close
// // the payment interface.
// ev.complete("fail");
// } else {
// // Report to the browser that the confirmation was successful, prompting
// // it to close the browser payment method collection interface.
// ev.complete("success");
// // Let Stripe.js handle the rest of the payment flow.
// const {
// error, //paymentIntent
// } = await stripe.confirmCardPayment("clientSecret");
// if (error) {
// // The payment failed -- ask your customer for a new payment method.
// } else {
// // The payment has succeeded.
// }
// }
// });
// return (
// <div style={{ height: "300px" }}>
// <PaymentRequestButtonElement options={{ paymentRequest }} />
// </div>
// );
// }
return <div></div>;
}
// return <div></div>;
// }

View File

@@ -1,23 +1,23 @@
import { Elements } from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";
import React from "react";
import MobilePaymentComponent from "./mobile-payment.component";
// import { Elements } from "@stripe/react-stripe-js";
// import { loadStripe } from "@stripe/stripe-js";
// import React from "react";
// import MobilePaymentComponent from "./mobile-payment.component";
const stripePromise = new Promise((resolve, reject) => {
resolve(
loadStripe(process.env.REACT_APP_STRIPE_PUBLIC_KEY, {
stripeAccount: "acct_1Fa7lFIEahEZW8b4",
})
);
});
// const stripePromise = new Promise((resolve, reject) => {
// resolve(
// loadStripe(process.env.REACT_APP_STRIPE_PUBLIC_KEY, {
// stripeAccount: "acct_1Fa7lFIEahEZW8b4",
// })
// );
// });
export default function MobilePaymentContainer() {
return (
<div>
The mobile payment container.
<Elements stripe={stripePromise}>
<MobilePaymentComponent />
</Elements>
</div>
);
}
// export default function MobilePaymentContainer() {
// return (
// <div>
// The mobile payment container.
// <Elements stripe={stripePromise}>
// <MobilePaymentComponent />
// </Elements>
// </div>
// );
// }

View File

@@ -1,3 +1,4 @@
import { Row } from "antd";
import React from "react";
import ProfileMyComponent from "../../components/profile-my/profile-my.component";
import ProfileShopsContainer from "../../components/profile-shops/profile-shops.container";
@@ -5,8 +6,10 @@ import ProfileShopsContainer from "../../components/profile-shops/profile-shops.
export default function ProfilePage() {
return (
<div>
<ProfileMyComponent />
<ProfileShopsContainer />
<Row gutter={[16, 16]}>
<ProfileMyComponent />
<ProfileShopsContainer />
</Row>
</div>
);
}

View File

@@ -35,6 +35,7 @@ export function* calculateScheduleLoad({ payload: end }) {
const load = {
productionTotal: {},
productionHours: 0,
};
//Set the current load.
@@ -45,6 +46,10 @@ export function* calculateScheduleLoad({ payload: end }) {
prodJobs.forEach((item) => {
//Add all of the jobs currently in production to the buckets so that we have a starting point.
const bucketId = CheckJobBucket(buckets, item);
load.productionHours =
load.productionHours +
item.labhrs.aggregate.sum.mod_lb_hrs +
item.larhrs.aggregate.sum.mod_lb_hrs;
if (bucketId) {
load.productionTotal[bucketId].count =
load.productionTotal[bucketId].count + 1;
@@ -149,6 +154,14 @@ export function* calculateScheduleLoad({ payload: end }) {
load[current].jobsIn || [],
load[current].jobsOut || []
);
load[current].expectedJobCount =
prodJobs.length +
(load[current].jobsIn || []).length -
(load[current].jobsOut || []).length;
load[current].expectedHours =
load.productionHours +
(load[current].hoursIn || 0) -
(load[current].hoursOut || 0);
} else {
load[current].expectedLoad = CalculateLoad(
load[prev].expectedLoad,
@@ -156,8 +169,17 @@ export function* calculateScheduleLoad({ payload: end }) {
load[current].jobsIn || [],
load[current].jobsOut || []
);
load[current].expectedJobCount =
load[prev].expectedJobCount +
(load[current].jobsIn || []).length -
(load[current].jobsOut || []).length;
load[current].expectedHours =
load[prev].expectedHours +
(load[current].hoursIn || 0) -
(load[current].hoursOut || 0);
}
}
yield put(setProblemJobs(problemJobs));
yield put(scheduleLoadSuccess(load));
} catch (error) {

View File

@@ -50,6 +50,8 @@
"cancelledappointment": "Canceled appointment for: ",
"completingjobs": "Completing Jobs",
"dataconsistency": "{{ro_number}} has a data consistency issue. It has been excluded for scheduling purposes. CODE: {{code}}.",
"expectedjobs": "Expected Jobs in Production: ",
"expectedprodhrs": "Expected Production Hours:",
"history": "History",
"inproduction": "Jobs In Production",
"manualevent": "Add Manual Appointment",
@@ -264,6 +266,7 @@
"dms": {
"cashierid": "Cashier ID",
"default_journal": "Default Journal",
"disablebillwip": "Disable bill WIP for A/P Posting",
"disablecontactvehiclecreation": "Disable Contact & Vehicle Updates/Creation",
"dms_acctnumber": "DMS Account #",
"dms_wip_acctnumber": "DMS W.I.P. Account #",
@@ -272,10 +275,12 @@
"itc_local": "Local Tax is ITC?",
"itc_state": "State Tax is ITC?",
"mappingname": "DMS Mapping Name",
"sendmaterialscosting": "Materials Cost as % of Sale",
"srcco": "Source Company #/Dealer #"
},
"email": "General Shop Email",
"enforce_class": "Enforce Class on Conversion?",
"enforce_conversion_csr": "Enforce CSR on Conversion?",
"enforce_referral": "Enforce Referrals",
"federal_tax_id": "Federal Tax ID (GST/HST)",
"ignoreblockeddays": "Scoreboard - Ignore Blocked Days",
@@ -881,6 +886,7 @@
"labels": {
"attachments": "Attachments",
"documents": "Documents",
"emailpreview": "Email Preview",
"generatingemail": "Generating email...",
"pdfcopywillbeattached": "A PDF copy of this email will be attached when it is sent.",
"preview": "Email Preview"
@@ -1137,6 +1143,7 @@
},
"fields": {
"act_price": "Retail Price",
"ah_detail_line": "Mark as Detail Labor Line (Autohouse Only)",
"db_price": "List Price",
"lbr_types": {
"LA1": "LA1",
@@ -1209,6 +1216,7 @@
"updated": "Job line updated successfully."
},
"validations": {
"ahdetailonlyonuserdefinedtypes": "Detail line indicator can only be set for LA1, LA2, LA3, LA4, and LAU labor types.",
"hrsrequirediflbrtyp": "Labor hours are required if a labor type is selected. Clear the labor type if there are no labor hours.",
"requiredifparttype": "Required if a part type has been specified.",
"zeropriceexistingpart": "This line cannot have any price since it uses an existing part."
@@ -1348,6 +1356,7 @@
"date_next_contact": "Next Contact Date",
"date_open": "Open",
"date_rentalresp": "Shop Rental Responsibility Start",
"date_repairstarted": "Repairs Started",
"date_scheduled": "Scheduled",
"date_towin": "Towed In",
"ded_amt": "Deductible",
@@ -1358,6 +1367,9 @@
"address": "Customer Address",
"amount": "Amount",
"center": "Center",
"control_type": {
"account_number": "Account Number"
},
"cost": "Cost",
"cost_dms_acctnumber": "Cost DMS Acct #",
"dms_make": "DMS Make",
@@ -1623,6 +1635,7 @@
"apexported": "AP export completed. See logs for details.",
"damageto": "Damage to $t(jobs.fields.area_of_damage_impact.{{area_of_damage}}).",
"defaultstory": "B/S RO: {{ro_number}}. Owner: {{ownr_nm}}. Insurance Co: {{ins_co_nm}}. Claim/PO #: {{clm_po}}",
"disablebillwip": "Cost and WIP for bills has been ignored per shop configuration.",
"invoicedatefuture": "Invoice date must be today or in the future for CDK posting.",
"kmoutnotgreaterthankmin": "Mileage out must be greater than mileage in.",
"logs": "Logs",
@@ -1684,6 +1697,7 @@
"partstotal": "This is the total of all parts and sublet amounts on the vehicle (some of these may require an in-house invoice).<br/>\nItems such as shop and paint materials, labor online lines, etc. are not included in this total.",
"totalreturns": "The total <b>retail</b> amount of returns created for this job."
},
"profileadjustments": "",
"prt_dsmk_total": "Line Item Adjustment",
"rates": "Rates",
"rates_subtotal": "All Rates Subtotal",
@@ -1906,9 +1920,11 @@
},
"errors": {
"invalidphone": "The phone number is invalid. Unable to open conversation. ",
"noattachedjobs": "No jobs have been associated to this conversation. "
"noattachedjobs": "No jobs have been associated to this conversation. ",
"updatinglabel": "Error updating label. {{error}}"
},
"labels": {
"addlabel": "Add a label to this conversation.",
"archive": "Archive",
"maxtenimages": "You can only select up to a maximum of 10 images at a time.",
"messaging": "Messaging",
@@ -2096,7 +2112,7 @@
},
"labels": {
"balance": "Balance",
"ca_bc_etf_table": "ICBC ETF Table Converter",
"ca_bc_etf_table": "ICBC EFT Table Converter",
"customer": "Customer",
"edit": "Edit Payment",
"electronicpayment": "Use Electronic Payment Processing?",
@@ -2159,6 +2175,7 @@
"courtesycarcontract": {
"courtesy_car_contract": "Courtesy Car Contract",
"courtesy_car_impound": "Impound Charges",
"courtesy_car_inventory": "Courtesy Car Inventory",
"courtesy_car_terms": "Courtesy Car Terms"
},
"errors": {
@@ -2245,6 +2262,7 @@
"supplement_request": "Supplement Request",
"thank_you_ro": "Thank You Letter",
"thirdpartypayer": "Third Party Payer",
"timetickets_ro": "Time Tickets",
"vehicle_check_in": "Vehicle Intake",
"vehicle_delivery_check": "Vehicle Delivery Checklist",
"window_tag": "Window Tag",
@@ -2272,7 +2290,7 @@
"title": "Print Center"
},
"payments": {
"ca_bc_etf_table": "ICBC ETF Table",
"ca_bc_etf_table": "ICBC EFT Table",
"exported_payroll": "Payroll Table"
},
"special": {
@@ -2400,6 +2418,7 @@
"credits_not_received_date": "Credits not Received by Date",
"credits_not_received_date_vendorid": "Credits not Received by Vendor",
"csi": "CSI Responses",
"cycle_time_analysis": "Cycle Time Analysis",
"estimates_written_converted": "Estimates Written/Converted",
"estimator_detail": "Jobs by Estimator (Detail)",
"estimator_summary": "Jobs by Estimator (Summary)",
@@ -2436,12 +2455,15 @@
"job_costing_ro_date_summary": "Job Costing by RO - Summary",
"job_costing_ro_estimator": "Job Costing by Estimator",
"job_costing_ro_ins_co": "Job Costing by RO Source",
"jobs_completed_not_invoiced": "Jobs Completed not Invoiced",
"jobs_invoiced_not_exported": "Jobs Invoiced not Exported",
"jobs_reconcile": "Parts/Sublet/Labor Reconciliation",
"lag_time": "Lag Time",
"open_orders": "Open Orders by Date",
"open_orders_csr": "Open Orders by CSR",
"open_orders_estimator": "Open Orders by Estimator",
"open_orders_ins_co": "Open Orders by Insurance Company",
"open_orders_specific_csr": "Open Orders filtered by CSR",
"open_orders_status": "Open Orders by Status",
"parts_backorder": "IOU Parts List",
"parts_not_recieved": "Parts Not Received",
@@ -2468,7 +2490,10 @@
"purchases_by_vendor_summary_date_range": "Purchases by Vendor - Summary",
"purchases_grouped_by_vendor_detailed": "Purchases Grouped by Vendor - Detailed",
"purchases_grouped_by_vendor_summary": "Purchases Grouped by Vendor - Summary",
"returns_grouped_by_vendor_detailed": "Returns Grouped by Vendor - Detailed",
"returns_grouped_by_vendor_summary": "Returns Grouped by Vendor - Summary",
"schedule": "Appointment Schedule",
"scheduled_parts_list": "Parts for Jobs Scheduled In",
"scoreboard_detail": "Scoreboard Detail",
"scoreboard_summary": "Scoreboard Summary",
"supplement_ratio_ins_co": "Supplement Ratio by Source",
@@ -2484,6 +2509,7 @@
},
"schedule": {
"labels": {
"atssummary": "ATS Summary",
"employeevacation": "Employee Vacations",
"intake": "Intake Events",
"manual": "Manual Events",
@@ -2726,7 +2752,9 @@
"photourl": "Avatar URL"
},
"labels": {
"actions": "Actions"
"actions": "Actions",
"changepassword": "Change Password",
"profileinfo": "Profile Info"
},
"successess": {
"passwordchanged": "Password changed successfully. "

View File

@@ -50,6 +50,8 @@
"cancelledappointment": "Cita cancelada para:",
"completingjobs": "",
"dataconsistency": "",
"expectedjobs": "",
"expectedprodhrs": "",
"history": "",
"inproduction": "",
"manualevent": "",
@@ -264,6 +266,7 @@
"dms": {
"cashierid": "",
"default_journal": "",
"disablebillwip": "",
"disablecontactvehiclecreation": "",
"dms_acctnumber": "",
"dms_wip_acctnumber": "",
@@ -272,10 +275,12 @@
"itc_local": "",
"itc_state": "",
"mappingname": "",
"sendmaterialscosting": "",
"srcco": ""
},
"email": "",
"enforce_class": "",
"enforce_conversion_csr": "",
"enforce_referral": "",
"federal_tax_id": "",
"ignoreblockeddays": "",
@@ -881,6 +886,7 @@
"labels": {
"attachments": "",
"documents": "",
"emailpreview": "",
"generatingemail": "",
"pdfcopywillbeattached": "",
"preview": ""
@@ -1137,6 +1143,7 @@
},
"fields": {
"act_price": "Precio actual",
"ah_detail_line": "",
"db_price": "Precio de base de datos",
"lbr_types": {
"LA1": "",
@@ -1209,6 +1216,7 @@
"updated": ""
},
"validations": {
"ahdetailonlyonuserdefinedtypes": "",
"hrsrequirediflbrtyp": "",
"requiredifparttype": "",
"zeropriceexistingpart": ""
@@ -1348,6 +1356,7 @@
"date_next_contact": "",
"date_open": "Abierto",
"date_rentalresp": "",
"date_repairstarted": "",
"date_scheduled": "Programado",
"date_towin": "",
"ded_amt": "Deducible",
@@ -1358,6 +1367,9 @@
"address": "",
"amount": "",
"center": "",
"control_type": {
"account_number": ""
},
"cost": "",
"cost_dms_acctnumber": "",
"dms_make": "",
@@ -1623,6 +1635,7 @@
"apexported": "",
"damageto": "",
"defaultstory": "",
"disablebillwip": "",
"invoicedatefuture": "",
"kmoutnotgreaterthankmin": "",
"logs": "",
@@ -1684,6 +1697,7 @@
"partstotal": "",
"totalreturns": ""
},
"profileadjustments": "",
"prt_dsmk_total": "",
"rates": "Tarifas",
"rates_subtotal": "",
@@ -1906,9 +1920,11 @@
},
"errors": {
"invalidphone": "",
"noattachedjobs": ""
"noattachedjobs": "",
"updatinglabel": ""
},
"labels": {
"addlabel": "",
"archive": "",
"maxtenimages": "",
"messaging": "Mensajería",
@@ -2159,6 +2175,7 @@
"courtesycarcontract": {
"courtesy_car_contract": "",
"courtesy_car_impound": "",
"courtesy_car_inventory": "",
"courtesy_car_terms": ""
},
"errors": {
@@ -2245,6 +2262,7 @@
"supplement_request": "",
"thank_you_ro": "",
"thirdpartypayer": "",
"timetickets_ro": "",
"vehicle_check_in": "",
"vehicle_delivery_check": "",
"window_tag": "",
@@ -2400,6 +2418,7 @@
"credits_not_received_date": "",
"credits_not_received_date_vendorid": "",
"csi": "",
"cycle_time_analysis": "",
"estimates_written_converted": "",
"estimator_detail": "",
"estimator_summary": "",
@@ -2436,12 +2455,15 @@
"job_costing_ro_date_summary": "",
"job_costing_ro_estimator": "",
"job_costing_ro_ins_co": "",
"jobs_completed_not_invoiced": "",
"jobs_invoiced_not_exported": "",
"jobs_reconcile": "",
"lag_time": "",
"open_orders": "",
"open_orders_csr": "",
"open_orders_estimator": "",
"open_orders_ins_co": "",
"open_orders_specific_csr": "",
"open_orders_status": "",
"parts_backorder": "",
"parts_not_recieved": "",
@@ -2468,7 +2490,10 @@
"purchases_by_vendor_summary_date_range": "",
"purchases_grouped_by_vendor_detailed": "",
"purchases_grouped_by_vendor_summary": "",
"returns_grouped_by_vendor_detailed": "",
"returns_grouped_by_vendor_summary": "",
"schedule": "",
"scheduled_parts_list": "",
"scoreboard_detail": "",
"scoreboard_summary": "",
"supplement_ratio_ins_co": "",
@@ -2484,6 +2509,7 @@
},
"schedule": {
"labels": {
"atssummary": "",
"employeevacation": "",
"intake": "",
"manual": "",
@@ -2726,7 +2752,9 @@
"photourl": "URL de avatar"
},
"labels": {
"actions": ""
"actions": "",
"changepassword": "",
"profileinfo": ""
},
"successess": {
"passwordchanged": ""

View File

@@ -50,6 +50,8 @@
"cancelledappointment": "Rendez-vous annulé pour:",
"completingjobs": "",
"dataconsistency": "",
"expectedjobs": "",
"expectedprodhrs": "",
"history": "",
"inproduction": "",
"manualevent": "",
@@ -264,6 +266,7 @@
"dms": {
"cashierid": "",
"default_journal": "",
"disablebillwip": "",
"disablecontactvehiclecreation": "",
"dms_acctnumber": "",
"dms_wip_acctnumber": "",
@@ -272,10 +275,12 @@
"itc_local": "",
"itc_state": "",
"mappingname": "",
"sendmaterialscosting": "",
"srcco": ""
},
"email": "",
"enforce_class": "",
"enforce_conversion_csr": "",
"enforce_referral": "",
"federal_tax_id": "",
"ignoreblockeddays": "",
@@ -881,6 +886,7 @@
"labels": {
"attachments": "",
"documents": "",
"emailpreview": "",
"generatingemail": "",
"pdfcopywillbeattached": "",
"preview": ""
@@ -1137,6 +1143,7 @@
},
"fields": {
"act_price": "Prix actuel",
"ah_detail_line": "",
"db_price": "Prix de la base de données",
"lbr_types": {
"LA1": "",
@@ -1209,6 +1216,7 @@
"updated": ""
},
"validations": {
"ahdetailonlyonuserdefinedtypes": "",
"hrsrequirediflbrtyp": "",
"requiredifparttype": "",
"zeropriceexistingpart": ""
@@ -1348,6 +1356,7 @@
"date_next_contact": "",
"date_open": "Ouvrir",
"date_rentalresp": "",
"date_repairstarted": "",
"date_scheduled": "Prévu",
"date_towin": "",
"ded_amt": "Déductible",
@@ -1358,6 +1367,9 @@
"address": "",
"amount": "",
"center": "",
"control_type": {
"account_number": ""
},
"cost": "",
"cost_dms_acctnumber": "",
"dms_make": "",
@@ -1623,6 +1635,7 @@
"apexported": "",
"damageto": "",
"defaultstory": "",
"disablebillwip": "",
"invoicedatefuture": "",
"kmoutnotgreaterthankmin": "",
"logs": "",
@@ -1684,6 +1697,7 @@
"partstotal": "",
"totalreturns": ""
},
"profileadjustments": "",
"prt_dsmk_total": "",
"rates": "Les taux",
"rates_subtotal": "",
@@ -1906,9 +1920,11 @@
},
"errors": {
"invalidphone": "",
"noattachedjobs": ""
"noattachedjobs": "",
"updatinglabel": ""
},
"labels": {
"addlabel": "",
"archive": "",
"maxtenimages": "",
"messaging": "Messagerie",
@@ -2159,6 +2175,7 @@
"courtesycarcontract": {
"courtesy_car_contract": "",
"courtesy_car_impound": "",
"courtesy_car_inventory": "",
"courtesy_car_terms": ""
},
"errors": {
@@ -2245,6 +2262,7 @@
"supplement_request": "",
"thank_you_ro": "",
"thirdpartypayer": "",
"timetickets_ro": "",
"vehicle_check_in": "",
"vehicle_delivery_check": "",
"window_tag": "",
@@ -2400,6 +2418,7 @@
"credits_not_received_date": "",
"credits_not_received_date_vendorid": "",
"csi": "",
"cycle_time_analysis": "",
"estimates_written_converted": "",
"estimator_detail": "",
"estimator_summary": "",
@@ -2436,12 +2455,15 @@
"job_costing_ro_date_summary": "",
"job_costing_ro_estimator": "",
"job_costing_ro_ins_co": "",
"jobs_completed_not_invoiced": "",
"jobs_invoiced_not_exported": "",
"jobs_reconcile": "",
"lag_time": "",
"open_orders": "",
"open_orders_csr": "",
"open_orders_estimator": "",
"open_orders_ins_co": "",
"open_orders_specific_csr": "",
"open_orders_status": "",
"parts_backorder": "",
"parts_not_recieved": "",
@@ -2468,7 +2490,10 @@
"purchases_by_vendor_summary_date_range": "",
"purchases_grouped_by_vendor_detailed": "",
"purchases_grouped_by_vendor_summary": "",
"returns_grouped_by_vendor_detailed": "",
"returns_grouped_by_vendor_summary": "",
"schedule": "",
"scheduled_parts_list": "",
"scoreboard_detail": "",
"scoreboard_summary": "",
"supplement_ratio_ins_co": "",
@@ -2484,6 +2509,7 @@
},
"schedule": {
"labels": {
"atssummary": "",
"employeevacation": "",
"intake": "",
"manual": "",
@@ -2726,7 +2752,9 @@
"photourl": "URL de l'avatar"
},
"labels": {
"actions": ""
"actions": "",
"changepassword": "",
"profileinfo": ""
},
"successess": {
"passwordchanged": ""

View File

@@ -22,5 +22,6 @@ const range = {
moment().startOf("quarter"),
moment().startOf("quarter").add(1, "quarter").subtract(1, "day"),
],
"Last 90 Days": [moment().add(-90, "days"), moment()],
};
export default range;

View File

@@ -488,6 +488,14 @@ export const TemplateList = (type, context) => {
disabled: false,
group: "pre",
},
timetickets_ro: {
title: i18n.t("printcenter.jobs.timetickets_ro"),
description: "CASL Authorization",
subject: i18n.t("printcenter.jobs.timetickets_ro"),
key: "timetickets_ro",
disabled: false,
group: "financial",
},
}
: {}),
...(!type || type === "job_special"
@@ -1413,6 +1421,19 @@ export const TemplateList = (type, context) => {
},
group: "jobs",
},
open_orders_specific_csr: {
title: i18n.t("reportcenter.templates.open_orders_specific_csr"),
description: "",
subject: i18n.t("reportcenter.templates.open_orders_specific_csr"),
key: "open_orders_specific_csr",
idtype: "employee",
disabled: false,
rangeFilter: {
object: i18n.t("reportcenter.labels.objects.jobs"),
field: i18n.t("jobs.fields.date_open"),
},
group: "jobs",
},
export_payables: {
title: i18n.t("reportcenter.templates.export_payables"),
description: "",
@@ -1682,6 +1703,90 @@ export const TemplateList = (type, context) => {
},
group: "sales",
},
cycle_time_analysis: {
title: i18n.t("reportcenter.templates.cycle_time_analysis"),
subject: i18n.t("reportcenter.templates.cycle_time_analysis"),
key: "cycle_time_analysis",
//idtype: "vendor",
disabled: false,
rangeFilter: {
object: i18n.t("reportcenter.labels.objects.jobs"),
field: i18n.t("jobs.fields.actual_completion"),
},
group: "jobs",
},
returns_grouped_by_vendor_summary: {
title: i18n.t(
"reportcenter.templates.returns_grouped_by_vendor_summary"
),
subject: i18n.t(
"reportcenter.templates.returns_grouped_by_vendor_summary"
),
key: "returns_grouped_by_vendor_summary",
//idtype: "vendor",
disabled: false,
rangeFilter: {
object: i18n.t("reportcenter.labels.objects.parts_orders"),
field: i18n.t("parts_orders.fields.order_date"),
},
group: "jobs",
},
returns_grouped_by_vendor_detailed: {
title: i18n.t(
"reportcenter.templates.returns_grouped_by_vendor_detailed"
),
subject: i18n.t(
"reportcenter.templates.returns_grouped_by_vendor_detailed"
),
key: "returns_grouped_by_vendor_detailed",
//idtype: "vendor",
disabled: false,
rangeFilter: {
object: i18n.t("reportcenter.labels.objects.parts_orders"),
field: i18n.t("parts_orders.fields.order_date"),
},
group: "jobs",
},
scheduled_parts_list: {
title: i18n.t("reportcenter.templates.scheduled_parts_list"),
subject: i18n.t("reportcenter.templates.scheduled_parts_list"),
key: "scheduled_parts_list",
//idtype: "vendor",
disabled: false,
rangeFilter: {
object: i18n.t("reportcenter.labels.objects.jobs"),
field: i18n.t("jobs.fields.scheduled_in"),
},
group: "jobs",
},
jobs_completed_not_invoiced: {
title: i18n.t("reportcenter.templates.jobs_completed_not_invoiced"),
subject: i18n.t(
"reportcenter.templates.jobs_completed_not_invoiced"
),
key: "jobs_completed_not_invoiced",
//idtype: "vendor",
disabled: false,
rangeFilter: {
object: i18n.t("reportcenter.labels.objects.jobs"),
field: i18n.t("jobs.fields.date_invoiced"),
},
group: "jobs",
},
jobs_invoiced_not_exported: {
title: i18n.t("reportcenter.templates.jobs_invoiced_not_exported"),
subject: i18n.t(
"reportcenter.templates.jobs_invoiced_not_exported"
),
key: "jobs_invoiced_not_exported",
//idtype: "vendor",
disabled: false,
rangeFilter: {
object: i18n.t("reportcenter.labels.objects.jobs"),
field: i18n.t("jobs.fields.date_invoiced"),
},
group: "jobs",
},
}
: {}),
...(!type || type === "courtesycarcontract"
@@ -1719,6 +1824,21 @@ export const TemplateList = (type, context) => {
},
}
: {}),
...(!type || type === "courtesycar"
? {
courtesy_car_inventory: {
title: i18n.t(
"printcenter.courtesycarcontract.courtesy_car_inventory"
),
description: "Est Detail",
subject: i18n.t(
"printcenter.courtesycarcontract.courtesy_car_inventory"
),
key: "courtesy_car_inventory",
disabled: false,
},
}
: {}),
...(!type || type === "bill"
? {
inhouse_invoice: {

View File

@@ -2178,20 +2178,21 @@
estree-walker "^1.0.1"
picomatch "^2.2.2"
"@sentry/browser@7.7.0":
version "7.7.0"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.7.0.tgz#7810ee98d4969bd0367e29ac0af6c5779db7e6c4"
integrity sha512-oyzpWcsjVZTaf14zAL89Ng1DUHlbjN+V8pl8dR9Y9anphbzL5BK9p0fSK4kPIrO4GukK+XrKnLJDPuE/o7WR3g==
"@sentry/browser@7.28.1":
version "7.28.1"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.28.1.tgz#c8086e26079809aa401a05d9b4a6e4df63a9c965"
integrity sha512-N8j93IcrWKWorfJ5D+RSKVAvcR4S5tIcZ/HvFPMrQWnfVa/jtJcrKThdjZYteA0wjmPiy8/D3KA8nB91yulBPA==
dependencies:
"@sentry/core" "7.7.0"
"@sentry/types" "7.7.0"
"@sentry/utils" "7.7.0"
"@sentry/core" "7.28.1"
"@sentry/replay" "7.28.1"
"@sentry/types" "7.28.1"
"@sentry/utils" "7.28.1"
tslib "^1.9.3"
"@sentry/cli@^1.74.4":
version "1.74.5"
resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.74.5.tgz#4a5c622913087c9ab6f82994da9a7526423779b8"
integrity sha512-Ze1ec306ZWHtrxKypOJ8nhtFqkrx2f/6bRH+DcJzEQ3bBePQ0ZnqJTTe4BBHADYBtxFIaUWzCZ6DquLz2Zv/sw==
"@sentry/cli@^1.74.6":
version "1.74.6"
resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.74.6.tgz#c4f276e52c6f5e8c8d692845a965988068ebc6f5"
integrity sha512-pJ7JJgozyjKZSTjOGi86chIngZMLUlYt2HOog+OJn+WGvqEkVymu8m462j1DiXAnex9NspB4zLLNuZ/R6rTQHg==
dependencies:
https-proxy-agent "^5.0.0"
mkdirp "^0.5.5"
@@ -2201,65 +2202,65 @@
proxy-from-env "^1.1.0"
which "^2.0.2"
"@sentry/core@7.7.0":
version "7.7.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.7.0.tgz#1a2d477897552d179380f7c54c7d81a4e98ea29a"
integrity sha512-Z15ACiuiFINFcK4gbMrnejLn4AVjKBPJOWKrrmpIe8mh+Y9diOuswt5mMUABs+jhpZvqht3PBLLGBL0WMsYMYA==
"@sentry/core@7.28.1":
version "7.28.1"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.28.1.tgz#c712ce17469b18b01606108817be24a99ed2116e"
integrity sha512-7wvnuvn/mrAfcugWoCG/3pqDIrUgH5t+HisMJMGw0h9Tc33KqrmqMDCQVvjlrr2pWrw/vuUCFdm8CbUHJ832oQ==
dependencies:
"@sentry/hub" "7.7.0"
"@sentry/types" "7.7.0"
"@sentry/utils" "7.7.0"
"@sentry/types" "7.28.1"
"@sentry/utils" "7.28.1"
tslib "^1.9.3"
"@sentry/hub@7.7.0":
version "7.7.0"
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-7.7.0.tgz#9ad3471cf5ecaf1a9d3a3a04ca2515ffec9e2c09"
integrity sha512-6gydK234+a0nKhBRDdIJ7Dp42CaiW2juTiHegUVDq+482balVzbZyEAmESCmuzKJhx5BhlCElVxs/cci1NjMpg==
"@sentry/react@^7.28.1":
version "7.28.1"
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.28.1.tgz#79531b98176765a788cdf7f8f09b8ba713a95cfb"
integrity sha512-sFKK7uDREh84GyJcXDNuiQQ5VhLx7XJTOAdELxLv4HEI6BxbBRz0zNRQiKamTRkz9NmL7bZtld5TfbpOo9kijg==
dependencies:
"@sentry/types" "7.7.0"
"@sentry/utils" "7.7.0"
tslib "^1.9.3"
"@sentry/react@^7.7.0":
version "7.7.0"
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.7.0.tgz#a519dd727f863c1abf1a77beac01a3336c856828"
integrity sha512-93Khad3YAln6mKU9E15QH09XC1ARIOpNTRpnBl6AGl3bVhSdLExsbKDLa7Rx0mW2j4z/prOC6VEHf5mBvg4mPg==
dependencies:
"@sentry/browser" "7.7.0"
"@sentry/types" "7.7.0"
"@sentry/utils" "7.7.0"
"@sentry/browser" "7.28.1"
"@sentry/types" "7.28.1"
"@sentry/utils" "7.28.1"
hoist-non-react-statics "^3.3.2"
tslib "^1.9.3"
"@sentry/tracing@^7.7.0":
version "7.7.0"
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.7.0.tgz#67324b755a28e115289755e44a0b8b467a63d0b2"
integrity sha512-HNmvTwemuc21q/K6HXsSp9njkne6N1JQ71TB+QGqYU5VtxsVgYSUhhYqV6WcHz7LK4Hj6TvNFoeu69/rO0ysgw==
"@sentry/replay@7.28.1":
version "7.28.1"
resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.28.1.tgz#fbdd377923e082423b95e3f128cb9af9451aca70"
integrity sha512-Os0PzMjKlwtHwzTU0kfVzGzsi4Vaj3g2arCl4Qnr3b6kYTb9WOFZo/n/v56ss7Z+nZG3K8W5PisoD4MRsRJRig==
dependencies:
"@sentry/hub" "7.7.0"
"@sentry/types" "7.7.0"
"@sentry/utils" "7.7.0"
"@sentry/core" "7.28.1"
"@sentry/types" "7.28.1"
"@sentry/utils" "7.28.1"
"@sentry/tracing@^7.28.1":
version "7.28.1"
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.28.1.tgz#d276e4d17a79190a88112696c73de12c209607a1"
integrity sha512-uWspnuz+7FyW8ES5lRaVA7O/YJSzMlSkvBFtgzaoKmdaueokU/sRLwlCsrdgwavG1wpm79df7R1iiSeqhaXDlw==
dependencies:
"@sentry/core" "7.28.1"
"@sentry/types" "7.28.1"
"@sentry/utils" "7.28.1"
tslib "^1.9.3"
"@sentry/types@7.7.0":
version "7.7.0"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.7.0.tgz#dd6bd3d119d7efea0e85dbaa4b17de1c22b63c7a"
integrity sha512-4x8O7uerSGLnYC10krHl9t8h7xXHn5FextqKYbTCXCnx2hC8D+9lz8wcbQAFo0d97wiUYqI8opmEgFVGx7c5hQ==
"@sentry/types@7.28.1":
version "7.28.1"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.28.1.tgz#9018b4c152b475de9bedd267237393d3c9b1253d"
integrity sha512-DvSplMVrVEmOzR2M161V5+B8Up3vR71xMqJOpWTzE9TqtFJRGPtqT/5OBsNJJw1+/j2ssMcnKwbEo9Q2EGeS6g==
"@sentry/utils@7.7.0":
version "7.7.0"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.7.0.tgz#013e3097c4268a76de578494c7df999635fb0ad4"
integrity sha512-fD+ROSFpeJlK7bEvUT2LOW7QqgjBpXJwVISKZ0P2fuzclRC3KoB2pbZgBM4PXMMTiSzRGWhvfRRjBiBvQJBBJQ==
"@sentry/utils@7.28.1":
version "7.28.1"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.28.1.tgz#0a7b6aa4b09e91e4d1aded2a8c8dbaf818cee96e"
integrity sha512-75/jzLUO9HH09iC9TslNimGbxOP3jgn89P+q7uR+rp2fJfRExHVeKJZQdK0Ij4/SmE7TJ3Uh2r154N0INZEx1g==
dependencies:
"@sentry/types" "7.7.0"
"@sentry/types" "7.28.1"
tslib "^1.9.3"
"@sentry/webpack-plugin@^1.19.0":
version "1.19.0"
resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.19.0.tgz#2b134318f1552ba7f3e3f9c83c71a202095f7a44"
integrity sha512-qSpdgdGMtdzagGveSWgo2b+t8PdPUscuOjbOyWCsJme9jlTFnNk0rX7JEA55OUozikKHM/+vVh08USLBnPboZw==
"@sentry/webpack-plugin@^1.20.0":
version "1.20.0"
resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.20.0.tgz#e7add76122708fb6b4ee7951294b521019720e58"
integrity sha512-Ssj1mJVFsfU6vMCOM2d+h+KQR7QHSfeIP16t4l20Uq/neqWXZUQ2yvQfe4S3BjdbJXz/X4Rw8Hfy1Sd0ocunYw==
dependencies:
"@sentry/cli" "^1.74.4"
"@sentry/cli" "^1.74.6"
webpack-sources "^2.0.0 || ^3.0.0"
"@sinonjs/commons@^1.7.0":
version "1.8.3"
@@ -2304,18 +2305,6 @@
shallowequal "^1.1.0"
unfetch "^4.2.0"
"@stripe/react-stripe-js@^1.9.0":
version "1.9.0"
resolved "https://registry.yarnpkg.com/@stripe/react-stripe-js/-/react-stripe-js-1.9.0.tgz#74809a274d7db110c3daf6f68ca4d62c6e6559c7"
integrity sha512-Fn49X+Gu5fOTxhPOita1cPMi0jw+0v4xfJ3FCXbbvmfuuDl3M7ZvpRkoijBjql11NXsaXO3TMm3rkN3mEolJzw==
dependencies:
prop-types "^15.7.2"
"@stripe/stripe-js@^1.32.0":
version "1.32.0"
resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.32.0.tgz#4ecdd298db61ad9b240622eafed58da974bd210e"
integrity sha512-7EvBnbBfS1aynfLRmBFcuumHNGjKxnNkO47rorFBktqDYHwo7Yw6pfDW2iqq0R8r7i7XiJEdWPvvEgQAiDrx3A==
"@surma/rollup-plugin-off-main-thread@^1.1.1":
version "1.4.2"
resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz#e6786b6af5799f82f7ab3a82e53f6182d2b91a58"
@@ -14615,6 +14604,11 @@ webpack-sources@^1.1.0, webpack-sources@^1.3.0, webpack-sources@^1.4.0, webpack-
source-list-map "^2.0.0"
source-map "~0.6.1"
"webpack-sources@^2.0.0 || ^3.0.0":
version "3.2.3"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
webpack@4.44.2:
version "4.44.2"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.2.tgz#6bfe2b0af055c8b2d1e90ed2cd9363f841266b72"

View File

@@ -855,6 +855,7 @@
- deliverchecklist
- email
- enforce_class
- enforce_conversion_csr
- enforce_referral
- entegral_configuration
- entegral_id
@@ -951,6 +952,7 @@
- deliverchecklist
- email
- enforce_class
- enforce_conversion_csr
- enforce_referral
- federal_tax_id
- id
@@ -1241,6 +1243,7 @@
- bodyshopid
- created_at
- id
- label
- phone_num
- unreadcnt
- updated_at
@@ -1252,6 +1255,7 @@
- bodyshopid
- created_at
- id
- label
- phone_num
- unreadcnt
- updated_at
@@ -1273,6 +1277,7 @@
- bodyshopid
- created_at
- id
- label
- phone_num
- unreadcnt
- updated_at
@@ -2477,6 +2482,7 @@
_eq: true
columns:
- act_price
- ah_detail_line
- alt_co_id
- alt_overrd
- alt_part_i
@@ -2542,6 +2548,7 @@
permission:
columns:
- act_price
- ah_detail_line
- alt_co_id
- alt_overrd
- alt_part_i
@@ -2618,6 +2625,7 @@
permission:
columns:
- act_price
- ah_detail_line
- alt_co_id
- alt_overrd
- alt_part_i
@@ -3025,6 +3033,7 @@
- date_next_contact
- date_open
- date_rentalresp
- date_repairstarted
- date_scheduled
- date_towin
- ded_amt
@@ -3288,6 +3297,7 @@
- date_next_contact
- date_open
- date_rentalresp
- date_repairstarted
- date_scheduled
- date_towin
- ded_amt
@@ -3561,6 +3571,7 @@
- date_next_contact
- date_open
- date_rentalresp
- date_repairstarted
- date_scheduled
- date_towin
- ded_amt
@@ -3769,6 +3780,27 @@
- active:
_eq: true
event_triggers:
- name: job_status_transition
definition:
enable_manual: false
insert:
columns: '*'
update:
columns:
- status
retry_conf:
interval_sec: 10
num_retries: 0
timeout_sec: 60
webhook_from_env: HASURA_API_URL
headers:
- name: event-secret
value_from_env: EVENT_SECRET
request_transform:
query_params: {}
template_engine: Kriti
url: '{{$base_url}}/job/statustransition'
version: 2
- name: jobs_arms
definition:
enable_manual: false

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