Compare commits

...

732 Commits

Author SHA1 Message Date
Dave Richer
9346a819f5 - The Great merge
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-02-06 19:16:47 -05:00
Dave Richer
4eb8faa5d9 - the great reformat
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-02-06 18:23:46 -05:00
Dave Richer
e83badb454 - the great reformat
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-02-06 18:20:58 -05:00
Dave Richer
30c530bcc4 - rectify
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-02-06 15:31:38 -05:00
Dave Richer
3ec9ea6ed1 Merge branch 'master' into feature/IO-1828-Front-End-Package-Updates
# Conflicts:
#	client/src/index.js
2024-02-06 11:51:38 -05:00
Dave Richer
cba63d609a - Add additional date time autocomplete formats
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-02-06 11:34:16 -05:00
Dave Richer
3abf3b9bfd - Add additional date time autocomplete formats
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-02-05 16:52:03 -05:00
Dave Richer
197d97dd99 - fix date picker
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-02-05 16:06:33 -05:00
Dave Richer
498292c2ec - Fix for job line null check
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-02-05 11:35:24 -05:00
Patrick Fic
6b0c211084 Resolve CI for master. 2024-01-31 13:14:01 -08:00
Patrick Fic
c4c65d1696 CI Updates. 2024-01-31 13:03:51 -08:00
Patrick Fic
7395450b7a CI update. 2024-01-31 10:36:45 -08:00
Patrick Fic
62852f4002 CI Changes. 2024-01-31 10:20:49 -08:00
Dave Richer
3b54fd27bb - replace require with import
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-31 12:05:12 -05:00
Dave Richer
b9bca31b57 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1248)
- replace require with import
2024-01-31 17:00:28 +00:00
Dave Richer
edc2a0f122 - replace require with import
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-31 11:59:25 -05:00
Patrick Fic
5ad5cca2ed Merge branch 'feature/IO-1828-Front-End-Package-Updates' into test-beta 2024-01-30 17:40:00 -08:00
Patrick Fic
530032b5ea Remove Jira from CI. 2024-01-30 17:39:46 -08:00
Patrick Fic
fd720f2a27 Merge branch 'feature/IO-1828-Front-End-Package-Updates' into test-beta 2024-01-30 17:38:25 -08:00
Patrick Fic
3ca48350a6 Update old orbs on CI 2024-01-30 17:37:59 -08:00
Patrick Fic
02957fa132 Merge branch 'feature/IO-1828-Front-End-Package-Updates' into test-beta 2024-01-30 17:33:29 -08:00
Patrick Fic
c8979091fd CI update. 2024-01-30 17:28:45 -08:00
Patrick Fic
2310f99787 Merge branch 'test-beta' of bitbucket.org:snaptsoft/bodyshop into test-beta 2024-01-30 17:17:39 -08:00
Patrick Fic
fea67e752b Merge branch 'feature/IO-1828-Front-End-Package-Updates' into test-beta 2024-01-30 17:17:32 -08:00
Patrick Fic
7358dee3e0 CI adjustment. 2024-01-30 17:17:10 -08:00
Patrick Fic
c8fc1b0f68 Merged in feature/Sentry-Improvements (pull request #1246)
Change tracing targets.
2024-01-31 01:08:37 +00:00
Patrick Fic
da1ddb874f Change tracing targets. 2024-01-30 16:58:11 -08:00
Dave Richer
0c2396eb12 - Merge and update
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-30 19:37:52 -05:00
Dave Richer
232109c2c7 Merge remote-tracking branch 'origin/rome/release/2024-01-26' into rome/test-beta
# Conflicts:
#	.circleci/config.yml
#	client/package-lock.json
#	client/src/components/header/header.component.jsx
#	client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx
#	client/src/components/jobs-admin-delete-intake/jobs-admin-delete-intake.component.jsx
#	client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx
#	client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx
#	client/src/components/production-list-detail/production-list-detail.component.jsx
#	client/src/components/report-center-modal/report-center-modal.component.jsx
#	client/src/pages/jobs-admin/jobs-admin.page.jsx
#	client/src/pages/jobs-detail/jobs-detail.page.component.jsx
#	client/src/utils/TemplateConstants.js
#	client/yarn.lock
#	package-lock.json
#	server.js
2024-01-30 18:42:45 -05:00
Patrick Fic
8c6ca5a4bd Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1245)
Customer runner.
2024-01-30 22:45:22 +00:00
Patrick Fic
ff151444d2 Customer runner. 2024-01-30 14:44:38 -08:00
Patrick Fic
9d1dc4e0bb Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1244)
Use self hosted runner.
2024-01-30 22:16:22 +00:00
Patrick Fic
000a2e471e Use self hosted runner. 2024-01-30 14:14:06 -08:00
Patrick Fic
caff9af1a3 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1243)
Increase CI allocation for beta builds.
2024-01-30 22:02:00 +00:00
Patrick Fic
94bcfa2afc Increase CI allocation for beta builds. 2024-01-30 14:01:22 -08:00
Patrick Fic
771f9ceaa8 Merged in feature/Sentry-Improvements (pull request #1242)
Feature/Sentry Improvements
2024-01-30 21:45:22 +00:00
Patrick Fic
929086061d Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1240)
Update S3 sync in CI for beta builds.
2024-01-30 21:44:38 +00:00
Patrick Fic
bcb319d571 Update S3 sync in CI for beta builds. 2024-01-30 13:44:14 -08:00
Dave Richer
1c716546d5 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1237)
Feature/IO-1828 Front End Package Updates
2024-01-30 21:34:30 +00:00
Dave Richer
ca246fa6fa Merge remote-tracking branch 'origin/feature/Sentry-Improvements' into feature/IO-1828-Front-End-Package-Updates 2024-01-30 16:33:45 -05:00
Dave Richer
2dcfa87fa6 - Merge and update
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-30 16:33:25 -05:00
Patrick Fic
7daf7540b3 Resolve Typo in CI. 2024-01-30 13:32:58 -08:00
Patrick Fic
ce6940629d Exclude source map upload in CI. 2024-01-30 13:25:48 -08:00
Patrick Fic
b706b96d32 Remove sentry test button. 2024-01-30 13:14:27 -08:00
Patrick Fic
2427bc72f2 Updated CI. 2024-01-30 12:53:07 -08:00
Patrick Fic
8bc1a9d9ee Initial sentry improvements to deploy and verify against test. 2024-01-30 12:47:12 -08:00
Dave Richer
1e669e100a Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1235)
- fix EULA
2024-01-30 18:30:47 +00:00
Dave Richer
5f8c878bec - fix EULA
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-30 13:29:58 -05:00
Patrick Fic
d5198edfc0 Improve team name label. 2024-01-29 12:59:55 -08:00
Patrick Fic
39bba3623a Resolve broken routes. 2024-01-29 12:56:14 -08:00
Patrick Fic
62dac2193f Resolve CI warnings for unused components. 2024-01-29 12:41:43 -08:00
Patrick Fic
72da0734c8 Resolve CI issue. 2024-01-29 12:27:52 -08:00
Patrick Fic
69b4b76501 Comment out beta switch while Rome Beta has not yet started. 2024-01-29 12:25:04 -08:00
Patrick Fic
ae56e27e5f Update CI for Rome Test branches. 2024-01-29 12:20:36 -08:00
Dave Richer
d6bb6a891d Merged in release/2024-01-29 (pull request #1232)
IO-1532 resolve update logic issue for status timings.
2024-01-29 18:18:52 +00:00
Dave Richer
1bda15e353 Merge branch 'feature/IO-1828-Front-End-Package-Updates' into test-beta 2024-01-29 12:12:55 -05:00
Dave Richer
fb47b45eb6 Merge remote-tracking branch 'origin/release/2024-01-29' into feature/IO-1828-Front-End-Package-Updates 2024-01-29 12:12:15 -05:00
Patrick Fic
ba30225ba1 Merged in release/2024-01-29 (pull request #1230)
IO-1532 resolve update logic issue for status timings.
2024-01-29 17:06:31 +00:00
Patrick Fic
cb4a6e8774 IO-1532 resolve update logic issue for status timings. 2024-01-29 09:05:46 -08:00
Allan Carr
2f83b0baa7 Query correction for GET_JOB_BY_PK 2024-01-26 20:29:37 -08:00
Dave Richer
23f640028d Merged in release/2024-01-26 (pull request #1227)
Release/2024 01 26
2024-01-27 02:25:22 +00:00
Dave Richer
04728690ca - merge adjustments
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-26 21:20:49 -05:00
Dave Richer
a928d72aac Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1225)
Feature/IO-1828 Front End Package Updates
2024-01-26 23:16:29 +00:00
Dave Richer
dc1c492c0b - fix keys in job lifecycle table
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-26 18:15:17 -05:00
Dave Richer
bdff9f62c0 Merge branch 'release/2024-01-26' into feature/IO-1828-Front-End-Package-Updates 2024-01-26 18:08:41 -05:00
Dave Richer
3e5e6263fe Merged in feature/IO-1532-Tracking-Department-Cycle-Times (pull request #1223)
- updates from lifecyle component.
2024-01-26 23:07:02 +00:00
Dave Richer
48cef3e188 - updates from lifecyle component.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-26 18:06:14 -05:00
Dave Richer
76b25a716c - updates from lifecyle component.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-26 17:46:37 -05:00
Dave Richer
86c3806e28 Merge branch 'feature/IO-1532-Tracking-Department-Cycle-Times' into feature/IO-1828-Front-End-Package-Updates 2024-01-26 16:35:25 -05:00
Dave Richer
8c0d6b2f6b Merged in feature/IO-1532-Tracking-Department-Cycle-Times (pull request #1221)
- Fix use hook
2024-01-26 21:34:17 +00:00
Dave Richer
22ee8acd0d - Fix use hook
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-26 16:33:40 -05:00
Dave Richer
548cfefc41 - Finish department cycle times.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-26 16:29:46 -05:00
Dave Richer
ae98566bbd Merge branch 'release/2024-01-26' into feature/IO-1828-Front-End-Package-Updates
# Conflicts:
#	client/src/pages/jobs-detail/jobs-detail.page.component.jsx
#	package-lock.json
#	package.json
2024-01-26 16:28:18 -05:00
Dave Richer
afdcfb7bf6 Merge branch 'feature/IO-1532-Tracking-Department-Cycle-Times' into release/2024-01-26 2024-01-26 16:14:01 -05:00
Dave Richer
c1f6d06128 - Finish department cycle times.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-26 16:10:24 -05:00
Dave Richer
120a8a4576 - Finish department cycle times.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-26 16:09:46 -05:00
Dave Richer
89224e871c - Progress Update
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-26 12:57:06 -05:00
Allan Carr
fa0d472fb6 Merged in feature/IO-2543-AR-Aging (pull request #1216)
IO-2543 Add wrap to space components to maintain limits of card

Approved-by: Dave Richer
2024-01-26 16:52:59 +00:00
Dave Richer
4475bf038b Merge branch 'feature/IO-1828-Front-End-Package-Updates' into test-beta 2024-01-26 11:50:07 -05:00
Dave Richer
29d5465afc Merge branch 'release/2024-01-26' into feature/IO-1828-Front-End-Package-Updates 2024-01-26 11:49:29 -05:00
Dave Richer
b0f4ad7e4f - Progress Update
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-26 11:48:43 -05:00
Allan Carr
7503d86c69 IO-2543 Add wrap to space components to maintain limits of card 2024-01-26 08:42:57 -08:00
Dave Richer
efd1c17033 - Revert Hasura
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-26 08:21:43 -08:00
Dave Richer
c7a0072f2d - Revert Hasura
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-26 11:19:03 -05:00
Allan Carr
908942ec09 IO-2543 Revert Lost Sales for Datedisable 2024-01-26 08:11:29 -08:00
Allan Carr
e4d3b53349 Merged in feature/IO-2543-AR-Aging (pull request #1215)
IO-2543 Revert Lost Sales for Datedisable

Approved-by: Dave Richer
2024-01-26 16:10:08 +00:00
Patrick Fic
2a31d740d5 Add date disable for load level report. 2024-01-26 08:08:51 -08:00
Dave Richer
53044d2790 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1214)
- Fix CC Cart stuff
2024-01-25 21:04:44 +00:00
Dave Richer
2b0ecbdd91 - Fix CC Cart stuff
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-25 16:03:34 -05:00
Dave Richer
7a36e48401 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1213)
Feature/IO-1828 Front End Package Updates
2024-01-25 20:27:01 +00:00
Dave Richer
461bc726aa - progress update.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-25 15:23:42 -05:00
Dave Richer
80483b617b Merge branch 'release/2024-01-26' into feature/IO-1828-Front-End-Package-Updates
# Conflicts:
#	client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx
#	client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx
#	client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx
#	client/src/components/report-center-modal/report-center-modal.component.jsx
2024-01-25 14:11:33 -05:00
Dave Richer
03ce5458b5 Merge branch 'release/2024-01-26' into feature/IO-1532-Tracking-Department-Cycle-Times 2024-01-25 14:00:26 -05:00
Dave Richer
f9528c5ff7 Merge branch 'release/2024-01-26' into feature/IO-1828-Front-End-Package-Updates 2024-01-25 13:59:18 -05:00
Dave Richer
61c03ee206 Merge branch 'release/2024-01-26' into feature/IO-1532-Tracking-Department-Cycle-Times 2024-01-25 13:56:25 -05:00
Dave Richer
0e4f5b8b2a - progress update.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-25 13:35:20 -05:00
Allan Carr
b5d4944ad8 Merged in feature/IO-2543-AR-Aging (pull request #1210)
IO-2543 AR Aging

Approved-by: Dave Richer
Approved-by: Patrick Fic
2024-01-25 18:33:20 +00:00
Patrick Fic
50f84d40e1 Allow negative balance for AR. 2024-01-25 10:30:03 -08:00
Dave Richer
ebc75e71d3 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1211)
- Fix empty strings passing validation.
2024-01-25 18:09:51 +00:00
Dave Richer
16b0381007 - Fix empty strings passing validation.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-25 13:04:53 -05:00
Dave Richer
a394d6b37e - Major Progress Commit
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-25 12:38:32 -05:00
Dave Richer
f8408908b2 - Major Progress Commit
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-24 21:40:05 -05:00
Allan Carr
eb8519dc1d IO-2543 Move queries to jobs.queries.js and correct layout 2024-01-24 18:37:41 -08:00
Allan Carr
36dd97394f IO-2543 Adjust for having no dates 2024-01-24 16:15:32 -08:00
Allan Carr
03d4e4dcd1 IO-2543 AR Aging 2024-01-24 16:01:48 -08:00
Dave Richer
6489a8666f - Progress
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-24 18:39:59 -05:00
Dave Richer
1c779b05c3 Merge branch 'feature/IO-1828-Front-End-Package-Updates' into test-beta 2024-01-24 17:29:16 -05:00
Dave Richer
da5739be8f - Progress
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-24 17:27:49 -05:00
Dave Richer
5ea64ed805 - Progress
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-24 17:18:43 -05:00
Dave Richer
9e6ee505ca Merge branch 'feature/IO-1828-Front-End-Package-Updates' into test-beta 2024-01-24 12:50:49 -05:00
Dave Richer
397ae72626 - Fix issues
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-24 12:49:18 -05:00
Dave Richer
ed15620884 Merge branch 'feature/IO-1828-Front-End-Package-Updates' into test-beta 2024-01-24 12:20:49 -05:00
Dave Richer
f138ab82fb - update npm packages
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-24 11:18:34 -05:00
Dave Richer
680583addf Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1208)
Feature/IO-1828 Front End Package Updates
2024-01-24 15:10:54 +00:00
Dave Richer
9e127d1c71 Merge branch 'feature/IO-1828-Front-End-Package-Updates' of bitbucket.org:snaptsoft/bodyshop into feature/IO-1828-Front-End-Package-Updates 2024-01-24 10:07:27 -05:00
Dave Richer
d740446ccb - Progress
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-24 10:07:07 -05:00
Dave Richer
cdec9840bf Merged in feature/IO-2477 (pull request #1207)
Feature/IO-2477 - EULA

Approved-by: Patrick Fic
2024-01-23 23:23:56 +00:00
Dave Richer
d0a2bb7da0 - human readable dates
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-23 12:58:57 -05:00
Dave Richer
5de4ef5d83 - human readable dates
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-23 12:54:38 -05:00
Dave Richer
f59bdf9030 - Progress Update
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-23 12:35:58 -05:00
Dave Richer
cfe0727447 - Rough in front end / backend
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-23 10:20:26 -05:00
Dave Richer
09d112350a - Rough in front end / backend
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-23 01:37:11 -05:00
Dave Richer
52f8eabd2b - Finish cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-23 00:02:18 -05:00
Dave Richer
a162b275a3 - Finish cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-22 23:11:10 -05:00
Dave Richer
2e7232bb65 - Finish cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-22 23:00:31 -05:00
Dave Richer
82dc9e1c56 - Finish cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-22 19:07:16 -05:00
Dave Richer
272a3f579a - Minor cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-22 18:53:57 -05:00
Dave Richer
ff1ceb20cb - Minor cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-22 18:39:27 -05:00
Dave Richer
343179d4fe - Minor cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-22 18:05:35 -05:00
Dave Richer
eabbc2211b - Minor cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-22 17:21:46 -05:00
Dave Richer
7f587680ca - Scaffolding.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-22 16:38:26 -05:00
Dave Richer
9deab7d5d5 - Theme provider update
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-22 15:30:43 -05:00
Patrick Fic
d61ed03ef1 Merge in EULA changes & update to AR Tracking schema. 2024-01-22 11:52:42 -08:00
Dave Richer
e46be6c12b - Add OnlyToday
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-22 14:38:56 -05:00
Dave Richer
166efdc877 progressUpdate
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-22 14:25:21 -05:00
Dave Richer
cac4f800ed Merge branch 'feature/IO-1828-Front-End-Package-Updates' into test-beta 2024-01-20 21:22:37 -05:00
Dave Richer
f02aa36b8d Merge branch 'feature/IO-1828-Front-End-Package-Updates' into feature/IO-2477 2024-01-20 21:20:53 -05:00
Dave Richer
d7faf11e27 - Restore the color diffs between dev and prod
- Clean up Craco config
- Updated SplitFactoryProvider

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-20 21:20:36 -05:00
Dave Richer
b25df2c7a8 Merge branch 'feature/IO-1828-Front-End-Package-Updates' into test-beta 2024-01-20 19:24:53 -05:00
Dave Richer
73058c4405 Merge branch 'feature/IO-1828-Front-End-Package-Updates' into feature/IO-2477 2024-01-20 19:22:42 -05:00
Dave Richer
72e8aba546 - Merge master
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-20 19:21:31 -05:00
Dave Richer
039f1e6a91 - move lib
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-19 22:30:35 -05:00
Dave Richer
ddea46ddef - Remove test data
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-19 22:28:47 -05:00
Dave Richer
2ada4ac44b - Eula finished
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-19 22:27:03 -05:00
Dave Richer
6937f33134 - Eula Progress
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-19 20:55:15 -05:00
Allan Carr
9274742520 Merged in release/2024-01-19 (pull request #1206)
Release/2024 01 19
2024-01-20 01:03:59 +00:00
Patrick Fic
9b4c85c9e3 IO-2543 additional schema correction. 2024-01-19 13:50:14 -08:00
Allan Carr
66c64ce9e0 Merged in feature/IO-2599-Techstation-Linking (pull request #1204)
IO-2599 Remove Space and put Div in to space components

Approved-by: Patrick Fic
2024-01-19 21:18:39 +00:00
Patrick Fic
c9cbffdec8 IO-2543 Schema changes for AR calculation. 2024-01-19 13:15:06 -08:00
Allan Carr
ca3145ce0f IO-2599 Remove Space and put Div in to space components 2024-01-19 12:19:07 -08:00
Dave Richer
06a8d4257a Merge branch 'feature/IO-1828-Front-End-Package-Updates' into feature/IO-2477 2024-01-19 12:31:46 -05:00
Dave Richer
1718ba5695 - merge
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-19 12:29:04 -05:00
Dave Richer
1cf47b91e2 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1202)
Feature/IO-1828 Front End Package Updates
2024-01-19 17:12:21 +00:00
Dave Richer
44a13ca0d5 Merge branch 'release/2024-01-19' into feature/IO-1828-Front-End-Package-Updates
# Conflicts:
#	client/src/App/App.jsx
#	client/src/components/shop-employees/shop-employees-list.component.jsx
2024-01-19 12:08:34 -05:00
Allan Carr
52f9106776 Merged in feature/IO-2608-Employee-Filter-and-Sort (pull request #1197)
IO-2608 Filter and Sort columns in Employee table

Approved-by: Dave Richer
2024-01-19 16:58:45 +00:00
Allan Carr
1a2cc5623d Merged in feature/IO-2598-Tech-Create-IOU (pull request #1201)
IO-2598 Restrict IOU from Tech Console

Approved-by: Dave Richer
2024-01-19 16:58:13 +00:00
Allan Carr
d06037df1f IO-2598 Restrict IOU from Tech Console 2024-01-19 08:47:17 -08:00
Dave Richer
0665bade1b Merge branch 'feature/IO-1828-Front-End-Package-Updates' into feature/IO-2477 2024-01-18 20:57:42 -05:00
Dave Richer
95c445c40f Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1199)
- optimize schedule out today in dashboard
2024-01-19 01:56:00 +00:00
Dave Richer
51483f62e1 - optimize schedule out today in dashboard
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 20:49:50 -05:00
Dave Richer
2826360627 - fixed scheduled-out-today.component.jsx
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 20:46:51 -05:00
Allan Carr
cb8632641e IO-2608 Filter and Sort columns in Employee table 2024-01-18 17:28:46 -08:00
Dave Richer
3690ea0332 - Merge client update into test-beta
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 19:20:08 -05:00
Dave Richer
8dc41519ce Merge branch 'feature/IO-1828-Front-End-Package-Updates' into feature/IO-2477 2024-01-18 16:52:20 -05:00
Dave Richer
913c81409a Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1195)
Feature/IO-1828 Front End Package Updates
2024-01-18 21:51:08 +00:00
Dave Richer
e255f0a664 - update handleBeta
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 16:50:30 -05:00
Dave Richer
adbfcddd9d Merged in feature/IO-1828-Beta-Updates-To-Test (pull request #1194)
Feature/IO-1828 Beta Updates To Test
2024-01-18 21:49:33 +00:00
Dave Richer
e3aea55e91 Merged in feature/IO-1828-Beta-Updates-To-Test (pull request #1193)
Feature/IO-1828 Beta Updates To Test
2024-01-18 21:48:51 +00:00
Dave Richer
bf6b1c202f - update handleBeta
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 16:35:30 -05:00
Dave Richer
0cab47f984 - update handleBeta
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 16:22:58 -05:00
Dave Richer
829e611692 - update handleBeta
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 16:16:06 -05:00
Patrick Fic
e0e62a52be Cherry pick schema chengs from IO-2477 2024-01-18 13:08:39 -08:00
Dave Richer
23c0f8e383 - update handleBeta
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 16:07:17 -05:00
Dave Richer
7da5d1a4fd - node versions
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 16:04:53 -05:00
Dave Richer
f6799c0436 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1187)
Feature/IO-1828 Front End Package Updates
2024-01-18 20:57:37 +00:00
Dave Richer
43621bc6a2 - add a reload on beta switch
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 15:57:15 -05:00
Dave Richer
909f6e8eb5 - add a reload on beta switch
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 15:55:23 -05:00
Dave Richer
39a69e60c9 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1185)
Feature/IO-1828 Front End Package Updates
2024-01-18 20:33:04 +00:00
Dave Richer
1e78106224 - add a reload on beta switch
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 15:31:46 -05:00
Dave Richer
d1cd0ea126 Merge branch 'release/2024-01-19' into feature/IO-1828-Front-End-Package-Updates
# Conflicts:
#	client/src/App/App.jsx
#	client/src/components/header/header.component.jsx
2024-01-18 14:41:29 -05:00
Allan Carr
764a89e5bf Merged in feature/IO-2599-Techstation-Linking (pull request #1183)
Feature/IO-2599 Techstation Linking

Approved-by: Dave Richer
2024-01-18 19:33:20 +00:00
Allan Carr
f4908ed265 IO-2599 Tech Station Linking 2024-01-18 11:30:58 -08:00
Dave Richer
3c0780e410 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1181)
Update CI for test.
2024-01-18 18:48:41 +00:00
Patrick Fic
ae9bff7e75 Update CI for test. 2024-01-18 10:48:17 -08:00
Dave Richer
fcd9c19f0b Merged in feature/IO-1828-Beta-Switch-For-Test (pull request #1180)
Feature/IO-1828 Beta Switch For Test
2024-01-18 18:20:51 +00:00
Dave Richer
430823dde0 - remove source maps from prod
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 13:20:04 -05:00
Dave Richer
7e919a7221 Merge branch 'master' into feature/IO-1828-Beta-Switch-For-Test 2024-01-18 13:19:09 -05:00
Dave Richer
4d20ac07e9 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1178)
- remove source maps from prod
2024-01-18 18:15:50 +00:00
Dave Richer
8031b4f91a - remove source maps from prod
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 13:15:02 -05:00
Dave Richer
2fc82aad62 Merge branch 'feature/IO-1828-Front-End-Package-Updates' into feature/IO-2477 2024-01-18 13:07:29 -05:00
Dave Richer
08bbfc6276 Merge branch 'feature/IO-1828-Front-End-Package-Updates' into test-beta 2024-01-18 13:06:31 -05:00
Dave Richer
4f93b5af13 - remove the word faster
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 13:05:59 -05:00
Dave Richer
67e475ce21 - Merge Release
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-17 22:26:32 -05:00
Dave Richer
86b84e75cb Merge branch 'feature/IO-1828-Front-End-Package-Updates' into feature/IO-2477 2024-01-17 20:59:09 -05:00
Dave Richer
8de4ebd30a - Merge Release
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-17 20:56:53 -05:00
Allan Carr
7e7f055c34 Merged in feature/IO-2600-Tech-Job-Logout-Console-Log (pull request #1167)
IO-2600 Tech Console Job Logout Console Log

Approved-by: Dave Richer
2024-01-18 01:51:46 +00:00
Allan Carr
6e04ed7c83 Merged in feature/IO-2589-Manual-Job-Ownr-Validation (pull request #1168)
IO-2589 Allow Company Only for Customer Creation

Approved-by: Dave Richer
2024-01-18 01:51:30 +00:00
Allan Carr
5ec07f9620 Merged in feature/IO-2606-Schedule-Appointment-Modal-Close (pull request #1171)
IO-2606 Modal Closeable for Schedule Appointment

Approved-by: Dave Richer
2024-01-18 01:51:06 +00:00
Allan Carr
d3da4a8a1e Merged in feature/IO-2601-Tech-Console-Titles (pull request #1177)
IO-2601 Tech Console Titles

Approved-by: Dave Richer
2024-01-18 01:50:40 +00:00
Allan Carr
9ee10dc5f8 IO-2601 Tech Console Titles 2024-01-17 17:52:14 -08:00
Dave Richer
664ec1803f Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1176)
- Update build resource
2024-01-18 01:25:35 +00:00
Dave Richer
94dd7c6f69 - Update build resource
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-17 20:25:09 -05:00
Dave Richer
380d7d7170 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1174)
- Generate sourcemaps
2024-01-18 01:22:20 +00:00
Dave Richer
bbbb7867a2 - Generate sourcemaps
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-17 20:21:34 -05:00
Allan Carr
572963d987 IO-2606 Modal Closeable for Schedule Appointment 2024-01-17 17:09:17 -08:00
Dave Richer
47db3fdbcd Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1172)
Feature/IO-1828 Front End Package Updates
2024-01-18 01:08:25 +00:00
Dave Richer
1cb4b228ce - fix issue
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-17 20:05:38 -05:00
Dave Richer
eb96f6467f - adjust circle ci
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-17 20:03:55 -05:00
Dave Richer
3c7134002d Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1170)
- adjust circle ci
2024-01-18 01:03:21 +00:00
Dave Richer
2699b80e1a - adjust circle ci
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-17 20:02:41 -05:00
Dave Richer
482f48ed6d Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1169)
Feature/IO-1828 Front End Package Updates
2024-01-18 00:54:58 +00:00
Dave Richer
c72b4a25cf - progress
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-17 19:54:03 -05:00
Dave Richer
4a9684ba87 - progress
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-17 19:36:21 -05:00
Allan Carr
636be8989e IO-2589 Allow Company Only for Customer Creation 2024-01-17 14:22:47 -08:00
Allan Carr
dea7fd71ef IO-2600 Tech Console Job Logout Console Log 2024-01-17 09:41:57 -08:00
Dave Richer
1a93e1de41 ### Eula V1
- Front end logic implemented

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-17 00:38:02 -05:00
Dave Richer
69791a3cdd - Fix spacing on so me alerts
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-17 00:19:51 -05:00
Dave Richer
c2d6c980ed - Fix the page layout, the footer was in the content section causing it not to remain at the bottom and just reside 'at the bottom' of the content section. Also added a 100% on the outer container height (100vh) so the grey background fills the page
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-16 15:32:35 -05:00
Allan Carr
be08ed8551 Merged in feature/IO-2531-Retain-Filter-State-on-Jobs-Page (pull request #1166)
IO-2531 Retain Filtered Statue for Jobs Pages

Approved-by: Dave Richer
2024-01-16 20:22:04 +00:00
Allan Carr
65ce588287 Merged in feature/IO-2603-Open-Orders-Excel (pull request #1164)
IO-2603 Open Orders Excel

Approved-by: Dave Richer
2024-01-16 20:20:25 +00:00
Dave Richer
78a136e277 - Fix the page layout, the footer was in the content section causing it not to remain at the bottom and just reside 'at the bottom' of the content section. Also added a 100% on the outer container height (100vh) so the grey background fills the page
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-16 15:17:00 -05:00
Allan Carr
0cc367b25e IO-2531 Remove Console Log 2024-01-16 12:12:53 -08:00
Allan Carr
2ce8549502 IO-2531 Retain Filtered Statue for Jobs Pages 2024-01-16 12:11:18 -08:00
Dave Richer
690e65df0b - A little refactor cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-16 14:14:00 -05:00
Dave Richer
a38611a584 - Fix chat list item selected background (regression)
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-16 14:12:54 -05:00
Dave Richer
b6b445dc21 - Update the look and feel of the chat message list (prevents breaking when zoomed in and out like previous implementation)
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-16 14:02:54 -05:00
Allan Carr
7245d4eab2 IO-2603 Open Orders Excel 2024-01-15 18:54:28 -08:00
Dave Richer
c10a136110 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1163)
- Scoreboard fixes
2024-01-15 23:24:10 +00:00
Dave Richer
0d0f24802f - Scoreboard fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-15 18:23:37 -05:00
Dave Richer
b09a1701cd Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1162)
Feature/IO-1828 Front End Package Updates
2024-01-15 22:29:45 +00:00
Dave Richer
cf9b03d073 - Chat formatting
- Scroll to Top Button

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-15 17:28:24 -05:00
Dave Richer
7b61c24461 - Add hover style
- Add default theme reference
- Revert react-grid-layout to 1.3.4

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-15 15:59:00 -05:00
Allan Carr
260607cb72 Merged in release/2024-01-12 (pull request #1161)
IO-2520 Adjust to imexshopid instead of shopname & prettify
2024-01-13 05:12:28 +00:00
Allan Carr
810738539b Merged in release/2024-01-12 (pull request #1160)
IO-2520 Adjust to imexshopid instead of shopname & prettify
2024-01-13 05:05:25 +00:00
Allan Carr
80539949fb Merged in feature/IO-2520-Kaizen-Data-Pump (pull request #1159)
IO-2520 Adjust to imexshopid instead of shopname & prettify
2024-01-13 05:04:54 +00:00
Allan Carr
ebe5c5b113 IO-2520 Adjust to imexshopid instead of shopname & prettify 2024-01-12 21:06:39 -08:00
Dave Richer
525182c2a7 Merged in feature/IO-1828-Beta-Switch-For-Test (pull request #1158)
- Add in the Beta Switch on test
2024-01-13 02:07:43 +00:00
Dave Richer
3704c0cb12 - Add in the Beta Switch on test
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-12 20:50:40 -05:00
Dave Richer
c8c844cfba Merged in feature/IO-1828-Beta-Switch-For-Test (pull request #1157)
- Add in the Beta Switch on test
2024-01-13 01:48:01 +00:00
Dave Richer
4c4e16b0c9 - Add in the Beta Switch on test
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-12 20:47:06 -05:00
Dave Richer
f3db5d83c7 Merge branch 'master' into feature/IO-1828-Front-End-Package-Updates 2024-01-12 20:30:12 -05:00
Dave Richer
63ae37e5a9 - small refactor
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-12 20:29:35 -05:00
Allan Carr
69f727c4e5 Merged in release/2024-01-12 (pull request #1156)
IO-2520 Add in Server Key format
2024-01-13 00:34:42 +00:00
Dave Richer
bff174fdb6 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1155)
Feature/IO-1828 Front End Package Updates
2024-01-13 00:33:16 +00:00
Dave Richer
76bcfce312 - Fix bug with lowercase yyyy formatting.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-12 19:29:14 -05:00
Allan Carr
04cff4acb1 IO-2520 Add in Server Key format 2024-01-12 16:26:09 -08:00
Allan Carr
4e4fcc3ae4 Merged in release/2024-01-12 (pull request #1154)
IO-2520 Add in Server Key format
2024-01-13 00:25:24 +00:00
Allan Carr
485f9d6025 Merged in feature/IO-2520-Kaizen-Data-Pump (pull request #1153)
IO-2520 Add in Server Key format
2024-01-13 00:24:19 +00:00
Allan Carr
a697ade93a Merged in release/2024-01-12 (pull request #1152)
IO-2602 Beta domain
2024-01-13 00:02:58 +00:00
Allan Carr
7db07b5a94 Merged in release/2024-01-12 (pull request #1151)
IO-2602 Beta domain
2024-01-12 23:41:38 +00:00
Allan Carr
9ec50875a2 Merged in feature/IO-2602-BETA-domain (pull request #1150)
IO-2602 Beta domain
2024-01-12 23:39:22 +00:00
Allan Carr
02b6875eec IO-2602 Beta domain 2024-01-12 15:41:10 -08:00
Dave Richer
34c332e077 - random cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-12 18:21:21 -05:00
Dave Richer
d360bcbb71 - random cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-12 17:40:23 -05:00
Dave Richer
ba32a71786 - nuke visible from the face of the earth with fire.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-12 17:25:25 -05:00
Dave Richer
7d6e61043e - Change Delete Scheduled jobs to a modal and not a popover
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-12 15:07:52 -05:00
Allan Carr
e7e4c534bc Merged in release/2024-01-12 (pull request #1149)
Release/2024 01 12
2024-01-12 19:59:15 +00:00
Dave Richer
9fc586434e - IO-2684 (Flex issues, taken care of here and a few other places)
- Add Log Rocket on beta.imex.online
- Updated Frontend and Backend npm packages, please do a NPM install on both

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-12 13:58:05 -05:00
Allan Carr
e438fa1d99 Merged in release/2024-01-12 (pull request #1148)
Release/2024 01 12
2024-01-12 18:50:45 +00:00
Allan Carr
4abbf50a46 Merged in feature/IO-2520-Kaizen-Data-Pump (pull request #1145)
IO-2520 Kaizen Data Pump
2024-01-12 18:16:07 +00:00
Dave Richer
ef0bc8c313 Fix Danger Buttons
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-12 12:11:14 -05:00
Dave Richer
aa8a719154 Job Close fixed
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-11 15:58:35 -05:00
Dave Richer
5aa3612e52 Misc Issues
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-11 15:50:13 -05:00
Dave Richer
7d16ae5194 Misc Issues
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-11 15:36:17 -05:00
Dave Richer
663dfe0441 Misc Issues
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-11 15:11:28 -05:00
Dave Richer
49131ba68b fix linting errors
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-11 12:32:51 -05:00
Dave Richer
c2dbdbd6cf Progress Update.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-11 12:24:58 -05:00
Dave Richer
0635c651a2 Progress Update.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-11 12:21:59 -05:00
Dave Richer
05667dd322 Progress Update.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-11 12:19:20 -05:00
Dave Richer
d3654ec16e Progress Update.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-11 01:29:36 -05:00
Dave Richer
ab299619dd Update Packages.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-10 13:32:07 -05:00
Dave Richer
231d20149a Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1147)
Update Packages.
2024-01-10 00:05:51 +00:00
Dave Richer
e9d1f3af67 Update Packages.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-09 19:04:53 -05:00
Dave Richer
dc3d522443 Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1146)
Feature/IO-1828 Front End Package Updates
2024-01-09 23:39:53 +00:00
Dave Richer
46b58a6e1b Fix IO-1828
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-09 17:14:30 -05:00
Allan Carr
3e9279d89a IO-2520 Change Query Time Bound 2024-01-09 12:00:24 -08:00
Allan Carr
1305277c09 IO-2520 Kaizen Data Pump 2024-01-09 11:08:02 -08:00
Dave Richer
3dcc1fe7e0 Merge branch 'master' into feature/IO-1828-Front-End-Package-Updates 2024-01-09 12:29:57 -05:00
Dave Richer
c6012f7335 additional cleanup of kanban utils.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-08 17:32:20 -05:00
Dave Richer
0c7b5087f1 Fix random undocumented bug in kanban utils.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-08 17:28:27 -05:00
Dave Richer
7589f78fe1 Fix for IO-2534
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-08 17:03:24 -05:00
Dave Richer
1b5ee1d07a Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1144)
Feature/IO-1828 Front End Package Updates
2024-01-08 20:45:25 +00:00
Dave Richer
2e589c44a6 Fix IO-2535
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-08 15:44:04 -05:00
Dave Richer
0074c73c2a Fix IO-2537
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-08 15:16:53 -05:00
Allan Carr
3c47c672d4 Merged in feature/IO-2518-Warning-on-VIN-Length (pull request #1143)
IO-2518 Null coalesce for v_vin for warning
2024-01-08 19:18:24 +00:00
Dave Richer
213a02d5f2 Fix IO-2533
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-08 14:11:49 -05:00
Allan Carr
258d99cd41 Merged in release/2024-01-12 (pull request #1142)
IO-2518 Null coalesce for v_vin for warning
2024-01-08 18:41:15 +00:00
Allan Carr
83356fa4ef Merged in feature/IO-2518-Warning-on-VIN-Length (pull request #1141)
IO-2518 Null coalesce for v_vin for warning
2024-01-08 18:40:43 +00:00
Allan Carr
25429e78f8 IO-2518 Null coalesce for v_vin for warning 2024-01-08 10:37:19 -08:00
Dave Richer
6e377f98a7 Fix IO-2538
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-08 12:51:44 -05:00
Dave Richer
3a3b3af13f Merge master
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-08 11:18:22 -05:00
Patrick Fic
ff7523ecb8 Merge branch 'rome/release/2024-01-05' into rome/master 2024-01-05 17:59:27 -08:00
Patrick Fic
b53fdadaee Merge branch 'rome/release/2024-01-05' into rome/test 2024-01-05 17:58:28 -08:00
Patrick Fic
93390bef63 Additional CI fix. 2024-01-05 17:57:23 -08:00
Patrick Fic
485e2ef4f1 Merged in rome/release/2024-01-05 (pull request #1140)
Resolve CI Issues
2024-01-06 01:06:45 +00:00
Patrick Fic
9de3b5efb6 Resolve CI Issues 2024-01-05 17:05:46 -08:00
Patrick Fic
2632282bba Merged in rome/release/2024-01-05 (pull request #1139)
Rome/release/2024 01 05
2024-01-06 00:59:30 +00:00
Patrick Fic
7379f50792 Merged in rome/release/2024-01-05 (pull request #1138)
Rome/release/2024 01 05
2024-01-06 00:56:31 +00:00
Patrick Fic
9ae53d090f Merge branch 'release/2024-01-05' into rome/release/2024-01-05 2024-01-05 16:55:24 -08:00
Allan Carr
de90bd1bb0 Merged in release/2024-01-05 (pull request #1137)
Release/2024 01 05
2024-01-05 22:43:56 +00:00
Allan Carr
aa6cb4c1d2 Merged in release/2024-01-05 (pull request #1136)
IO-2514 Only Unique items in Menu
2024-01-05 21:08:10 +00:00
Allan Carr
e871ba600f Merged in feature/IO-2514-Production-Board-Estimators (pull request #1135)
IO-2514 Only Unique items in Menu
2024-01-05 21:07:36 +00:00
Allan Carr
fe3698980d IO-2514 Only Unique items in Menu 2024-01-05 13:09:15 -08:00
Allan Carr
677c7bb4cc Merged in feature/IO-2522-Load-Level-Report (pull request #1132)
IO-2522 Load Level Report App Side

Approved-by: Patrick Fic
2024-01-05 20:21:41 +00:00
Dave Richer
1f14688199 Update packages
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-05 15:10:45 -05:00
Allan Carr
89b640f71c Merged in release/2024-01-05 (pull request #1133)
Release/2024 01 05
2024-01-05 20:04:10 +00:00
Allan Carr
d13a9cd04a Merged in feature/IO-2522-Load-Level-Table (pull request #1134)
IO-2522 Load Level Table Change
2024-01-05 20:02:26 +00:00
Allan Carr
c0dab92d0e IO-2522 Load Level Table Change 2024-01-05 12:01:47 -08:00
Allan Carr
4fdc241b9c IO-2522 Load Level Report App Side 2024-01-05 10:56:30 -08:00
Dave Richer
bc50f5e983 Fix Tab Icon Spacing.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-05 13:37:54 -05:00
Patrick Fic
1c4879e57b Merge remote-tracking branch 'origin/client-update' into test-beta 2024-01-05 09:44:48 -08:00
Patrick Fic
06ca7603b9 Merged in rome/release/2024-01-05 (pull request #1131)
Rome/release/2024 01 05
2024-01-05 17:05:22 +00:00
Patrick Fic
28dc4867db Remove unnecessary debug button. 2024-01-05 09:02:52 -08:00
Patrick Fic
1cf13da413 Merge branch 'release/2024-01-05' into rome/release/2024-01-05 2024-01-05 09:02:01 -08:00
Patrick Fic
9c897972ad Minor intellipay change. 2024-01-05 08:53:17 -08:00
Allan Carr
307e244475 Merged in feature/IO-2514-Production-Board-Estimators (pull request #1130)
Feature/IO-2514 Production Board Estimators

Approved-by: Dave Richer
2024-01-05 00:57:44 +00:00
Dave Richer
33a1ac9be4 Fix tabs.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-04 16:34:51 -05:00
Dave Richer
2c8d1accea Additional Cleanup on Job Details Header Actions Menu
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-04 16:03:19 -05:00
Dave Richer
351d6f274b Fix / Merge / Rewrite Job Details Header Actions Menu
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-04 15:51:44 -05:00
Dave Richer
e43bfe0d3a Additional Menu Refactors
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-04 13:34:22 -05:00
Dave Richer
61ed0087e7 Additional Menu Refactors
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-04 13:31:44 -05:00
Allan Carr
9d3aca646b IO-2514 Production Board Estimator filter by table data 2024-01-03 10:55:45 -08:00
Allan Carr
e6e61466df Merged in feature/IO-2518-Warning-on-VIN-Length (pull request #1129)
IO-2518 Dealership Vin Warning

Approved-by: Dave Richer
2024-01-02 15:01:51 +00:00
Allan Carr
db7f9fe2ab Merged in feature/IO-2517-All-Courtesy-Car-Warning (pull request #1128)
IO-2517 All Courtesy Car Warning Indicator

Approved-by: Dave Richer
2024-01-02 15:01:22 +00:00
Allan Carr
ded798fdf1 IO-2518 Dealership Vin Warning 2023-12-29 16:37:34 -08:00
Allan Carr
bfe94e3068 IO-2517 Add same check within C/C form 2023-12-29 16:17:37 -08:00
Allan Carr
823f07409a IO-2517 All Courtesy Car Warning Indicator 2023-12-29 16:03:40 -08:00
Allan Carr
1a4bc720c2 Merged in release/2023-12-29 (pull request #1127)
Release/2023 12 29
2023-12-29 22:08:52 +00:00
Allan Carr
73cacdec24 Merged in release/2023-12-29 (pull request #1126)
Release/2023 12 29
2023-12-29 21:29:21 +00:00
Dave Richer
17791ac971 Additional Menu Refactors
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-29 15:34:53 -05:00
Dave Richer
a0cb30f986 Additional Menu Refactors
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-29 15:18:38 -05:00
Dave Richer
07b46ed92b Majority of Dropdown Overlay Menu refactors.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-29 13:26:37 -05:00
Dave Richer
79dce5d069 Allow for Component Token Overrides.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-28 17:33:21 -05:00
Dave Richer
e5d8cc2bea Allow for Component Token Overrides.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-28 15:16:29 -05:00
Dave Richer
7b83430c02 Update both server and client deps
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-28 14:53:19 -05:00
Dave Richer
ed0da08326 Merge branch 'master' into client-update 2023-12-28 14:32:02 -05:00
Allan Carr
18998c4dbe Merged in feature/IO-2489-Regi-#-in-Vehicle-Box (pull request #1125)
IO-2489 Registration # in Vehicle Info Box

Approved-by: Dave Richer
2023-12-28 18:56:27 +00:00
Allan Carr
e236d6e912 IO-2489 Registration # in Vehicle Info Box 2023-12-28 10:57:03 -08:00
Allan Carr
523df670df Merged in feature/IO-2512-Date-Estimated-Manual-Job (pull request #1122)
IO-2512 Date Esimated on Manual Created Jobs

Approved-by: Dave Richer
2023-12-28 18:22:43 +00:00
Allan Carr
ce58181fc3 Merged in feature/IO-2500-Courtesy-Car-Readiness-&-Fuel-Level (pull request #1123)
IO-2500 Readiness and Fuel Level

Approved-by: Dave Richer
2023-12-28 18:21:35 +00:00
Allan Carr
bed0669f73 Merged in feature/IO-2513-Fuel-Level-Tooltip (pull request #1124)
IO-2500 Courtesy Car Readiness

Approved-by: Dave Richer
2023-12-28 18:19:16 +00:00
Allan Carr
b0d077e104 IO-2514 Production Board Estimators 2023-12-28 10:12:59 -08:00
Allan Carr
bdb2951330 IO-2500 Courtesy Car Readiness 2023-12-27 13:55:31 -08:00
Allan Carr
87a01208fb IO-2500 Readiness and Fuel Level 2023-12-27 13:35:29 -08:00
Allan Carr
2daee84fbf IO-2512 Date Esimated on Manual Created Jobs 2023-12-27 11:07:17 -08:00
Allan Carr
cdbf58f3ac Merged in feature/IO-2511-Bill-Label-Reprint (pull request #1121)
IO-2511 Bill Label Reprint

Approved-by: Dave Richer
2023-12-27 16:18:44 +00:00
Allan Carr
f6a59bdf55 IO-2511 Bill Label Reprint 2023-12-26 11:18:39 -08:00
Allan Carr
e12edd977e Merged in release/2023-12-15 (pull request #1120)
Release/2023 12 15

Approved-by: Dave Richer
2023-12-22 18:16:40 +00:00
Allan Carr
ea72d44b42 Merged in release/2023-12-15 (pull request #1119)
IO-2501 Correct for missing query variables
2023-12-22 04:32:06 +00:00
Allan Carr
b925c991eb Merged in feature/IO-2501-Add-Jobs-Completed-Delivered-Not-Invoiced-Section (pull request #1118)
IO-2501 Correct for missing query variables

Approved-by: Dave Richer
2023-12-22 02:33:30 +00:00
Allan Carr
1e7f43fe3d IO-2501 Correct for missing query variables 2023-12-21 18:32:37 -08:00
Dave Richer
c8460f6092 Scoreboard and Dashboard now function as expected!
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-21 19:26:20 -05:00
Dave Richer
d2e4b7d9ec merge test (release pending tomorrow) into client-update and make required changes.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-21 13:12:24 -05:00
Allan Carr
d1b9b5546b Merged in release/2023-12-15 (pull request #1117)
IO-2505 Conversation List Print
2023-12-21 17:39:49 +00:00
Allan Carr
6f21de1901 Merged in feature/IO-2505-Conversation-List-Print (pull request #1116)
IO-2505 Conversation List Print

Approved-by: Dave Richer
2023-12-21 17:37:47 +00:00
Allan Carr
25e8eaa1d4 IO-2505 Conversation List Print 2023-12-21 09:24:25 -08:00
Dave Richer
1c5f74e4f0 Additional stable refactors, redux deprecation, substr deprecation. Clearing stage as to not lose low risk work.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-20 16:30:22 -05:00
Allan Carr
84f0affaed Merged in release/2023-12-15 (pull request #1115)
Release/2023 12 15
2023-12-20 21:04:54 +00:00
Dave Richer
46d514ad1c Patch updates on packages.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-20 15:58:55 -05:00
Allan Carr
6fe736ce06 Merged in feature/IO-1366-Audit-Logging (pull request #1114)
IO-1366 Invoice Job Audit Trail

Approved-by: Dave Richer
2023-12-20 20:44:11 +00:00
Allan Carr
482b03c2d1 IO-1366 Invoice Job Audit Trail 2023-12-20 11:52:04 -08:00
Allan Carr
ce3c72fc47 Merged in feature/IO-1366-Audit-Logging (pull request #1113)
IO-1366 Audit Logging for Production Alert

Approved-by: Dave Richer
2023-12-20 19:38:46 +00:00
Allan Carr
1ff5ed4141 IO-1366 Audit Logging for Production Alert 2023-12-20 11:36:42 -08:00
Allan Carr
fc4b5c6b1d Merged in release/2023-12-15 (pull request #1112)
IO-2506 Correct for variable immutibility and nested ifs
2023-12-19 17:17:16 +00:00
Allan Carr
10e3421572 Merged in feature/IO-2506-Federal-Tax-Exempt-on-Bill-Entry (pull request #1111)
IO-2506 Correct for variable immutibility and nested ifs
2023-12-19 17:16:48 +00:00
Allan Carr
0117237988 IO-2506 Correct for variable immutibility and nested ifs 2023-12-19 09:18:00 -08:00
Allan Carr
2c232a71d5 Merged in release/2023-12-15 (pull request #1110)
Release/2023 12 15
2023-12-19 16:38:10 +00:00
Allan Carr
373fd817d0 Merged in feature/IO-2506-Federal-Tax-Exempt-on-Bill-Entry (pull request #1108)
IO-2506 Federal Tax Exempt on Bill Entry

Approved-by: Dave Richer
2023-12-19 16:34:38 +00:00
Allan Carr
0ef2d9646d Merged in feature/IO-2509-Report-Center-RBAC (pull request #1109)
IO-2509 Report Center RBAC

Approved-by: Dave Richer
2023-12-19 16:32:29 +00:00
Allan Carr
c8ac417200 IO-2509 Report Center RBAC 2023-12-18 14:12:21 -08:00
Allan Carr
661bedbe5b IO-2506 Federal Tax Exempt on Bill Entry
Will Toggle Federal Tax off on any new line or retroactively toggle it off on all lines when switch is enabled. Limited to PBS or CDK setups.
2023-12-18 12:36:46 -08:00
Dave Richer
0514fbe89d even more updates.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-15 12:43:11 -05:00
Dave Richer
87391ff06a even more updates.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-15 12:26:02 -05:00
Dave Richer
b2c8e45d5e even more updates.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-14 16:27:00 -05:00
Dave Richer
1261e8001b Updates
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-14 13:27:58 -05:00
Dave Richer
83e4fb3dc4 Updates
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-14 13:20:43 -05:00
Allan Carr
2dd56590d3 Admin panel to force email addresses to be lowercase to conform with firebase 2023-12-14 08:57:36 -08:00
Dave Richer
a67fb3576c Issues with Scoreboard. Most things check out with dayjs besides that.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-13 19:46:37 -05:00
Dave Richer
65157a094f This is a breaking change, moment is no longer with us, let us have a dayjs of silence.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-13 19:06:15 -05:00
Dave Richer
25173b0903 This marks the Antd upgrades, it is not in a stable state.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-13 16:19:04 -05:00
Allan Carr
98b760251c Merged in feature/IO-2501-Add-Jobs-Completed-Delivered-Not-Invoiced-Section (pull request #1107)
IO-2501 Add Jobs Complete Not Invoiced Section to Stats

Approved-by: Dave Richer
2023-12-13 18:47:04 +00:00
Allan Carr
b97de32a44 IO-2501 Add Jobs Complete Not Invoiced Section to Stats 2023-12-12 15:41:36 -08:00
Dave Richer
64f56d20dd Additional Cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-12 16:13:47 -05:00
Dave Richer
5b3c547316 Additional Cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-12 15:59:54 -05:00
Dave Richer
16d040daf9 Fix prompt, and modal.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-12 15:18:51 -05:00
Dave Richer
a22c4bdf8c Updates, bug fix, prompt refactor
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-12 14:48:37 -05:00
Dave Richer
9cb2a4a021 Update StylizedComponents package, no breaking changes.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2023-12-12 13:54:56 -05:00
Dave Richer
95c9978ee7 Fix found bugs during demo 2023-12-12 13:38:23 -05:00
Dave Richer
fe80256a40 Big progress! 2023-12-12 12:37:50 -05:00
Dave Richer
b0d1a7b65e Big progress! 2023-12-11 19:28:27 -05:00
Dave Richer
ad79344709 Progress 2023-12-11 17:34:05 -05:00
Patrick Fic
3919efaa77 Merged in rome/release/2023-12-01 (pull request #1106)
Rome/release/2023 12 01
2023-12-07 19:33:18 +00:00
Dave Richer
a76fc780cb Merged in rome/release/2023-12-01 (pull request #1105)
Rome/release/2023 12 01

Approved-by: Patrick Fic
2023-12-07 17:46:32 +00:00
Dave Richer
5c164f807d Progress 2023-12-06 17:35:27 -05:00
Dave Richer
a043f7be24 Workbox 2023-12-06 13:21:37 -05:00
Dave Richer
8d9611333c web vitals migration 2023-12-05 15:07:20 -05:00
Dave Richer
02bb2c06eb Cypress migration 2023-12-05 15:01:52 -05:00
Dave Richer
008bcaf41b Cypress migration 2023-12-05 15:01:07 -05:00
Dave Richer
a9dbfbd231 Firebase 2023-12-05 14:56:00 -05:00
Dave Richer
d915c123db Some additional progress / start on updating future deprecations 2023-12-05 13:41:52 -05:00
Dave Richer
1df870ee4e Some additional progress / start on updating future deprecations 2023-12-04 16:48:10 -05:00
Dave Richer
517a087186 Upgrade reselect 2023-12-04 15:08:28 -05:00
Dave Richer
51747c554e Initial Changes 2023-12-04 15:04:00 -05:00
Dave Richer
92c8b54f85 Merged in release/2023-12-01 (pull request #1103)
Reversion

Approved-by: Allan Carr
2023-12-04 16:50:13 +00:00
Dave Richer
d8420f472c Merged in feature/reversion-to-active-jobs-pagination (pull request #1102)
Reversion
2023-12-04 16:40:50 +00:00
Dave Richer
34d93c4de0 Reversion 2023-12-04 11:39:20 -05:00
Dave Richer
1c400cd456 Merged in release/2023-12-01 (pull request #1099)
Release/2023 12 01

Approved-by: Allan Carr
2023-12-01 18:18:23 +00:00
Allan Carr
f8e1758788 Merged in revert-pr-1097 (pull request #1098)
Revert "Revert "Revert "Revert "Fix issues with limits.
2023-12-01 02:37:45 +00:00
Allan Carr
5c95c72f40 Revert "Revert "Revert "Revert "Fix issues with limits. (pull request #1097)" 2023-12-01 02:37:10 +00:00
Allan Carr
98f816b069 Merged in revert-pr-1091 (pull request #1097)
Revert "Revert "Revert "Fix issues with limits.
2023-11-30 20:23:05 +00:00
Allan Carr
3ca6308dd2 Revert "Revert "Revert "Fix issues with limits. (pull request #1091)" 2023-11-30 20:22:42 +00:00
Allan Carr
a2c2aa11ac Merged in release/2023-12-01 (pull request #1096)
Release/2023 12 01
2023-11-30 16:58:33 +00:00
Allan Carr
a3cf97fcab Merged in feature/IO-2485-Fix-onlyFuture-Prop (pull request #1095)
IO-2485 Correct onlyFuture on typed values

Approved-by: Dave Richer
2023-11-30 16:56:57 +00:00
Allan Carr
1a9dc7a377 Merged in feature/IO-2484-Next-Service-KMs (pull request #1094)
IO-2484 Next Service KMs

Approved-by: Dave Richer
2023-11-30 16:55:55 +00:00
Allan Carr
806daebd3f IO-2485 Correct onlyFuture on typed values 2023-11-29 19:51:03 -08:00
Allan Carr
b5b772d0c2 Merged in release/2023-12-01 (pull request #1093)
IO-2465 Adjust Headerfile override and comment out line
2023-11-30 01:16:39 +00:00
Allan Carr
170108b339 Merged in feature/IO-2465-Add-Vehicle-to-Override-Headers (pull request #1092)
IO-2465 Adjust Headerfile override and comment out line
2023-11-30 01:15:53 +00:00
Allan Carr
9f1f58a9c7 IO-2465 Adjust Headerfile override and comment out line 2023-11-29 17:14:39 -08:00
Allan Carr
4d8a2e635c Merged in revert-pr-1090 (pull request #1091)
Revert "Revert "Fix issues with limits.
2023-11-30 00:25:08 +00:00
Allan Carr
0852d55837 Revert "Revert "Fix issues with limits. (pull request #1090)" 2023-11-30 00:22:20 +00:00
Allan Carr
4c38ddf3cd Merged in revert-pr-1089 (pull request #1090)
Revert "Fix issues with limits.
2023-11-29 23:55:28 +00:00
Allan Carr
e15edeadb5 Revert "Fix issues with limits. (pull request #1089)" 2023-11-29 23:54:37 +00:00
Dave Richer
422c7baada Merged in release/2023-12-01 (pull request #1089)
Fix issues with limits.

Approved-by: Allan Carr
2023-11-29 22:30:12 +00:00
Dave Richer
4288e2d986 Merged in feature/IO-2403-Paginated-Active-Jobs (pull request #1088)
Fix issues with limits.
2023-11-29 22:27:49 +00:00
Dave Richer
4b289388bf Fix issues with limits. 2023-11-29 17:27:08 -05:00
Dave Richer
2a2f8e51b3 Merged in release/2023-12-01 (pull request #1087)
Release/2023 12 01

Approved-by: Allan Carr
2023-11-29 21:27:34 +00:00
Dave Richer
ed0136090c Merged in feature/IO-2403-Paginated-Active-Jobs (pull request #1086)
Fix order issue on all jobs
2023-11-29 21:10:56 +00:00
Dave Richer
0d70545b98 Fix order issue on all jobs 2023-11-29 16:10:30 -05:00
Dave Richer
2252091b53 Fix order issue on all jobs 2023-11-29 16:09:20 -05:00
Dave Richer
85b1875a22 Merged in release/2023-12-01 (pull request #1085)
Release/2023 12 01

Approved-by: Allan Carr
2023-11-29 18:59:37 +00:00
Dave Richer
386531884b Merged in feature/IO-2403-Paginated-Active-Jobs (pull request #1068)
Paginated Active Jobs / Pagination refactor
2023-11-29 18:43:00 +00:00
Dave Richer
afbe328aa7 Merged release/2023-12-01 into feature/IO-2403-Paginated-Active-Jobs 2023-11-29 18:40:47 +00:00
Allan Carr
b7c0fba48b Merged in feature/IO-2483-Translation-Update (pull request #1084)
IO-2483 Update Transations

Approved-by: Dave Richer
2023-11-29 18:40:01 +00:00
Allan Carr
68635b1629 Merged in feature/IO-2465-Add-Vehicle-to-Override-Headers (pull request #1083)
IO-2465 Restrict Update of Vehicle on Supplement to Override Header

Approved-by: Dave Richer
2023-11-29 18:39:42 +00:00
Allan Carr
3bd0058dc8 Merged in feature/IO-2481-Parts-Queue-Query (pull request #1082)
Feature/IO-2481 Parts Queue Query

Approved-by: Dave Richer
2023-11-29 18:39:24 +00:00
Allan Carr
270a512585 Merged in feature/IO-2480-Unqueue-Parts-Queue-Label (pull request #1081)
IO-2480 Unqueue Parts Label instead of Remove

Approved-by: Dave Richer
2023-11-29 18:38:49 +00:00
Dave Richer
ec2519eae4 Move PageSize (PageLimit) to an external configuration file. 2023-11-29 13:37:02 -05:00
Dave Richer
d7f52d864a Add Global search to Active Jobs. 2023-11-28 16:05:23 -05:00
Allan Carr
5cb2b3940e IO-2483 Update Transations 2023-11-28 10:08:33 -08:00
Dave Richer
b5efaa944d Merge branch 'master' into feature/IO-2403-Paginated-Active-Jobs 2023-11-28 12:55:00 -05:00
Allan Carr
bbcfc420d2 IO-2465 Restrict Update of Vehicle on Supplement to Override Header 2023-11-27 14:34:36 -08:00
Allan Carr
8ebf7baa71 IO-2481 Parts Queue Query
prettyier
2023-11-27 10:16:10 -08:00
Allan Carr
742d2b5ff2 IO-2481 Parts Queue Query
Adjust query to only show converted Jobs
2023-11-27 10:13:43 -08:00
Allan Carr
f96fefbfdc IO-2480 Unqueue Parts Label instead of Remove
Remove is the uncorrect work as it doesn't actually remove just unqueue
2023-11-27 10:10:02 -08:00
Dave Richer
547b58f05a Merged in release/2023-11-24 (pull request #1079)
Update translations, move configuration toggle for autopartsqueue

Approved-by: Allan Carr
2023-11-24 17:52:32 +00:00
Dave Richer
432aa9f1e1 Progress 2023-11-24 12:34:17 -05:00
Dave Richer
c5bed4f36d Progress 2023-11-24 12:32:59 -05:00
Patrick Fic
151c9c0add Merged in rome/release/2023-11-24 (pull request #1077)
Rome/release/2023 11 24
2023-11-24 12:59:44 +00:00
Allan Carr
334306e3c9 Merged in release/2023-11-24 (pull request #1076)
IO-2438 Remove unneeded imports
2023-11-24 03:14:25 +00:00
Allan Carr
2a7606836c Merged in release/2023-11-24 (pull request #1074)
IO-2438 Adjust Start & End dates for timetickets
2023-11-24 03:11:22 +00:00
Allan Carr
79c966f9e4 Merged in release/2023-11-24 (pull request #1072)
Release/2023 11 24
2023-11-23 23:16:27 +00:00
Dave Richer
65f960db00 Add Margin around the Messaging Icon 2023-11-23 16:58:56 -05:00
Patrick Fic
f14dc497cf Merge branch 'rome/feature/IO-2478-payroll-adjustment-correction' into rome/release/2023-11-24 2023-11-23 09:38:08 -08:00
Patrick Fic
89339e1033 IO-2478 resolve incorrect labor type during conversion calculation. 2023-11-23 09:37:49 -08:00
Patrick Fic
146a61c9cf Merged in rome/test (pull request #1070)
Rome/test
2023-11-23 00:14:54 +00:00
Patrick Fic
5250d97935 Add missing CI change for Node 18. 2023-11-22 16:14:28 -08:00
Patrick Fic
18dce9795d Merge remote-tracking branch 'origin/feature/IO-2460-Node-18-Server' into rome/test 2023-11-22 15:58:10 -08:00
Patrick Fic
7add2bb12e IO-2436 add PPC to bill posting. 2023-11-22 14:36:07 -08:00
Dave Richer
8670f386dc refactors 2023-11-22 17:14:52 -05:00
Allan Carr
54e673176c Merged in release/2023-11-17 (pull request #1059)
IO-2470-CC-Year-b-Make-UI
2023-11-17 19:09:14 +00:00
Patrick Fic
756fc07193 Merged in rome/test (pull request #1057)
Rome/test
2023-11-15 22:45:33 +00:00
Dave Richer
189c60a6d1 Merged in release/2023-11-17 (pull request #1056)
IO-2331 Remove required CC fields Next Service KMS and Next Service Date

Approved-by: Patrick Fic
2023-11-15 22:15:30 +00:00
Dave Richer
a718f2a012 Merged in release/2023-11-17 (pull request #1054)
Release/2023 11 17

Approved-by: Patrick Fic
2023-11-15 21:42:36 +00:00
Patrick Fic
71a5722b0e Merge branch 'feature/america' into rome/test 2023-11-10 15:26:14 -08:00
Patrick Fic
4507135a1b Merge branch 'master' into feature/america 2023-11-10 15:25:47 -08:00
Patrick Fic
7f2479f597 Merge branch 'feature/america' into rome/test 2023-11-06 14:55:49 -08:00
Patrick Fic
66b97be9d2 Merge branch 'master' into feature/america 2023-11-06 14:48:49 -08:00
Allan Carr
57909ebc61 Merged in feature/IO-2425-US-Reconcilliation-Non-Parts-w-$$$ (pull request #1036)
IO-2425 US Reconcilliation for Non-Parts that have Misc amt
2023-10-27 17:20:57 +00:00
Allan Carr
d1090670a8 Merged in feature/IO-2425-US-Reconcilliation-Non-Parts-w-$$$ (pull request #1033)
IO-2425 US Reconciliation for Non-Parts that have Misc amt
2023-10-26 23:18:52 +00:00
Allan Carr
f4bcad1b06 IO-2425 US Reconcilliation for Non-Parts that have Misc amt
Non-part lines that had a Misc_amt where missing from reconciliation also remove any part that didn't have a act_price > 0 and a qty > 0
2023-10-26 16:11:47 -07:00
Patrick Fic
6656708c8e Merged in feature/america (pull request #1031)
Add Rome Support Chat Widget
2023-10-24 17:56:59 +00:00
Patrick Fic
bfe3fb2ed0 Merge branch 'feature/america' into rome/test 2023-10-23 15:22:44 -07:00
Patrick Fic
ec21521281 Add Rome Support Chat Widget 2023-10-23 15:22:33 -07:00
Patrick Fic
e71e671d7d Merge branch 'release/2023-10-20' into rome/test 2023-10-20 13:14:29 -07:00
Patrick Fic
df6b0fae21 Merged in rome/test (pull request #1023)
Improve tax display on totals page.
2023-10-19 15:59:46 +00:00
Patrick Fic
69723a8bf4 Merge branch 'feature/payroll' into rome/test 2023-10-19 08:53:22 -07:00
Patrick Fic
76d907987a Remove unused destructuring. 2023-10-19 08:52:40 -07:00
Patrick Fic
241caa6132 Merge branch 'feature/ems-tax-calculation' into rome/test 2023-10-19 08:50:56 -07:00
Patrick Fic
13b93f6d9d Improve tax display on totals page. 2023-10-19 08:49:05 -07:00
Patrick Fic
77555366f4 Merged in feature/payroll (pull request #1020)
Feature/payroll
2023-10-19 00:29:56 +00:00
Patrick Fic
f3e8132bfc Merged in feature/payroll (pull request #1019)
Improve labor deduction for enhanced payroll.
2023-10-19 00:29:34 +00:00
Patrick Fic
7510385cf4 Merged in feature/payroll (pull request #1018)
Improve labor deduction for enhanced payroll.
2023-10-19 00:29:15 +00:00
Patrick Fic
e05b72615e Improve labor deduction for enhanced payroll. 2023-10-18 17:28:48 -07:00
Patrick Fic
b3f69d4088 Merged in feature/payroll (pull request #1015)
Feature/payroll
2023-10-18 16:52:44 +00:00
Patrick Fic
8796c8fe06 Merged in feature/payroll (pull request #1014)
Feature/payroll
2023-10-18 16:51:50 +00:00
Patrick Fic
b9a6a98fee Resolve deduct from labor calculations. 2023-10-18 09:51:17 -07:00
Patrick Fic
acc9145d52 Enhanced payroll deduct from labor correction. 2023-10-17 10:45:16 -07:00
Patrick Fic
f9c8f53474 Merge branch 'rome/master' into feature/payroll 2023-10-16 12:10:51 -07:00
Patrick Fic
004e96517f Merged in rome/test (pull request #1008)
Rome/test
2023-10-13 15:00:35 +00:00
Patrick Fic
957265b1c8 Merged in feature/ems-tax-calculation (pull request #1007)
Add warning for jobs missing profile information.
2023-10-13 14:57:38 +00:00
Patrick Fic
8807e282f4 Add warning for jobs missing profile information. 2023-10-11 14:44:07 -07:00
Patrick Fic
c394974dc8 Merged in feature/america (pull request #1001)
Add error handling when unable to caclulate job totals.
2023-10-11 18:14:13 +00:00
Patrick Fic
28386a4234 Merged in feature/ems-tax-calculation (pull request #1000)
Add error handling when unable to caclulate job totals.
2023-10-11 18:13:31 +00:00
Patrick Fic
6f16c47d4f Add error handling when unable to caclulate job totals. 2023-10-11 11:13:08 -07:00
Patrick Fic
25062e37f4 Merged in feature/america (pull request #999)
Add taxable overrides to shop configuration.
2023-10-11 17:59:49 +00:00
Patrick Fic
2b1f8e4335 Merged in feature/ems-tax-calculation (pull request #998)
Add taxable overrides to shop configuration.
2023-10-11 17:53:16 +00:00
Patrick Fic
02690b6796 Add taxable overrides to shop configuration. 2023-10-11 10:49:30 -07:00
Patrick Fic
3897281015 Merged in feature/ems-tax-calculation (pull request #997)
Resolved calculations for profile markups and discounts.
2023-10-06 14:58:29 +00:00
Patrick Fic
8d0e5b93ed Merged in feature/ems-tax-calculation (pull request #996)
Resolved calculations for profile markups and discounts.
2023-10-06 14:58:09 +00:00
Patrick Fic
ef146032df Resolved calculations for profile markups and discounts. 2023-10-06 07:57:26 -07:00
Patrick Fic
1dc025fb36 Merged in feature/america (pull request #995)
Remove GST related sections.
2023-10-03 17:47:05 +00:00
Patrick Fic
30c0c84b93 Merged in feature/ems-tax-calculation (pull request #994)
Remove GST related sections.
2023-10-03 17:46:40 +00:00
Patrick Fic
4bd139f93b Remove GST related sections. 2023-09-29 11:08:29 -07:00
Patrick Fic
f59787add0 Merged in feature/america (pull request #993)
Feature/america
2023-09-28 21:19:54 +00:00
Patrick Fic
20c304a2db Merged in feature/ems-tax-calculation (pull request #992)
Feature/ems tax calculation
2023-09-28 21:19:32 +00:00
Patrick Fic
53526d9c80 Add UI elements to Job to new cieca profile fields. 2023-09-28 13:32:01 -07:00
Patrick Fic
68b4bc66ff QB/O Exporting Adjustments 2023-09-28 09:31:32 -07:00
Patrick Fic
805149daea Final adjustments to job totals calculation for 99% accuracy. 2023-09-27 15:16:01 -07:00
Patrick Fic
b2529207e1 Merge branch 'release/2023-09-29' into feature/ems-tax-calculation 2023-09-26 12:59:42 -07:00
Patrick Fic
d2fe9b0590 Updates to QuickBooks and DMS export. 2023-09-26 12:35:49 -07:00
Patrick Fic
eff4f82ad7 Add tax rates to shop config, resolve rate population on job detail. 2023-09-19 15:23:47 -07:00
Patrick Fic
57327332c9 Merged in feature/america (pull request #982)
Feature/america
2023-09-15 19:58:23 +00:00
Patrick Fic
a2144ccb61 Merged in master (pull request #981)
Master
2023-09-15 19:57:46 +00:00
Patrick Fic
aa478fc510 Merge branch 'feature/america' of bitbucket.org:snaptsoft/bodyshop into feature/america 2023-09-15 12:56:45 -07:00
Patrick Fic
659a0bc0fd Updated test.env and circle CI for rome test. 2023-09-15 12:56:31 -07:00
Patrick Fic
f1ef28e544 Updated test.env and circle CI for rome test. 2023-09-15 12:53:53 -07:00
Patrick Fic
fef680fb99 Add labor to tax thresholds. 2023-09-14 15:18:59 -07:00
Patrick Fic
91a45a621a Merged in feature/america (pull request #974)
Feature/america
2023-09-14 18:20:26 +00:00
Patrick Fic
fe9512ca9c Merge branch 'feature/IO-2399-import-status' into feature/america 2023-09-14 11:19:13 -07:00
Patrick Fic
ff318599f5 Add regression check. 2023-09-13 14:55:20 -07:00
Patrick Fic
d1ba90408d Update hazard waste calculation. 2023-09-13 14:39:58 -07:00
Patrick Fic
536f8d9cb9 Add UI elements for part tax and improve calculations. 2023-09-12 14:16:01 -07:00
Patrick Fic
6a9e871b08 Add parts tax calculations. 2023-09-11 20:45:19 -07:00
Patrick Fic
d163d145d0 Merge remote-tracking branch 'origin/release/2023-09-15' into feature/ems-tax-calculation 2023-09-11 11:46:10 -07:00
Patrick Fic
fdf0506976 Merge remote-tracking branch 'origin/master' into feature/america 2023-09-11 11:29:55 -07:00
Patrick Fic
c9d8fc3072 Merged in feature/america (pull request #960)
Improve totals calculation.
2023-08-31 21:31:25 +00:00
Patrick Fic
0bcf67a5f5 Improve totals calculation. 2023-08-31 14:30:49 -07:00
Patrick Fic
3e48753329 Merged in feature/america (pull request #959)
Update US_NE parts calculation using PFL.
2023-08-31 15:31:35 +00:00
Patrick Fic
96441dbb33 Update US_NE parts calculation using PFL. 2023-08-31 08:30:30 -07:00
Patrick Fic
6a0b63b185 Merged in feature/america (pull request #958)
Add US_NE tax calc.
2023-08-31 15:25:21 +00:00
Patrick Fic
9dea43fd34 Add US_NE tax calc. 2023-08-31 08:24:52 -07:00
Patrick Fic
465980dd8c Merged in feature/america (pull request #957)
Feature/america
2023-08-30 16:40:13 +00:00
Patrick Fic
03d04fd8d1 Resolve enter again issue seen only on RO. 2023-08-30 08:49:50 -07:00
Patrick Fic
7d18c9b160 Merge branch 'master' into feature/america 2023-08-30 08:04:57 -07:00
Patrick Fic
c097f98959 Resolve issue when selecting lines. 2023-08-29 14:13:07 -07:00
Patrick Fic
213d4ad928 Add CIECA PFL info. 2023-08-28 12:06:13 -07:00
Patrick Fic
710b3b00f5 Remove parts scanning / critical item highlighting. 2023-08-28 11:18:10 -07:00
Patrick Fic
d041d03fbf Merged in feature/america (pull request #955)
Remove rescue link.
2023-08-28 16:47:23 +00:00
Patrick Fic
24b90e9888 Remove rescue link. 2023-08-28 09:46:02 -07:00
Patrick Fic
4b83e798ac Merged in feature/america (pull request #950)
Remove errant import
2023-08-24 21:50:05 +00:00
Patrick Fic
468f93f3df Remove errant import 2023-08-24 14:47:30 -07:00
Patrick Fic
78d9dd5acb Merged in feature/america (pull request #949)
Resolve UNK mileage from CCC.
2023-08-24 21:47:11 +00:00
Patrick Fic
6ef7d4653d Resolve UNK mileage from CCC. 2023-08-24 14:45:23 -07:00
Patrick Fic
645eb637f2 Merged in feature/america (pull request #948)
Remove Crisp from Rome.
2023-08-24 19:56:10 +00:00
Patrick Fic
268fdce5ac Remove Crisp from Rome. 2023-08-24 12:55:51 -07:00
Patrick Fic
f9f3a05a43 Merged in feature/america (pull request #947)
Feature/america
2023-08-24 18:19:26 +00:00
Patrick Fic
8a92919b2e Merge branch 'feature/payroll' into feature/america 2023-08-24 11:16:41 -07:00
Patrick Fic
dbcd675300 Clear selected lines on assignment. 2023-08-24 11:16:31 -07:00
Patrick Fic
4628af0e43 Merge branch 'feature/payroll' into feature/america 2023-08-24 11:05:22 -07:00
Patrick Fic
b1fedf5904 Resolve treatment misfire. 2023-08-24 11:05:10 -07:00
Patrick Fic
45ec03e615 Add crisp tagging for US users. 2023-08-23 11:20:45 -07:00
Patrick Fic
570d36b695 Remove QBO sandbox. 2023-08-21 16:01:45 -07:00
Patrick Fic
b36697054e Merged in feature/america (pull request #941)
Feature/america
2023-08-18 14:47:57 +00:00
Patrick Fic
17149fe853 Merge branch 'feature/payroll' into feature/america 2023-08-18 07:47:08 -07:00
Allan Carr
15c837f745 IO-2206 Filter Enhanced and Non-Enhanced Payroll Reports 2023-08-16 17:19:37 -07:00
Allan Carr
3f43ff05d0 IO-2206 Enhanced Payroll Reports 2023-08-16 12:12:22 -07:00
Patrick Fic
d4dee21383 Merged in feature/america (pull request #933)
Feature/america
2023-08-14 22:39:18 +00:00
Patrick Fic
79da904767 Merge remote-tracking branch 'origin/master' into feature/america 2023-08-14 15:38:49 -07:00
Patrick Fic
0821797044 Merge branch 'feature/payroll' into feature/america 2023-08-14 15:36:52 -07:00
Patrick Fic
ad7ff62b56 Shift employee cost centers to follow DMS standard. 2023-08-14 15:28:10 -07:00
Patrick Fic
f148d7d0d0 Merged in feature/america (pull request #930)
Resolve dispatch line error.
2023-08-11 17:31:03 +00:00
Patrick Fic
e19e3865e7 Resolve dispatch line error. 2023-08-11 10:30:17 -07:00
Patrick Fic
35f062d4e0 Merged in feature/america (pull request #923)
Remove Zoho.
2023-08-08 20:19:03 +00:00
Patrick Fic
01328ba33c Remove Zoho. 2023-08-08 13:18:39 -07:00
Patrick Fic
7caa138184 Merged in feature/america (pull request #922)
Resolve CI issue.
2023-08-08 19:15:02 +00:00
Patrick Fic
1b8c3f3081 Resolve CI issue. 2023-08-08 12:07:25 -07:00
Patrick Fic
3e4f36fb6f Merged in feature/america (pull request #921)
Feature/america
2023-08-04 20:58:05 +00:00
Patrick Fic
aedcb973f5 Merge branch 'feature/IO-2278-parts-dispatching' into feature/america 2023-08-04 13:57:25 -07:00
Patrick Fic
26dc720929 Add technician side to part dispatching. 2023-08-04 13:24:41 -07:00
Patrick Fic
b5cc1c06df Merge branch 'release/2023-08-11' into feature/IO-2278-parts-dispatching 2023-08-04 12:36:30 -07:00
Patrick Fic
786c790307 WIP Tech Claiming Ability 2023-08-04 12:28:08 -07:00
Patrick Fic
3e8660bb61 Validation and confirmation messages. 2023-08-03 14:14:01 -07:00
Patrick Fic
997aed4ab3 Update RO logos. 2023-08-03 08:42:15 -07:00
Patrick Fic
f64ea058b9 Merged in feature/america (pull request #915)
Feature/america
2023-08-01 22:30:47 +00:00
Patrick Fic
96485ba252 Merge branch 'master' into feature/america 2023-08-01 15:30:26 -07:00
Patrick Fic
a9bdcbcdd4 Merged in feature/payroll (pull request #914)
Add audit trail and resolve status update.
2023-08-01 22:29:49 +00:00
Patrick Fic
1d7f1cccba Add audit trail and resolve status update. 2023-08-01 15:29:19 -07:00
Patrick Fic
b002477c0d Merged in feature/america (pull request #910)
Feature/america
2023-07-28 16:42:01 +00:00
Patrick Fic
27f1447469 Merge branch 'feature/payroll' into feature/america 2023-07-28 09:39:05 -07:00
Patrick Fic
ff153cdd81 Add task name to queries. 2023-07-28 09:34:27 -07:00
Patrick Fic
fe16329443 Add claimed task name to tickets. 2023-07-28 08:22:38 -07:00
Patrick Fic
744e1cf2be Update QBO callback. 2023-07-27 11:41:08 -07:00
Patrick Fic
ab2cf8c8c7 Merge branch 'release/2023-07-28' into feature/payroll 2023-07-27 11:24:31 -07:00
Patrick Fic
fbd001b797 Merged in feature/america (pull request #909)
Feature/america
2023-07-27 15:12:41 +00:00
Patrick Fic
4610be6f15 Merged in master (pull request #908)
Master
2023-07-27 15:11:56 +00:00
Patrick Fic
d5e34b649f Redirect quickbooks to sandbox. 2023-07-27 08:10:22 -07:00
Patrick Fic
7b49a94edd Updated UI and added tech elements. 2023-07-21 13:40:39 -07:00
Patrick Fic
8dfcda6c5e WIP Payroll. 2023-07-21 10:04:44 -07:00
Patrick Fic
756d97a9cb Prevent previously claimed tasks. 2023-07-19 16:42:11 -07:00
Patrick Fic
c0887dbeb9 Merged in feature/america (pull request #897)
Remove Zoho code to fix CSS styling.
2023-07-19 22:45:50 +00:00
Patrick Fic
b8f0ff217f Remove Zoho code to fix CSS styling. 2023-07-19 15:45:07 -07:00
Patrick Fic
cc805781e3 Merged in feature/america (pull request #896)
Feature/america
2023-07-18 20:00:42 +00:00
Patrick Fic
9531eca7a7 Merge branch 'master' into feature/america 2023-07-18 12:59:26 -07:00
Patrick Fic
d7a1d5bbd2 Refactor task claiming and implement basic claim functionality. 2023-07-18 12:59:06 -07:00
Patrick Fic
c214168dcd Establish working version of pay all and labor calculations. 2023-07-17 14:58:28 -07:00
Patrick Fic
dd085be5c7 Updated pay all calculations and introduction of split. 2023-07-13 09:13:45 -07:00
Patrick Fic
bd7fbfff37 WIP Payroll. Added line assignment & begin server side calc. 2023-07-07 15:01:46 -07:00
Allan Carr
52a25fc720 Merged in master (pull request #884)
Master
2023-07-07 19:02:42 +00:00
Patrick Fic
384153d914 Merge branch 'feature/IO-2278-parts-dispatching' into feature/payroll 2023-07-06 15:07:44 -07:00
Patrick Fic
511ac5068b Merge branch 'release/2023-07-07' into feature/payroll 2023-07-06 13:51:31 -07:00
Patrick Fic
67e490ab53 Merge branch 'release/2023-07-07' into feature/payroll 2023-07-06 13:23:25 -07:00
Patrick Fic
b84cde1633 Merge branch 'master' into feature/payroll 2023-07-06 13:04:50 -07:00
Patrick Fic
3350f7bd56 Merge branch 'master' into feature/america 2023-07-06 13:02:29 -07:00
Allan Carr
7510419836 Merged in feature/IO-2302-California-Consumer-Law-Update-1 (pull request #860)
IO-2302 California Consumer Law Update 1

Approved-by: Patrick Fic
2023-06-12 23:37:27 +00:00
Allan Carr
7da3ef4e0c IO-2302 California Consumer Law Update 1
Change label for FIPPA switch
2023-06-12 15:00:17 -07:00
Patrick Fic
4c32171fbb Merged in feature/america (pull request #859)
Feature/america
2023-06-12 19:42:56 +00:00
Patrick Fic
470f178cde Remove "provincial" text references. 2023-06-12 12:42:11 -07:00
Patrick Fic
f9633505a2 Merge branch 'master' into feature/america 2023-06-12 10:05:03 -07:00
Patrick Fic
de102d9898 IO-2278 Parts Dispatching tables & buttons. 2023-06-07 08:25:49 -07:00
Patrick Fic
9d503b12e6 Merged in feature/america (pull request #847)
Feature/america
2023-06-06 23:04:34 +00:00
Patrick Fic
4dc3bc1532 Merge branch 'release/2023-06-09' into feature/IO-2278-parts-dispatching 2023-06-06 13:33:25 -07:00
Patrick Fic
50da8cfbc6 Merge branch 'release/2023-06-09' into feature/IO-2278-parts-dispatching 2023-06-06 13:20:10 -07:00
Patrick Fic
bccfc127f3 Resolve null line desc issue. 2023-06-06 12:26:26 -07:00
Patrick Fic
2332d8756d Resolve password reset issue. 2023-06-06 08:11:28 -07:00
Patrick Fic
a4abaed30a Merged in feature/america (pull request #841)
IO-2294 add parts summary list table.
2023-06-02 21:09:25 +00:00
Patrick Fic
d47e18df1f Merge branch 'feature/IO-2294-parts-summary-list' into feature/america 2023-06-02 14:08:24 -07:00
Patrick Fic
c2d094da35 IO-2294 add parts summary list table. 2023-06-02 14:08:01 -07:00
Patrick Fic
6e54b10239 Merged in feature/america (pull request #839)
Feature/america
2023-06-02 19:21:58 +00:00
Patrick Fic
e6c44ec52a Resolve CI issues. 2023-06-02 09:43:46 -07:00
Patrick Fic
39b8ecf785 IO-2313 Remove part type for secondary CCC lines. 2023-06-02 09:38:54 -07:00
Patrick Fic
d87f871334 Merged in feature/america (pull request #838)
Feature/america
2023-06-02 16:36:40 +00:00
Patrick Fic
07cea56e2b Merged in release/2023-06-02 (pull request #837)
Release/2023 06 02
2023-06-02 16:35:52 +00:00
Patrick Fic
dbf3226f97 Merge branch 'feature/payroll' into feature/america 2023-06-02 09:32:00 -07:00
Patrick Fic
4b926edf24 Merged in feature/america (pull request #831)
Feature/america
2023-06-02 02:04:14 +00:00
Patrick Fic
ce0fd42995 Merge branch 'feature/IO-2310-active-jobs-ro-sort' into feature/america 2023-06-01 18:30:00 -07:00
Patrick Fic
bdf91443e0 IO-2276 Change file handler to adjuster. 2023-06-01 18:13:36 -07:00
Patrick Fic
68f4237e15 IO-2278 Begin parts dispatching including basic items and schema. 2023-06-01 13:27:08 -07:00
Patrick Fic
81fc747c03 Update noticeable link to Rome Online. 2023-05-30 11:31:35 -07:00
Patrick Fic
3a25ed13b9 Merged in feature/america (pull request #825)
Feature/america
2023-05-30 18:19:30 +00:00
Patrick Fic
21c5eb6786 Increase Zoho waiting time. 2023-05-30 11:18:29 -07:00
Patrick Fic
e85203e429 Merge branch 'master' into feature/america 2023-05-29 14:49:13 -07:00
Patrick Fic
6b2d10d589 Zoho changes. 2023-05-26 11:15:50 -07:00
Patrick Fic
3d03de193e Add commit and uncommit functionality. 2023-05-25 15:23:14 -07:00
Patrick Fic
a56de72a6b Time Ticket Task Improvmenets. 2023-05-25 11:44:01 -07:00
Patrick Fic
0849bbbba6 Update translation laberl. 2023-05-25 10:14:17 -07:00
Patrick Fic
0cd41d2036 Merged in feature/america (pull request #792)
Feature/america
2023-05-18 22:00:12 +00:00
Patrick Fic
a93bcd6ab6 Resolve calculation issue for private jobs. 2023-05-17 15:19:11 -07:00
Patrick Fic
77b72e160b Update noticeable widget to Rome Online. 2023-05-17 14:47:06 -07:00
Patrick Fic
b32c37f4af Merged in feature/america (pull request #791)
feature/america

Approved-by: Patrick Fic
2023-05-17 20:49:37 +00:00
Patrick Fic
d0beea5cb3 Merge branch 'release/2023-05-19' into feature/america 2023-05-17 13:49:05 -07:00
Patrick Fic
30df6887c5 Resolve missing intellipay translations. 2023-05-17 12:27:27 -07:00
Patrick Fic
bc7823dda1 Merged in feature/america (pull request #790)
Feature/america
2023-05-17 14:52:41 +00:00
Patrick Fic
cbb195a313 Merge branch 'feature/payroll' into feature/america 2023-05-17 07:51:57 -07:00
Patrick Fic
097dc06c65 Merge branch 'release/2023-05-19' into feature/payroll 2023-05-17 07:51:23 -07:00
Patrick Fic
b06fbd25a0 Add shop config section. 2023-05-17 07:49:25 -07:00
Patrick Fic
89bbf274e5 Merged in release/2023-05-12 (pull request #787)
Release/2023 05 12
2023-05-12 18:18:28 +00:00
Patrick Fic
d854177e5a Merged in feature/america (pull request #774)
Resolve null coalescing when entering bill and add Zoho.
2023-05-10 17:55:26 +00:00
Patrick Fic
aa9f82f2d4 Resolve null coalescing when entering bill and add Zoho. 2023-05-10 10:54:35 -07:00
Patrick Fic
2b45264628 Merged in feature/america (pull request #772)
Feature/america
2023-05-08 15:54:39 +00:00
Patrick Fic
4da299f431 Merged in master (pull request #771)
Master
2023-05-08 15:53:29 +00:00
Patrick Fic
9f9aa447a6 Merged in feature/america (pull request #770)
Update to part price change for CCC.
2023-05-08 15:52:11 +00:00
Patrick Fic
6a9f1597cb Update to part price change for CCC. 2023-05-08 08:51:29 -07:00
Patrick Fic
cddc48b851 Merged in feature/america (pull request #769)
Remove filter on PPC button.
2023-05-08 15:17:35 +00:00
Patrick Fic
84ab6d300c Remove filter on PPC button. 2023-05-08 08:16:50 -07:00
Patrick Fic
3c5026c2fb Merged in feature/america (pull request #755)
Feature/america
2023-05-04 20:54:29 +00:00
Patrick Fic
c3c8959d2e Merge branch 'release/2023-05-05' into feature/america 2023-05-04 13:52:32 -07:00
Patrick Fic
2c459d2636 Merged in feature/america (pull request #747)
Default log rocket on in Rome Production.
2023-05-03 21:52:10 +00:00
Patrick Fic
a33c481dd5 Default log rocket on in Rome Production. 2023-05-03 14:51:51 -07:00
Patrick Fic
d6b2f93e54 Merged in feature/america (pull request #740)
Fresh Chat ID.
2023-05-01 22:40:33 +00:00
Patrick Fic
802e945829 Fresh Chat ID. 2023-05-01 15:39:51 -07:00
Patrick Fic
a4a885f33a Merged in feature/america (pull request #739)
Replace Crisp with FreshChat.
2023-05-01 22:30:35 +00:00
Patrick Fic
3380cebb28 Replace Crisp with FreshChat. 2023-05-01 15:29:37 -07:00
Patrick Fic
21ed415f4f Merged in feature/america (pull request #734)
Feature/america
2023-04-27 22:58:39 +00:00
Patrick Fic
51dd89d36a Merge branch 'feature/payroll' into feature/america 2023-04-27 15:52:37 -07:00
Patrick Fic
bad96f231c Code clean up prior to merge. 2023-04-27 15:51:39 -07:00
Patrick Fic
184d72c444 Merge branch 'release/2023-04-28' into feature/america 2023-04-27 15:21:42 -07:00
Patrick Fic
6ca773050f WIP Payroll Commit process. 2023-04-25 10:24:26 -07:00
Patrick Fic
648e8aaae0 QBO USA Changes for tax and non tax items. 2023-04-24 13:13:32 -07:00
Patrick Fic
ad9868b575 IO-2206 WIP Time Ticket Approval Queue. 2023-04-21 11:23:48 -07:00
Patrick Fic
d4d10998f8 Merge branch 'release/2023-04-21' into feature/payroll 2023-04-20 15:05:48 -07:00
Patrick Fic
ba22c31deb Merged in feature/america (pull request #709)
Feature/america
2023-04-18 20:28:08 +00:00
Patrick Fic
f6be133a78 Merge branch 'feature/payroll' into feature/america 2023-04-18 13:27:02 -07:00
Patrick Fic
3768164f1f IO-2206 Refine claim tasks modal to add validations and insertions. 2023-04-18 13:25:42 -07:00
Patrick Fic
8465e7539f Merge remote-tracking branch 'origin/master' into feature/payroll 2023-04-17 13:12:47 -07:00
Patrick Fic
542eca5867 Claim Tasks WIP. 2023-04-12 12:44:19 -07:00
Patrick Fic
27a67c5f4a Added team pay calculator. 2023-04-06 10:36:29 -07:00
Patrick Fic
e00c40f2d5 Merge branch 'release/2023-04-07' into feature/payroll 2023-04-06 08:10:57 -07:00
Patrick Fic
b664e231dc Merge branch 'release/2023-04-07' into feature/america 2023-04-05 17:23:15 -07:00
Patrick Fic
92d6977f9e Merge branch 'rome/master' of https://bitbucket.org/snaptsoft/bodyshop into rome/master 2023-04-05 15:30:10 -07:00
Patrick Fic
4059700468 Merge branch 'release/2023-04-07' into feature/america 2023-04-05 15:29:36 -07:00
Patrick Fic
196bdd83ba IO-2206 Payroll UI updates for discussions with Rome Clients. 2023-04-05 09:13:37 -07:00
Patrick Fic
fbd52bc14e QB USA Changes 2023-04-04 14:03:08 -07:00
Patrick Fic
8013c988d0 Merged in feature/america (pull request #699)
added the logic for aws secrets manager
2023-03-28 17:17:50 +00:00
Patrick Fic
460d6fcf12 Merge branch 'feature/intellipay' into feature/america 2023-03-28 10:16:51 -07:00
Patrick Fic
92353c4853 Merged in feature/america (pull request #698)
Feature/america
2023-03-28 16:55:36 +00:00
Patrick Fic
8ca2a89f0f Improved totals calculations 2023-03-28 09:54:47 -07:00
Patrick Fic
f54c2367f3 Merge branch 'release/2023-03-24' into feature/america 2023-03-24 08:39:36 -07:00
Patrick Fic
27452085e9 Merge remote-tracking branch 'origin/release/2023-03-24' into feature/america 2023-03-21 09:13:08 -07:00
Patrick Fic
2bff7d9567 Merge branch 'release/2023-03-21' into release/2023-03-24 2023-03-21 09:10:15 -07:00
Patrick Fic
c3749f62fe Updated supplementing mechanism. 2023-03-20 14:56:02 -07:00
Patrick Fic
b82c04a16a Merge branch 'feature/intellipay' into feature/america 2023-03-20 14:11:39 -07:00
Patrick Fic
0ec099cdf5 IO-2217 Part Price Changes for CCC. 2023-03-20 14:10:06 -07:00
Patrick Fic
d3f49094d8 Add ppc field to job lines. 2023-03-20 13:20:43 -07:00
Patrick Fic
4e2ad3bc62 IO-2222 Service Side Generation of part price changes. 2023-03-16 13:33:20 -07:00
Patrick Fic
05c287fcf7 Merged in feature/america (pull request #683)
Additional whitelabel changes.

Approved-by: Patrick Fic
2023-02-27 23:23:52 +00:00
Patrick Fic
c11cef4119 Additional whitelabel changes. 2023-02-27 15:23:14 -08:00
Patrick Fic
d6126cc5ce Merged in feature/america (pull request #681)
feature/america

Approved-by: Patrick Fic
2023-02-25 00:04:44 +00:00
Patrick Fic
d88c925a68 Environment setup and email white labeling. 2023-02-24 16:04:04 -08:00
Patrick Fic
372a572400 Merge branch 'master' into feature/america 2023-02-22 08:06:29 -08:00
Patrick Fic
623ee8fbb1 WIP TotalsUpdates. 2023-02-22 08:02:10 -08:00
Patrick Fic
729e0fc5ca Resolve CI issues. 2023-02-14 16:21:17 -08:00
Patrick Fic
d052cde6ca Add circle ci for Rome. 2023-02-14 16:08:31 -08:00
Patrick Fic
b52bbab903 Updates to landing pages. 2023-02-14 16:03:41 -08:00
Patrick Fic
9d42135ebf Merged in master (pull request #677)
Integrate master into USA branch.
2023-02-14 23:12:48 +00:00
Patrick Fic
9ce5aa2189 Rome Firebase Changes. 2023-02-13 10:09:43 -08:00
Patrick Fic
e277292194 Remove unnecesary firebase deployment items. 2023-02-10 14:29:22 -08:00
Patrick Fic
649961c831 Update API email. 2023-02-10 09:56:35 -08:00
Patrick Fic
e00cde2fbd Merge branch 'release/2023-01-27' into feature/america 2023-01-27 15:33:59 -08:00
Patrick Fic
25b89d191b Futher calculations refinments and QBD testing. 2023-01-26 17:01:12 -08:00
Patrick Fic
0a60f77bfc WIP America 2023-01-26 10:58:35 -08:00
Patrick Fic
66a80e439f Revert all package upgrades to unblock testing. 2023-01-25 11:20:51 -08:00
Patrick Fic
d8cc25a54f Rome whitelabelling. 2023-01-24 14:11:53 -08:00
Patrick Fic
39b9cfb348 Merge branch 'feature/major-package-upgrades' into feature/america 2023-01-24 13:22:10 -08:00
Patrick Fic
c6087574be Resolve master merge conflicts. 2023-01-24 10:56:28 -08:00
Patrick Fic
41c63cbfe9 Improve backwards compatibility for job totals calculations. 2023-01-20 07:59:47 -08:00
Patrick Fic
f1afc81e7d Resolve UI issue. 2023-01-20 07:59:18 -08:00
Patrick Fic
018f8a19bb Merge remote-tracking branch 'origin/feature/major-package-upgrades' into feature/america 2023-01-19 13:23:57 -08:00
Patrick Fic
cccd007ba6 Additional changes for CCC calculations. 2023-01-19 08:58:23 -08:00
Patrick Fic
6d5b8baadf Automatic code mods. 2023-01-17 20:22:03 -08:00
Patrick Fic
07e36415e4 Automatic code mods. 2023-01-17 20:21:49 -08:00
Patrick Fic
8dc480826b Antd package update. 2023-01-17 20:10:59 -08:00
Patrick Fic
533a5b87ec Changing of deprecated antd props. 2023-01-17 20:00:29 -08:00
Patrick Fic
7bd83557c1 Remainder of menu refactoring updates. 2023-01-17 19:48:37 -08:00
Patrick Fic
ef290e79b1 Antd 4.24.x compatibility updates => Menu fixes. 2023-01-17 19:14:31 -08:00
Patrick Fic
713b3f4f6d Documents Gallery Package Fixes 2023-01-17 13:59:44 -08:00
Patrick Fic
8fd9614f69 Package cleanup and upgrades. 2023-01-17 11:41:45 -08:00
Patrick Fic
6682a98770 Merge branch 'master' into feature/major-package-upgrades 2023-01-17 09:43:54 -08:00
Patrick Fic
392b405978 Add massaging of data to CCC import. 2023-01-16 15:54:23 -08:00
Patrick Fic
be61850d18 Merge in latest release. 2023-01-04 11:33:53 -08:00
Patrick Fic
f4208a2212 Client side package updates. 2022-12-22 15:06:10 -08:00
Patrick Fic
0b7278a2a8 Server side upgrades 2022-12-22 12:31:16 -08:00
Patrick Fic
bee078fe18 Add user definted rates to labor misc for autohouse. 2022-12-20 12:38:41 -08:00
1129 changed files with 200954 additions and 147380 deletions

View File

@@ -2,9 +2,9 @@ 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
aws-s3: circleci/aws-s3@4.0.0
aws-cli: circleci/aws-cli@4.0
eb: circleci/aws-elastic-beanstalk@2.0.1
jobs:
api-deploy:
docker:
@@ -18,7 +18,6 @@ jobs:
eb status --verbose
eb deploy
eb status
- jira/notify
hasura-migrate:
docker:
@@ -45,6 +44,58 @@ jobs:
working_directory: ~/repo/client
steps:
- checkout:
path: ~/repo
- run:
name: Install Dependencies
command: npm i
- run: npm run build
- aws-s3/sync:
from: build
to: "s3://imex-online-production/"
arguments: "--exclude '*.map'"
rome-api-deploy:
docker:
- image: "cimg/base:stable"
steps:
- checkout
- eb/setup
- run:
command: |
eb init romeonline-productionapi -r us-east-2 -p "Node.js 18 running on 64bit Amazon Linux 2"
eb status --verbose
eb deploy
eb status
rome-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.romeonline.io/ --admin-secret << parameters.secret >>
hasura metadata apply --endpoint https://db.romeonline.io/ --admin-secret << parameters.secret >>
hasura metadata reload --endpoint https://db.romeonline.io/ --admin-secret << parameters.secret >>
rome-app-build:
docker:
- image: cimg/node:16.15.0
working_directory: ~/repo/client
steps:
- checkout:
path: ~/repo
@@ -66,7 +117,103 @@ jobs:
- aws-s3/sync:
from: build
to: "s3://imex-online-production/"
to: "s3://rome-online-production/"
- jira/notify
test-rome-hasura-migrate:
docker:
- image: cimg/node:16.15.0
parameters:
secret:
type: string
default: $HASURA_ROME_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.romeonline.io/ --admin-secret << parameters.secret >>
hasura metadata apply --endpoint https://db.test.romeonline.io/ --admin-secret << parameters.secret >>
hasura metadata reload --endpoint https://db.test.romeonline.io/ --admin-secret << parameters.secret >>
test-rome-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://rome-online-test/"
- jira/notify
app-beta-build:
docker:
- image: cimg/node:18.18.2
resource_class: large
working_directory: ~/repo/client
steps:
- checkout:
path: ~/repo
- run:
name: Install Dependencies
command: npm i
- run: npm run build
- aws-cli/setup:
aws_access_key_id: AWS_ACCESS_KEY_ID
aws_secret_access_key: AWS_SECRET_ACCESS_KEY
region: AWS_REGION
- aws-s3/sync:
from: build
to: "s3://imex-online-beta/"
arguments: "--exclude '*.map'"
- jira/notify
rome-app-beta-build:
docker:
- image: cimg/node:18.18.2
resource_class: large
working_directory: ~/repo/client
steps:
- checkout:
path: ~/repo
- run:
name: Install Dependencies
command: npm i
- run: npm run build
- aws-s3/sync:
from: build
to: "s3://rome-online-production-beta/"
- jira/notify
test-hasura-migrate:
@@ -98,26 +245,65 @@ jobs:
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
command: npm i
- run: yarn run build:test
- run: npm run build:test
- aws-s3/sync:
from: build
to: "s3://imex-online-test/"
- jira/notify
arguments: "--exclude '*.map'"
test-app-beta-build:
docker:
- image: cimg/node:18.18.2
resource_class: large
working_directory: ~/repo/client
steps:
- checkout:
path: ~/repo
- run:
name: Install Dependencies
command: npm i
- run: npm run build:test
- run: npm run sentry:sourcemaps
- aws-cli/setup:
aws_access_key_id: AWS_ACCESS_KEY_ID
aws_secret_access_key: AWS_SECRET_ACCESS_KEY
region: AWS_REGION
- aws-s3/sync:
from: build
to: "s3://imex-online-test-beta/"
arguments: "--exclude '*.map'"
rome-test-app-beta-build:
docker:
- image: cimg/node:18.18.2
resource_class: large
working_directory: ~/repo/client
steps:
- checkout:
path: ~/repo
- run:
name: Install Dependencies
command: npm i
- run: npm run build:test
- aws-s3/sync:
from: build
to: "s3://rome-online-test-beta/"
admin-app-build:
docker:
@@ -160,20 +346,58 @@ workflows:
filters:
branches:
only: master
- app-beta-build:
filters:
branches:
only: master-beta
- rome-app-beta-build:
filters:
branches:
only: rome/master-beta
- hasura-migrate:
secret: ${HASURA_PROD_SECRET}
filters:
branches:
only: master
- rome-api-deploy:
filters:
branches:
only: rome/master
- rome-app-build:
filters:
branches:
only: rome/master
- rome-hasura-migrate:
secret: ${HASURA_PROD_SECRET}
filters:
branches:
only: rome/master
- test-app-build:
filters:
branches:
only: test
- rome-test-app-beta-build:
filters:
branches:
only: rome/test-beta
- test-app-beta-build:
filters:
branches:
only: test-beta
- test-hasura-migrate:
secret: ${HASURA_TEST_SECRET}
filters:
branches:
only: test
- test-rome-app-build:
filters:
branches:
only: rome/test
- test-rome-hasura-migrate:
secret: ${HASURA_ROME_TEST_SECRET}
filters:
branches:
only: rome/test
#- admin-app-build:
#filters:
#branches:

View File

@@ -8,7 +8,6 @@
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"

1
.vscode/launch.json vendored
View File

@@ -8,7 +8,6 @@
"type": "pwa-chrome",
"webRoot": "${workspaceFolder}/client/src"
},
{
"name": "Chrome",
"type": "chrome",

View File

@@ -6,8 +6,9 @@ npx deadfile ./src/index.js --exclude build templates
#Crushing all hasura migrations by creating a new initialization from the server.
hasura migrate create "Init" --from-server --endpoint https://db.imex.online/ --admin-secret 'Production-ImEXOnline!@#'
hasura migrate apply --version "1620771761757" --skip-execution --endpoint https://db.imex.online/ --admin-secret 'Production-ImEXOnline!@#'
hasura migrate apply --version "1620771761757" --skip-execution --endpoint https://db.imex.online/ --admin-secret '
Production-ImEXOnline!@#'
hasura migrate status --endpoint https://db.imex.online/ --admin-secret 'Production-ImEXOnline!@#'
Generate the license file:
Generate the license file:
$ generate-license-file --input package.json --output third-party-licenses.txt --overwrite

View File

@@ -1,5 +1,4 @@
Ensure following environment variables are set:
Ensure following environment variables are set:
__S3 Related__
AWSAccessKeyId=

View File

@@ -16,9 +16,11 @@ jsreport configure
sudo apt-get install -y libgconf-2-4
sudo wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >>
/etc/apt/sources.list.d/google.list'
sudo apt-get update
sudo apt-get install -y google-chrome-unstable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst --no-install-recommends
sudo apt-get install -y google-chrome-unstable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst
--no-install-recommends
# on ubuntu 20 run also

View File

@@ -6,7 +6,9 @@
</div>
_I recommend [Mrm](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-jest) and [jest-codemods](https://github.com/skovhus/jest-codemods) for single-command Jest installation and easy migration from other frameworks._
_I recommend [Mrm](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm-task-jest)
and [jest-codemods](https://github.com/skovhus/jest-codemods) for single-command Jest installation and easy migration
from other frameworks._
<!-- To reformat run: npx prettier --print-width 100 --single-quote --no-semi --prose-wrap never --write Readme.md -->
@@ -16,31 +18,31 @@ _I recommend [Mrm](https://github.com/sapegin/mrm-tasks/tree/master/packages/mrm
- [Test structure](#test-structure)
- [Matchers](#matchers)
- [Basic matchers](#basic-matchers)
- [Truthiness](#truthiness)
- [Numbers](#numbers)
- [Strings](#strings)
- [Arrays](#arrays)
- [Objects](#objects)
- [Exceptions](#exceptions)
- [Snapshots](#snapshots)
- [Mock functions](#mock-functions)
- [Misc](#misc)
- [Promise matchers (Jest 20+)](#promise-matchers-jest-20)
- [Basic matchers](#basic-matchers)
- [Truthiness](#truthiness)
- [Numbers](#numbers)
- [Strings](#strings)
- [Arrays](#arrays)
- [Objects](#objects)
- [Exceptions](#exceptions)
- [Snapshots](#snapshots)
- [Mock functions](#mock-functions)
- [Misc](#misc)
- [Promise matchers (Jest 20+)](#promise-matchers-jest-20)
- [Async tests](#async-tests)
- [async/await](#asyncawait)
- [Promises](#promises)
- [done() callback](#done-callback)
- [async/await](#asyncawait)
- [Promises](#promises)
- [done() callback](#done-callback)
- [Mocks](#mocks)
- [Mock functions](#mock-functions-1)
- [Mock modules using jest.mock method](#mock-modules-using-jestmock-method)
- [Mock modules using a mock file](#mock-modules-using-a-mock-file)
- [Mock object methods](#mock-object-methods)
- [Mock getters and setters (Jest 22.1.0+)](#mock-getters-and-setters-jest-2210)
- [Mock getters and setters](#mock-getters-and-setters)
- [Clearing and restoring mocks](#clearing-and-restoring-mocks)
- [Accessing the original module when using mocks](#accessing-the-original-module-when-using-mocks)
- [Timer mocks](#timer-mocks)
- [Mock functions](#mock-functions-1)
- [Mock modules using jest.mock method](#mock-modules-using-jestmock-method)
- [Mock modules using a mock file](#mock-modules-using-a-mock-file)
- [Mock object methods](#mock-object-methods)
- [Mock getters and setters (Jest 22.1.0+)](#mock-getters-and-setters-jest-2210)
- [Mock getters and setters](#mock-getters-and-setters)
- [Clearing and restoring mocks](#clearing-and-restoring-mocks)
- [Accessing the original module when using mocks](#accessing-the-original-module-when-using-mocks)
- [Timer mocks](#timer-mocks)
- [Data-driven tests (Jest 23+)](#data-driven-tests-jest-23)
- [Skipping tests](#skipping-tests)
- [Testing modules with side effects](#testing-modules-with-side-effects)
@@ -205,8 +207,8 @@ expect(fn.mock.calls[0][0]).toBe(2) // fn.mock.calls[0][0] — the first argumen
- `nthCalledWith``toHaveBeenNthCalledWith`
- `toReturnTimes``toHaveReturnedTimes`
- `toReturnWith``toHaveReturnedWith`
- `lastReturnedWith` `toHaveLastReturnedWith`
- `nthReturnedWith` `toHaveNthReturnedWith`
- `lastReturnedWith``toHaveLastReturnedWith`
- `nthReturnedWith``toHaveNthReturnedWith`
</details>
### Misc
@@ -244,7 +246,8 @@ test('resolve to lemon', async () => {
See [more examples](https://facebook.github.io/jest/docs/en/tutorial-async.html) in Jest docs.
Its a good practice to specify a number of expected assertions in async tests, so the test will fail if your assertions werent called at all.
Its a good practice to specify a number of expected assertions in async tests, so the test will fail if your assertions
werent called at all.
```js
test('async test', () => {
@@ -343,23 +346,25 @@ jest.mock('lodash/memoize', () => a => a, { virtual: true }) // The original lod
[jest.mock docs](https://facebook.github.io/jest/docs/jest-object.html#jestmockmodulename-factory-options)
> Note: When using `babel-jest`, calls to `jest.mock` will automatically be hoisted to the top of the code block. Use `jest.doMock` if you want to explicitly avoid this behavior.
> Note: When using `babel-jest`, calls to `jest.mock` will automatically be hoisted to the top of the code block.
> Use `jest.doMock` if you want to explicitly avoid this behavior.
### Mock modules using a mock file
1. Create a file like `__mocks__/lodash/memoize.js`:
1. Create a file like `__mocks__/lodash/memoize.js`:
```js
module.exports = a => a
```
```js
module.exports = a => a
```
2. Add to your test:
2. Add to your test:
```js
jest.mock('lodash/memoize')
```
```js
jest.mock('lodash/memoize')
```
> Note: When using `babel-jest`, calls to `jest.mock` will automatically be hoisted to the top of the code block. Use `jest.doMock` if you want to explicitly avoid this behavior.
> Note: When using `babel-jest`, calls to `jest.mock` will automatically be hoisted to the top of the code block.
> Use `jest.doMock` if you want to explicitly avoid this behavior.
[Manual mocks docs](https://facebook.github.io/jest/docs/manual-mocks.html)
@@ -407,7 +412,7 @@ fn.mockReset() // Clears and removes any mocked return values or implementations
fn.mockRestore() // Resets and restores the initial implementation
```
> Note: `mockRestore` works only with mocks created by `jest.spyOn`.
> Note: `mockRestore`works only with mocks created by `jest.spyOn`.
For all mocks:
@@ -427,7 +432,8 @@ const fs = require.requireActual('fs') // Original module
### Timer mocks
Write synchronous test for code that uses native timer functions (`setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`).
Write synchronous test for code that uses native timer
functions (`setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`).
```js
// Enable fake timers
@@ -471,7 +477,7 @@ test.each`
})
```
Or on `describe` level:
Or on `describe` level:
```js
describe.each([['mobile'], ['tablet'], ['desktop']])('checkout flow on %s', (viewport) => {
@@ -481,7 +487,7 @@ describe.each([['mobile'], ['tablet'], ['desktop']])('checkout flow on %s', (vie
})
```
[describe.each() docs](https://jestjs.io/docs/en/api.html#describeeachtablename-fn-timeout), [test.each() docs](https://jestjs.io/docs/en/api.html#testeachtablename-fn-timeout),
[describe.each() docs](https://jestjs.io/docs/en/api.html#describeeachtablename-fn-timeout), [test.each() docs](https://jestjs.io/docs/en/api.html#testeachtablename-fn-timeout),
## Skipping tests
@@ -501,7 +507,8 @@ tests.only('make each pony pink'...
## Testing modules with side effects
Node.js and Jest will cache modules you `require`. To test modules with side effects youll need to reset the module registry between tests:
Node.js and Jest will cache modules you `require`. To test modules with side effects youll need to reset the module
registry between tests:
```js
const modulePath = '../module-to-test'
@@ -525,7 +532,8 @@ test('second text', () => {
## Usage with Babel and TypeScript
Add [babel-jest](https://github.com/facebook/jest/tree/master/packages/babel-jest) or [ts-jest](https://github.com/kulshekhar/ts-jest). Check their docs for installation instructions.
Add [babel-jest](https://github.com/facebook/jest/tree/master/packages/babel-jest)
or [ts-jest](https://github.com/kulshekhar/ts-jest). Check their docs for installation instructions.
## Resources
@@ -536,10 +544,14 @@ Add [babel-jest](https://github.com/facebook/jest/tree/master/packages/babel-jes
- [Effective Snapshot Testing](https://blog.kentcdodds.com/effective-snapshot-testing-e0d1a2c28eca) by Kent C. Dodds
- [Migrating to Jest](https://medium.com/@kentcdodds/migrating-to-jest-881f75366e7e#.pc4s5ut6z) by Kent C. Dodds
- [Migrating AVA to Jest](http://browniefed.com/blog/migrating-ava-to-jest/) by Jason Brown
- [How to Test React and MobX with Jest](https://semaphoreci.com/community/tutorials/how-to-test-react-and-mobx-with-jest) by Will Stern
- [Testing React Intl components with Jest and Enzyme](https://medium.com/@sapegin/testing-react-intl-components-with-jest-and-enzyme-f9d43d9c923e) by Artem Sapegin
- [Testing with Jest: 15 Awesome Tips and Tricks](https://medium.com/@stipsan/testing-with-jest-15-awesome-tips-and-tricks-42150ec4c262) by Stian Didriksen
- Taking Advantage of Jest Matchers by Ben McCormick: [Part 1](https://benmccormick.org/2017/08/15/jest-matchers-1/), [Part 2](https://benmccormick.org/2017/09/04/jest-matchers-2/)
- [How to Test React and MobX with Jest](https://semaphoreci.com/community/tutorials/how-to-test-react-and-mobx-with-jest)
by Will Stern
- [Testing React Intl components with Jest and Enzyme](https://medium.com/@sapegin/testing-react-intl-components-with-jest-and-enzyme-f9d43d9c923e)
by Artem Sapegin
- [Testing with Jest: 15 Awesome Tips and Tricks](https://medium.com/@stipsan/testing-with-jest-15-awesome-tips-and-tricks-42150ec4c262)
by Stian Didriksen
- Taking Advantage of Jest Matchers by Ben
McCormick: [Part 1](https://benmccormick.org/2017/08/15/jest-matchers-1/), [Part 2](https://benmccormick.org/2017/09/04/jest-matchers-2/)
---
@@ -559,6 +571,8 @@ This software has been developed with lots of coffee, buy me one more cup to kee
## Author and license
[Artem Sapegin](http://sapegin.me/), a frontend engineer at [Omio](https://omio.com/) and the creator of [React Styleguidist](https://react-styleguidist.js.org/). I also write about frontend at [my blog](https://blog.sapegin.me/).
[Artem Sapegin](http://sapegin.me/), a frontend engineer at [Omio](https://omio.com/) and the creator
of [React Styleguidist](https://react-styleguidist.js.org/). I also write about frontend
at [my blog](https://blog.sapegin.me/).
CC0 1.0 Universal license, see the included [License.md](/License.md) file.

View File

@@ -46,7 +46,8 @@ $ hasura migrate create "init" --from-server
## mark the migration as applied on this server
$ hasura migrate apply --version "<version>" --skip-execution
If you are using schemas other than public, use --schema "schema_name" flag to indicate each one of them in the create command. This flag can be used multiple times. See more details about the usage in the docs.
If you are using schemas other than public, use --schema "schema_name" flag to indicate each one of them in the create
command. This flag can be used multiple times. See more details about the usage in the docs.
Step 4: Verify the status
Execute the following command to verify status of migration:
@@ -54,4 +55,5 @@ Execute the following command to verify status of migration:
$ hasura migrate status
You have brand new migrations now!
This can also be used to combine (kind of squash) all of your migration files into a single one. You're snapshotting the state of a server and adding it as a new migration.
This can also be used to combine (kind of squash) all of your migration files into a single one. You're snapshotting the
state of a server and adding it as a new migration.

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:for-each select="//TranslatedData">
<xsl:element name="TranslatedData">
@@ -8,23 +8,23 @@
</xsl:attribute>
<xsl:choose>
<xsl:when test="Details/@PrgID">
<xsl:copy-of select="Details" />
<xsl:copy-of select="Details"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="Details">
<xsl:attribute name="PrgID">OECTrans.ImportTrans</xsl:attribute>
<xsl:for-each select="Details/@*">
<xsl:copy-of select="." />
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:for-each select="Details/*">
<xsl:copy-of select="." />
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
<xsl:element name="Header">
<xsl:attribute name="RONum">
<xsl:value-of select="//Envelope/@RONum" />
<xsl:value-of select="//Envelope/@RONum"/>
</xsl:attribute>
<xsl:attribute name="OwnerFName">
<xsl:value-of select="//Admin/@OwnerF"/>
@@ -33,49 +33,49 @@
<xsl:value-of select="//Admin/@OwnerL"/>
</xsl:attribute>
<xsl:attribute name="VIN">
<xsl:value-of select="//Vehicle/@TransVIN" />
<xsl:value-of select="//Vehicle/@TransVIN"/>
</xsl:attribute>
<xsl:attribute name="Mileage">
<xsl:value-of select="//Vehicle/@TransMileage" />
<xsl:value-of select="//Vehicle/@TransMileage"/>
</xsl:attribute>
<xsl:attribute name="Year">
<xsl:value-of select="//Vehicle/@TransYear" />
<xsl:value-of select="//Vehicle/@TransYear"/>
</xsl:attribute>
<xsl:attribute name="Make">
<xsl:if test="//Vehicle/@ManufName[. != '']" >
<xsl:if test="//Vehicle/@ManufName[. != '']">
<xsl:choose>
<xsl:when test="//Vehicle/@ManufName[. = 'Geo']">CHEV</xsl:when>
<xsl:when test="//Vehicle/@ManufName[. = 'Chev-GMC Truck']">CHEV</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Vehicle/@ManufName" />
<xsl:value-of select="//Vehicle/@ManufName"/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:if test="//Vehicle/@ManufName[. = '']" >
<xsl:value-of select="//Vehicle/@ManufCode" />
<xsl:if test="//Vehicle/@ManufName[. = '']">
<xsl:value-of select="//Vehicle/@ManufCode"/>
</xsl:if>
</xsl:attribute>
<xsl:attribute name="Model">
<xsl:value-of select="//Vehicle/@TransModel" />
<xsl:value-of select="//Vehicle/@TransModel"/>
</xsl:attribute>
<xsl:attribute name="Description">
<xsl:value-of select="//Vehicle/@TransYear" />
<xsl:text> </xsl:text>
<xsl:value-of select="//Vehicle/@ManufName" />
<xsl:text> </xsl:text>
<xsl:value-of select="//Vehicle/@TransModel" />
<xsl:value-of select="//Vehicle/@TransYear"/>
<xsl:text></xsl:text>
<xsl:value-of select="//Vehicle/@ManufName"/>
<xsl:text></xsl:text>
<xsl:value-of select="//Vehicle/@TransModel"/>
</xsl:attribute>
<xsl:attribute name="LastSupplLevel">
<xsl:choose>
<xsl:when test="//Envelope/@TransactionType = 'E'">0</xsl:when>
<xsl:when test="substring(//Envelope/@SupplementNum, 1, 1) = 'S'">
<xsl:value-of select="substring(//Envelope/@SupplementNum, 2)" />
<xsl:value-of select="substring(//Envelope/@SupplementNum, 2)"/>
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:element>
<xsl:apply-templates select="PartsList" />
<xsl:apply-templates select="PartsList"/>
<xsl:element name="Envelope">
<xsl:element name="Software">
<xsl:attribute name="Manifest">Audatex.xml</xsl:attribute>
@@ -96,10 +96,13 @@
<xsl:value-of select="//Envelope/@UniqueFileID"/>
</xsl:attribute>
<xsl:attribute name="EstimateID">
<xsl:value-of select="//Envelope/@EstimatingSystem"/>-<xsl:value-of select="//Envelope/@SoftwareVersion"/>-<xsl:value-of select="//Envelope/@UniqueFileID"/>
<xsl:value-of select="//Envelope/@EstimatingSystem"/>-<xsl:value-of
select="//Envelope/@SoftwareVersion"/>-
<xsl:value-of select="//Envelope/@UniqueFileID"/>
</xsl:attribute>
<xsl:attribute name="EstimateIDv2">
<xsl:value-of select="//Envelope/@EstimatingSystem"/>-<xsl:value-of select="//Envelope/@UniqueFileID"/>
<xsl:value-of select="//Envelope/@EstimatingSystem"/>-
<xsl:value-of select="//Envelope/@UniqueFileID"/>
</xsl:attribute>
<xsl:attribute name="EstimateFormatVersion">
<xsl:value-of select="//Envelope/@EMSVersion"/>
@@ -107,9 +110,9 @@
</xsl:element>
</xsl:element>
<xsl:element name="Totals">
<xsl:attribute name="GrandTotalAmount">
<xsl:value-of select="//Total/@GrandTotalAmount"/>
</xsl:attribute>
<xsl:attribute name="GrandTotalAmount">
<xsl:value-of select="//Total/@GrandTotalAmount"/>
</xsl:attribute>
</xsl:element>
<xsl:element name="Administrative">
<xsl:element name="Owner">
@@ -220,7 +223,8 @@
<xsl:choose>
<xsl:when test="string-length(substring-before(//Admin/@InsuranceZip, '-'))=5">
<xsl:choose>
<xsl:when test="string-length(substring-after(//Admin/@InsuranceZip, '-'))=4">
<xsl:when
test="string-length(substring-after(//Admin/@InsuranceZip, '-'))=4">
<xsl:value-of select="//Admin/@InsuranceZip"/>
</xsl:when>
<xsl:otherwise>
@@ -231,7 +235,8 @@
</xsl:choose>
</xsl:when>
<xsl:when test="string-length(//Admin/@InsuranceZip)=9">
<xsl:value-of select="substring(//Admin/@InsuranceZip, 1, 5)"/>-<xsl:value-of select="substring(//Admin/@InsuranceZip, 6, 4)"/>
<xsl:value-of select="substring(//Admin/@InsuranceZip, 1, 5)"/>-
<xsl:value-of select="substring(//Admin/@InsuranceZip, 6, 4)"/>
</xsl:when>
<xsl:when test="string-length(//Admin/@InsuranceZip)&gt;4">
<xsl:value-of select="substring(//Admin/@InsuranceZip, 1, 5)"/>
@@ -244,7 +249,8 @@
<xsl:attribute name="Phone">
<xsl:choose>
<xsl:when test="//Admin/@InsurancePhone1Ext[. != '']">
<xsl:value-of select="//Admin/@InsurancePhone1"/>&#32;x<xsl:value-of select="//Admin/@InsurancePhone1Ext"/>
<xsl:value-of select="//Admin/@InsurancePhone1"/>&#32;x
<xsl:value-of select="//Admin/@InsurancePhone1Ext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin/@InsurancePhone1"/>
@@ -254,7 +260,8 @@
<xsl:attribute name="Phone2">
<xsl:choose>
<xsl:when test="//Admin/@InsurancePhone2Ext[. != '']">
<xsl:value-of select="//Admin/@InsurancePhone2"/>&#32;x<xsl:value-of select="//Admin/@InsurancePhone2Ext"/>
<xsl:value-of select="//Admin/@InsurancePhone2"/>&#32;x
<xsl:value-of select="//Admin/@InsurancePhone2Ext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin/@InsurancePhone2"/>
@@ -264,7 +271,8 @@
<xsl:attribute name="Fax">
<xsl:choose>
<xsl:when test="//Admin/@InsuranceFaxExt[. != '']">
<xsl:value-of select="//Admin/@InsuranceFax"/>&#32;x<xsl:value-of select="//Admin/@InsuranceFaxExt"/>
<xsl:value-of select="//Admin/@InsuranceFax"/>&#32;x
<xsl:value-of select="//Admin/@InsuranceFaxExt"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin/@InsuranceFax"/>
@@ -277,7 +285,7 @@
</xsl:element>
<xsl:element name="Insured">
<xsl:attribute name="LastName">
<xsl:value-of select="//Admin/@InsuranceLName" />
<xsl:value-of select="//Admin/@InsuranceLName"/>
</xsl:attribute>
</xsl:element>
<xsl:element name="Claim">
@@ -319,7 +327,8 @@
<xsl:choose>
<xsl:when test="string-length(substring-before(//Admin2/@EstimatorZip, '-'))=5">
<xsl:choose>
<xsl:when test="string-length(substring-after(//Admin2/@EstimatorZip, '-'))=4">
<xsl:when
test="string-length(substring-after(//Admin2/@EstimatorZip, '-'))=4">
<xsl:value-of select="//Admin2/@EstimatorZip"/>
</xsl:when>
<xsl:otherwise>
@@ -330,7 +339,8 @@
</xsl:choose>
</xsl:when>
<xsl:when test="string-length(//Admin2/@EstimatorZip)=9">
<xsl:value-of select="substring(//Admin2/@EstimatorZip, 1, 5)"/>-<xsl:value-of select="substring(//Admin2/@EstimatorZip, 6, 4)"/>
<xsl:value-of select="substring(//Admin2/@EstimatorZip, 1, 5)"/>-
<xsl:value-of select="substring(//Admin2/@EstimatorZip, 6, 4)"/>
</xsl:when>
<xsl:when test="string-length(//Admin2/@EstimatorZip)&gt;4">
<xsl:value-of select="substring(//Admin2/@EstimatorZip, 1, 5)"/>
@@ -343,7 +353,8 @@
<xsl:attribute name="Phone">
<xsl:choose>
<xsl:when test="//Admin2/@EstimatorPhone1Ext[. != '']">
<xsl:value-of select="//Admin2/@EstimatorPhone1"/>&#32;x<xsl:value-of select="//Admin2/@EstimatorPhone1Ext"/>
<xsl:value-of select="//Admin2/@EstimatorPhone1"/>&#32;x
<xsl:value-of select="//Admin2/@EstimatorPhone1Ext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin2/@EstimatorPhone1"/>
@@ -353,7 +364,8 @@
<xsl:attribute name="Phone2">
<xsl:choose>
<xsl:when test="//Admin2/@EstimatorPhone2Ext[. != '']">
<xsl:value-of select="//Admin2/@EstimatorPhone2"/>&#32;x<xsl:value-of select="//Admin2/@EstimatorPhone2Ext"/>
<xsl:value-of select="//Admin2/@EstimatorPhone2"/>&#32;x
<xsl:value-of select="//Admin2/@EstimatorPhone2Ext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin2/@EstimatorPhone2"/>
@@ -363,7 +375,8 @@
<xsl:attribute name="Fax">
<xsl:choose>
<xsl:when test="//Admin2/@EstimatorFaxExt[. != '']">
<xsl:value-of select="//Admin2/@EstimatorFax"/>&#32;x<xsl:value-of select="//Admin2/@EstimatorFaxExt"/>
<xsl:value-of select="//Admin2/@EstimatorFax"/>&#32;x
<xsl:value-of select="//Admin2/@EstimatorFaxExt"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin2/@EstimatorFax"/>
@@ -379,7 +392,8 @@
<xsl:if test="string-length(//Admin2/@VehicleInDate)&gt;6">
<xsl:value-of select="substring-before(//Admin2/@VehicleInDate, ' ')"/>
<xsl:if test="string-length(//Admin2/@VehicleInTime)=4">
&#32;<xsl:value-of select="substring(//Admin2/@VehicleInTime, 1, 2)"/>:<xsl:value-of select="substring(//Admin2/@VehicleInTime, 3, 2)"/>
&#32;<xsl:value-of select="substring(//Admin2/@VehicleInTime, 1, 2)"/>:
<xsl:value-of select="substring(//Admin2/@VehicleInTime, 3, 2)"/>
</xsl:if>
</xsl:if>
</xsl:attribute>
@@ -387,7 +401,8 @@
<xsl:if test="string-length(//Admin2/@TargetVehicleOutDate)&gt;6">
<xsl:value-of select="substring-before(//Admin2/@TargetVehicleOutDate,' ')"/>
<xsl:if test="string-length(//Admin2/@TargetVehicleOutTime)=4">
&#32;<xsl:value-of select="substring(//Admin2/@TargetVehicleOutTime, 1, 2)"/>:<xsl:value-of select="substring(//Admin2/@TargetVehicleOutTime, 3, 2)"/>
&#32;<xsl:value-of select="substring(//Admin2/@TargetVehicleOutTime, 1, 2)"/>:
<xsl:value-of select="substring(//Admin2/@TargetVehicleOutTime, 3, 2)"/>
</xsl:if>
</xsl:if>
</xsl:attribute>
@@ -395,7 +410,8 @@
<xsl:if test="string-length(//Admin2/@VehicleOutDate)&gt;6">
<xsl:value-of select="substring-before(//Admin2/@VehicleOutDate, ' ')"/>
<xsl:if test="string-length(//Admin2/@VehicleOutTime)=4">
&#32;<xsl:value-of select="substring(//Admin2/@VehicleOutTime, 1, 2)"/>:<xsl:value-of select="substring(//Admin2/@VehicleOutTime, 3, 2)"/>
&#32;<xsl:value-of select="substring(//Admin2/@VehicleOutTime, 1, 2)"/>:
<xsl:value-of select="substring(//Admin2/@VehicleOutTime, 3, 2)"/>
</xsl:if>
</xsl:if>
</xsl:attribute>
@@ -405,16 +421,16 @@
</xsl:for-each>
</xsl:template>
<xsl:template match="PartsList">
<xsl:element name="PartsList" >
<xsl:element name="PartsList">
<xsl:for-each select="Part">
<xsl:element name="Part" >
<xsl:element name="Part">
<!-- Part number translation rules -->
<xsl:variable name="OEMPartNumber">
<xsl:if test="substring(@TDPartNum, string-length(@TDPartNum) - 7) != ' GM PART'">
<xsl:value-of select="@TDPartNum" />
<xsl:value-of select="@TDPartNum"/>
</xsl:if>
<xsl:if test="substring(@TDPartNum, string-length(@TDPartNum) - 7) = ' GM PART'">
<xsl:value-of select="substring-before(@TDPartNum,' GM PART')" />
<xsl:value-of select="substring-before(@TDPartNum,' GM PART')"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="AltPartNumber">
@@ -457,20 +473,22 @@
<xsl:value-of select="$PrimaryPartNumber"/>
</xsl:attribute>
<xsl:attribute name="AltPartNum">
<xsl:value-of select="$SecondaryPartNumber" />
<xsl:value-of select="$SecondaryPartNumber"/>
</xsl:attribute>
<xsl:attribute name="ExternalPartType">
<xsl:value-of select="$PrimaryPartType" />
<xsl:value-of select="$PrimaryPartType"/>
</xsl:attribute>
<xsl:attribute name="ExternalAltPartType">
<xsl:value-of select="$SecondaryPartType" />
<xsl:value-of select="$SecondaryPartType"/>
</xsl:attribute>
<xsl:attribute name="TDPartType">
<xsl:choose>
<xsl:when test="$PrimaryPartType='PAN' or $PrimaryPartType='PAP'">1</xsl:when>
<xsl:when test="$PrimaryPartType='PAA' or $PrimaryPartType='PATR'">2</xsl:when>
<xsl:when test="$PrimaryPartType='PAL'">3</xsl:when>
<xsl:when test="$PrimaryPartType='PAM' or $PrimaryPartType='PAC' or $PrimaryPartType='PAR'">4</xsl:when>
<xsl:when test="$PrimaryPartType='PAM' or $PrimaryPartType='PAC' or $PrimaryPartType='PAR'">
4
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
@@ -479,64 +497,67 @@
<xsl:when test="$SecondaryPartType='PAN'">1</xsl:when>
<xsl:when test="$SecondaryPartType='PAA' or $SecondaryPartType='PATR'">2</xsl:when>
<xsl:when test="$SecondaryPartType='PAL'">3</xsl:when>
<xsl:when test="$SecondaryPartType='PAM' or $SecondaryPartType='PAC' or $SecondaryPartType='PAR'">4</xsl:when>
<xsl:when
test="$SecondaryPartType='PAM' or $SecondaryPartType='PAC' or $SecondaryPartType='PAR'">
4
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="TDPartDesc">
<xsl:value-of select="@TDPartDesc" />
<xsl:value-of select="@TDPartDesc"/>
</xsl:attribute>
<xsl:attribute name="TDEstimate">
<xsl:choose>
<xsl:when test="@PartType='PAN'">
<xsl:value-of select="@TDEstimate" />
<xsl:value-of select="@TDEstimate"/>
</xsl:when>
<xsl:when test="@PartType='PAM'">
<xsl:value-of select="@ActPrice" />
<xsl:value-of select="@ActPrice"/>
</xsl:when>
<xsl:when test="@PartType='PAA'">
<xsl:value-of select="@ActPrice" />
<xsl:value-of select="@ActPrice"/>
</xsl:when>
<xsl:when test="@PartType='PAL'">
<xsl:value-of select="@ActPrice" />
<xsl:value-of select="@ActPrice"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@ActPrice" />
<xsl:value-of select="@ActPrice"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="TDPartQty">
<xsl:value-of select="@TDPartQty" />
<xsl:value-of select="@TDPartQty"/>
</xsl:attribute>
<xsl:attribute name="LineNumber">
<xsl:value-of select="@LineNumber" />
<xsl:value-of select="@LineNumber"/>
</xsl:attribute>
<xsl:attribute name="SequenceNumber">
<xsl:value-of select="@SequenceNumber" />
<xsl:value-of select="@SequenceNumber"/>
</xsl:attribute>
<xsl:attribute name="SupplLevel">
<xsl:choose>
<xsl:when test="@SupplementLevel = 'E'">0</xsl:when>
<xsl:when test="substring(@SupplementLevel, 1, 1) = 'S'">
<xsl:value-of select="substring(@SupplementLevel, 2)" />
<xsl:value-of select="substring(@SupplementLevel, 2)"/>
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="LaborType">
<xsl:value-of select="@LaborType" />
<xsl:value-of select="@LaborType"/>
</xsl:attribute>
<xsl:attribute name="LaborHours">
<xsl:value-of select="@LaborHours" />
<xsl:value-of select="@LaborHours"/>
</xsl:attribute>
<xsl:attribute name="OperationCode">
<xsl:value-of select="@LaborOp" />
<xsl:value-of select="@LaborOp"/>
</xsl:attribute>
<xsl:attribute name="PriceIncluded">
<xsl:value-of select="@PriceIncluded" />
<xsl:value-of select="@PriceIncluded"/>
</xsl:attribute>
<xsl:attribute name="MarkUp">
<xsl:value-of select="@MarkUp" />
<xsl:value-of select="@MarkUp"/>
</xsl:attribute>
<xsl:attribute name="CLPart">
<!-- CLPart is false if TRAN_CODE == 2 or TRAN_CODE == 3 -->
@@ -546,11 +567,16 @@
<!-- If LaborOp is OP1, then allow the part to import CP 12/28/08 for Shop Client Release 4.1.4 -->
<xsl:choose>
<xsl:when test="@TransactionCode='3'">False</xsl:when>
<xsl:when test="@TransactionCode='1' or @TransactionCode=' ' or @TransactionCode='' or @TransactionCode='2'">
<xsl:when
test="@TransactionCode='1' or @TransactionCode=' ' or @TransactionCode='' or @TransactionCode='2'">
<xsl:choose>
<xsl:when test="@PartType='PAN' or @PartType='PAG' or @PartType='PAM' or @PartType='PAP' or @PartType='PAL' or @PartType='PAA' or @PartType='PAC' or @PartType='PATR'">
<xsl:when
test="@PartType='PAN' or @PartType='PAG' or @PartType='PAM' or @PartType='PAP' or @PartType='PAL' or @PartType='PAA' or @PartType='PAC' or @PartType='PATR'">
<xsl:choose>
<xsl:when test="@LaborType='LAD' or @LaborType='LAE' or @LaborType='LAU' or @LaborType='LAT'">False</xsl:when>
<xsl:when
test="@LaborType='LAD' or @LaborType='LAE' or @LaborType='LAU' or @LaborType='LAT'">
False
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<!--xsl:when test="@LaborOp='OP0'">False</xsl:when -->

View File

@@ -1,128 +1,223 @@
<?xml version="1.0" encoding="UTF-8"?>
<TranslationDescriptor>
<FileTranslations FormatName="ADP EMS" ElementName="Estimate" Description="Translation Descriptor for a ADP ShopLink Estimate, Version EMS 2.0">
<FileTranslations FormatName="ADP EMS" ElementName="Estimate"
Description="Translation Descriptor for a ADP ShopLink Estimate, Version EMS 2.0">
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.env">
<DBFFileTranslation ID="ID1" ElementName="Envelope" Description="Envelope Table">
<DBFFieldSpec FieldName="RO_ID" Form="attribute" Name="RONum" FieldType="" Description="RO Number"/>
<DBFFieldSpec FieldName="UNQFILE_ID" Form="attribute" Name="UniqueFileID" FieldType="" Description="Unique File Identifier"/>
<DBFFieldSpec FieldName="ESTFILE_ID" Form="attribute" Name="EstimateFileID" FieldType="" Description="Estimate File Identifier"/>
<DBFFieldSpec FieldName="INCL_ADMIN" Form="attribute" Name="IncludesAdminInfo" FieldType="Boolean" Description="Includes Admin Info Flag"/>
<DBFFieldSpec FieldName="INCL_VEH" Form="attribute" Name="IncludesVehicleInfo" FieldType="Boolean" Description="Includes Vehicle Info Flag"/>
<DBFFieldSpec FieldName="INCL_EST" Form="attribute" Name="IncludesEstimateInfo" FieldType="Boolean" Description="Includes Estimate Info Flag"/>
<DBFFieldSpec FieldName="INCL_PROFL" Form="attribute" Name="IncludesProfileInfo" FieldType="Boolean" Description="Includes Profile Info Flag"/>
<DBFFieldSpec FieldName="INCL_TOTAL" Form="attribute" Name="IncludesTotalsInfo" FieldType="Boolean" Description="Includes Totals Info Flag"/>
<DBFFieldSpec FieldName="INCL_VENDR" Form="attribute" Name="IncludesVendorInfo" FieldType="Boolean" Description="Includes Vendor Info Flag"/>
<DBFFieldSpec FieldName="EMS_VER" Form="attribute" Name="EMSVersion" FieldType="" Description="EMS Version Number"/>
<DBFFieldSpec FieldName="SUPP_NO" Form="attribute" Name="SupplementNum" FieldType="" Description="Supplement Number"/>
<DBFFieldSpec FieldName="TRANS_TYPE" Form="attribute" Name="TransactionType" FieldType="" Description="Transaction Type"/>
<DBFFieldSpec FieldName="EST_SYSTEM" Form="attribute" Name="EstimatingSystem" FieldType="" Description="Estimating System Software"/>
<DBFFieldSpec FieldName="SW_VERSION" Form="attribute" Name="SoftwareVersion" FieldType="" Description="Software Version Identifier"/>
<DBFFieldSpec FieldName="UNQFILE_ID" Form="attribute" Name="UniqueFileID" FieldType=""
Description="Unique File Identifier"/>
<DBFFieldSpec FieldName="ESTFILE_ID" Form="attribute" Name="EstimateFileID" FieldType=""
Description="Estimate File Identifier"/>
<DBFFieldSpec FieldName="INCL_ADMIN" Form="attribute" Name="IncludesAdminInfo" FieldType="Boolean"
Description="Includes Admin Info Flag"/>
<DBFFieldSpec FieldName="INCL_VEH" Form="attribute" Name="IncludesVehicleInfo" FieldType="Boolean"
Description="Includes Vehicle Info Flag"/>
<DBFFieldSpec FieldName="INCL_EST" Form="attribute" Name="IncludesEstimateInfo" FieldType="Boolean"
Description="Includes Estimate Info Flag"/>
<DBFFieldSpec FieldName="INCL_PROFL" Form="attribute" Name="IncludesProfileInfo" FieldType="Boolean"
Description="Includes Profile Info Flag"/>
<DBFFieldSpec FieldName="INCL_TOTAL" Form="attribute" Name="IncludesTotalsInfo" FieldType="Boolean"
Description="Includes Totals Info Flag"/>
<DBFFieldSpec FieldName="INCL_VENDR" Form="attribute" Name="IncludesVendorInfo" FieldType="Boolean"
Description="Includes Vendor Info Flag"/>
<DBFFieldSpec FieldName="EMS_VER" Form="attribute" Name="EMSVersion" FieldType=""
Description="EMS Version Number"/>
<DBFFieldSpec FieldName="SUPP_NO" Form="attribute" Name="SupplementNum" FieldType=""
Description="Supplement Number"/>
<DBFFieldSpec FieldName="TRANS_TYPE" Form="attribute" Name="TransactionType" FieldType=""
Description="Transaction Type"/>
<DBFFieldSpec FieldName="EST_SYSTEM" Form="attribute" Name="EstimatingSystem" FieldType=""
Description="Estimating System Software"/>
<DBFFieldSpec FieldName="SW_VERSION" Form="attribute" Name="SoftwareVersion" FieldType=""
Description="Software Version Identifier"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.LIN">
<DBFFileTranslation ID="ID2" ElementSetName="PartsList" ElementName="Part" Description="Parts List Table">
<DBFFieldSpec FieldName="OEM_PARTNO" Form="attribute" Name="TDPartNum" FieldType="" Description="Part Number"/>
<DBFFieldSpec FieldName="ALT_PARTNO" Form="attribute" Name="AltPartNum" FieldType="" Description="Alternate Part Number"/>
<DBFFieldSpec FieldName="ACT_PRICE" Form="attribute" Name="ActPrice" FieldType="" Description="Actual Part Price"/>
<DBFFieldSpec FieldName="LINE_DESC" Form="attribute" Name="TDPartDesc" FieldType="" Description="Part Description"/>
<DBFFieldSpec FieldName="DB_PRICE" Form="attribute" Name="TDEstimate" FieldType="" Description="DB_Price"/>
<DBFFieldSpec FieldName="PART_QTY" Form="attribute" Name="TDPartQty" FieldType="" Description="Part Quantity"/>
<DBFFieldSpec FieldName="PART_TYPE" Form="attribute" Name="PartType" FieldType="" Description="Part Type"/>
<DBFFieldSpec FieldName="MOD_LBR_TY" Form="attribute" Name="LaborType" FieldType="" Description="Labor Type"/>
<DBFFieldSpec FieldName="MOD_LB_HRS" Form="attribute" Name="LaborHours" FieldType="" Description="Labor Hours"/>
<DBFFieldSpec FieldName="OEM_PARTNO" Form="attribute" Name="TDPartNum" FieldType=""
Description="Part Number"/>
<DBFFieldSpec FieldName="ALT_PARTNO" Form="attribute" Name="AltPartNum" FieldType=""
Description="Alternate Part Number"/>
<DBFFieldSpec FieldName="ACT_PRICE" Form="attribute" Name="ActPrice" FieldType=""
Description="Actual Part Price"/>
<DBFFieldSpec FieldName="LINE_DESC" Form="attribute" Name="TDPartDesc" FieldType=""
Description="Part Description"/>
<DBFFieldSpec FieldName="DB_PRICE" Form="attribute" Name="TDEstimate" FieldType=""
Description="DB_Price"/>
<DBFFieldSpec FieldName="PART_QTY" Form="attribute" Name="TDPartQty" FieldType=""
Description="Part Quantity"/>
<DBFFieldSpec FieldName="PART_TYPE" Form="attribute" Name="PartType" FieldType=""
Description="Part Type"/>
<DBFFieldSpec FieldName="MOD_LBR_TY" Form="attribute" Name="LaborType" FieldType=""
Description="Labor Type"/>
<DBFFieldSpec FieldName="MOD_LB_HRS" Form="attribute" Name="LaborHours" FieldType=""
Description="Labor Hours"/>
<DBFFieldSpec FieldName="LBR_OP" Form="attribute" Name="LaborOp" FieldType="" Description="Labor Op"/>
<DBFFieldSpec FieldName="LINE_NO" Form="attribute" Name="LineNumber" FieldType="" Description="Line number"/>
<DBFFieldSpec FieldName="LINE_NO" Form="attribute" Name="LineNumber" FieldType=""
Description="Line number"/>
<DBFFieldSpec FieldName="UNQ_SEQ" Form="attribute" Name="SequenceNumber" FieldType="" Description=""/>
<DBFFieldSpec FieldName="LINE_IND" Form="attribute" Name="SupplementLevel" FieldType="" Description="Supplement Level"/>
<DBFFieldSpec FieldName="TRAN_CODE" Form="attribute" Name="TransactionCode" FieldType="" Description="Transaction Code"/>
<DBFFieldSpec FieldName="PRICE_INC" Form="attribute" Name="PriceIncluded" FieldType="" Description="Price Included"/>
<DBFFieldSpec FieldName="PRT_DSMK_P" Form="attribute" Name="MarkUp" FieldType="" Description="Price Mark up for non OEM parts"/>
<DBFFieldSpec FieldName="LINE_IND" Form="attribute" Name="SupplementLevel" FieldType=""
Description="Supplement Level"/>
<DBFFieldSpec FieldName="TRAN_CODE" Form="attribute" Name="TransactionCode" FieldType=""
Description="Transaction Code"/>
<DBFFieldSpec FieldName="PRICE_INC" Form="attribute" Name="PriceIncluded" FieldType=""
Description="Price Included"/>
<DBFFieldSpec FieldName="PRT_DSMK_P" Form="attribute" Name="MarkUp" FieldType=""
Description="Price Mark up for non OEM parts"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.VEH">
<DBFFileTranslation ID="ID3" ElementName="Vehicle" Description="Vehicle Table">
<DBFFieldSpec FieldName="V_VIN" Form="attribute" Name="TransVIN" FieldType="" Description=""/>
<DBFFieldSpec FieldName="V_MODEL_YR" Form="attribute" Name="TransYear" FieldType="" Description="V_MODEL_YR"/>
<DBFFieldSpec FieldName="V_MAKEDESC" Form="attribute" Name="ManufName" FieldType="" Description="V_MAKEDESC"/>
<DBFFieldSpec FieldName="V_MAKECODE" Form="attribute" Name="ManufCode" FieldType="" Description="V_MAKECODE"/>
<DBFFieldSpec FieldName="V_MODEL" Form="attribute" Name="TransModel" FieldType="" Description="V_MODEL"/>
<DBFFieldSpec FieldName="V_MILEAGE" Form="attribute" Name="TransMileage" FieldType="" Description="V_MILEAGE"/>
<DBFFieldSpec FieldName="V_MODEL_YR" Form="attribute" Name="TransYear" FieldType=""
Description="V_MODEL_YR"/>
<DBFFieldSpec FieldName="V_MAKEDESC" Form="attribute" Name="ManufName" FieldType=""
Description="V_MAKEDESC"/>
<DBFFieldSpec FieldName="V_MAKECODE" Form="attribute" Name="ManufCode" FieldType=""
Description="V_MAKECODE"/>
<DBFFieldSpec FieldName="V_MODEL" Form="attribute" Name="TransModel" FieldType=""
Description="V_MODEL"/>
<DBFFieldSpec FieldName="V_MILEAGE" Form="attribute" Name="TransMileage" FieldType=""
Description="V_MILEAGE"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.AD1">
<DBFFileTranslation ID="ID4" ElementName="Admin" Description="Administrative information">
<DBFFieldSpec FieldName="OWNR_LN" Form="attribute" Name="OwnerL" FieldType="" Description="Owner Lastname"/>
<DBFFieldSpec FieldName="OWNR_FN" Form="attribute" Name="OwnerF" FieldType="" Description="Owner Firstname"/>
<DBFFieldSpec FieldName="OWNR_CO_NM" Form="attribute" Name="OwnerCompanyName" FieldType="" Description="Owner Company Name"/>
<DBFFieldSpec FieldName="OWNR_TITLE" Form="attribute" Name="OwnerTitle" FieldType="" Description="Owner Title"/>
<DBFFieldSpec FieldName="OWNR_ADDR1" Form="attribute" Name="OwnerAddr1" FieldType="" Description="Owner Address Line 1"/>
<DBFFieldSpec FieldName="OWNR_ADDR2" Form="attribute" Name="OwnerAddr2" FieldType="" Description="Owner Address Line 2"/>
<DBFFieldSpec FieldName="OWNR_CITY" Form="attribute" Name="OwnerCity" FieldType="" Description="Owner City"/>
<DBFFieldSpec FieldName="OWNR_ST" Form="attribute" Name="OwnerState" FieldType="" Description="Owner State"/>
<DBFFieldSpec FieldName="OWNR_ZIP" Form="attribute" Name="OwnerZip" FieldType="" Description="Owner Zip"/>
<DBFFieldSpec FieldName="OWNR_CTRY" Form="attribute" Name="OwnerCountry" FieldType="" Description="Owner Country"/>
<DBFFieldSpec FieldName="OWNR_PH1" Form="attribute" Name="OwnerPhone1" FieldType="" Description="Owner Primary Phone"/>
<DBFFieldSpec FieldName="OWNR_PH1X" Form="attribute" Name="OwnerPhone1Ext" FieldType="" Description="Owner Primary Phone Extension"/>
<DBFFieldSpec FieldName="OWNR_PH2" Form="attribute" Name="OwnerPhone2" FieldType="" Description="Owner Secondary Phone"/>
<DBFFieldSpec FieldName="OWNR_PH2X" Form="attribute" Name="OwnerPhone2Ext" FieldType="" Description="Owner Secondary Phone Extension"/>
<DBFFieldSpec FieldName="OWNR_FAX" Form="attribute" Name="OwnerFax" FieldType="" Description="Owner Fax"/>
<DBFFieldSpec FieldName="OWNR_FAXX" Form="attribute" Name="OwnerFaxExt" FieldType="" Description="Owner Fax Extension"/>
<DBFFieldSpec FieldName="OWNR_EA" Form="attribute" Name="OwnerEmail" FieldType="" Description="Owner Email Address"/>
<DBFFieldSpec FieldName="INS_CO_NM" Form="attribute" Name="InsuranceCompanyName" FieldType="" Description="Insurance Company Name"/>
<DBFFieldSpec FieldName="INS_CO_ID" Form="attribute" Name="InsuranceCompanyID" FieldType="" Description="Insurance Company Identifier"/>
<DBFFieldSpec FieldName="INS_ADDR1" Form="attribute" Name="InsuranceAddr1" FieldType="" Description="Insurance Address Line 1"/>
<DBFFieldSpec FieldName="INS_ADDR2" Form="attribute" Name="InsuranceAddr2" FieldType="" Description="Insurance Address Line 2"/>
<DBFFieldSpec FieldName="INS_CITY" Form="attribute" Name="InsuranceCity" FieldType="" Description="Insurance City"/>
<DBFFieldSpec FieldName="INS_ST" Form="attribute" Name="InsuranceState" FieldType="" Description="Insurance State"/>
<DBFFieldSpec FieldName="INS_ZIP" Form="attribute" Name="InsuranceZip" FieldType="" Description="Insurance Zip"/>
<DBFFieldSpec FieldName="INS_CTRY" Form="attribute" Name="InsuranceCountry" FieldType="" Description="Insurance Country"/>
<DBFFieldSpec FieldName="INS_PH1" Form="attribute" Name="InsurancePhone1" FieldType="" Description="Insurance Primary Phone"/>
<DBFFieldSpec FieldName="INS_PH1X" Form="attribute" Name="InsurancePhone1Ext" FieldType="" Description="Insurance Primary Phone Extension"/>
<DBFFieldSpec FieldName="INS_PH2" Form="attribute" Name="InsurancePhone2" FieldType="" Description="Insurance Secondary Phone"/>
<DBFFieldSpec FieldName="INS_PH2X" Form="attribute" Name="InsurancePhone2Ext" FieldType="" Description="Insurance Secondary Phone Extension"/>
<DBFFieldSpec FieldName="INS_FAX" Form="attribute" Name="InsuranceFax" FieldType="" Description="Insurance Fax"/>
<DBFFieldSpec FieldName="INS_FAXX" Form="attribute" Name="InsuranceFaxExt" FieldType="" Description="Insurance Fax Extension"/>
<DBFFieldSpec FieldName="INS_EA" Form="attribute" Name="InsuranceEmail" FieldType="" Description="Insurance Email Address"/>
<DBFFieldSpec FieldName="INSD_LN" Form="attribute" Name="InsuranceLName" FieldType="" Description="Insurance Last Name"/>
<DBFFieldSpec FieldName="CLM_NO" Form="attribute" Name="ClaimNumber" FieldType="" Description="Claim Number"/>
<DBFFieldSpec FieldName="OWNR_LN" Form="attribute" Name="OwnerL" FieldType=""
Description="Owner Lastname"/>
<DBFFieldSpec FieldName="OWNR_FN" Form="attribute" Name="OwnerF" FieldType=""
Description="Owner Firstname"/>
<DBFFieldSpec FieldName="OWNR_CO_NM" Form="attribute" Name="OwnerCompanyName" FieldType=""
Description="Owner Company Name"/>
<DBFFieldSpec FieldName="OWNR_TITLE" Form="attribute" Name="OwnerTitle" FieldType=""
Description="Owner Title"/>
<DBFFieldSpec FieldName="OWNR_ADDR1" Form="attribute" Name="OwnerAddr1" FieldType=""
Description="Owner Address Line 1"/>
<DBFFieldSpec FieldName="OWNR_ADDR2" Form="attribute" Name="OwnerAddr2" FieldType=""
Description="Owner Address Line 2"/>
<DBFFieldSpec FieldName="OWNR_CITY" Form="attribute" Name="OwnerCity" FieldType=""
Description="Owner City"/>
<DBFFieldSpec FieldName="OWNR_ST" Form="attribute" Name="OwnerState" FieldType=""
Description="Owner State"/>
<DBFFieldSpec FieldName="OWNR_ZIP" Form="attribute" Name="OwnerZip" FieldType=""
Description="Owner Zip"/>
<DBFFieldSpec FieldName="OWNR_CTRY" Form="attribute" Name="OwnerCountry" FieldType=""
Description="Owner Country"/>
<DBFFieldSpec FieldName="OWNR_PH1" Form="attribute" Name="OwnerPhone1" FieldType=""
Description="Owner Primary Phone"/>
<DBFFieldSpec FieldName="OWNR_PH1X" Form="attribute" Name="OwnerPhone1Ext" FieldType=""
Description="Owner Primary Phone Extension"/>
<DBFFieldSpec FieldName="OWNR_PH2" Form="attribute" Name="OwnerPhone2" FieldType=""
Description="Owner Secondary Phone"/>
<DBFFieldSpec FieldName="OWNR_PH2X" Form="attribute" Name="OwnerPhone2Ext" FieldType=""
Description="Owner Secondary Phone Extension"/>
<DBFFieldSpec FieldName="OWNR_FAX" Form="attribute" Name="OwnerFax" FieldType=""
Description="Owner Fax"/>
<DBFFieldSpec FieldName="OWNR_FAXX" Form="attribute" Name="OwnerFaxExt" FieldType=""
Description="Owner Fax Extension"/>
<DBFFieldSpec FieldName="OWNR_EA" Form="attribute" Name="OwnerEmail" FieldType=""
Description="Owner Email Address"/>
<DBFFieldSpec FieldName="INS_CO_NM" Form="attribute" Name="InsuranceCompanyName" FieldType=""
Description="Insurance Company Name"/>
<DBFFieldSpec FieldName="INS_CO_ID" Form="attribute" Name="InsuranceCompanyID" FieldType=""
Description="Insurance Company Identifier"/>
<DBFFieldSpec FieldName="INS_ADDR1" Form="attribute" Name="InsuranceAddr1" FieldType=""
Description="Insurance Address Line 1"/>
<DBFFieldSpec FieldName="INS_ADDR2" Form="attribute" Name="InsuranceAddr2" FieldType=""
Description="Insurance Address Line 2"/>
<DBFFieldSpec FieldName="INS_CITY" Form="attribute" Name="InsuranceCity" FieldType=""
Description="Insurance City"/>
<DBFFieldSpec FieldName="INS_ST" Form="attribute" Name="InsuranceState" FieldType=""
Description="Insurance State"/>
<DBFFieldSpec FieldName="INS_ZIP" Form="attribute" Name="InsuranceZip" FieldType=""
Description="Insurance Zip"/>
<DBFFieldSpec FieldName="INS_CTRY" Form="attribute" Name="InsuranceCountry" FieldType=""
Description="Insurance Country"/>
<DBFFieldSpec FieldName="INS_PH1" Form="attribute" Name="InsurancePhone1" FieldType=""
Description="Insurance Primary Phone"/>
<DBFFieldSpec FieldName="INS_PH1X" Form="attribute" Name="InsurancePhone1Ext" FieldType=""
Description="Insurance Primary Phone Extension"/>
<DBFFieldSpec FieldName="INS_PH2" Form="attribute" Name="InsurancePhone2" FieldType=""
Description="Insurance Secondary Phone"/>
<DBFFieldSpec FieldName="INS_PH2X" Form="attribute" Name="InsurancePhone2Ext" FieldType=""
Description="Insurance Secondary Phone Extension"/>
<DBFFieldSpec FieldName="INS_FAX" Form="attribute" Name="InsuranceFax" FieldType=""
Description="Insurance Fax"/>
<DBFFieldSpec FieldName="INS_FAXX" Form="attribute" Name="InsuranceFaxExt" FieldType=""
Description="Insurance Fax Extension"/>
<DBFFieldSpec FieldName="INS_EA" Form="attribute" Name="InsuranceEmail" FieldType=""
Description="Insurance Email Address"/>
<DBFFieldSpec FieldName="INSD_LN" Form="attribute" Name="InsuranceLName" FieldType=""
Description="Insurance Last Name"/>
<DBFFieldSpec FieldName="CLM_NO" Form="attribute" Name="ClaimNumber" FieldType=""
Description="Claim Number"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.AD2">
<DBFFileTranslation ID="ID5" ElementName="Admin2" Description="Administrative information2">
<DBFFieldSpec FieldName="EST_CT_LN" Form="attribute" Name="EstimatorL" FieldType="" Description="Estimator Lastname"/>
<DBFFieldSpec FieldName="EST_CT_FN" Form="attribute" Name="EstimatorF" FieldType="" Description="Estimator Firstname"/>
<DBFFieldSpec FieldName="EST_CO_NM" Form="attribute" Name="EstimatorCompanyName" FieldType="" Description="Estimator Company Name"/>
<DBFFieldSpec FieldName="EST_CO_ID" Form="attribute" Name="EstimatorCompanyID" FieldType="" Description="Estimator Company Identifier"/>
<DBFFieldSpec FieldName="EST_ADDR1" Form="attribute" Name="EstimatorAddr1" FieldType="" Description="Estimator Address1"/>
<DBFFieldSpec FieldName="EST_ADDR2" Form="attribute" Name="EstimatorAddr2" FieldType="" Description="Estimator Address2"/>
<DBFFieldSpec FieldName="EST_CITY" Form="attribute" Name="EstimatorCity" FieldType="" Description="Estimator City"/>
<DBFFieldSpec FieldName="EST_ST" Form="attribute" Name="EstimatorState" FieldType="" Description="Estimator State"/>
<DBFFieldSpec FieldName="EST_ZIP" Form="attribute" Name="EstimatorZip" FieldType="" Description="Estimator Zip"/>
<DBFFieldSpec FieldName="EST_CTRY" Form="attribute" Name="EstimatorCountry" FieldType="" Description="Estimator Country"/>
<DBFFieldSpec FieldName="EST_PH1" Form="attribute" Name="EstimatorPhone1" FieldType="" Description="Estimator Primary Phone"/>
<DBFFieldSpec FieldName="EST_PH1X" Form="attribute" Name="EstimatorPhone1Ext" FieldType="" Description="Estimator Primary Phone Extension"/>
<DBFFieldSpec FieldName="EST_PH2" Form="attribute" Name="EstimatorPhone2" FieldType="" Description="Estimator Secondary Phone"/>
<DBFFieldSpec FieldName="EST_PH2X" Form="attribute" Name="EstimatorPhone2Ext" FieldType="" Description="Estimator Secondary Phone Extension"/>
<DBFFieldSpec FieldName="EST_FAX" Form="attribute" Name="EstimatorFax" FieldType="" Description="Estimator Fax"/>
<DBFFieldSpec FieldName="EST_FAXX" Form="attribute" Name="EstimatorFaxExt" FieldType="" Description="Estimator Fax Extension"/>
<DBFFieldSpec FieldName="EST_EA" Form="attribute" Name="EstimatorEmail" FieldType="" Description="Estimator Email Address"/>
<DBFFieldSpec FieldName="EST_LIC_NO" Form="attribute" Name="EstimatorLicenseNumber" FieldType="" Description="Estimator License Number"/>
<DBFFieldSpec FieldName="EST_FILENO" Form="attribute" Name="EstimatorFileNumber" FieldType="" Description="Estimator File Number"/>
<DBFFieldSpec FieldName="RO_IN_DATE" Form="attribute" Name="VehicleInDate" FieldType="" Description="Date arrived in shop"/>
<DBFFieldSpec FieldName="RO_IN_TIME" Form="attribute" Name="VehicleInTime" FieldType="" Description="Time arrived in shop"/>
<DBFFieldSpec FieldName="TAR_DATE" Form="attribute" Name="TargetVehicleOutDate" FieldType="" Description="Target date to be completed"/>
<DBFFieldSpec FieldName="TAR_TIME" Form="attribute" Name="TargetVehicleOutTime" FieldType="" Description="Target time to be completed"/>
<DBFFieldSpec FieldName="RO_CMPDATE" Form="attribute" Name="VehicleOutDate" FieldType="" Description="Date completed"/>
<DBFFieldSpec FieldName="RO_CMPTIME" Form="attribute" Name="VehicleOutTime" FieldType="" Description="Time completed"/>
<DBFFieldSpec FieldName="RF_CITY" Form="attribute" Name="BodyShopCity" FieldType="" Description="Body Shop City"/>
<DBFFieldSpec FieldName="RF_CO_NM" Form="attribute" Name="BodyShopName" FieldType="" Description="Body Shop Name"/>
<DBFFieldSpec FieldName="EST_CT_LN" Form="attribute" Name="EstimatorL" FieldType=""
Description="Estimator Lastname"/>
<DBFFieldSpec FieldName="EST_CT_FN" Form="attribute" Name="EstimatorF" FieldType=""
Description="Estimator Firstname"/>
<DBFFieldSpec FieldName="EST_CO_NM" Form="attribute" Name="EstimatorCompanyName" FieldType=""
Description="Estimator Company Name"/>
<DBFFieldSpec FieldName="EST_CO_ID" Form="attribute" Name="EstimatorCompanyID" FieldType=""
Description="Estimator Company Identifier"/>
<DBFFieldSpec FieldName="EST_ADDR1" Form="attribute" Name="EstimatorAddr1" FieldType=""
Description="Estimator Address1"/>
<DBFFieldSpec FieldName="EST_ADDR2" Form="attribute" Name="EstimatorAddr2" FieldType=""
Description="Estimator Address2"/>
<DBFFieldSpec FieldName="EST_CITY" Form="attribute" Name="EstimatorCity" FieldType=""
Description="Estimator City"/>
<DBFFieldSpec FieldName="EST_ST" Form="attribute" Name="EstimatorState" FieldType=""
Description="Estimator State"/>
<DBFFieldSpec FieldName="EST_ZIP" Form="attribute" Name="EstimatorZip" FieldType=""
Description="Estimator Zip"/>
<DBFFieldSpec FieldName="EST_CTRY" Form="attribute" Name="EstimatorCountry" FieldType=""
Description="Estimator Country"/>
<DBFFieldSpec FieldName="EST_PH1" Form="attribute" Name="EstimatorPhone1" FieldType=""
Description="Estimator Primary Phone"/>
<DBFFieldSpec FieldName="EST_PH1X" Form="attribute" Name="EstimatorPhone1Ext" FieldType=""
Description="Estimator Primary Phone Extension"/>
<DBFFieldSpec FieldName="EST_PH2" Form="attribute" Name="EstimatorPhone2" FieldType=""
Description="Estimator Secondary Phone"/>
<DBFFieldSpec FieldName="EST_PH2X" Form="attribute" Name="EstimatorPhone2Ext" FieldType=""
Description="Estimator Secondary Phone Extension"/>
<DBFFieldSpec FieldName="EST_FAX" Form="attribute" Name="EstimatorFax" FieldType=""
Description="Estimator Fax"/>
<DBFFieldSpec FieldName="EST_FAXX" Form="attribute" Name="EstimatorFaxExt" FieldType=""
Description="Estimator Fax Extension"/>
<DBFFieldSpec FieldName="EST_EA" Form="attribute" Name="EstimatorEmail" FieldType=""
Description="Estimator Email Address"/>
<DBFFieldSpec FieldName="EST_LIC_NO" Form="attribute" Name="EstimatorLicenseNumber" FieldType=""
Description="Estimator License Number"/>
<DBFFieldSpec FieldName="EST_FILENO" Form="attribute" Name="EstimatorFileNumber" FieldType=""
Description="Estimator File Number"/>
<DBFFieldSpec FieldName="RO_IN_DATE" Form="attribute" Name="VehicleInDate" FieldType=""
Description="Date arrived in shop"/>
<DBFFieldSpec FieldName="RO_IN_TIME" Form="attribute" Name="VehicleInTime" FieldType=""
Description="Time arrived in shop"/>
<DBFFieldSpec FieldName="TAR_DATE" Form="attribute" Name="TargetVehicleOutDate" FieldType=""
Description="Target date to be completed"/>
<DBFFieldSpec FieldName="TAR_TIME" Form="attribute" Name="TargetVehicleOutTime" FieldType=""
Description="Target time to be completed"/>
<DBFFieldSpec FieldName="RO_CMPDATE" Form="attribute" Name="VehicleOutDate" FieldType=""
Description="Date completed"/>
<DBFFieldSpec FieldName="RO_CMPTIME" Form="attribute" Name="VehicleOutTime" FieldType=""
Description="Time completed"/>
<DBFFieldSpec FieldName="RF_CITY" Form="attribute" Name="BodyShopCity" FieldType=""
Description="Body Shop City"/>
<DBFFieldSpec FieldName="RF_CO_NM" Form="attribute" Name="BodyShopName" FieldType=""
Description="Body Shop Name"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.TTL">
<DBFFileTranslation ID="ID6" ElementName="Total" Description="Total Table">
<DBFFieldSpec FieldName="G_TTL_AMT" Form="attribute" Name="GrandTotalAmount" FieldType="" Description=""/>
</DBFFileTranslation>
<DBFFileTranslation ID="ID6" ElementName="Total" Description="Total Table">
<DBFFieldSpec FieldName="G_TTL_AMT" Form="attribute" Name="GrandTotalAmount" FieldType=""
Description=""/>
</DBFFileTranslation>
</FileTranslation>
</FileTranslations>
<StyleSheetTranslation>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:for-each select="//TranslatedData">
<xsl:element name="TranslatedData">
@@ -9,23 +8,23 @@
</xsl:attribute>
<xsl:choose>
<xsl:when test="Details/@PrgID">
<xsl:copy-of select="Details" />
<xsl:copy-of select="Details"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="Details">
<xsl:attribute name="PrgID">OECTrans.ImportTrans</xsl:attribute>
<xsl:for-each select="Details/@*">
<xsl:copy-of select="." />
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:for-each select="Details/*">
<xsl:copy-of select="." />
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
<xsl:element name="Header">
<xsl:attribute name="RONum">
<xsl:value-of select="//Envelope/@RONum" />
<xsl:value-of select="//Envelope/@RONum"/>
</xsl:attribute>
<xsl:attribute name="OwnerFName">
<xsl:value-of select="//Admin/@OwnerF"/>
@@ -34,43 +33,43 @@
<xsl:value-of select="//Admin/@OwnerL"/>
</xsl:attribute>
<xsl:attribute name="VIN">
<xsl:value-of select="//Vehicle/@TransVIN" />
<xsl:value-of select="//Vehicle/@TransVIN"/>
</xsl:attribute>
<xsl:attribute name="Mileage">
<xsl:value-of select="//Vehicle/@TransMileage" />
<xsl:value-of select="//Vehicle/@TransMileage"/>
</xsl:attribute>
<xsl:attribute name="Year">
<xsl:value-of select="//Vehicle/@TransYear" />
<xsl:value-of select="//Vehicle/@TransYear"/>
</xsl:attribute>
<xsl:attribute name="Make">
<xsl:if test="//Vehicle/@ManufName[. != '']" >
<xsl:value-of select="//Vehicle/@ManufName" />
<xsl:if test="//Vehicle/@ManufName[. != '']">
<xsl:value-of select="//Vehicle/@ManufName"/>
</xsl:if>
<xsl:if test="//Vehicle/@ManufName[. = '']" >
<xsl:value-of select="//Vehicle/@ManufCode" />
<xsl:if test="//Vehicle/@ManufName[. = '']">
<xsl:value-of select="//Vehicle/@ManufCode"/>
</xsl:if>
</xsl:attribute>
<xsl:attribute name="Model">
<xsl:value-of select="//Vehicle/@TransModel" />
<xsl:value-of select="//Vehicle/@TransModel"/>
</xsl:attribute>
<xsl:attribute name="Description">
<xsl:value-of select="//Vehicle/@TransYear" />
<xsl:text> </xsl:text>
<xsl:value-of select="//Vehicle/@ManufName" />
<xsl:text> </xsl:text>
<xsl:value-of select="//Vehicle/@TransModel" />
<xsl:value-of select="//Vehicle/@TransYear"/>
<xsl:text></xsl:text>
<xsl:value-of select="//Vehicle/@ManufName"/>
<xsl:text></xsl:text>
<xsl:value-of select="//Vehicle/@TransModel"/>
</xsl:attribute>
<xsl:attribute name="LastSupplLevel">
<xsl:choose>
<xsl:when test="//Envelope/@TransactionType = 'E'">0</xsl:when>
<xsl:when test="//Envelope/@TransactionType = 'S'">
<xsl:value-of select="substring(//Envelope/@SupplementNum, 2)" />
<xsl:value-of select="substring(//Envelope/@SupplementNum, 2)"/>
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:element>
<xsl:apply-templates select="PartsList" />
<xsl:apply-templates select="PartsList"/>
<xsl:element name="Envelope">
<xsl:element name="Software">
<xsl:attribute name="Manifest">CCC.xml</xsl:attribute>
@@ -91,10 +90,13 @@
<xsl:value-of select="//Envelope/@UniqueFileID"/>
</xsl:attribute>
<xsl:attribute name="EstimateID">
<xsl:value-of select="//Envelope/@EstimatingSystem"/>-<xsl:value-of select="//Envelope/@SoftwareVersion"/>-<xsl:value-of select="//Envelope/@UniqueFileID"/>
<xsl:value-of select="//Envelope/@EstimatingSystem"/>-<xsl:value-of
select="//Envelope/@SoftwareVersion"/>-
<xsl:value-of select="//Envelope/@UniqueFileID"/>
</xsl:attribute>
<xsl:attribute name="EstimateIDv2">
<xsl:value-of select="//Envelope/@EstimatingSystem"/>-<xsl:value-of select="//Envelope/@UniqueFileID"/>
<xsl:value-of select="//Envelope/@EstimatingSystem"/>-
<xsl:value-of select="//Envelope/@UniqueFileID"/>
</xsl:attribute>
<xsl:attribute name="EstimateFormatVersion">
<xsl:value-of select="//Envelope/@EMSVersion"/>
@@ -102,9 +104,9 @@
</xsl:element>
</xsl:element>
<xsl:element name="Totals">
<xsl:attribute name="GrandTotalAmount">
<xsl:value-of select="//Total/@GrandTotalAmount"/>
</xsl:attribute>
<xsl:attribute name="GrandTotalAmount">
<xsl:value-of select="//Total/@GrandTotalAmount"/>
</xsl:attribute>
</xsl:element>
<xsl:element name="Administrative">
<xsl:element name="Owner">
@@ -215,7 +217,8 @@
<xsl:choose>
<xsl:when test="string-length(substring-before(//Admin/@InsuranceZip, '-'))=5">
<xsl:choose>
<xsl:when test="string-length(substring-after(//Admin/@InsuranceZip, '-'))=4">
<xsl:when
test="string-length(substring-after(//Admin/@InsuranceZip, '-'))=4">
<xsl:value-of select="//Admin/@InsuranceZip"/>
</xsl:when>
<xsl:otherwise>
@@ -226,7 +229,8 @@
</xsl:choose>
</xsl:when>
<xsl:when test="string-length(//Admin/@InsuranceZip)=9">
<xsl:value-of select="substring(//Admin/@InsuranceZip, 1, 5)"/>-<xsl:value-of select="substring(//Admin/@InsuranceZip, 6, 4)"/>
<xsl:value-of select="substring(//Admin/@InsuranceZip, 1, 5)"/>-
<xsl:value-of select="substring(//Admin/@InsuranceZip, 6, 4)"/>
</xsl:when>
<xsl:when test="string-length(//Admin/@InsuranceZip)&gt;4">
<xsl:value-of select="substring(//Admin/@InsuranceZip, 1, 5)"/>
@@ -239,7 +243,8 @@
<xsl:attribute name="Phone">
<xsl:choose>
<xsl:when test="//Admin/@InsurancePhone1Ext[. != '']">
<xsl:value-of select="//Admin/@InsurancePhone1"/>&#32;x<xsl:value-of select="//Admin/@InsurancePhone1Ext"/>
<xsl:value-of select="//Admin/@InsurancePhone1"/>&#32;x
<xsl:value-of select="//Admin/@InsurancePhone1Ext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin/@InsurancePhone1"/>
@@ -249,7 +254,8 @@
<xsl:attribute name="Phone2">
<xsl:choose>
<xsl:when test="//Admin/@InsurancePhone2Ext[. != '']">
<xsl:value-of select="//Admin/@InsurancePhone2"/>&#32;x<xsl:value-of select="//Admin/@InsurancePhone2Ext"/>
<xsl:value-of select="//Admin/@InsurancePhone2"/>&#32;x
<xsl:value-of select="//Admin/@InsurancePhone2Ext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin/@InsurancePhone2"/>
@@ -259,7 +265,8 @@
<xsl:attribute name="Fax">
<xsl:choose>
<xsl:when test="//Admin/@InsuranceFaxExt[. != '']">
<xsl:value-of select="//Admin/@InsuranceFax"/>&#32;x<xsl:value-of select="//Admin/@InsuranceFaxExt"/>
<xsl:value-of select="//Admin/@InsuranceFax"/>&#32;x
<xsl:value-of select="//Admin/@InsuranceFaxExt"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin/@InsuranceFax"/>
@@ -272,7 +279,7 @@
</xsl:element>
<xsl:element name="Insured">
<xsl:attribute name="LastName">
<xsl:value-of select="//Admin/@InsuranceLName" />
<xsl:value-of select="//Admin/@InsuranceLName"/>
</xsl:attribute>
</xsl:element>
<xsl:element name="Claim">
@@ -308,7 +315,8 @@
<xsl:choose>
<xsl:when test="string-length(substring-before(//Admin2/@EstimatorZip, '-'))=5">
<xsl:choose>
<xsl:when test="string-length(substring-after(//Admin2/@EstimatorZip, '-'))=4">
<xsl:when
test="string-length(substring-after(//Admin2/@EstimatorZip, '-'))=4">
<xsl:value-of select="//Admin2/@EstimatorZip"/>
</xsl:when>
<xsl:otherwise>
@@ -319,7 +327,8 @@
</xsl:choose>
</xsl:when>
<xsl:when test="string-length(//Admin2/@EstimatorZip)=9">
<xsl:value-of select="substring(//Admin2/@EstimatorZip, 1, 5)"/>-<xsl:value-of select="substring(//Admin2/@EstimatorZip, 6, 4)"/>
<xsl:value-of select="substring(//Admin2/@EstimatorZip, 1, 5)"/>-
<xsl:value-of select="substring(//Admin2/@EstimatorZip, 6, 4)"/>
</xsl:when>
<xsl:when test="string-length(//Admin2/@EstimatorZip)&gt;4">
<xsl:value-of select="substring(//Admin2/@EstimatorZip, 1, 5)"/>
@@ -332,7 +341,8 @@
<xsl:attribute name="Phone">
<xsl:choose>
<xsl:when test="//Admin2/@EstimatorPhone1Ext[. != '']">
<xsl:value-of select="//Admin2/@EstimatorPhone1"/>&#32;x<xsl:value-of select="//Admin2/@EstimatorPhone1Ext"/>
<xsl:value-of select="//Admin2/@EstimatorPhone1"/>&#32;x
<xsl:value-of select="//Admin2/@EstimatorPhone1Ext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin2/@EstimatorPhone1"/>
@@ -342,7 +352,8 @@
<xsl:attribute name="Phone2">
<xsl:choose>
<xsl:when test="//Admin2/@EstimatorPhone2Ext[. != '']">
<xsl:value-of select="//Admin2/@EstimatorPhone2"/>&#32;x<xsl:value-of select="//Admin2/@EstimatorPhone2Ext"/>
<xsl:value-of select="//Admin2/@EstimatorPhone2"/>&#32;x
<xsl:value-of select="//Admin2/@EstimatorPhone2Ext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin2/@EstimatorPhone2"/>
@@ -352,7 +363,8 @@
<xsl:attribute name="Fax">
<xsl:choose>
<xsl:when test="//Admin2/@EstimatorFaxExt[. != '']">
<xsl:value-of select="//Admin2/@EstimatorFax"/>&#32;x<xsl:value-of select="//Admin2/@EstimatorFaxExt"/>
<xsl:value-of select="//Admin2/@EstimatorFax"/>&#32;x
<xsl:value-of select="//Admin2/@EstimatorFaxExt"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin2/@EstimatorFax"/>
@@ -368,7 +380,8 @@
<xsl:if test="string-length(//Admin2/@VehicleInDate)&gt;6">
<xsl:value-of select="substring-before(//Admin2/@VehicleInDate, ' ')"/>
<xsl:if test="string-length(//Admin2/@VehicleInTime)=4">
&#32;<xsl:value-of select="substring(//Admin2/@VehicleInTime, 1, 2)"/>:<xsl:value-of select="substring(//Admin2/@VehicleInTime, 3, 2)"/>
&#32;<xsl:value-of select="substring(//Admin2/@VehicleInTime, 1, 2)"/>:
<xsl:value-of select="substring(//Admin2/@VehicleInTime, 3, 2)"/>
</xsl:if>
</xsl:if>
</xsl:attribute>
@@ -376,7 +389,8 @@
<xsl:if test="string-length(//Admin2/@TargetVehicleOutDate)&gt;6">
<xsl:value-of select="substring-before(//Admin2/@TargetVehicleOutDate,' ')"/>
<xsl:if test="string-length(//Admin2/@TargetVehicleOutTime)=4">
&#32;<xsl:value-of select="substring(//Admin2/@TargetVehicleOutTime, 1, 2)"/>:<xsl:value-of select="substring(//Admin2/@TargetVehicleOutTime, 3, 2)"/>
&#32;<xsl:value-of select="substring(//Admin2/@TargetVehicleOutTime, 1, 2)"/>:
<xsl:value-of select="substring(//Admin2/@TargetVehicleOutTime, 3, 2)"/>
</xsl:if>
</xsl:if>
</xsl:attribute>
@@ -384,7 +398,8 @@
<xsl:if test="string-length(//Admin2/@VehicleOutDate)&gt;6">
<xsl:value-of select="substring-before(//Admin2/@VehicleOutDate, ' ')"/>
<xsl:if test="string-length(//Admin2/@VehicleOutTime)=4">
&#32;<xsl:value-of select="substring(//Admin2/@VehicleOutTime, 1, 2)"/>:<xsl:value-of select="substring(//Admin2/@VehicleOutTime, 3, 2)"/>
&#32;<xsl:value-of select="substring(//Admin2/@VehicleOutTime, 1, 2)"/>:
<xsl:value-of select="substring(//Admin2/@VehicleOutTime, 3, 2)"/>
</xsl:if>
</xsl:if>
</xsl:attribute>
@@ -394,16 +409,16 @@
</xsl:for-each>
</xsl:template>
<xsl:template match="PartsList">
<xsl:element name="PartsList" >
<xsl:element name="PartsList">
<xsl:for-each select="Part">
<xsl:element name="Part" >
<xsl:element name="Part">
<!-- Part number translation rules -->
<xsl:variable name="OEMPartNumber">
<xsl:if test="substring(@TDPartNum, string-length(@TDPartNum) - 7) != ' GM PART'">
<xsl:value-of select="@TDPartNum" />
<xsl:value-of select="@TDPartNum"/>
</xsl:if>
<xsl:if test="substring(@TDPartNum, string-length(@TDPartNum) - 7) = ' GM PART'">
<xsl:value-of select="substring-before(@TDPartNum,' GM PART')" />
<xsl:value-of select="substring-before(@TDPartNum,' GM PART')"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="AltPartNumber">
@@ -476,13 +491,13 @@
<xsl:value-of select="$PrimaryPartNumber"/>
</xsl:attribute>
<xsl:attribute name="AltPartNum">
<xsl:value-of select="$SecondaryPartNumber" />
<xsl:value-of select="$SecondaryPartNumber"/>
</xsl:attribute>
<xsl:attribute name="ExternalPartType">
<xsl:value-of select="$PrimaryPartType" />
<xsl:value-of select="$PrimaryPartType"/>
</xsl:attribute>
<xsl:attribute name="ExternalAltPartType">
<xsl:value-of select="$SecondaryPartType" />
<xsl:value-of select="$SecondaryPartType"/>
</xsl:attribute>
<xsl:attribute name="TDPartType">
<xsl:choose>
@@ -505,56 +520,56 @@
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="TDPartDesc">
<xsl:value-of select="@TDPartDesc" />
<xsl:value-of select="@TDPartDesc"/>
</xsl:attribute>
<xsl:attribute name="TDLineRef">
<xsl:value-of select="@TDLineRef" />
<xsl:value-of select="@TDLineRef"/>
</xsl:attribute>
<xsl:attribute name="TDEstimate">
<xsl:choose>
<xsl:when test="@PartType='PAN'">
<xsl:value-of select="@TDEstimate" />
<xsl:value-of select="@TDEstimate"/>
</xsl:when>
<xsl:when test="@PartType='PAM'">
<xsl:value-of select="@ActPrice" />
<xsl:value-of select="@ActPrice"/>
</xsl:when>
<xsl:when test="@PartType='PAA'">
<xsl:value-of select="@ActPrice" />
<xsl:value-of select="@ActPrice"/>
</xsl:when>
<xsl:when test="@PartType='PAL'">
<xsl:value-of select="@ActPrice" />
<xsl:value-of select="@ActPrice"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@ActPrice" />
<xsl:value-of select="@ActPrice"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="TDPartQty">
<xsl:value-of select="@TDPartQty" />
<xsl:value-of select="@TDPartQty"/>
</xsl:attribute>
<xsl:attribute name="LineNumber">
<xsl:value-of select="@LineNumber" />
<xsl:value-of select="@LineNumber"/>
</xsl:attribute>
<xsl:attribute name="SequenceNumber">
<xsl:value-of select="@SequenceNumber" />
<xsl:value-of select="@SequenceNumber"/>
</xsl:attribute>
<xsl:attribute name="SupplLevel">
<xsl:choose>
<xsl:when test="@SupplementLevel = 'E01'">0</xsl:when>
<xsl:when test="substring(@SupplementLevel, 1, 1) = 'S'">
<xsl:value-of select="substring(@SupplementLevel, 2)" />
<xsl:value-of select="substring(@SupplementLevel, 2)"/>
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="LaborType">
<xsl:value-of select="@LaborType" />
<xsl:value-of select="@LaborType"/>
</xsl:attribute>
<xsl:attribute name="LaborHours">
<xsl:value-of select="@LaborHours" />
<xsl:value-of select="@LaborHours"/>
</xsl:attribute>
<xsl:attribute name="OperationCode">
<xsl:value-of select="@LaborOp" />
<xsl:value-of select="@LaborOp"/>
</xsl:attribute>
<xsl:attribute name="CLPart">
<!-- CLPart is false if TRAN_CODE == 2 or TRAN_CODE == 3 -->
@@ -565,10 +580,14 @@
<xsl:when test="@TransactionCode='3'">False</xsl:when>
<xsl:when test="@TransactionCode='1' or @TransactionCode ='2'">
<xsl:choose>
<xsl:when test="@PartType='PAN' or @PartType='PAG' or @PartType='PAM' or @PartType='PAP' or @PartType='PAL' or @PartType='PAA' or @PartType='PAO' or @PartType='PAR' or @PartType=''" >
<xsl:when
test="@PartType='PAN' or @PartType='PAG' or @PartType='PAM' or @PartType='PAP' or @PartType='PAL' or @PartType='PAA' or @PartType='PAO' or @PartType='PAR' or @PartType=''">
<!-- we now handle blank part types-->
<xsl:choose>
<xsl:when test="@LaborType='LAD' or @LaborType='LAE' or @LaborType='LAU' or @LaborType='LAT'">False</xsl:when>
<xsl:when
test="@LaborType='LAD' or @LaborType='LAE' or @LaborType='LAU' or @LaborType='LAT'">
False
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="@LaborOp=''">False</xsl:when>

View File

@@ -1,126 +1,217 @@
<?xml version="1.0" encoding="UTF-8"?>
<TranslationDescriptor>
<FileTranslations FormatName="CCC" ElementName="Estimate" Description="Translation Descriptor for a CCC Estimate, Version 2.0">
<FileTranslations FormatName="CCC" ElementName="Estimate"
Description="Translation Descriptor for a CCC Estimate, Version 2.0">
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.env">
<DBFFileTranslation ID="ID1" ElementName="Envelope" Description="Envelope Table">
<DBFFieldSpec FieldName="RO_ID" Form="attribute" Name="RONum" FieldType="" Description="RO Number"/>
<DBFFieldSpec FieldName="UNQFILE_ID" Form="attribute" Name="UniqueFileID" FieldType="" Description="Unique File Identifier"/>
<DBFFieldSpec FieldName="ESTFILE_ID" Form="attribute" Name="EstimateFileID" FieldType="" Description="Estimate File Identifier"/>
<DBFFieldSpec FieldName="INCL_ADMIN" Form="attribute" Name="IncludesAdminInfo" FieldType="Boolean" Description="Includes Admin Info Flag"/>
<DBFFieldSpec FieldName="INCL_VEH" Form="attribute" Name="IncludesVehicleInfo" FieldType="Boolean" Description="Includes Vehicle Info Flag"/>
<DBFFieldSpec FieldName="INCL_EST" Form="attribute" Name="IncludesEstimateInfo" FieldType="Boolean" Description="Includes Estimate Info Flag"/>
<DBFFieldSpec FieldName="INCL_PROFL" Form="attribute" Name="IncludesProfileInfo" FieldType="Boolean" Description="Includes Profile Info Flag"/>
<DBFFieldSpec FieldName="INCL_TOTAL" Form="attribute" Name="IncludesTotalsInfo" FieldType="Boolean" Description="Includes Totals Info Flag"/>
<DBFFieldSpec FieldName="INCL_VENDR" Form="attribute" Name="IncludesVendorInfo" FieldType="Boolean" Description="Includes Vendor Info Flag"/>
<DBFFieldSpec FieldName="EMS_VER" Form="attribute" Name="EMSVersion" FieldType="" Description="EMS Version Number"/>
<DBFFieldSpec FieldName="SUPP_NO" Form="attribute" Name="SupplementNum" FieldType="" Description="Supplement Number"/>
<DBFFieldSpec FieldName="TRANS_TYPE" Form="attribute" Name="TransactionType" FieldType="" Description="Transaction Type"/>
<DBFFieldSpec FieldName="EST_SYSTEM" Form="attribute" Name="EstimatingSystem" FieldType="" Description="Estimating System Software"/>
<DBFFieldSpec FieldName="SW_VERSION" Form="attribute" Name="SoftwareVersion" FieldType="" Description="Software Version Identifier"/>
<DBFFieldSpec FieldName="UNQFILE_ID" Form="attribute" Name="UniqueFileID" FieldType=""
Description="Unique File Identifier"/>
<DBFFieldSpec FieldName="ESTFILE_ID" Form="attribute" Name="EstimateFileID" FieldType=""
Description="Estimate File Identifier"/>
<DBFFieldSpec FieldName="INCL_ADMIN" Form="attribute" Name="IncludesAdminInfo" FieldType="Boolean"
Description="Includes Admin Info Flag"/>
<DBFFieldSpec FieldName="INCL_VEH" Form="attribute" Name="IncludesVehicleInfo" FieldType="Boolean"
Description="Includes Vehicle Info Flag"/>
<DBFFieldSpec FieldName="INCL_EST" Form="attribute" Name="IncludesEstimateInfo" FieldType="Boolean"
Description="Includes Estimate Info Flag"/>
<DBFFieldSpec FieldName="INCL_PROFL" Form="attribute" Name="IncludesProfileInfo" FieldType="Boolean"
Description="Includes Profile Info Flag"/>
<DBFFieldSpec FieldName="INCL_TOTAL" Form="attribute" Name="IncludesTotalsInfo" FieldType="Boolean"
Description="Includes Totals Info Flag"/>
<DBFFieldSpec FieldName="INCL_VENDR" Form="attribute" Name="IncludesVendorInfo" FieldType="Boolean"
Description="Includes Vendor Info Flag"/>
<DBFFieldSpec FieldName="EMS_VER" Form="attribute" Name="EMSVersion" FieldType=""
Description="EMS Version Number"/>
<DBFFieldSpec FieldName="SUPP_NO" Form="attribute" Name="SupplementNum" FieldType=""
Description="Supplement Number"/>
<DBFFieldSpec FieldName="TRANS_TYPE" Form="attribute" Name="TransactionType" FieldType=""
Description="Transaction Type"/>
<DBFFieldSpec FieldName="EST_SYSTEM" Form="attribute" Name="EstimatingSystem" FieldType=""
Description="Estimating System Software"/>
<DBFFieldSpec FieldName="SW_VERSION" Form="attribute" Name="SoftwareVersion" FieldType=""
Description="Software Version Identifier"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.LIN">
<DBFFileTranslation ID="ID2" ElementSetName="PartsList" ElementName="Part" Description="Parts List Table">
<DBFFieldSpec FieldName="OEM_PARTNO" Form="attribute" Name="TDPartNum" FieldType="" Description="Part Number"/>
<DBFFieldSpec FieldName="ALT_PARTNO" Form="attribute" Name="AltPartNum" FieldType="" Description="Alternate Part Number"/>
<DBFFieldSpec FieldName="ACT_PRICE" Form="attribute" Name="ActPrice" FieldType="" Description="Actual Part Price"/>
<DBFFieldSpec FieldName="LINE_DESC" Form="attribute" Name="TDPartDesc" FieldType="" Description="Part Description"/>
<DBFFieldSpec FieldName="DB_PRICE" Form="attribute" Name="TDEstimate" FieldType="" Description="DB_Price"/>
<DBFFieldSpec FieldName="PART_QTY" Form="attribute" Name="TDPartQty" FieldType="" Description="PART_QTY"/>
<DBFFieldSpec FieldName="OEM_PARTNO" Form="attribute" Name="TDPartNum" FieldType=""
Description="Part Number"/>
<DBFFieldSpec FieldName="ALT_PARTNO" Form="attribute" Name="AltPartNum" FieldType=""
Description="Alternate Part Number"/>
<DBFFieldSpec FieldName="ACT_PRICE" Form="attribute" Name="ActPrice" FieldType=""
Description="Actual Part Price"/>
<DBFFieldSpec FieldName="LINE_DESC" Form="attribute" Name="TDPartDesc" FieldType=""
Description="Part Description"/>
<DBFFieldSpec FieldName="DB_PRICE" Form="attribute" Name="TDEstimate" FieldType=""
Description="DB_Price"/>
<DBFFieldSpec FieldName="PART_QTY" Form="attribute" Name="TDPartQty" FieldType=""
Description="PART_QTY"/>
<DBFFieldSpec FieldName="LINE_NO" Form="attribute" Name="LineNumber" FieldType="" Description=""/>
<DBFFieldSpec FieldName="UNQ_SEQ" Form="attribute" Name="SequenceNumber" FieldType="" Description=""/>
<DBFFieldSpec FieldName="PART_TYPE" Form="attribute" Name="PartType" FieldType="" Description="Part Type"/>
<DBFFieldSpec FieldName="MOD_LBR_TY" Form="attribute" Name="LaborType" FieldType="" Description="Labor Type"/>
<DBFFieldSpec FieldName="MOD_LB_HRS" Form="attribute" Name="LaborHours" FieldType="" Description="Labor Hours"/>
<DBFFieldSpec FieldName="PART_TYPE" Form="attribute" Name="PartType" FieldType=""
Description="Part Type"/>
<DBFFieldSpec FieldName="MOD_LBR_TY" Form="attribute" Name="LaborType" FieldType=""
Description="Labor Type"/>
<DBFFieldSpec FieldName="MOD_LB_HRS" Form="attribute" Name="LaborHours" FieldType=""
Description="Labor Hours"/>
<DBFFieldSpec FieldName="LBR_OP" Form="attribute" Name="LaborOp" FieldType="" Description="Labor Op"/>
<DBFFieldSpec FieldName="LINE_IND" Form="attribute" Name="SupplementLevel" FieldType="" Description="Supplement Level"/>
<DBFFieldSpec FieldName="TRAN_CODE" Form="attribute" Name="TransactionCode" FieldType="" Description="Transaction Code"/>
<DBFFieldSpec FieldName="LINE_REF" Form="attribute" Name="TDLineRef" FieldType="" Description="Line Reference Number"/>
<DBFFieldSpec FieldName="LINE_IND" Form="attribute" Name="SupplementLevel" FieldType=""
Description="Supplement Level"/>
<DBFFieldSpec FieldName="TRAN_CODE" Form="attribute" Name="TransactionCode" FieldType=""
Description="Transaction Code"/>
<DBFFieldSpec FieldName="LINE_REF" Form="attribute" Name="TDLineRef" FieldType=""
Description="Line Reference Number"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.VEH">
<DBFFileTranslation ID="ID3" ElementName="Vehicle" Description="Vehicle Table">
<DBFFieldSpec FieldName="V_VIN" Form="attribute" Name="TransVIN" FieldType="" Description="V_VIN"/>
<DBFFieldSpec FieldName="V_MODEL_YR" Form="attribute" Name="TransYear" FieldType="" Description="V_MODEL_YR"/>
<DBFFieldSpec FieldName="V_MAKEDESC" Form="attribute" Name="ManufName" FieldType="" Description="V_MAKEDESC"/>
<DBFFieldSpec FieldName="V_MAKECODE" Form="attribute" Name="ManufCode" FieldType="" Description="V_MAKECODE"/>
<DBFFieldSpec FieldName="V_MODEL" Form="attribute" Name="TransModel" FieldType="" Description="V_MODEL"/>
<DBFFieldSpec FieldName="V_MILEAGE" Form="attribute" Name="TransMileage" FieldType="" Description="V_MILEAGE"/>
<DBFFieldSpec FieldName="V_MODEL_YR" Form="attribute" Name="TransYear" FieldType=""
Description="V_MODEL_YR"/>
<DBFFieldSpec FieldName="V_MAKEDESC" Form="attribute" Name="ManufName" FieldType=""
Description="V_MAKEDESC"/>
<DBFFieldSpec FieldName="V_MAKECODE" Form="attribute" Name="ManufCode" FieldType=""
Description="V_MAKECODE"/>
<DBFFieldSpec FieldName="V_MODEL" Form="attribute" Name="TransModel" FieldType=""
Description="V_MODEL"/>
<DBFFieldSpec FieldName="V_MILEAGE" Form="attribute" Name="TransMileage" FieldType=""
Description="V_MILEAGE"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.AD1">
<DBFFileTranslation ID="ID4" ElementName="Admin" Description="Administrative information">
<DBFFieldSpec FieldName="OWNR_LN" Form="attribute" Name="OwnerL" FieldType="" Description="Owner Lastname"/>
<DBFFieldSpec FieldName="OWNR_FN" Form="attribute" Name="OwnerF" FieldType="" Description="Owner Firstname"/>
<DBFFieldSpec FieldName="OWNR_CO_NM" Form="attribute" Name="OwnerCompanyName" FieldType="" Description="Owner Company Name"/>
<DBFFieldSpec FieldName="OWNR_TITLE" Form="attribute" Name="OwnerTitle" FieldType="" Description="Owner Title"/>
<DBFFieldSpec FieldName="OWNR_ADDR1" Form="attribute" Name="OwnerAddr1" FieldType="" Description="Owner Address Line 1"/>
<DBFFieldSpec FieldName="OWNR_ADDR2" Form="attribute" Name="OwnerAddr2" FieldType="" Description="Owner Address Line 2"/>
<DBFFieldSpec FieldName="OWNR_CITY" Form="attribute" Name="OwnerCity" FieldType="" Description="Owner City"/>
<DBFFieldSpec FieldName="OWNR_ST" Form="attribute" Name="OwnerState" FieldType="" Description="Owner State"/>
<DBFFieldSpec FieldName="OWNR_ZIP" Form="attribute" Name="OwnerZip" FieldType="" Description="Owner Zip"/>
<DBFFieldSpec FieldName="OWNR_CTRY" Form="attribute" Name="OwnerCountry" FieldType="" Description="Owner Country"/>
<DBFFieldSpec FieldName="OWNR_PH1" Form="attribute" Name="OwnerPhone1" FieldType="" Description="Owner Primary Phone"/>
<DBFFieldSpec FieldName="OWNR_PH1X" Form="attribute" Name="OwnerPhone1Ext" FieldType="" Description="Owner Primary Phone Extension"/>
<DBFFieldSpec FieldName="OWNR_PH2" Form="attribute" Name="OwnerPhone2" FieldType="" Description="Owner Secondary Phone"/>
<DBFFieldSpec FieldName="OWNR_PH2X" Form="attribute" Name="OwnerPhone2Ext" FieldType="" Description="Owner Secondary Phone Extension"/>
<DBFFieldSpec FieldName="OWNR_FAX" Form="attribute" Name="OwnerFax" FieldType="" Description="Owner Fax"/>
<DBFFieldSpec FieldName="OWNR_FAXX" Form="attribute" Name="OwnerFaxExt" FieldType="" Description="Owner Fax Extension"/>
<DBFFieldSpec FieldName="OWNR_EA" Form="attribute" Name="OwnerEmail" FieldType="" Description="Owner Email Address"/>
<DBFFieldSpec FieldName="INS_CO_NM" Form="attribute" Name="InsuranceCompanyName" FieldType="" Description="Insurance Company Name"/>
<DBFFieldSpec FieldName="INS_CO_ID" Form="attribute" Name="InsuranceCompanyID" FieldType="" Description="Insurance Company Identifier"/>
<DBFFieldSpec FieldName="INS_ADDR1" Form="attribute" Name="InsuranceAddr1" FieldType="" Description="Insurance Address Line 1"/>
<DBFFieldSpec FieldName="INS_ADDR2" Form="attribute" Name="InsuranceAddr2" FieldType="" Description="Insurance Address Line 2"/>
<DBFFieldSpec FieldName="INS_CITY" Form="attribute" Name="InsuranceCity" FieldType="" Description="Insurance City"/>
<DBFFieldSpec FieldName="INS_ST" Form="attribute" Name="InsuranceState" FieldType="" Description="Insurance State"/>
<DBFFieldSpec FieldName="INS_ZIP" Form="attribute" Name="InsuranceZip" FieldType="" Description="Insurance Zip"/>
<DBFFieldSpec FieldName="INS_CTRY" Form="attribute" Name="InsuranceCountry" FieldType="" Description="Insurance Country"/>
<DBFFieldSpec FieldName="INS_PH1" Form="attribute" Name="InsurancePhone1" FieldType="" Description="Insurance Primary Phone"/>
<DBFFieldSpec FieldName="INS_PH1X" Form="attribute" Name="InsurancePhone1Ext" FieldType="" Description="Insurance Primary Phone Extension"/>
<DBFFieldSpec FieldName="INS_PH2" Form="attribute" Name="InsurancePhone2" FieldType="" Description="Insurance Secondary Phone"/>
<DBFFieldSpec FieldName="INS_PH2X" Form="attribute" Name="InsurancePhone2Ext" FieldType="" Description="Insurance Secondary Phone Extension"/>
<DBFFieldSpec FieldName="INS_FAX" Form="attribute" Name="InsuranceFax" FieldType="" Description="Insurance Fax"/>
<DBFFieldSpec FieldName="INS_FAXX" Form="attribute" Name="InsuranceFaxExt" FieldType="" Description="Insurance Fax Extension"/>
<DBFFieldSpec FieldName="INS_EA" Form="attribute" Name="InsuranceEmail" FieldType="" Description="Insurance Email Address"/>
<DBFFieldSpec FieldName="INSD_LN" Form="attribute" Name="InsuranceLName" FieldType="" Description="Insurance Last Name"/>
<DBFFieldSpec FieldName="CLM_NO" Form="attribute" Name="ClaimNumber" FieldType="" Description="Claim Number"/>
<DBFFieldSpec FieldName="OWNR_LN" Form="attribute" Name="OwnerL" FieldType=""
Description="Owner Lastname"/>
<DBFFieldSpec FieldName="OWNR_FN" Form="attribute" Name="OwnerF" FieldType=""
Description="Owner Firstname"/>
<DBFFieldSpec FieldName="OWNR_CO_NM" Form="attribute" Name="OwnerCompanyName" FieldType=""
Description="Owner Company Name"/>
<DBFFieldSpec FieldName="OWNR_TITLE" Form="attribute" Name="OwnerTitle" FieldType=""
Description="Owner Title"/>
<DBFFieldSpec FieldName="OWNR_ADDR1" Form="attribute" Name="OwnerAddr1" FieldType=""
Description="Owner Address Line 1"/>
<DBFFieldSpec FieldName="OWNR_ADDR2" Form="attribute" Name="OwnerAddr2" FieldType=""
Description="Owner Address Line 2"/>
<DBFFieldSpec FieldName="OWNR_CITY" Form="attribute" Name="OwnerCity" FieldType=""
Description="Owner City"/>
<DBFFieldSpec FieldName="OWNR_ST" Form="attribute" Name="OwnerState" FieldType=""
Description="Owner State"/>
<DBFFieldSpec FieldName="OWNR_ZIP" Form="attribute" Name="OwnerZip" FieldType=""
Description="Owner Zip"/>
<DBFFieldSpec FieldName="OWNR_CTRY" Form="attribute" Name="OwnerCountry" FieldType=""
Description="Owner Country"/>
<DBFFieldSpec FieldName="OWNR_PH1" Form="attribute" Name="OwnerPhone1" FieldType=""
Description="Owner Primary Phone"/>
<DBFFieldSpec FieldName="OWNR_PH1X" Form="attribute" Name="OwnerPhone1Ext" FieldType=""
Description="Owner Primary Phone Extension"/>
<DBFFieldSpec FieldName="OWNR_PH2" Form="attribute" Name="OwnerPhone2" FieldType=""
Description="Owner Secondary Phone"/>
<DBFFieldSpec FieldName="OWNR_PH2X" Form="attribute" Name="OwnerPhone2Ext" FieldType=""
Description="Owner Secondary Phone Extension"/>
<DBFFieldSpec FieldName="OWNR_FAX" Form="attribute" Name="OwnerFax" FieldType=""
Description="Owner Fax"/>
<DBFFieldSpec FieldName="OWNR_FAXX" Form="attribute" Name="OwnerFaxExt" FieldType=""
Description="Owner Fax Extension"/>
<DBFFieldSpec FieldName="OWNR_EA" Form="attribute" Name="OwnerEmail" FieldType=""
Description="Owner Email Address"/>
<DBFFieldSpec FieldName="INS_CO_NM" Form="attribute" Name="InsuranceCompanyName" FieldType=""
Description="Insurance Company Name"/>
<DBFFieldSpec FieldName="INS_CO_ID" Form="attribute" Name="InsuranceCompanyID" FieldType=""
Description="Insurance Company Identifier"/>
<DBFFieldSpec FieldName="INS_ADDR1" Form="attribute" Name="InsuranceAddr1" FieldType=""
Description="Insurance Address Line 1"/>
<DBFFieldSpec FieldName="INS_ADDR2" Form="attribute" Name="InsuranceAddr2" FieldType=""
Description="Insurance Address Line 2"/>
<DBFFieldSpec FieldName="INS_CITY" Form="attribute" Name="InsuranceCity" FieldType=""
Description="Insurance City"/>
<DBFFieldSpec FieldName="INS_ST" Form="attribute" Name="InsuranceState" FieldType=""
Description="Insurance State"/>
<DBFFieldSpec FieldName="INS_ZIP" Form="attribute" Name="InsuranceZip" FieldType=""
Description="Insurance Zip"/>
<DBFFieldSpec FieldName="INS_CTRY" Form="attribute" Name="InsuranceCountry" FieldType=""
Description="Insurance Country"/>
<DBFFieldSpec FieldName="INS_PH1" Form="attribute" Name="InsurancePhone1" FieldType=""
Description="Insurance Primary Phone"/>
<DBFFieldSpec FieldName="INS_PH1X" Form="attribute" Name="InsurancePhone1Ext" FieldType=""
Description="Insurance Primary Phone Extension"/>
<DBFFieldSpec FieldName="INS_PH2" Form="attribute" Name="InsurancePhone2" FieldType=""
Description="Insurance Secondary Phone"/>
<DBFFieldSpec FieldName="INS_PH2X" Form="attribute" Name="InsurancePhone2Ext" FieldType=""
Description="Insurance Secondary Phone Extension"/>
<DBFFieldSpec FieldName="INS_FAX" Form="attribute" Name="InsuranceFax" FieldType=""
Description="Insurance Fax"/>
<DBFFieldSpec FieldName="INS_FAXX" Form="attribute" Name="InsuranceFaxExt" FieldType=""
Description="Insurance Fax Extension"/>
<DBFFieldSpec FieldName="INS_EA" Form="attribute" Name="InsuranceEmail" FieldType=""
Description="Insurance Email Address"/>
<DBFFieldSpec FieldName="INSD_LN" Form="attribute" Name="InsuranceLName" FieldType=""
Description="Insurance Last Name"/>
<DBFFieldSpec FieldName="CLM_NO" Form="attribute" Name="ClaimNumber" FieldType=""
Description="Claim Number"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.AD2">
<DBFFileTranslation ID="ID5" ElementName="Admin2" Description="Administrative information2">
<DBFFieldSpec FieldName="EST_CT_LN" Form="attribute" Name="EstimatorL" FieldType="" Description="Estimator Lastname"/>
<DBFFieldSpec FieldName="EST_CT_FN" Form="attribute" Name="EstimatorF" FieldType="" Description="Estimator Firstname"/>
<DBFFieldSpec FieldName="EST_CO_NM" Form="attribute" Name="EstimatorCompanyName" FieldType="" Description="Estimator Company Name"/>
<DBFFieldSpec FieldName="EST_CO_ID" Form="attribute" Name="EstimatorCompanyID" FieldType="" Description="Estimator Company Identifier"/>
<DBFFieldSpec FieldName="EST_ADDR1" Form="attribute" Name="EstimatorAddr1" FieldType="" Description="Estimator Address1"/>
<DBFFieldSpec FieldName="EST_ADDR2" Form="attribute" Name="EstimatorAddr2" FieldType="" Description="Estimator Address2"/>
<DBFFieldSpec FieldName="EST_CITY" Form="attribute" Name="EstimatorCity" FieldType="" Description="Estimator City"/>
<DBFFieldSpec FieldName="EST_ST" Form="attribute" Name="EstimatorState" FieldType="" Description="Estimator State"/>
<DBFFieldSpec FieldName="EST_ZIP" Form="attribute" Name="EstimatorZip" FieldType="" Description="Estimator Zip"/>
<DBFFieldSpec FieldName="EST_CTRY" Form="attribute" Name="EstimatorCountry" FieldType="" Description="Estimator Country"/>
<DBFFieldSpec FieldName="EST_PH1" Form="attribute" Name="EstimatorPhone1" FieldType="" Description="Estimator Primary Phone"/>
<DBFFieldSpec FieldName="EST_PH1X" Form="attribute" Name="EstimatorPhone1Ext" FieldType="" Description="Estimator Primary Phone Extension"/>
<DBFFieldSpec FieldName="EST_PH2" Form="attribute" Name="EstimatorPhone2" FieldType="" Description="Estimator Secondary Phone"/>
<DBFFieldSpec FieldName="EST_PH2X" Form="attribute" Name="EstimatorPhone2Ext" FieldType="" Description="Estimator Secondary Phone Extension"/>
<DBFFieldSpec FieldName="EST_FAX" Form="attribute" Name="EstimatorFax" FieldType="" Description="Estimator Fax"/>
<DBFFieldSpec FieldName="EST_FAXX" Form="attribute" Name="EstimatorFaxExt" FieldType="" Description="Estimator Fax Extension"/>
<DBFFieldSpec FieldName="EST_EA" Form="attribute" Name="EstimatorEmail" FieldType="" Description="Estimator Email Address"/>
<DBFFieldSpec FieldName="EST_LIC_NO" Form="attribute" Name="EstimatorLicenseNumber" FieldType="" Description="Estimator License Number"/>
<DBFFieldSpec FieldName="EST_FILENO" Form="attribute" Name="EstimatorFileNumber" FieldType="" Description="Estimator File Number"/>
<DBFFieldSpec FieldName="RO_IN_DATE" Form="attribute" Name="VehicleInDate" FieldType="" Description="Date arrived in shop"/>
<DBFFieldSpec FieldName="RO_IN_TIME" Form="attribute" Name="VehicleInTime" FieldType="" Description="Time arrived in shop"/>
<DBFFieldSpec FieldName="TAR_DATE" Form="attribute" Name="TargetVehicleOutDate" FieldType="" Description="Target date to be completed"/>
<DBFFieldSpec FieldName="TAR_TIME" Form="attribute" Name="TargetVehicleOutTime" FieldType="" Description="Target time to be completed"/>
<DBFFieldSpec FieldName="RO_CMPDATE" Form="attribute" Name="VehicleOutDate" FieldType="" Description="Date completed"/>
<DBFFieldSpec FieldName="RO_CMPTIME" Form="attribute" Name="VehicleOutTime" FieldType="" Description="Time completed"/>
<DBFFieldSpec FieldName="EST_CT_LN" Form="attribute" Name="EstimatorL" FieldType=""
Description="Estimator Lastname"/>
<DBFFieldSpec FieldName="EST_CT_FN" Form="attribute" Name="EstimatorF" FieldType=""
Description="Estimator Firstname"/>
<DBFFieldSpec FieldName="EST_CO_NM" Form="attribute" Name="EstimatorCompanyName" FieldType=""
Description="Estimator Company Name"/>
<DBFFieldSpec FieldName="EST_CO_ID" Form="attribute" Name="EstimatorCompanyID" FieldType=""
Description="Estimator Company Identifier"/>
<DBFFieldSpec FieldName="EST_ADDR1" Form="attribute" Name="EstimatorAddr1" FieldType=""
Description="Estimator Address1"/>
<DBFFieldSpec FieldName="EST_ADDR2" Form="attribute" Name="EstimatorAddr2" FieldType=""
Description="Estimator Address2"/>
<DBFFieldSpec FieldName="EST_CITY" Form="attribute" Name="EstimatorCity" FieldType=""
Description="Estimator City"/>
<DBFFieldSpec FieldName="EST_ST" Form="attribute" Name="EstimatorState" FieldType=""
Description="Estimator State"/>
<DBFFieldSpec FieldName="EST_ZIP" Form="attribute" Name="EstimatorZip" FieldType=""
Description="Estimator Zip"/>
<DBFFieldSpec FieldName="EST_CTRY" Form="attribute" Name="EstimatorCountry" FieldType=""
Description="Estimator Country"/>
<DBFFieldSpec FieldName="EST_PH1" Form="attribute" Name="EstimatorPhone1" FieldType=""
Description="Estimator Primary Phone"/>
<DBFFieldSpec FieldName="EST_PH1X" Form="attribute" Name="EstimatorPhone1Ext" FieldType=""
Description="Estimator Primary Phone Extension"/>
<DBFFieldSpec FieldName="EST_PH2" Form="attribute" Name="EstimatorPhone2" FieldType=""
Description="Estimator Secondary Phone"/>
<DBFFieldSpec FieldName="EST_PH2X" Form="attribute" Name="EstimatorPhone2Ext" FieldType=""
Description="Estimator Secondary Phone Extension"/>
<DBFFieldSpec FieldName="EST_FAX" Form="attribute" Name="EstimatorFax" FieldType=""
Description="Estimator Fax"/>
<DBFFieldSpec FieldName="EST_FAXX" Form="attribute" Name="EstimatorFaxExt" FieldType=""
Description="Estimator Fax Extension"/>
<DBFFieldSpec FieldName="EST_EA" Form="attribute" Name="EstimatorEmail" FieldType=""
Description="Estimator Email Address"/>
<DBFFieldSpec FieldName="EST_LIC_NO" Form="attribute" Name="EstimatorLicenseNumber" FieldType=""
Description="Estimator License Number"/>
<DBFFieldSpec FieldName="EST_FILENO" Form="attribute" Name="EstimatorFileNumber" FieldType=""
Description="Estimator File Number"/>
<DBFFieldSpec FieldName="RO_IN_DATE" Form="attribute" Name="VehicleInDate" FieldType=""
Description="Date arrived in shop"/>
<DBFFieldSpec FieldName="RO_IN_TIME" Form="attribute" Name="VehicleInTime" FieldType=""
Description="Time arrived in shop"/>
<DBFFieldSpec FieldName="TAR_DATE" Form="attribute" Name="TargetVehicleOutDate" FieldType=""
Description="Target date to be completed"/>
<DBFFieldSpec FieldName="TAR_TIME" Form="attribute" Name="TargetVehicleOutTime" FieldType=""
Description="Target time to be completed"/>
<DBFFieldSpec FieldName="RO_CMPDATE" Form="attribute" Name="VehicleOutDate" FieldType=""
Description="Date completed"/>
<DBFFieldSpec FieldName="RO_CMPTIME" Form="attribute" Name="VehicleOutTime" FieldType=""
Description="Time completed"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.TTL">
<DBFFileTranslation ID="ID6" ElementName="Total" Description="Total Table">
<DBFFieldSpec FieldName="G_TTL_AMT" Form="attribute" Name="GrandTotalAmount" FieldType="" Description=""/>
</DBFFileTranslation>
<DBFFileTranslation ID="ID6" ElementName="Total" Description="Total Table">
<DBFFieldSpec FieldName="G_TTL_AMT" Form="attribute" Name="GrandTotalAmount" FieldType=""
Description=""/>
</DBFFileTranslation>
</FileTranslation>
</FileTranslations>
<StyleSheetTranslation>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:for-each select="//TranslatedData">
@@ -9,23 +9,23 @@
</xsl:attribute>
<xsl:choose>
<xsl:when test="Details/@PrgID">
<xsl:copy-of select="Details" />
<xsl:copy-of select="Details"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="Details">
<xsl:attribute name="PrgID">OECTrans.ImportTrans</xsl:attribute>
<xsl:for-each select="Details/@*">
<xsl:copy-of select="." />
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:for-each select="Details/*">
<xsl:copy-of select="." />
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
<xsl:element name="Header">
<xsl:attribute name="RONum">
<xsl:value-of select="//Envelope/@RONum" />
<xsl:value-of select="//Envelope/@RONum"/>
</xsl:attribute>
<xsl:attribute name="OwnerFName">
<xsl:value-of select="//Admin/@OwnerF"/>
@@ -34,42 +34,42 @@
<xsl:value-of select="//Admin/@OwnerL"/>
</xsl:attribute>
<xsl:attribute name="VIN">
<xsl:value-of select="//Vehicle/@TransVIN" />
<xsl:value-of select="//Vehicle/@TransVIN"/>
</xsl:attribute>
<xsl:attribute name="Mileage">
<xsl:value-of select="//Vehicle/@TransMileage" />
<xsl:value-of select="//Vehicle/@TransMileage"/>
</xsl:attribute>
<xsl:attribute name="Year">
<xsl:value-of select="//Vehicle/@TransYear" />
<xsl:value-of select="//Vehicle/@TransYear"/>
</xsl:attribute>
<xsl:attribute name="Make">
<xsl:if test="//Vehicle/@ManufName[. != '']" >
<xsl:value-of select="//Vehicle/@ManufName" />
<xsl:if test="//Vehicle/@ManufName[. != '']">
<xsl:value-of select="//Vehicle/@ManufName"/>
</xsl:if>
<xsl:if test="//Vehicle/@ManufName[. = '']" >
<xsl:value-of select="//Vehicle/@ManufCode" />
<xsl:if test="//Vehicle/@ManufName[. = '']">
<xsl:value-of select="//Vehicle/@ManufCode"/>
</xsl:if>
</xsl:attribute>
<xsl:attribute name="Model">
<xsl:value-of select="//Vehicle/@TransModel" />
<xsl:value-of select="//Vehicle/@TransModel"/>
</xsl:attribute>
<xsl:attribute name="Description">
<xsl:value-of select="//Vehicle/@TransYear" />
<xsl:text> </xsl:text>
<xsl:value-of select="//Vehicle/@ManufName" />
<xsl:text> </xsl:text>
<xsl:value-of select="//Vehicle/@TransModel" />
<xsl:value-of select="//Vehicle/@TransYear"/>
<xsl:text></xsl:text>
<xsl:value-of select="//Vehicle/@ManufName"/>
<xsl:text></xsl:text>
<xsl:value-of select="//Vehicle/@TransModel"/>
</xsl:attribute>
<xsl:attribute name="LastSupplLevel">
<xsl:choose>
<xsl:when test="string-length(//Envelope/@SupplementNum) > 0">
<xsl:value-of select="//Envelope/@SupplementNum" />
<xsl:value-of select="//Envelope/@SupplementNum"/>
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:element>
<xsl:apply-templates select="PartsList" />
<xsl:apply-templates select="PartsList"/>
<xsl:element name="Envelope">
<xsl:element name="Software">
<xsl:attribute name="Manifest">Mitchell.xml</xsl:attribute>
@@ -90,10 +90,13 @@
<xsl:value-of select="//Envelope/@UniqueFileID"/>
</xsl:attribute>
<xsl:attribute name="EstimateID">
<xsl:value-of select="//Envelope/@EstimatingSystem"/>-<xsl:value-of select="//Envelope/@SoftwareVersion"/>-<xsl:value-of select="//Envelope/@EstimateFileID"/>
<xsl:value-of select="//Envelope/@EstimatingSystem"/>-<xsl:value-of
select="//Envelope/@SoftwareVersion"/>-
<xsl:value-of select="//Envelope/@EstimateFileID"/>
</xsl:attribute>
<xsl:attribute name="EstimateIDv2">
<xsl:value-of select="//Envelope/@EstimatingSystem"/>-<xsl:value-of select="//Envelope/@EstimateFileID"/>
<xsl:value-of select="//Envelope/@EstimatingSystem"/>-
<xsl:value-of select="//Envelope/@EstimateFileID"/>
</xsl:attribute>
<xsl:attribute name="EstimateFormatVersion">
<xsl:value-of select="//Envelope/@EMSVersion"/>
@@ -102,7 +105,7 @@
</xsl:element>
<xsl:element name="Totals">
<xsl:attribute name="GrandTotalAmount">
<xsl:value-of select="//Total/@GrandTotalAmount"/>
<xsl:value-of select="//Total/@GrandTotalAmount"/>
</xsl:attribute>
</xsl:element>
<xsl:element name="Administrative">
@@ -214,7 +217,8 @@
<xsl:choose>
<xsl:when test="string-length(substring-before(//Admin/@InsuranceZip, '-'))=5">
<xsl:choose>
<xsl:when test="string-length(substring-after(//Admin/@InsuranceZip, '-'))=4">
<xsl:when
test="string-length(substring-after(//Admin/@InsuranceZip, '-'))=4">
<xsl:value-of select="//Admin/@InsuranceZip"/>
</xsl:when>
<xsl:otherwise>
@@ -225,7 +229,8 @@
</xsl:choose>
</xsl:when>
<xsl:when test="string-length(//Admin/@InsuranceZip)=9">
<xsl:value-of select="substring(//Admin/@InsuranceZip, 1, 5)"/>-<xsl:value-of select="substring(//Admin/@InsuranceZip, 6, 4)"/>
<xsl:value-of select="substring(//Admin/@InsuranceZip, 1, 5)"/>-
<xsl:value-of select="substring(//Admin/@InsuranceZip, 6, 4)"/>
</xsl:when>
<xsl:when test="string-length(//Admin/@InsuranceZip)&gt;4">
<xsl:value-of select="substring(//Admin/@InsuranceZip, 1, 5)"/>
@@ -238,7 +243,8 @@
<xsl:attribute name="Phone">
<xsl:choose>
<xsl:when test="//Admin/@InsurancePhone1Ext[. != '']">
<xsl:value-of select="//Admin/@InsurancePhone1"/>&#32;x<xsl:value-of select="//Admin/@InsurancePhone1Ext"/>
<xsl:value-of select="//Admin/@InsurancePhone1"/>&#32;x
<xsl:value-of select="//Admin/@InsurancePhone1Ext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin/@InsurancePhone1"/>
@@ -248,7 +254,8 @@
<xsl:attribute name="Phone2">
<xsl:choose>
<xsl:when test="//Admin/@InsurancePhone2Ext[. != '']">
<xsl:value-of select="//Admin/@InsurancePhone2"/>&#32;x<xsl:value-of select="//Admin/@InsurancePhone2Ext"/>
<xsl:value-of select="//Admin/@InsurancePhone2"/>&#32;x
<xsl:value-of select="//Admin/@InsurancePhone2Ext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin/@InsurancePhone2"/>
@@ -258,7 +265,8 @@
<xsl:attribute name="Fax">
<xsl:choose>
<xsl:when test="//Admin/@InsuranceFaxExt[. != '']">
<xsl:value-of select="//Admin/@InsuranceFax"/>&#32;x<xsl:value-of select="//Admin/@InsuranceFaxExt"/>
<xsl:value-of select="//Admin/@InsuranceFax"/>&#32;x
<xsl:value-of select="//Admin/@InsuranceFaxExt"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin/@InsuranceFax"/>
@@ -310,7 +318,8 @@
<xsl:choose>
<xsl:when test="string-length(substring-before(//Admin2/@EstimatorZip, '-'))=5">
<xsl:choose>
<xsl:when test="string-length(substring-after(//Admin2/@EstimatorZip, '-'))=4">
<xsl:when
test="string-length(substring-after(//Admin2/@EstimatorZip, '-'))=4">
<xsl:value-of select="//Admin2/@EstimatorZip"/>
</xsl:when>
<xsl:otherwise>
@@ -321,7 +330,8 @@
</xsl:choose>
</xsl:when>
<xsl:when test="string-length(//Admin2/@EstimatorZip)=9">
<xsl:value-of select="substring(//Admin2/@EstimatorZip, 1, 5)"/>-<xsl:value-of select="substring(//Admin2/@EstimatorZip, 6, 4)"/>
<xsl:value-of select="substring(//Admin2/@EstimatorZip, 1, 5)"/>-
<xsl:value-of select="substring(//Admin2/@EstimatorZip, 6, 4)"/>
</xsl:when>
<xsl:when test="string-length(//Admin2/@EstimatorZip)&gt;4">
<xsl:value-of select="substring(//Admin2/@EstimatorZip, 1, 5)"/>
@@ -334,7 +344,8 @@
<xsl:attribute name="Phone">
<xsl:choose>
<xsl:when test="//Admin2/@EstimatorPhone1Ext[. != '']">
<xsl:value-of select="//Admin2/@EstimatorPhone1"/>&#32;x<xsl:value-of select="//Admin2/@EstimatorPhone1Ext"/>
<xsl:value-of select="//Admin2/@EstimatorPhone1"/>&#32;x
<xsl:value-of select="//Admin2/@EstimatorPhone1Ext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin2/@EstimatorPhone1"/>
@@ -344,7 +355,8 @@
<xsl:attribute name="Phone2">
<xsl:choose>
<xsl:when test="//Admin2/@EstimatorPhone2Ext[. != '']">
<xsl:value-of select="//Admin2/@EstimatorPhone2"/>&#32;x<xsl:value-of select="//Admin2/@EstimatorPhone2Ext"/>
<xsl:value-of select="//Admin2/@EstimatorPhone2"/>&#32;x
<xsl:value-of select="//Admin2/@EstimatorPhone2Ext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin2/@EstimatorPhone2"/>
@@ -354,7 +366,8 @@
<xsl:attribute name="Fax">
<xsl:choose>
<xsl:when test="//Admin2/@EstimatorFaxExt[. != '']">
<xsl:value-of select="//Admin2/@EstimatorFax"/>&#32;x<xsl:value-of select="//Admin2/@EstimatorFaxExt"/>
<xsl:value-of select="//Admin2/@EstimatorFax"/>&#32;x
<xsl:value-of select="//Admin2/@EstimatorFaxExt"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//Admin2/@EstimatorFax"/>
@@ -370,7 +383,8 @@
<xsl:if test="string-length(//Admin2/@VehicleInDate)&gt;6">
<xsl:value-of select="substring-before(//Admin2/@VehicleInDate, ' ')"/>
<xsl:if test="string-length(//Admin2/@VehicleInTime)=4">
&#32;<xsl:value-of select="substring(//Admin2/@VehicleInTime, 1, 2)"/>:<xsl:value-of select="substring(//Admin2/@VehicleInTime, 3, 2)"/>
&#32;<xsl:value-of select="substring(//Admin2/@VehicleInTime, 1, 2)"/>:
<xsl:value-of select="substring(//Admin2/@VehicleInTime, 3, 2)"/>
</xsl:if>
</xsl:if>
</xsl:attribute>
@@ -378,7 +392,8 @@
<xsl:if test="string-length(//Admin2/@TargetVehicleOutDate)&gt;6">
<xsl:value-of select="substring-before(//Admin2/@TargetVehicleOutDate,' ')"/>
<xsl:if test="string-length(//Admin2/@TargetVehicleOutTime)=4">
&#32;<xsl:value-of select="substring(//Admin2/@TargetVehicleOutTime, 1, 2)"/>:<xsl:value-of select="substring(//Admin2/@TargetVehicleOutTime, 3, 2)"/>
&#32;<xsl:value-of select="substring(//Admin2/@TargetVehicleOutTime, 1, 2)"/>:
<xsl:value-of select="substring(//Admin2/@TargetVehicleOutTime, 3, 2)"/>
</xsl:if>
</xsl:if>
</xsl:attribute>
@@ -386,7 +401,8 @@
<xsl:if test="string-length(//Admin2/@VehicleOutDate)&gt;6">
<xsl:value-of select="substring-before(//Admin2/@VehicleOutDate, ' ')"/>
<xsl:if test="string-length(//Admin2/@VehicleOutTime)=4">
&#32;<xsl:value-of select="substring(//Admin2/@VehicleOutTime, 1, 2)"/>:<xsl:value-of select="substring(//Admin2/@VehicleOutTime, 3, 2)"/>
&#32;<xsl:value-of select="substring(//Admin2/@VehicleOutTime, 1, 2)"/>:
<xsl:value-of select="substring(//Admin2/@VehicleOutTime, 3, 2)"/>
</xsl:if>
</xsl:if>
</xsl:attribute>
@@ -396,16 +412,16 @@
</xsl:for-each>
</xsl:template>
<xsl:template match="PartsList">
<xsl:element name="PartsList" >
<xsl:element name="PartsList">
<xsl:for-each select="Part">
<xsl:element name="Part" >
<xsl:element name="Part">
<!-- Part number translation rules -->
<xsl:variable name="OEMPartNumber">
<xsl:if test="substring(@TDPartNum, string-length(@TDPartNum) - 7) != ' GM PART'">
<xsl:value-of select="@TDPartNum" />
<xsl:value-of select="@TDPartNum"/>
</xsl:if>
<xsl:if test="substring(@TDPartNum, string-length(@TDPartNum) - 7) = ' GM PART'">
<xsl:value-of select="substring-before(@TDPartNum,' GM PART')" />
<xsl:value-of select="substring-before(@TDPartNum,' GM PART')"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="AltPartNumber">
@@ -448,13 +464,13 @@
<xsl:value-of select="$PrimaryPartNumber"/>
</xsl:attribute>
<xsl:attribute name="AltPartNum">
<xsl:value-of select="$SecondaryPartNumber" />
<xsl:value-of select="$SecondaryPartNumber"/>
</xsl:attribute>
<xsl:attribute name="ExternalPartType">
<xsl:value-of select="$PrimaryPartType" />
<xsl:value-of select="$PrimaryPartType"/>
</xsl:attribute>
<xsl:attribute name="ExternalAltPartType">
<xsl:value-of select="$SecondaryPartType" />
<xsl:value-of select="$SecondaryPartType"/>
</xsl:attribute>
<xsl:attribute name="TDPartType">
<xsl:choose>
@@ -479,59 +495,59 @@
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="TDPartDesc">
<xsl:value-of select="@TDPartDesc" />
<xsl:value-of select="@TDPartDesc"/>
</xsl:attribute>
<xsl:attribute name="TDEstimate">
<xsl:choose>
<xsl:when test="@PartType='PAN'">
<xsl:value-of select="@TDEstimate" />
<xsl:value-of select="@TDEstimate"/>
</xsl:when>
<xsl:when test="@PartType='PAM'">
<xsl:value-of select="@ActPrice" />
<xsl:value-of select="@ActPrice"/>
</xsl:when>
<xsl:when test="@PartType='PAA'">
<xsl:value-of select="@ActPrice" />
<xsl:value-of select="@ActPrice"/>
</xsl:when>
<xsl:when test="@PartType='PAL'">
<xsl:value-of select="@ActPrice" />
<xsl:value-of select="@ActPrice"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@ActPrice" />
<xsl:value-of select="@ActPrice"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="TDPartQty">
<xsl:value-of select="@TDPartQty" />
<xsl:value-of select="@TDPartQty"/>
</xsl:attribute>
<xsl:attribute name="LineNumber">
<xsl:value-of select="@LineNumber" />
<xsl:value-of select="@LineNumber"/>
</xsl:attribute>
<xsl:attribute name="SequenceNumber">
<xsl:value-of select="@SequenceNumber" />
<xsl:value-of select="@SequenceNumber"/>
</xsl:attribute>
<xsl:attribute name="SupplLevel">
<xsl:choose>
<xsl:when test="@SupplementLevel = 'E'">0</xsl:when>
<xsl:when test="substring(@SupplementLevel, 1, 1) = 'S'">
<xsl:value-of select="substring(@SupplementLevel, 2)" />
<xsl:value-of select="substring(@SupplementLevel, 2)"/>
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="LaborType">
<xsl:value-of select="@LaborType" />
<xsl:value-of select="@LaborType"/>
</xsl:attribute>
<xsl:attribute name="LaborHours">
<xsl:value-of select="@LaborHours" />
<xsl:value-of select="@LaborHours"/>
</xsl:attribute>
<xsl:attribute name="OperationCode">
<xsl:value-of select="@LaborOp" />
<xsl:value-of select="@LaborOp"/>
</xsl:attribute>
<xsl:attribute name="GlassFlag">
<xsl:value-of select="@GlassFlag" />
<xsl:value-of select="@GlassFlag"/>
</xsl:attribute>
<xsl:attribute name="MarkUp">
<xsl:value-of select="@MarkUp" />
<xsl:value-of select="@MarkUp"/>
</xsl:attribute>
<xsl:attribute name="CLPart">
<!-- CLPart is false if TRAN_CODE == 2 or TRAN_CODE == 3 -->
@@ -542,9 +558,13 @@
<xsl:when test="@TransactionCode='3'">False</xsl:when>
<xsl:when test="@TransactionCode='1' or @TransactionCode='2'">
<xsl:choose>
<xsl:when test="@PartType='PAN' or @PartType='PAG' or @PartType='PAM' or @PartType='PAP' or @PartType='PAL' or @PartType='PAA' or @PartType='PAR' or @PartType='PAC'">
<xsl:when
test="@PartType='PAN' or @PartType='PAG' or @PartType='PAM' or @PartType='PAP' or @PartType='PAL' or @PartType='PAA' or @PartType='PAR' or @PartType='PAC'">
<xsl:choose>
<xsl:when test="@LaborType='LAD' or @LaborType='LAE' or @LaborType='LAU' or @LaborType='LAT'">False</xsl:when>
<xsl:when
test="@LaborType='LAD' or @LaborType='LAE' or @LaborType='LAU' or @LaborType='LAT'">
False
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="@LaborOp='OP0'">False</xsl:when>

View File

@@ -1,129 +1,222 @@
<?xml version="1.0" encoding="UTF-8"?>
<TranslationDescriptor>
<FileTranslations FormatName="Mitchell" ElementName="Estimate" Description="Translation Descriptor for a Mitchell Estimate, Version EMS 2.0">
<FileTranslations FormatName="Mitchell" ElementName="Estimate"
Description="Translation Descriptor for a Mitchell Estimate, Version EMS 2.0">
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.env">
<DBFFileTranslation ID="ID1" ElementName="Envelope" Description="Envelope Table">
<DBFFieldSpec FieldName="RO_ID" Form="attribute" Name="RONum" FieldType="" Description="RO Number"/>
<DBFFieldSpec FieldName="UNQFILE_ID" Form="attribute" Name="UniqueFileID" FieldType="" Description="Unique File Identifier"/>
<DBFFieldSpec FieldName="ESTFILE_ID" Form="attribute" Name="EstimateFileID" FieldType="" Description="Estimate File Identifier"/>
<DBFFieldSpec FieldName="INCL_ADMIN" Form="attribute" Name="IncludesAdminInfo" FieldType="Boolean" Description="Includes Admin Info Flag"/>
<DBFFieldSpec FieldName="INCL_VEH" Form="attribute" Name="IncludesVehicleInfo" FieldType="Boolean" Description="Includes Vehicle Info Flag"/>
<DBFFieldSpec FieldName="INCL_EST" Form="attribute" Name="IncludesEstimateInfo" FieldType="Boolean" Description="Includes Estimate Info Flag"/>
<DBFFieldSpec FieldName="INCL_PROFL" Form="attribute" Name="IncludesProfileInfo" FieldType="Boolean" Description="Includes Profile Info Flag"/>
<DBFFieldSpec FieldName="INCL_TOTAL" Form="attribute" Name="IncludesTotalsInfo" FieldType="Boolean" Description="Includes Totals Info Flag"/>
<DBFFieldSpec FieldName="INCL_VENDR" Form="attribute" Name="IncludesVendorInfo" FieldType="Boolean" Description="Includes Vendor Info Flag"/>
<DBFFieldSpec FieldName="EMS_VER" Form="attribute" Name="EMSVersion" FieldType="" Description="EMS Version Number"/>
<DBFFieldSpec FieldName="SUPP_NO" Form="attribute" Name="SupplementNum" FieldType="" Description="Supplement Number"/>
<DBFFieldSpec FieldName="TRANS_TYPE" Form="attribute" Name="TransactionType" FieldType="" Description="Transaction Type"/>
<DBFFieldSpec FieldName="EST_SYSTEM" Form="attribute" Name="EstimatingSystem" FieldType="" Description="Estimating System Software"/>
<DBFFieldSpec FieldName="SW_VERSION" Form="attribute" Name="SoftwareVersion" FieldType="" Description="Software Version Identifier"/>
<DBFFieldSpec FieldName="UNQFILE_ID" Form="attribute" Name="UniqueFileID" FieldType=""
Description="Unique File Identifier"/>
<DBFFieldSpec FieldName="ESTFILE_ID" Form="attribute" Name="EstimateFileID" FieldType=""
Description="Estimate File Identifier"/>
<DBFFieldSpec FieldName="INCL_ADMIN" Form="attribute" Name="IncludesAdminInfo" FieldType="Boolean"
Description="Includes Admin Info Flag"/>
<DBFFieldSpec FieldName="INCL_VEH" Form="attribute" Name="IncludesVehicleInfo" FieldType="Boolean"
Description="Includes Vehicle Info Flag"/>
<DBFFieldSpec FieldName="INCL_EST" Form="attribute" Name="IncludesEstimateInfo" FieldType="Boolean"
Description="Includes Estimate Info Flag"/>
<DBFFieldSpec FieldName="INCL_PROFL" Form="attribute" Name="IncludesProfileInfo" FieldType="Boolean"
Description="Includes Profile Info Flag"/>
<DBFFieldSpec FieldName="INCL_TOTAL" Form="attribute" Name="IncludesTotalsInfo" FieldType="Boolean"
Description="Includes Totals Info Flag"/>
<DBFFieldSpec FieldName="INCL_VENDR" Form="attribute" Name="IncludesVendorInfo" FieldType="Boolean"
Description="Includes Vendor Info Flag"/>
<DBFFieldSpec FieldName="EMS_VER" Form="attribute" Name="EMSVersion" FieldType=""
Description="EMS Version Number"/>
<DBFFieldSpec FieldName="SUPP_NO" Form="attribute" Name="SupplementNum" FieldType=""
Description="Supplement Number"/>
<DBFFieldSpec FieldName="TRANS_TYPE" Form="attribute" Name="TransactionType" FieldType=""
Description="Transaction Type"/>
<DBFFieldSpec FieldName="EST_SYSTEM" Form="attribute" Name="EstimatingSystem" FieldType=""
Description="Estimating System Software"/>
<DBFFieldSpec FieldName="SW_VERSION" Form="attribute" Name="SoftwareVersion" FieldType=""
Description="Software Version Identifier"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.LIN">
<DBFFileTranslation ID="ID2" ElementSetName="PartsList" ElementName="Part" Description="Parts List Table">
<DBFFieldSpec FieldName="OEM_PARTNO" Form="attribute" Name="TDPartNum" FieldType="" Description="Part Number"/>
<DBFFieldSpec FieldName="ALT_PARTNO" Form="attribute" Name="AltPartNum" FieldType="" Description="Alternate Part Number"/>
<DBFFieldSpec FieldName="ACT_PRICE" Form="attribute" Name="ActPrice" FieldType="" Description="Actual Part Price"/>
<DBFFieldSpec FieldName="LINE_DESC" Form="attribute" Name="TDPartDesc" FieldType="" Description="Part Description"/>
<DBFFieldSpec FieldName="DB_PRICE" Form="attribute" Name="TDEstimate" FieldType="" Description="DB_Price"/>
<DBFFieldSpec FieldName="PART_QTY" Form="attribute" Name="TDPartQty" FieldType="" Description="Part Quantity"/>
<DBFFieldSpec FieldName="OEM_PARTNO" Form="attribute" Name="TDPartNum" FieldType=""
Description="Part Number"/>
<DBFFieldSpec FieldName="ALT_PARTNO" Form="attribute" Name="AltPartNum" FieldType=""
Description="Alternate Part Number"/>
<DBFFieldSpec FieldName="ACT_PRICE" Form="attribute" Name="ActPrice" FieldType=""
Description="Actual Part Price"/>
<DBFFieldSpec FieldName="LINE_DESC" Form="attribute" Name="TDPartDesc" FieldType=""
Description="Part Description"/>
<DBFFieldSpec FieldName="DB_PRICE" Form="attribute" Name="TDEstimate" FieldType=""
Description="DB_Price"/>
<DBFFieldSpec FieldName="PART_QTY" Form="attribute" Name="TDPartQty" FieldType=""
Description="Part Quantity"/>
<DBFFieldSpec FieldName="LINE_NO" Form="attribute" Name="LineNumber" FieldType="" Description=""/>
<DBFFieldSpec FieldName="UNQ_SEQ" Form="attribute" Name="SequenceNumber" FieldType="" Description=""/>
<DBFFieldSpec FieldName="PART_TYPE" Form="attribute" Name="PartType" FieldType="" Description="Part Type"/>
<DBFFieldSpec FieldName="MOD_LBR_TY" Form="attribute" Name="LaborType" FieldType="" Description="Labor Type"/>
<DBFFieldSpec FieldName="MOD_LB_HRS" Form="attribute" Name="LaborHours" FieldType="" Description="Labor Hours"/>
<DBFFieldSpec FieldName="PART_TYPE" Form="attribute" Name="PartType" FieldType=""
Description="Part Type"/>
<DBFFieldSpec FieldName="MOD_LBR_TY" Form="attribute" Name="LaborType" FieldType=""
Description="Labor Type"/>
<DBFFieldSpec FieldName="MOD_LB_HRS" Form="attribute" Name="LaborHours" FieldType=""
Description="Labor Hours"/>
<DBFFieldSpec FieldName="LBR_OP" Form="attribute" Name="LaborOp" FieldType="" Description="Labor Op"/>
<DBFFieldSpec FieldName="LINE_IND" Form="attribute" Name="SupplementLevel" FieldType="" Description="Supplement Level"/>
<DBFFieldSpec FieldName="TRAN_CODE" Form="attribute" Name="TransactionCode" FieldType="" Description="Transaction Code"/>
<DBFFieldSpec FieldName="GLASS_FLAG" Form="attribute" Name="GlassFlag" FieldType="" Description="Glass Flag"/>
<DBFFieldSpec FieldName="PRT_DSMK_M" Form="attribute" Name="MarkUp" FieldType="" Description="Price Mark up for non OEM parts"/>
<DBFFieldSpec FieldName="LINE_IND" Form="attribute" Name="SupplementLevel" FieldType=""
Description="Supplement Level"/>
<DBFFieldSpec FieldName="TRAN_CODE" Form="attribute" Name="TransactionCode" FieldType=""
Description="Transaction Code"/>
<DBFFieldSpec FieldName="GLASS_FLAG" Form="attribute" Name="GlassFlag" FieldType=""
Description="Glass Flag"/>
<DBFFieldSpec FieldName="PRT_DSMK_M" Form="attribute" Name="MarkUp" FieldType=""
Description="Price Mark up for non OEM parts"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.VEH">
<DBFFileTranslation ID="ID3" ElementName="Vehicle" Description="Vehicle Table">
<DBFFieldSpec FieldName="V_VIN" Form="attribute" Name="TransVIN" FieldType="" Description=""/>
<DBFFieldSpec FieldName="V_MODEL_YR" Form="attribute" Name="TransYear" FieldType="" Description="V_MODEL_YR"/>
<DBFFieldSpec FieldName="V_MAKEDESC" Form="attribute" Name="ManufName" FieldType="" Description="V_MAKEDESC"/>
<DBFFieldSpec FieldName="V_MAKECODE" Form="attribute" Name="ManufCode" FieldType="" Description="V_MAKECODE"/>
<DBFFieldSpec FieldName="V_MODEL" Form="attribute" Name="TransModel" FieldType="" Description="V_MODEL"/>
<DBFFieldSpec FieldName="V_MILEAGE" Form="attribute" Name="TransMileage" FieldType="" Description="V_MILEAGE"/>
<DBFFieldSpec FieldName="V_MODEL_YR" Form="attribute" Name="TransYear" FieldType=""
Description="V_MODEL_YR"/>
<DBFFieldSpec FieldName="V_MAKEDESC" Form="attribute" Name="ManufName" FieldType=""
Description="V_MAKEDESC"/>
<DBFFieldSpec FieldName="V_MAKECODE" Form="attribute" Name="ManufCode" FieldType=""
Description="V_MAKECODE"/>
<DBFFieldSpec FieldName="V_MODEL" Form="attribute" Name="TransModel" FieldType=""
Description="V_MODEL"/>
<DBFFieldSpec FieldName="V_MILEAGE" Form="attribute" Name="TransMileage" FieldType=""
Description="V_MILEAGE"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.AD1">
<DBFFileTranslation ID="ID4" ElementName="Admin" Description="Administrative information">
<DBFFieldSpec FieldName="OWNR_LN" Form="attribute" Name="OwnerL" FieldType="" Description="Owner Lastname"/>
<DBFFieldSpec FieldName="OWNR_FN" Form="attribute" Name="OwnerF" FieldType="" Description="Owner Firstname"/>
<DBFFieldSpec FieldName="OWNR_CO_NM" Form="attribute" Name="OwnerCompanyName" FieldType="" Description="Owner Company Name"/>
<DBFFieldSpec FieldName="OWNR_TITLE" Form="attribute" Name="OwnerTitle" FieldType="" Description="Owner Title"/>
<DBFFieldSpec FieldName="OWNR_ADDR1" Form="attribute" Name="OwnerAddr1" FieldType="" Description="Owner Address Line 1"/>
<DBFFieldSpec FieldName="OWNR_ADDR2" Form="attribute" Name="OwnerAddr2" FieldType="" Description="Owner Address Line 2"/>
<DBFFieldSpec FieldName="OWNR_CITY" Form="attribute" Name="OwnerCity" FieldType="" Description="Owner City"/>
<DBFFieldSpec FieldName="OWNR_ST" Form="attribute" Name="OwnerState" FieldType="" Description="Owner State"/>
<DBFFieldSpec FieldName="OWNR_ZIP" Form="attribute" Name="OwnerZip" FieldType="" Description="Owner Zip"/>
<DBFFieldSpec FieldName="OWNR_CTRY" Form="attribute" Name="OwnerCountry" FieldType="" Description="Owner Country"/>
<DBFFieldSpec FieldName="OWNR_PH1" Form="attribute" Name="OwnerPhone1" FieldType="" Description="Owner Primary Phone"/>
<DBFFieldSpec FieldName="OWNR_PH1X" Form="attribute" Name="OwnerPhone1Ext" FieldType="" Description="Owner Primary Phone Extension"/>
<DBFFieldSpec FieldName="OWNR_PH2" Form="attribute" Name="OwnerPhone2" FieldType="" Description="Owner Secondary Phone"/>
<DBFFieldSpec FieldName="OWNR_PH2X" Form="attribute" Name="OwnerPhone2Ext" FieldType="" Description="Owner Secondary Phone Extension"/>
<DBFFieldSpec FieldName="OWNR_FAX" Form="attribute" Name="OwnerFax" FieldType="" Description="Owner Fax"/>
<DBFFieldSpec FieldName="OWNR_FAXX" Form="attribute" Name="OwnerFaxExt" FieldType="" Description="Owner Fax Extension"/>
<DBFFieldSpec FieldName="OWNR_EA" Form="attribute" Name="OwnerEmail" FieldType="" Description="Owner Email Address"/>
<DBFFieldSpec FieldName="INS_CO_NM" Form="attribute" Name="InsuranceCompanyName" FieldType="" Description="Insurance Company Name"/>
<DBFFieldSpec FieldName="INS_CO_ID" Form="attribute" Name="InsuranceCompanyID" FieldType="" Description="Insurance Company Identifier"/>
<DBFFieldSpec FieldName="INS_ADDR1" Form="attribute" Name="InsuranceAddr1" FieldType="" Description="Insurance Address Line 1"/>
<DBFFieldSpec FieldName="INS_ADDR2" Form="attribute" Name="InsuranceAddr2" FieldType="" Description="Insurance Address Line 2"/>
<DBFFieldSpec FieldName="INS_CITY" Form="attribute" Name="InsuranceCity" FieldType="" Description="Insurance City"/>
<DBFFieldSpec FieldName="INS_ST" Form="attribute" Name="InsuranceState" FieldType="" Description="Insurance State"/>
<DBFFieldSpec FieldName="INS_ZIP" Form="attribute" Name="InsuranceZip" FieldType="" Description="Insurance Zip"/>
<DBFFieldSpec FieldName="INS_CTRY" Form="attribute" Name="InsuranceCountry" FieldType="" Description="Insurance Country"/>
<DBFFieldSpec FieldName="INS_PH1" Form="attribute" Name="InsurancePhone1" FieldType="" Description="Insurance Primary Phone"/>
<DBFFieldSpec FieldName="INS_PH1X" Form="attribute" Name="InsurancePhone1Ext" FieldType="" Description="Insurance Primary Phone Extension"/>
<DBFFieldSpec FieldName="INS_PH2" Form="attribute" Name="InsurancePhone2" FieldType="" Description="Insurance Secondary Phone"/>
<DBFFieldSpec FieldName="INS_PH2X" Form="attribute" Name="InsurancePhone2Ext" FieldType="" Description="Insurance Secondary Phone Extension"/>
<DBFFieldSpec FieldName="INS_FAX" Form="attribute" Name="InsuranceFax" FieldType="" Description="Insurance Fax"/>
<DBFFieldSpec FieldName="INS_FAXX" Form="attribute" Name="InsuranceFaxExt" FieldType="" Description="Insurance Fax Extension"/>
<DBFFieldSpec FieldName="INS_EA" Form="attribute" Name="InsuranceEmail" FieldType="" Description="Insurance Email Address"/>
<DBFFieldSpec FieldName="INSD_LN" Form="attribute" Name="InsuranceLName" FieldType="" Description="Insurance Last Name"/>
<DBFFieldSpec FieldName="CLM_NO" Form="attribute" Name="ClaimNumber" FieldType="" Description="Claim Number"/>
<DBFFieldSpec FieldName="OWNR_LN" Form="attribute" Name="OwnerL" FieldType=""
Description="Owner Lastname"/>
<DBFFieldSpec FieldName="OWNR_FN" Form="attribute" Name="OwnerF" FieldType=""
Description="Owner Firstname"/>
<DBFFieldSpec FieldName="OWNR_CO_NM" Form="attribute" Name="OwnerCompanyName" FieldType=""
Description="Owner Company Name"/>
<DBFFieldSpec FieldName="OWNR_TITLE" Form="attribute" Name="OwnerTitle" FieldType=""
Description="Owner Title"/>
<DBFFieldSpec FieldName="OWNR_ADDR1" Form="attribute" Name="OwnerAddr1" FieldType=""
Description="Owner Address Line 1"/>
<DBFFieldSpec FieldName="OWNR_ADDR2" Form="attribute" Name="OwnerAddr2" FieldType=""
Description="Owner Address Line 2"/>
<DBFFieldSpec FieldName="OWNR_CITY" Form="attribute" Name="OwnerCity" FieldType=""
Description="Owner City"/>
<DBFFieldSpec FieldName="OWNR_ST" Form="attribute" Name="OwnerState" FieldType=""
Description="Owner State"/>
<DBFFieldSpec FieldName="OWNR_ZIP" Form="attribute" Name="OwnerZip" FieldType=""
Description="Owner Zip"/>
<DBFFieldSpec FieldName="OWNR_CTRY" Form="attribute" Name="OwnerCountry" FieldType=""
Description="Owner Country"/>
<DBFFieldSpec FieldName="OWNR_PH1" Form="attribute" Name="OwnerPhone1" FieldType=""
Description="Owner Primary Phone"/>
<DBFFieldSpec FieldName="OWNR_PH1X" Form="attribute" Name="OwnerPhone1Ext" FieldType=""
Description="Owner Primary Phone Extension"/>
<DBFFieldSpec FieldName="OWNR_PH2" Form="attribute" Name="OwnerPhone2" FieldType=""
Description="Owner Secondary Phone"/>
<DBFFieldSpec FieldName="OWNR_PH2X" Form="attribute" Name="OwnerPhone2Ext" FieldType=""
Description="Owner Secondary Phone Extension"/>
<DBFFieldSpec FieldName="OWNR_FAX" Form="attribute" Name="OwnerFax" FieldType=""
Description="Owner Fax"/>
<DBFFieldSpec FieldName="OWNR_FAXX" Form="attribute" Name="OwnerFaxExt" FieldType=""
Description="Owner Fax Extension"/>
<DBFFieldSpec FieldName="OWNR_EA" Form="attribute" Name="OwnerEmail" FieldType=""
Description="Owner Email Address"/>
<DBFFieldSpec FieldName="INS_CO_NM" Form="attribute" Name="InsuranceCompanyName" FieldType=""
Description="Insurance Company Name"/>
<DBFFieldSpec FieldName="INS_CO_ID" Form="attribute" Name="InsuranceCompanyID" FieldType=""
Description="Insurance Company Identifier"/>
<DBFFieldSpec FieldName="INS_ADDR1" Form="attribute" Name="InsuranceAddr1" FieldType=""
Description="Insurance Address Line 1"/>
<DBFFieldSpec FieldName="INS_ADDR2" Form="attribute" Name="InsuranceAddr2" FieldType=""
Description="Insurance Address Line 2"/>
<DBFFieldSpec FieldName="INS_CITY" Form="attribute" Name="InsuranceCity" FieldType=""
Description="Insurance City"/>
<DBFFieldSpec FieldName="INS_ST" Form="attribute" Name="InsuranceState" FieldType=""
Description="Insurance State"/>
<DBFFieldSpec FieldName="INS_ZIP" Form="attribute" Name="InsuranceZip" FieldType=""
Description="Insurance Zip"/>
<DBFFieldSpec FieldName="INS_CTRY" Form="attribute" Name="InsuranceCountry" FieldType=""
Description="Insurance Country"/>
<DBFFieldSpec FieldName="INS_PH1" Form="attribute" Name="InsurancePhone1" FieldType=""
Description="Insurance Primary Phone"/>
<DBFFieldSpec FieldName="INS_PH1X" Form="attribute" Name="InsurancePhone1Ext" FieldType=""
Description="Insurance Primary Phone Extension"/>
<DBFFieldSpec FieldName="INS_PH2" Form="attribute" Name="InsurancePhone2" FieldType=""
Description="Insurance Secondary Phone"/>
<DBFFieldSpec FieldName="INS_PH2X" Form="attribute" Name="InsurancePhone2Ext" FieldType=""
Description="Insurance Secondary Phone Extension"/>
<DBFFieldSpec FieldName="INS_FAX" Form="attribute" Name="InsuranceFax" FieldType=""
Description="Insurance Fax"/>
<DBFFieldSpec FieldName="INS_FAXX" Form="attribute" Name="InsuranceFaxExt" FieldType=""
Description="Insurance Fax Extension"/>
<DBFFieldSpec FieldName="INS_EA" Form="attribute" Name="InsuranceEmail" FieldType=""
Description="Insurance Email Address"/>
<DBFFieldSpec FieldName="INSD_LN" Form="attribute" Name="InsuranceLName" FieldType=""
Description="Insurance Last Name"/>
<DBFFieldSpec FieldName="CLM_NO" Form="attribute" Name="ClaimNumber" FieldType=""
Description="Claim Number"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.AD2">
<DBFFileTranslation ID="ID5" ElementName="Admin2" Description="Administrative information2">
<DBFFieldSpec FieldName="EST_CT_LN" Form="attribute" Name="EstimatorL" FieldType="" Description="Estimator Lastname"/>
<DBFFieldSpec FieldName="EST_CT_FN" Form="attribute" Name="EstimatorF" FieldType="" Description="Estimator Firstname"/>
<DBFFieldSpec FieldName="EST_CO_NM" Form="attribute" Name="EstimatorCompanyName" FieldType="" Description="Estimator Company Name"/>
<DBFFieldSpec FieldName="EST_CO_ID" Form="attribute" Name="EstimatorCompanyID" FieldType="" Description="Estimator Company Identifier"/>
<DBFFieldSpec FieldName="EST_ADDR1" Form="attribute" Name="EstimatorAddr1" FieldType="" Description="Estimator Address1"/>
<DBFFieldSpec FieldName="EST_ADDR2" Form="attribute" Name="EstimatorAddr2" FieldType="" Description="Estimator Address2"/>
<DBFFieldSpec FieldName="EST_CITY" Form="attribute" Name="EstimatorCity" FieldType="" Description="Estimator City"/>
<DBFFieldSpec FieldName="EST_ST" Form="attribute" Name="EstimatorState" FieldType="" Description="Estimator State"/>
<DBFFieldSpec FieldName="EST_ZIP" Form="attribute" Name="EstimatorZip" FieldType="" Description="Estimator Zip"/>
<DBFFieldSpec FieldName="EST_CTRY" Form="attribute" Name="EstimatorCountry" FieldType="" Description="Estimator Country"/>
<DBFFieldSpec FieldName="EST_PH1" Form="attribute" Name="EstimatorPhone1" FieldType="" Description="Estimator Primary Phone"/>
<DBFFieldSpec FieldName="EST_PH1X" Form="attribute" Name="EstimatorPhone1Ext" FieldType="" Description="Estimator Primary Phone Extension"/>
<DBFFieldSpec FieldName="EST_PH2" Form="attribute" Name="EstimatorPhone2" FieldType="" Description="Estimator Secondary Phone"/>
<DBFFieldSpec FieldName="EST_PH2X" Form="attribute" Name="EstimatorPhone2Ext" FieldType="" Description="Estimator Secondary Phone Extension"/>
<DBFFieldSpec FieldName="EST_FAX" Form="attribute" Name="EstimatorFax" FieldType="" Description="Estimator Fax"/>
<DBFFieldSpec FieldName="EST_FAXX" Form="attribute" Name="EstimatorFaxExt" FieldType="" Description="Estimator Fax Extension"/>
<DBFFieldSpec FieldName="EST_EA" Form="attribute" Name="EstimatorEmail" FieldType="" Description="Estimator Email Address"/>
<DBFFieldSpec FieldName="EST_LIC_NO" Form="attribute" Name="EstimatorLicenseNumber" FieldType="" Description="Estimator License Number"/>
<DBFFieldSpec FieldName="EST_FILENO" Form="attribute" Name="EstimatorFileNumber" FieldType="" Description="Estimator File Number"/>
<DBFFieldSpec FieldName="RO_IN_DATE" Form="attribute" Name="VehicleInDate" FieldType="" Description="Date arrived in shop"/>
<DBFFieldSpec FieldName="RO_IN_TIME" Form="attribute" Name="VehicleInTime" FieldType="" Description="Time arrived in shop"/>
<DBFFieldSpec FieldName="TAR_DATE" Form="attribute" Name="TargetVehicleOutDate" FieldType="" Description="Target date to be completed"/>
<DBFFieldSpec FieldName="TAR_TIME" Form="attribute" Name="TargetVehicleOutTime" FieldType="" Description="Target time to be completed"/>
<DBFFieldSpec FieldName="RO_CMPDATE" Form="attribute" Name="VehicleOutDate" FieldType="" Description="Date completed"/>
<DBFFieldSpec FieldName="RO_CMPTIME" Form="attribute" Name="VehicleOutTime" FieldType="" Description="Time completed"/>
<DBFFieldSpec FieldName="RF_CO_NM" Form="attribute" Name="BodyShopName" FieldType="" Description="Body Shop Name"/>
<DBFFieldSpec FieldName="EST_CT_LN" Form="attribute" Name="EstimatorL" FieldType=""
Description="Estimator Lastname"/>
<DBFFieldSpec FieldName="EST_CT_FN" Form="attribute" Name="EstimatorF" FieldType=""
Description="Estimator Firstname"/>
<DBFFieldSpec FieldName="EST_CO_NM" Form="attribute" Name="EstimatorCompanyName" FieldType=""
Description="Estimator Company Name"/>
<DBFFieldSpec FieldName="EST_CO_ID" Form="attribute" Name="EstimatorCompanyID" FieldType=""
Description="Estimator Company Identifier"/>
<DBFFieldSpec FieldName="EST_ADDR1" Form="attribute" Name="EstimatorAddr1" FieldType=""
Description="Estimator Address1"/>
<DBFFieldSpec FieldName="EST_ADDR2" Form="attribute" Name="EstimatorAddr2" FieldType=""
Description="Estimator Address2"/>
<DBFFieldSpec FieldName="EST_CITY" Form="attribute" Name="EstimatorCity" FieldType=""
Description="Estimator City"/>
<DBFFieldSpec FieldName="EST_ST" Form="attribute" Name="EstimatorState" FieldType=""
Description="Estimator State"/>
<DBFFieldSpec FieldName="EST_ZIP" Form="attribute" Name="EstimatorZip" FieldType=""
Description="Estimator Zip"/>
<DBFFieldSpec FieldName="EST_CTRY" Form="attribute" Name="EstimatorCountry" FieldType=""
Description="Estimator Country"/>
<DBFFieldSpec FieldName="EST_PH1" Form="attribute" Name="EstimatorPhone1" FieldType=""
Description="Estimator Primary Phone"/>
<DBFFieldSpec FieldName="EST_PH1X" Form="attribute" Name="EstimatorPhone1Ext" FieldType=""
Description="Estimator Primary Phone Extension"/>
<DBFFieldSpec FieldName="EST_PH2" Form="attribute" Name="EstimatorPhone2" FieldType=""
Description="Estimator Secondary Phone"/>
<DBFFieldSpec FieldName="EST_PH2X" Form="attribute" Name="EstimatorPhone2Ext" FieldType=""
Description="Estimator Secondary Phone Extension"/>
<DBFFieldSpec FieldName="EST_FAX" Form="attribute" Name="EstimatorFax" FieldType=""
Description="Estimator Fax"/>
<DBFFieldSpec FieldName="EST_FAXX" Form="attribute" Name="EstimatorFaxExt" FieldType=""
Description="Estimator Fax Extension"/>
<DBFFieldSpec FieldName="EST_EA" Form="attribute" Name="EstimatorEmail" FieldType=""
Description="Estimator Email Address"/>
<DBFFieldSpec FieldName="EST_LIC_NO" Form="attribute" Name="EstimatorLicenseNumber" FieldType=""
Description="Estimator License Number"/>
<DBFFieldSpec FieldName="EST_FILENO" Form="attribute" Name="EstimatorFileNumber" FieldType=""
Description="Estimator File Number"/>
<DBFFieldSpec FieldName="RO_IN_DATE" Form="attribute" Name="VehicleInDate" FieldType=""
Description="Date arrived in shop"/>
<DBFFieldSpec FieldName="RO_IN_TIME" Form="attribute" Name="VehicleInTime" FieldType=""
Description="Time arrived in shop"/>
<DBFFieldSpec FieldName="TAR_DATE" Form="attribute" Name="TargetVehicleOutDate" FieldType=""
Description="Target date to be completed"/>
<DBFFieldSpec FieldName="TAR_TIME" Form="attribute" Name="TargetVehicleOutTime" FieldType=""
Description="Target time to be completed"/>
<DBFFieldSpec FieldName="RO_CMPDATE" Form="attribute" Name="VehicleOutDate" FieldType=""
Description="Date completed"/>
<DBFFieldSpec FieldName="RO_CMPTIME" Form="attribute" Name="VehicleOutTime" FieldType=""
Description="Time completed"/>
<DBFFieldSpec FieldName="RF_CO_NM" Form="attribute" Name="BodyShopName" FieldType=""
Description="Body Shop Name"/>
</DBFFileTranslation>
</FileTranslation>
<FileTranslation TranslatorID="OECImportEngine.DBFTranslator" FileNameMask="*.TTL">
<DBFFileTranslation ID="ID6" ElementName="Total" Description="Total Table">
<DBFFieldSpec FieldName="G_TTL_AMT" Form="attribute" Name="GrandTotalAmount" FieldType="" Description=""/>
</DBFFileTranslation>
<DBFFileTranslation ID="ID6" ElementName="Total" Description="Total Table">
<DBFFieldSpec FieldName="G_TTL_AMT" Form="attribute" Name="GrandTotalAmount" FieldType=""
Description=""/>
</DBFFileTranslation>
</FileTranslation>
</FileTranslations>
<StyleSheetTranslation>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -13,47 +13,47 @@ Copy the new key to clipboard:
Add the SSH key to the drop creation screen.
1. Create a new user to replace root user
1. # adduser imex
2. # usermod -aG sudo imex
3. # su - imex
4. $ mkdir ~/.ssh
5. $ chmod 700 ~/.ssh
6. $ nano ~/.ssh/authorized_keys
7. Add the copied SSH key and save.
8. $ chmod 600 ~/.ssh/authorized_keys #Restrict access to authorized keys.
1. # adduser imex
2. # usermod -aG sudo imex
3. # su - imex
4. $ mkdir ~/.ssh
5. $ chmod 700 ~/.ssh
6. $ nano ~/.ssh/authorized_keys
7. Add the copied SSH key and save.
8. $ chmod 600 ~/.ssh/authorized_keys #Restrict access to authorized keys.
2. Setup the Firewall
1. $ sudo ufw allow OpenSSH.
2. $ sudo ufw enable
1. $ sudo ufw allow OpenSSH.
2. $ sudo ufw enable
3. Add Nginx & Configure
1. $ sudo apt-get update
2. $ sudo apt-get install nginx
3. $ sudo ufw allow 'Nginx Full'
4. $ sudo ufw app list
1. Nginx Full: Opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic)
2. Nginx Http: Opens only port 80 (normal, unencrypted web traffic)
3. Nginx Https: Opens only port 443 (TLS/SSL encrypted traffic)
5. Should now be able to go to IP and see nginx responding with a blank page.
1. $ sudo apt-get update
2. $ sudo apt-get install nginx
3. $ sudo ufw allow 'Nginx Full'
4. $ sudo ufw app list
1. Nginx Full: Opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic)
2. Nginx Http: Opens only port 80 (normal, unencrypted web traffic)
3. Nginx Https: Opens only port 443 (TLS/SSL encrypted traffic)
5. Should now be able to go to IP and see nginx responding with a blank page.
4. Install NodeJs
1. $ curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
2. $ sudo apt install nodejs
3. $ node --version
1. $ curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
2. $ sudo apt install nodejs
3. $ node --version
5. Clone Source Code
1. $ git clone git@bitbucket.org:snaptsoft/bodyshop.git //Requires SSH setup.
2. $ cd bodyshop && npm install //Install all server dependencies.
1. $ git clone git@bitbucket.org:snaptsoft/bodyshop.git //Requires SSH setup.
2. $ cd bodyshop && npm install //Install all server dependencies.
6. Setup PM2
1. $ npm install pm2 -g //Had to be run as root.
2. $ pm2 start ecosystem.config.js
3. $ pm2 startup ubuntu //Ensure it starts when server does.
1. $ npm install pm2 -g //Had to be run as root.
2. $ pm2 start ecosystem.config.js
3. $ pm2 startup ubuntu //Ensure it starts when server does.
7. Alter Nginx config
1. sudo nano /etc/nginx/sites-available/default
2. //Add Appropriate server names to the file. www. and non-www.
3. Add the following inside the location of the server block: (Remove the 404 bit.)
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
1. sudo nano /etc/nginx/sites-available/default
2. //Add Appropriate server names to the file. www. and non-www.
3. Add the following inside the location of the server block: (Remove the 404 bit.)
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
8. Install Certbot
9. $ sudo add-apt-repository ppa:certbot/certbot //Potential issue on ubuntu 20.04
10. $ sudo apt-get update

View File

@@ -1,16 +1,16 @@
1. Create a new project
2. Setup sign in methods to be user and email only.
3. Update .env to include config.
4. Setup the Firebase CLI
1. cd to client firebase at server directory.
2. ensure all dependencies installed
1. $ npm install firebase-functions@latest firebase-admin@latest --save
2. $ npm install -g firebase-tools
3. $ firebase login //Login as needed.
3. Update .env to include config.
4. Setup the Firebase CLI
1. cd to client firebase at server directory.
2. ensure all dependencies installed
1. $ npm install firebase-functions@latest firebase-admin@latest --save
2. $ npm install -g firebase-tools
3. $ firebase login //Login as needed.
5. Set the current projct
1. firebase use <projectname>
1. firebase use <projectname>
6. Deploy the function
1. $ firebase deploy --only functions
7. Add the allowed domains.
1. $ firebase deploy --only functions
7. Add the allowed domains.
8. Update server variables including FIREBASE_ADMINSDK_JSON, FIREBASE_DATABASE_URL
9. Create the firestore and copy the rules from dev for userinstances.

View File

@@ -1,20 +1,20 @@
module.exports = {
apps: [
{
name: "IO Test API",
cwd: "./io",
script: "./server.js",
env: {
NODE_ENV: "test",
},
},
apps: [
{
name: "IO Test API",
cwd: "./io",
script: "./server.js",
env: {
NODE_ENV: "test",
},
},
{
name: "Bitbucket Webhook",
script: "./webhook/index.js",
env: {
NODE_ENV: "production",
},
},
],
{
name: "Bitbucket Webhook",
script: "./webhook/index.js",
env: {
NODE_ENV: "production",
},
},
],
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,14 @@
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_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
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_FIREBASE_PUBLIC_VAPID_KEY='BP1B7ZTYpn-KMt6nOxlld6aS8Skt3Q7ZLEqP0hAvGHxG4UojPYiXZ6kPlzZkUC5jH-EcWXomTLtmadAIxurfcHo'
REACT_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
REACT_APP_AXIOS_BASE_API_URL=http://localhost:4000
REACT_APP_REPORTS_SERVER_URL=https://reports3.test.imex.online
REACT_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc
REACT_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc
REACT_APP_COUNTRY=USA

View File

@@ -1,14 +1,14 @@
GENERATE_SOURCEMAP=false
REACT_APP_GRAPHQL_ENDPOINT=https://db.imex.online/v1/graphql
REACT_APP_GRAPHQL_ENDPOINT_WS=wss://db.imex.online/v1/graphql
GENERATE_SOURCEMAP=true
REACT_APP_GRAPHQL_ENDPOINT=https://db.romeonline.io/v1/graphql
REACT_APP_GRAPHQL_ENDPOINT_WS=wss://db.romeonline.io/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_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
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_FIREBASE_PUBLIC_VAPID_KEY='BP1B7ZTYpn-KMt6nOxlld6aS8Skt3Q7ZLEqP0hAvGHxG4UojPYiXZ6kPlzZkUC5jH-EcWXomTLtmadAIxurfcHo'
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_AXIOS_BASE_API_URL=https://api.romeonline.io/
REACT_APP_REPORTS_SERVER_URL=https://reports.romeonline.io
REACT_APP_SPLIT_API=et9pjkik6bn67he5evpmpr1agoo7gactphgk

View File

@@ -1,14 +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_GRAPHQL_ENDPOINT=https://db.test.romeonline.io/v1/graphql
REACT_APP_GRAPHQL_ENDPOINT_WS=wss://db.test.romeonline.io/v1/graphql
REACT_APP_GA_CODE=231103507
REACT_APP_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
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_FIREBASE_PUBLIC_VAPID_KEY='BP1B7ZTYpn-KMt6nOxlld6aS8Skt3Q7ZLEqP0hAvGHxG4UojPYiXZ6kPlzZkUC5jH-EcWXomTLtmadAIxurfcHo'
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_AXIOS_BASE_API_URL=https://api.test.romeonline.io/
REACT_APP_REPORTS_SERVER_URL=https://reports.test.romeonline.io
REACT_APP_IS_TEST=true
REACT_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc

3
client/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
# Sentry Config File
.sentryclirc

1
client/.npmrc Normal file
View File

@@ -0,0 +1 @@
legacy-peer-deps=true

View File

@@ -15,7 +15,8 @@ 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.
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more
information.
### `yarn build`
@@ -31,15 +32,21 @@ See the section about [deployment](https://facebook.github.io/create-react-app/d
**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.
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.
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.
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).
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/).
@@ -65,4 +72,5 @@ This section has moved here: https://facebook.github.io/create-react-app/docs/de
### `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
This section has moved
here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify

View File

@@ -1,73 +1,68 @@
// craco.config.js
const TerserPlugin = require("terser-webpack-plugin");
const CracoLessPlugin = require("craco-less");
const SentryWebpackPlugin = require("@sentry/webpack-plugin");
const {convertLegacyToken} = require('@ant-design/compatible/lib');
const {theme} = require('antd/lib');
const {defaultAlgorithm, defaultSeed} = theme;
const mapToken = defaultAlgorithm(defaultSeed);
const v4Token = convertLegacyToken(mapToken);
// TODO, At the moment we are using less in the Dashboard. Once we remove this we can remove the less processor entirely.
module.exports = {
plugins: [
{
plugin: SentryWebpackPlugin,
options: {
// sentry-cli configuration
authToken:
"6b45b028a02342db97a9a2f92c0959058665443d379d4a3a876430009e744260",
org: "snapt-software",
project: "imexonline",
release: process.env.REACT_APP_GIT_SHA,
// webpack-specific configuration
include: ".",
ignore: ["node_modules", "webpack.config.js"],
},
},
{
plugin: CracoLessPlugin,
options: {
lessLoaderOptions: {
lessOptions: {
modifyVars: {
...(process.env.NODE_ENV === "development"
? { "@primary-color": "#a51d1d" }
: {
//"@primary-color": "#1DA57A"
}),
// "@primary-color": " #1890ff", // primary color for all components
// "@link-color": "#1890ff", // link color
// "@success-color": "#52c41a", // success state color
// "@warning-color": "#faad14", // warning state color
// "@error-color": "#f5222d", // error state color
// "@font-size-base": "14px", // major text font size
// " @heading-color": "rgba(0, 0, 0, 0.85)", // heading text color
// "@text-color": "rgba(0, 0, 0, 0.65)", // major text color
// "@text-color-secondary": "rgba(0, 0, 0, 0.45)", // secondary text color
// "@disabled-color": "rgba(0, 0, 0, 0.25)", // disable state color
// "@border-radius-base": "2px", // major border radius
// "@border-color-base": "#d9d9d9", // major border color
// "@box-shadow-base":
// "0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08),0 9px 28px 8px rgba(0, 0, 0, 0.05); // major shadow for layers }",
plugins: [
// {
// plugin: SentryWebpackPlugin,
// options: {
// // sentry-cli configuration
// authToken:
// "6b45b028a02342db97a9a2f92c0959058665443d379d4a3a876430009e744260",
// org: "snapt-software",
// project: "rome-online",
// release: process.env.REACT_APP_GIT_SHA,
//
// // webpack-specific configuration
// include: ".",
// ignore: ["node_modules", "webpack.config.js"],
// },
// },
{
plugin: CracoLessPlugin,
options: {
lessLoaderOptions: {
lessOptions: {
modifyVars: {...v4Token},
javascriptEnabled: true,
},
},
},
javascriptEnabled: true,
},
},
},
},
],
webpack: {
configure: (webpackConfig) => ({
...webpackConfig,
optimization: {
...webpackConfig.optimization,
// Workaround for CircleCI bug caused by the number of CPUs shown
// https://github.com/facebook/create-react-app/issues/8320
minimizer: webpackConfig.optimization.minimizer.map((item) => {
if (item instanceof TerserPlugin) {
item.options.parallel = 2;
}
],
webpack: {
configure: (webpackConfig) => {
return {
...webpackConfig,
// Required for Dev Server
devServer: {
...webpackConfig.devServer,
allowedHosts: 'all',
},
optimization: {
...webpackConfig.optimization,
// Workaround for CircleCI bug caused by the number of CPUs shown
// https://github.com/facebook/create-react-app/issues/8320
minimizer: webpackConfig.optimization.minimizer.map((item) => {
if (item instanceof TerserPlugin) {
item.options.parallel = 2;
}
return item;
}),
},
}),
},
devtool: "source-map",
return item;
}),
},
};
},
},
devtool: "source-map",
};

17
client/cypress.config.js Normal file
View File

@@ -0,0 +1,17 @@
const {defineConfig} = require('cypress')
module.exports = defineConfig({
experimentalStudio: true,
env: {
FIREBASE_USERNAME: 'cypress@imex.test',
FIREBASE_PASSWORD: 'cypress',
},
e2e: {
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
setupNodeEvents(on, config) {
return require('./cypress/plugins/index.js')(on, config)
},
baseUrl: 'http://localhost:3000',
},
})

View File

@@ -1,8 +0,0 @@
{
"baseUrl": "http://localhost:3000",
"experimentalStudio": true,
"env": {
"FIREBASE_USERNAME": "cypress@imex.test",
"FIREBASE_PASSWORD": "cypress"
}
}

View File

@@ -0,0 +1,24 @@
/// <reference types="Cypress" />
const {FIREBASE_USERNAME, FIREBASE_PASSWORcD} = Cypress.env();
describe("Renders the General Page", () => {
beforeEach(() => {
cy.visit("/");
});
it("Renders Correctly", () => {
});
it("Has the Slogan", () => {
cy.findByText("A whole x22new kind of shop management system.").should(
"exist"
);
/* ==== Generated with Cypress Studio ==== */
cy.get(
".ant-menu-item-active > .ant-menu-title-content > .header0-item-block"
).click();
cy.get("#email").clear();
cy.get("#email").type("patrick@imex.dev");
cy.get("#password").clear();
cy.get("#password").type("patrick123{enter}");
cy.get(".ant-form > .ant-btn").click();
/* ==== End Cypress Studio ==== */
});
});

View File

@@ -0,0 +1,143 @@
/// <reference types="cypress" />
// Welcome to Cypress!
//
// This spec file contains a variety of sample tests
// for a todo list app that are designed to demonstrate
// the power of writing tests in Cypress.
//
// To learn more about how Cypress works and
// what makes it such an awesome testing tool,
// please read our getting started guide:
// https://on.cypress.io/introduction-to-cypress
describe('example to-do app', () => {
beforeEach(() => {
// Cypress starts out with a blank slate for each test
// so we must tell it to visit our website with the `cy.visit()` command.
// Since we want to visit the same URL at the start of all our tests,
// we include it in our beforeEach function so that it runs before each test
cy.visit('https://example.cypress.io/todo')
})
it('displays two todo items by default', () => {
// We use the `cy.get()` command to get all elements that match the selector.
// Then, we use `should` to assert that there are two matched items,
// which are the two default items.
cy.get('.todo-list li').should('have.length', 2)
// We can go even further and check that the default todos each contain
// the correct text. We use the `first` and `last` functions
// to get just the first and last matched elements individually,
// and then perform an assertion with `should`.
cy.get('.todo-list li').first().should('have.text', 'Pay electric bill')
cy.get('.todo-list li').last().should('have.text', 'Walk the dog')
})
it('can add new todo items', () => {
// We'll store our item text in a variable so we can reuse it
const newItem = 'Feed the cat'
// Let's get the input element and use the `type` command to
// input our new list item. After typing the content of our item,
// we need to type the enter key as well in order to submit the input.
// This input has a data-test attribute so we'll use that to select the
// element in accordance with best practices:
// https://on.cypress.io/selecting-elements
cy.get('[data-test=new-todo]').type(`${newItem}{enter}`)
// Now that we've typed our new item, let's check that it actually was added to the list.
// Since it's the newest item, it should exist as the last element in the list.
// In addition, with the two default items, we should have a total of 3 elements in the list.
// Since assertions yield the element that was asserted on,
// we can chain both of these assertions together into a single statement.
cy.get('.todo-list li')
.should('have.length', 3)
.last()
.should('have.text', newItem)
})
it('can check off an item as completed', () => {
// In addition to using the `get` command to get an element by selector,
// we can also use the `contains` command to get an element by its contents.
// However, this will yield the <label>, which is lowest-level element that contains the text.
// In order to check the item, we'll find the <input> element for this <label>
// by traversing up the dom to the parent element. From there, we can `find`
// the child checkbox <input> element and use the `check` command to check it.
cy.contains('Pay electric bill')
.parent()
.find('input[type=checkbox]')
.check()
// Now that we've checked the button, we can go ahead and make sure
// that the list element is now marked as completed.
// Again we'll use `contains` to find the <label> element and then use the `parents` command
// to traverse multiple levels up the dom until we find the corresponding <li> element.
// Once we get that element, we can assert that it has the completed class.
cy.contains('Pay electric bill')
.parents('li')
.should('have.class', 'completed')
})
context('with a checked task', () => {
beforeEach(() => {
// We'll take the command we used above to check off an element
// Since we want to perform multiple tests that start with checking
// one element, we put it in the beforeEach hook
// so that it runs at the start of every test.
cy.contains('Pay electric bill')
.parent()
.find('input[type=checkbox]')
.check()
})
it('can filter for uncompleted tasks', () => {
// We'll click on the "active" button in order to
// display only incomplete items
cy.contains('Active').click()
// After filtering, we can assert that there is only the one
// incomplete item in the list.
cy.get('.todo-list li')
.should('have.length', 1)
.first()
.should('have.text', 'Walk the dog')
// For good measure, let's also assert that the task we checked off
// does not exist on the page.
cy.contains('Pay electric bill').should('not.exist')
})
it('can filter for completed tasks', () => {
// We can perform similar steps as the test above to ensure
// that only completed tasks are shown
cy.contains('Completed').click()
cy.get('.todo-list li')
.should('have.length', 1)
.first()
.should('have.text', 'Pay electric bill')
cy.contains('Walk the dog').should('not.exist')
})
it('can delete all completed tasks', () => {
// First, let's click the "Clear completed" button
// `contains` is actually serving two purposes here.
// First, it's ensuring that the button exists within the dom.
// This button only appears when at least one task is checked
// so this command is implicitly verifying that it does exist.
// Second, it selects the button so we can click it.
cy.contains('Clear completed').click()
// Then we can make sure that there is only one element
// in the list and our element does not exist
cy.get('.todo-list li')
.should('have.length', 1)
.should('not.have.text', 'Pay electric bill')
// Finally, make sure that the clear button no longer exists.
cy.contains('Clear completed').should('not.exist')
})
})
})

View File

@@ -0,0 +1,299 @@
/// <reference types="cypress" />
context('Actions', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/actions')
})
// https://on.cypress.io/interacting-with-elements
it('.type() - type into a DOM element', () => {
// https://on.cypress.io/type
cy.get('.action-email')
.type('fake@email.com').should('have.value', 'fake@email.com')
// .type() with special character sequences
.type('{leftarrow}{rightarrow}{uparrow}{downarrow}')
.type('{del}{selectall}{backspace}')
// .type() with key modifiers
.type('{alt}{option}') //these are equivalent
.type('{ctrl}{control}') //these are equivalent
.type('{meta}{command}{cmd}') //these are equivalent
.type('{shift}')
// Delay each keypress by 0.1 sec
.type('slow.typing@email.com', {delay: 100})
.should('have.value', 'slow.typing@email.com')
cy.get('.action-disabled')
// Ignore error checking prior to type
// like whether the input is visible or disabled
.type('disabled error checking', {force: true})
.should('have.value', 'disabled error checking')
})
it('.focus() - focus on a DOM element', () => {
// https://on.cypress.io/focus
cy.get('.action-focus').focus()
.should('have.class', 'focus')
.prev().should('have.attr', 'style', 'color: orange;')
})
it('.blur() - blur off a DOM element', () => {
// https://on.cypress.io/blur
cy.get('.action-blur').type('About to blur').blur()
.should('have.class', 'error')
.prev().should('have.attr', 'style', 'color: red;')
})
it('.clear() - clears an input or textarea element', () => {
// https://on.cypress.io/clear
cy.get('.action-clear').type('Clear this text')
.should('have.value', 'Clear this text')
.clear()
.should('have.value', '')
})
it('.submit() - submit a form', () => {
// https://on.cypress.io/submit
cy.get('.action-form')
.find('[type="text"]').type('HALFOFF')
cy.get('.action-form').submit()
.next().should('contain', 'Your form has been submitted!')
})
it('.click() - click on a DOM element', () => {
// https://on.cypress.io/click
cy.get('.action-btn').click()
// You can click on 9 specific positions of an element:
// -----------------------------------
// | topLeft top topRight |
// | |
// | |
// | |
// | left center right |
// | |
// | |
// | |
// | bottomLeft bottom bottomRight |
// -----------------------------------
// clicking in the center of the element is the default
cy.get('#action-canvas').click()
cy.get('#action-canvas').click('topLeft')
cy.get('#action-canvas').click('top')
cy.get('#action-canvas').click('topRight')
cy.get('#action-canvas').click('left')
cy.get('#action-canvas').click('right')
cy.get('#action-canvas').click('bottomLeft')
cy.get('#action-canvas').click('bottom')
cy.get('#action-canvas').click('bottomRight')
// .click() accepts an x and y coordinate
// that controls where the click occurs :)
cy.get('#action-canvas')
.click(80, 75) // click 80px on x coord and 75px on y coord
.click(170, 75)
.click(80, 165)
.click(100, 185)
.click(125, 190)
.click(150, 185)
.click(170, 165)
// click multiple elements by passing multiple: true
cy.get('.action-labels>.label').click({multiple: true})
// Ignore error checking prior to clicking
cy.get('.action-opacity>.btn').click({force: true})
})
it('.dblclick() - double click on a DOM element', () => {
// https://on.cypress.io/dblclick
// Our app has a listener on 'dblclick' event in our 'scripts.js'
// that hides the div and shows an input on double click
cy.get('.action-div').dblclick().should('not.be.visible')
cy.get('.action-input-hidden').should('be.visible')
})
it('.rightclick() - right click on a DOM element', () => {
// https://on.cypress.io/rightclick
// Our app has a listener on 'contextmenu' event in our 'scripts.js'
// that hides the div and shows an input on right click
cy.get('.rightclick-action-div').rightclick().should('not.be.visible')
cy.get('.rightclick-action-input-hidden').should('be.visible')
})
it('.check() - check a checkbox or radio element', () => {
// https://on.cypress.io/check
// By default, .check() will check all
// matching checkbox or radio elements in succession, one after another
cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]')
.check().should('be.checked')
cy.get('.action-radios [type="radio"]').not('[disabled]')
.check().should('be.checked')
// .check() accepts a value argument
cy.get('.action-radios [type="radio"]')
.check('radio1').should('be.checked')
// .check() accepts an array of values
cy.get('.action-multiple-checkboxes [type="checkbox"]')
.check(['checkbox1', 'checkbox2']).should('be.checked')
// Ignore error checking prior to checking
cy.get('.action-checkboxes [disabled]')
.check({force: true}).should('be.checked')
cy.get('.action-radios [type="radio"]')
.check('radio3', {force: true}).should('be.checked')
})
it('.uncheck() - uncheck a checkbox element', () => {
// https://on.cypress.io/uncheck
// By default, .uncheck() will uncheck all matching
// checkbox elements in succession, one after another
cy.get('.action-check [type="checkbox"]')
.not('[disabled]')
.uncheck().should('not.be.checked')
// .uncheck() accepts a value argument
cy.get('.action-check [type="checkbox"]')
.check('checkbox1')
.uncheck('checkbox1').should('not.be.checked')
// .uncheck() accepts an array of values
cy.get('.action-check [type="checkbox"]')
.check(['checkbox1', 'checkbox3'])
.uncheck(['checkbox1', 'checkbox3']).should('not.be.checked')
// Ignore error checking prior to unchecking
cy.get('.action-check [disabled]')
.uncheck({force: true}).should('not.be.checked')
})
it('.select() - select an option in a <select> element', () => {
// https://on.cypress.io/select
// at first, no option should be selected
cy.get('.action-select')
.should('have.value', '--Select a fruit--')
// Select option(s) with matching text content
cy.get('.action-select').select('apples')
// confirm the apples were selected
// note that each value starts with "fr-" in our HTML
cy.get('.action-select').should('have.value', 'fr-apples')
cy.get('.action-select-multiple')
.select(['apples', 'oranges', 'bananas'])
// when getting multiple values, invoke "val" method first
.invoke('val')
.should('deep.equal', ['fr-apples', 'fr-oranges', 'fr-bananas'])
// Select option(s) with matching value
cy.get('.action-select').select('fr-bananas')
// can attach an assertion right away to the element
.should('have.value', 'fr-bananas')
cy.get('.action-select-multiple')
.select(['fr-apples', 'fr-oranges', 'fr-bananas'])
.invoke('val')
.should('deep.equal', ['fr-apples', 'fr-oranges', 'fr-bananas'])
// assert the selected values include oranges
cy.get('.action-select-multiple')
.invoke('val').should('include', 'fr-oranges')
})
it('.scrollIntoView() - scroll an element into view', () => {
// https://on.cypress.io/scrollintoview
// normally all of these buttons are hidden,
// because they're not within
// the viewable area of their parent
// (we need to scroll to see them)
cy.get('#scroll-horizontal button')
.should('not.be.visible')
// scroll the button into view, as if the user had scrolled
cy.get('#scroll-horizontal button').scrollIntoView()
.should('be.visible')
cy.get('#scroll-vertical button')
.should('not.be.visible')
// Cypress handles the scroll direction needed
cy.get('#scroll-vertical button').scrollIntoView()
.should('be.visible')
cy.get('#scroll-both button')
.should('not.be.visible')
// Cypress knows to scroll to the right and down
cy.get('#scroll-both button').scrollIntoView()
.should('be.visible')
})
it('.trigger() - trigger an event on a DOM element', () => {
// https://on.cypress.io/trigger
// To interact with a range input (slider)
// we need to set its value & trigger the
// event to signal it changed
// Here, we invoke jQuery's val() method to set
// the value and trigger the 'change' event
cy.get('.trigger-input-range')
.invoke('val', 25)
.trigger('change')
.get('input[type=range]').siblings('p')
.should('have.text', '25')
})
it('cy.scrollTo() - scroll the window or element to a position', () => {
// https://on.cypress.io/scrollto
// You can scroll to 9 specific positions of an element:
// -----------------------------------
// | topLeft top topRight |
// | |
// | |
// | |
// | left center right |
// | |
// | |
// | |
// | bottomLeft bottom bottomRight |
// -----------------------------------
// if you chain .scrollTo() off of cy, we will
// scroll the entire window
cy.scrollTo('bottom')
cy.get('#scrollable-horizontal').scrollTo('right')
// or you can scroll to a specific coordinate:
// (x axis, y axis) in pixels
cy.get('#scrollable-vertical').scrollTo(250, 250)
// or you can scroll to a specific percentage
// of the (width, height) of the element
cy.get('#scrollable-both').scrollTo('75%', '25%')
// control the easing of the scroll (default is 'swing')
cy.get('#scrollable-vertical').scrollTo('center', {easing: 'linear'})
// control the duration of the scroll (in ms)
cy.get('#scrollable-both').scrollTo('center', {duration: 2000})
})
})

View File

@@ -0,0 +1,39 @@
/// <reference types="cypress" />
context('Aliasing', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/aliasing')
})
it('.as() - alias a DOM element for later use', () => {
// https://on.cypress.io/as
// Alias a DOM element for use later
// We don't have to traverse to the element
// later in our code, we reference it with @
cy.get('.as-table').find('tbody>tr')
.first().find('td').first()
.find('button').as('firstBtn')
// when we reference the alias, we place an
// @ in front of its name
cy.get('@firstBtn').click()
cy.get('@firstBtn')
.should('have.class', 'btn-success')
.and('contain', 'Changed')
})
it('.as() - alias a route for later use', () => {
// Alias the route to wait for its response
cy.intercept('GET', '**/comments/*').as('getComment')
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.network-btn').click()
// https://on.cypress.io/wait
cy.wait('@getComment').its('response.statusCode').should('eq', 200)
})
})

View File

@@ -0,0 +1,177 @@
/// <reference types="cypress" />
context('Assertions', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/assertions')
})
describe('Implicit Assertions', () => {
it('.should() - make an assertion about the current subject', () => {
// https://on.cypress.io/should
cy.get('.assertion-table')
.find('tbody tr:last')
.should('have.class', 'success')
.find('td')
.first()
// checking the text of the <td> element in various ways
.should('have.text', 'Column content')
.should('contain', 'Column content')
.should('have.html', 'Column content')
// chai-jquery uses "is()" to check if element matches selector
.should('match', 'td')
// to match text content against a regular expression
// first need to invoke jQuery method text()
// and then match using regular expression
.invoke('text')
.should('match', /column content/i)
// a better way to check element's text content against a regular expression
// is to use "cy.contains"
// https://on.cypress.io/contains
cy.get('.assertion-table')
.find('tbody tr:last')
// finds first <td> element with text content matching regular expression
.contains('td', /column content/i)
.should('be.visible')
// for more information about asserting element's text
// see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-elements-text-contents
})
it('.and() - chain multiple assertions together', () => {
// https://on.cypress.io/and
cy.get('.assertions-link')
.should('have.class', 'active')
.and('have.attr', 'href')
.and('include', 'cypress.io')
})
})
describe('Explicit Assertions', () => {
// https://on.cypress.io/assertions
it('expect - make an assertion about a specified subject', () => {
// We can use Chai's BDD style assertions
expect(true).to.be.true
const o = {foo: 'bar'}
expect(o).to.equal(o)
expect(o).to.deep.equal({foo: 'bar'})
// matching text using regular expression
expect('FooBar').to.match(/bar$/i)
})
it('pass your own callback function to should()', () => {
// Pass a function to should that can have any number
// of explicit assertions within it.
// The ".should(cb)" function will be retried
// automatically until it passes all your explicit assertions or times out.
cy.get('.assertions-p')
.find('p')
.should(($p) => {
// https://on.cypress.io/$
// return an array of texts from all of the p's
// @ts-ignore TS6133 unused variable
const texts = $p.map((i, el) => Cypress.$(el).text())
// jquery map returns jquery object
// and .get() convert this to simple array
const paragraphs = texts.get()
// array should have length of 3
expect(paragraphs, 'has 3 paragraphs').to.have.length(3)
// use second argument to expect(...) to provide clear
// message with each assertion
expect(paragraphs, 'has expected text in each paragraph').to.deep.eq([
'Some text from first p',
'More text from second p',
'And even more text from third p',
])
})
})
it('finds element by class name regex', () => {
cy.get('.docs-header')
.find('div')
// .should(cb) callback function will be retried
.should(($div) => {
expect($div).to.have.length(1)
const className = $div[0].className
expect(className).to.match(/heading-/)
})
// .then(cb) callback is not retried,
// it either passes or fails
.then(($div) => {
expect($div, 'text content').to.have.text('Introduction')
})
})
it('can throw any error', () => {
cy.get('.docs-header')
.find('div')
.should(($div) => {
if ($div.length !== 1) {
// you can throw your own errors
throw new Error('Did not find 1 element')
}
const className = $div[0].className
if (!className.match(/heading-/)) {
throw new Error(`Could not find class "heading-" in ${className}`)
}
})
})
it('matches unknown text between two elements', () => {
/**
* Text from the first element.
* @type {string}
*/
let text
/**
* Normalizes passed text,
* useful before comparing text with spaces and different capitalization.
* @param {string} s Text to normalize
*/
const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase()
cy.get('.two-elements')
.find('.first')
.then(($first) => {
// save text from the first element
text = normalizeText($first.text())
})
cy.get('.two-elements')
.find('.second')
.should(($div) => {
// we can massage text before comparing
const secondText = normalizeText($div.text())
expect(secondText, 'second text').to.equal(text)
})
})
it('assert - assert shape of an object', () => {
const person = {
name: 'Joe',
age: 20,
}
assert.isObject(person, 'value is object')
})
it('retries the should callback until assertions pass', () => {
cy.get('#random-number')
.should(($div) => {
const n = parseFloat($div.text())
expect(n).to.be.gte(1).and.be.lte(10)
})
})
})
})

View File

@@ -0,0 +1,97 @@
/// <reference types="cypress" />
context('Connectors', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/connectors')
})
it('.each() - iterate over an array of elements', () => {
// https://on.cypress.io/each
cy.get('.connectors-each-ul>li')
.each(($el, index, $list) => {
console.log($el, index, $list)
})
})
it('.its() - get properties on the current subject', () => {
// https://on.cypress.io/its
cy.get('.connectors-its-ul>li')
// calls the 'length' property yielding that value
.its('length')
.should('be.gt', 2)
})
it('.invoke() - invoke a function on the current subject', () => {
// our div is hidden in our script.js
// $('.connectors-div').hide()
// https://on.cypress.io/invoke
cy.get('.connectors-div').should('be.hidden')
// call the jquery method 'show' on the 'div.container'
.invoke('show')
.should('be.visible')
})
it('.spread() - spread an array as individual args to callback function', () => {
// https://on.cypress.io/spread
const arr = ['foo', 'bar', 'baz']
cy.wrap(arr).spread((foo, bar, baz) => {
expect(foo).to.eq('foo')
expect(bar).to.eq('bar')
expect(baz).to.eq('baz')
})
})
describe('.then()', () => {
it('invokes a callback function with the current subject', () => {
// https://on.cypress.io/then
cy.get('.connectors-list > li')
.then(($lis) => {
expect($lis, '3 items').to.have.length(3)
expect($lis.eq(0), 'first item').to.contain('Walk the dog')
expect($lis.eq(1), 'second item').to.contain('Feed the cat')
expect($lis.eq(2), 'third item').to.contain('Write JavaScript')
})
})
it('yields the returned value to the next command', () => {
cy.wrap(1)
.then((num) => {
expect(num).to.equal(1)
return 2
})
.then((num) => {
expect(num).to.equal(2)
})
})
it('yields the original subject without return', () => {
cy.wrap(1)
.then((num) => {
expect(num).to.equal(1)
// note that nothing is returned from this callback
})
.then((num) => {
// this callback receives the original unchanged value 1
expect(num).to.equal(1)
})
})
it('yields the value yielded by the last Cypress command inside', () => {
cy.wrap(1)
.then((num) => {
expect(num).to.equal(1)
// note how we run a Cypress command
// the result yielded by this Cypress command
// will be passed to the second ".then"
cy.wrap(2)
})
.then((num) => {
// this callback receives the value yielded by "cy.wrap(2)"
expect(num).to.equal(2)
})
})
})
})

View File

@@ -0,0 +1,77 @@
/// <reference types="cypress" />
context('Cookies', () => {
beforeEach(() => {
Cypress.Cookies.debug(true)
cy.visit('https://example.cypress.io/commands/cookies')
// clear cookies again after visiting to remove
// any 3rd party cookies picked up such as cloudflare
cy.clearCookies()
})
it('cy.getCookie() - get a browser cookie', () => {
// https://on.cypress.io/getcookie
cy.get('#getCookie .set-a-cookie').click()
// cy.getCookie() yields a cookie object
cy.getCookie('token').should('have.property', 'value', '123ABC')
})
it('cy.getCookies() - get browser cookies', () => {
// https://on.cypress.io/getcookies
cy.getCookies().should('be.empty')
cy.get('#getCookies .set-a-cookie').click()
// cy.getCookies() yields an array of cookies
cy.getCookies().should('have.length', 1).should((cookies) => {
// each cookie has these properties
expect(cookies[0]).to.have.property('name', 'token')
expect(cookies[0]).to.have.property('value', '123ABC')
expect(cookies[0]).to.have.property('httpOnly', false)
expect(cookies[0]).to.have.property('secure', false)
expect(cookies[0]).to.have.property('domain')
expect(cookies[0]).to.have.property('path')
})
})
it('cy.setCookie() - set a browser cookie', () => {
// https://on.cypress.io/setcookie
cy.getCookies().should('be.empty')
cy.setCookie('foo', 'bar')
// cy.getCookie() yields a cookie object
cy.getCookie('foo').should('have.property', 'value', 'bar')
})
it('cy.clearCookie() - clear a browser cookie', () => {
// https://on.cypress.io/clearcookie
cy.getCookie('token').should('be.null')
cy.get('#clearCookie .set-a-cookie').click()
cy.getCookie('token').should('have.property', 'value', '123ABC')
// cy.clearCookies() yields null
cy.clearCookie('token').should('be.null')
cy.getCookie('token').should('be.null')
})
it('cy.clearCookies() - clear browser cookies', () => {
// https://on.cypress.io/clearcookies
cy.getCookies().should('be.empty')
cy.get('#clearCookies .set-a-cookie').click()
cy.getCookies().should('have.length', 1)
// cy.clearCookies() yields null
cy.clearCookies()
cy.getCookies().should('be.empty')
})
})

View File

@@ -0,0 +1,202 @@
/// <reference types="cypress" />
context('Cypress.Commands', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
// https://on.cypress.io/custom-commands
it('.add() - create a custom command', () => {
Cypress.Commands.add('console', {
prevSubject: true,
}, (subject, method) => {
// the previous subject is automatically received
// and the commands arguments are shifted
// allow us to change the console method used
method = method || 'log'
// log the subject to the console
// @ts-ignore TS7017
console[method]('The subject is', subject)
// whatever we return becomes the new subject
// we don't want to change the subject so
// we return whatever was passed in
return subject
})
// @ts-ignore TS2339
cy.get('button').console('info').then(($button) => {
// subject is still $button
})
})
})
context('Cypress.Cookies', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
// https://on.cypress.io/cookies
it('.debug() - enable or disable debugging', () => {
Cypress.Cookies.debug(true)
// Cypress will now log in the console when
// cookies are set or cleared
cy.setCookie('fakeCookie', '123ABC')
cy.clearCookie('fakeCookie')
cy.setCookie('fakeCookie', '123ABC')
cy.clearCookie('fakeCookie')
cy.setCookie('fakeCookie', '123ABC')
})
it('.preserveOnce() - preserve cookies by key', () => {
// normally cookies are reset after each test
cy.getCookie('fakeCookie').should('not.be.ok')
// preserving a cookie will not clear it when
// the next test starts
cy.setCookie('lastCookie', '789XYZ')
Cypress.Cookies.preserveOnce('lastCookie')
})
it('.defaults() - set defaults for all cookies', () => {
// now any cookie with the name 'session_id' will
// not be cleared before each new test runs
Cypress.Cookies.defaults({
preserve: 'session_id',
})
})
})
context('Cypress.arch', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
it('Get CPU architecture name of underlying OS', () => {
// https://on.cypress.io/arch
expect(Cypress.arch).to.exist
})
})
context('Cypress.config()', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
it('Get and set configuration options', () => {
// https://on.cypress.io/config
let myConfig = Cypress.config()
expect(myConfig).to.have.property('animationDistanceThreshold', 5)
expect(myConfig).to.have.property('baseUrl', null)
expect(myConfig).to.have.property('defaultCommandTimeout', 4000)
expect(myConfig).to.have.property('requestTimeout', 5000)
expect(myConfig).to.have.property('responseTimeout', 30000)
expect(myConfig).to.have.property('viewportHeight', 660)
expect(myConfig).to.have.property('viewportWidth', 1000)
expect(myConfig).to.have.property('pageLoadTimeout', 60000)
expect(myConfig).to.have.property('waitForAnimations', true)
expect(Cypress.config('pageLoadTimeout')).to.eq(60000)
// this will change the config for the rest of your tests!
Cypress.config('pageLoadTimeout', 20000)
expect(Cypress.config('pageLoadTimeout')).to.eq(20000)
Cypress.config('pageLoadTimeout', 60000)
})
})
context('Cypress.dom', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
// https://on.cypress.io/dom
it('.isHidden() - determine if a DOM element is hidden', () => {
let hiddenP = Cypress.$('.dom-p p.hidden').get(0)
let visibleP = Cypress.$('.dom-p p.visible').get(0)
// our first paragraph has css class 'hidden'
expect(Cypress.dom.isHidden(hiddenP)).to.be.true
expect(Cypress.dom.isHidden(visibleP)).to.be.false
})
})
context('Cypress.env()', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
// We can set environment variables for highly dynamic values
// https://on.cypress.io/environment-variables
it('Get environment variables', () => {
// https://on.cypress.io/env
// set multiple environment variables
Cypress.env({
host: 'veronica.dev.local',
api_server: 'http://localhost:8888/v1/',
})
// get environment variable
expect(Cypress.env('host')).to.eq('veronica.dev.local')
// set environment variable
Cypress.env('api_server', 'http://localhost:8888/v2/')
expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/')
// get all environment variable
expect(Cypress.env()).to.have.property('host', 'veronica.dev.local')
expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/')
})
})
context('Cypress.log', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
it('Control what is printed to the Command Log', () => {
// https://on.cypress.io/cypress-log
})
})
context('Cypress.platform', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
it('Get underlying OS name', () => {
// https://on.cypress.io/platform
expect(Cypress.platform).to.be.exist
})
})
context('Cypress.version', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
it('Get current version of Cypress being run', () => {
// https://on.cypress.io/version
expect(Cypress.version).to.be.exist
})
})
context('Cypress.spec', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
it('Get current spec information', () => {
// https://on.cypress.io/spec
// wrap the object so we can inspect it easily by clicking in the command log
cy.wrap(Cypress.spec).should('include.keys', ['name', 'relative', 'absolute'])
})
})

View File

@@ -0,0 +1,88 @@
/// <reference types="cypress" />
/// JSON fixture file can be loaded directly using
// the built-in JavaScript bundler
// @ts-ignore
const requiredExample = require('../../fixtures/example')
context('Files', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/files')
})
beforeEach(() => {
// load example.json fixture file and store
// in the test context object
cy.fixture('example.json').as('example')
})
it('cy.fixture() - load a fixture', () => {
// https://on.cypress.io/fixture
// Instead of writing a response inline you can
// use a fixture file's content.
// when application makes an Ajax request matching "GET **/comments/*"
// Cypress will intercept it and reply with the object in `example.json` fixture
cy.intercept('GET', '**/comments/*', {fixture: 'example.json'}).as('getComment')
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.fixture-btn').click()
cy.wait('@getComment').its('response.body')
.should('have.property', 'name')
.and('include', 'Using fixtures to represent data')
})
it('cy.fixture() or require - load a fixture', function () {
// we are inside the "function () { ... }"
// callback and can use test context object "this"
// "this.example" was loaded in "beforeEach" function callback
expect(this.example, 'fixture in the test context')
.to.deep.equal(requiredExample)
// or use "cy.wrap" and "should('deep.equal', ...)" assertion
cy.wrap(this.example)
.should('deep.equal', requiredExample)
})
it('cy.readFile() - read file contents', () => {
// https://on.cypress.io/readfile
// You can read a file and yield its contents
// The filePath is relative to your project's root.
cy.readFile('cypress.json').then((json) => {
expect(json).to.be.an('object')
})
})
it('cy.writeFile() - write to a file', () => {
// https://on.cypress.io/writefile
// You can write to a file
// Use a response from a request to automatically
// generate a fixture file for use later
cy.request('https://jsonplaceholder.cypress.io/users')
.then((response) => {
cy.writeFile('cypress/fixtures/users.json', response.body)
})
cy.fixture('users').should((users) => {
expect(users[0].name).to.exist
})
// JavaScript arrays and objects are stringified
// and formatted into text.
cy.writeFile('cypress/fixtures/profile.json', {
id: 8739,
name: 'Jane',
email: 'jane@example.com',
})
cy.fixture('profile').should((profile) => {
expect(profile.name).to.eq('Jane')
})
})
})

View File

@@ -0,0 +1,52 @@
/// <reference types="cypress" />
context('Local Storage', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/local-storage')
})
// Although local storage is automatically cleared
// in between tests to maintain a clean state
// sometimes we need to clear the local storage manually
it('cy.clearLocalStorage() - clear all data in local storage', () => {
// https://on.cypress.io/clearlocalstorage
cy.get('.ls-btn').click().should(() => {
expect(localStorage.getItem('prop1')).to.eq('red')
expect(localStorage.getItem('prop2')).to.eq('blue')
expect(localStorage.getItem('prop3')).to.eq('magenta')
})
// clearLocalStorage() yields the localStorage object
cy.clearLocalStorage().should((ls) => {
expect(ls.getItem('prop1')).to.be.null
expect(ls.getItem('prop2')).to.be.null
expect(ls.getItem('prop3')).to.be.null
})
cy.get('.ls-btn').click().should(() => {
expect(localStorage.getItem('prop1')).to.eq('red')
expect(localStorage.getItem('prop2')).to.eq('blue')
expect(localStorage.getItem('prop3')).to.eq('magenta')
})
// Clear key matching string in Local Storage
cy.clearLocalStorage('prop1').should((ls) => {
expect(ls.getItem('prop1')).to.be.null
expect(ls.getItem('prop2')).to.eq('blue')
expect(ls.getItem('prop3')).to.eq('magenta')
})
cy.get('.ls-btn').click().should(() => {
expect(localStorage.getItem('prop1')).to.eq('red')
expect(localStorage.getItem('prop2')).to.eq('blue')
expect(localStorage.getItem('prop3')).to.eq('magenta')
})
// Clear keys matching regex in Local Storage
cy.clearLocalStorage(/prop1|2/).should((ls) => {
expect(ls.getItem('prop1')).to.be.null
expect(ls.getItem('prop2')).to.be.null
expect(ls.getItem('prop3')).to.eq('magenta')
})
})
})

View File

@@ -0,0 +1,32 @@
/// <reference types="cypress" />
context('Location', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/location')
})
it('cy.hash() - get the current URL hash', () => {
// https://on.cypress.io/hash
cy.hash().should('be.empty')
})
it('cy.location() - get window.location', () => {
// https://on.cypress.io/location
cy.location().should((location) => {
expect(location.hash).to.be.empty
expect(location.href).to.eq('https://example.cypress.io/commands/location')
expect(location.host).to.eq('example.cypress.io')
expect(location.hostname).to.eq('example.cypress.io')
expect(location.origin).to.eq('https://example.cypress.io')
expect(location.pathname).to.eq('/commands/location')
expect(location.port).to.eq('')
expect(location.protocol).to.eq('https:')
expect(location.search).to.be.empty
})
})
it('cy.url() - get the current URL', () => {
// https://on.cypress.io/url
cy.url().should('eq', 'https://example.cypress.io/commands/location')
})
})

View File

@@ -0,0 +1,106 @@
/// <reference types="cypress" />
context('Misc', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/misc')
})
it('.end() - end the command chain', () => {
// https://on.cypress.io/end
// cy.end is useful when you want to end a chain of commands
// and force Cypress to re-query from the root element
cy.get('.misc-table').within(() => {
// ends the current chain and yields null
cy.contains('Cheryl').click().end()
// queries the entire table again
cy.contains('Charles').click()
})
})
it('cy.exec() - execute a system command', () => {
// execute a system command.
// so you can take actions necessary for
// your test outside the scope of Cypress.
// https://on.cypress.io/exec
// we can use Cypress.platform string to
// select appropriate command
// https://on.cypress/io/platform
cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`)
// on CircleCI Windows build machines we have a failure to run bash shell
// https://github.com/cypress-io/cypress/issues/5169
// so skip some of the tests by passing flag "--env circle=true"
const isCircleOnWindows = Cypress.platform === 'win32' && Cypress.env('circle')
if (isCircleOnWindows) {
cy.log('Skipping test on CircleCI')
return
}
// cy.exec problem on Shippable CI
// https://github.com/cypress-io/cypress/issues/6718
const isShippable = Cypress.platform === 'linux' && Cypress.env('shippable')
if (isShippable) {
cy.log('Skipping test on ShippableCI')
return
}
cy.exec('echo Jane Lane')
.its('stdout').should('contain', 'Jane Lane')
if (Cypress.platform === 'win32') {
cy.exec('print cypress.json')
.its('stderr').should('be.empty')
} else {
cy.exec('cat cypress.json')
.its('stderr').should('be.empty')
cy.exec('pwd')
.its('code').should('eq', 0)
}
})
it('cy.focused() - get the DOM element that has focus', () => {
// https://on.cypress.io/focused
cy.get('.misc-form').find('#name').click()
cy.focused().should('have.id', 'name')
cy.get('.misc-form').find('#description').click()
cy.focused().should('have.id', 'description')
})
context('Cypress.Screenshot', function () {
it('cy.screenshot() - take a screenshot', () => {
// https://on.cypress.io/screenshot
cy.screenshot('my-image')
})
it('Cypress.Screenshot.defaults() - change default config of screenshots', function () {
Cypress.Screenshot.defaults({
blackout: ['.foo'],
capture: 'viewport',
clip: {x: 0, y: 0, width: 200, height: 200},
scale: false,
disableTimersAndAnimations: true,
screenshotOnRunFailure: true,
onBeforeScreenshot() {
},
onAfterScreenshot() {
},
})
})
})
it('cy.wrap() - wrap an object', () => {
// https://on.cypress.io/wrap
cy.wrap({foo: 'bar'})
.should('have.property', 'foo')
.and('include', 'bar')
})
})

View File

@@ -0,0 +1,56 @@
/// <reference types="cypress" />
context('Navigation', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io')
cy.get('.navbar-nav').contains('Commands').click()
cy.get('.dropdown-menu').contains('Navigation').click()
})
it('cy.go() - go back or forward in the browser\'s history', () => {
// https://on.cypress.io/go
cy.location('pathname').should('include', 'navigation')
cy.go('back')
cy.location('pathname').should('not.include', 'navigation')
cy.go('forward')
cy.location('pathname').should('include', 'navigation')
// clicking back
cy.go(-1)
cy.location('pathname').should('not.include', 'navigation')
// clicking forward
cy.go(1)
cy.location('pathname').should('include', 'navigation')
})
it('cy.reload() - reload the page', () => {
// https://on.cypress.io/reload
cy.reload()
// reload the page without using the cache
cy.reload(true)
})
it('cy.visit() - visit a remote url', () => {
// https://on.cypress.io/visit
// Visit any sub-domain of your current domain
// Pass options to the visit
cy.visit('https://example.cypress.io/commands/navigation', {
timeout: 50000, // increase total time for the visit to resolve
onBeforeLoad(contentWindow) {
// contentWindow is the remote page's window object
expect(typeof contentWindow === 'object').to.be.true
},
onLoad(contentWindow) {
// contentWindow is the remote page's window object
expect(typeof contentWindow === 'object').to.be.true
},
})
})
})

View File

@@ -0,0 +1,163 @@
/// <reference types="cypress" />
context('Network Requests', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/network-requests')
})
// Manage HTTP requests in your app
it('cy.request() - make an XHR request', () => {
// https://on.cypress.io/request
cy.request('https://jsonplaceholder.cypress.io/comments')
.should((response) => {
expect(response.status).to.eq(200)
// the server sometimes gets an extra comment posted from another machine
// which gets returned as 1 extra object
expect(response.body).to.have.property('length').and.be.oneOf([500, 501])
expect(response).to.have.property('headers')
expect(response).to.have.property('duration')
})
})
it('cy.request() - verify response using BDD syntax', () => {
cy.request('https://jsonplaceholder.cypress.io/comments')
.then((response) => {
// https://on.cypress.io/assertions
expect(response).property('status').to.equal(200)
expect(response).property('body').to.have.property('length').and.be.oneOf([500, 501])
expect(response).to.include.keys('headers', 'duration')
})
})
it('cy.request() with query parameters', () => {
// will execute request
// https://jsonplaceholder.cypress.io/comments?postId=1&id=3
cy.request({
url: 'https://jsonplaceholder.cypress.io/comments',
qs: {
postId: 1,
id: 3,
},
})
.its('body')
.should('be.an', 'array')
.and('have.length', 1)
.its('0') // yields first element of the array
.should('contain', {
postId: 1,
id: 3,
})
})
it('cy.request() - pass result to the second request', () => {
// first, let's find out the userId of the first user we have
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
.its('body') // yields the response object
.its('0') // yields the first element of the returned list
// the above two commands its('body').its('0')
// can be written as its('body.0')
// if you do not care about TypeScript checks
.then((user) => {
expect(user).property('id').to.be.a('number')
// make a new post on behalf of the user
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
userId: user.id,
title: 'Cypress Test Runner',
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
})
})
// note that the value here is the returned value of the 2nd request
// which is the new post object
.then((response) => {
expect(response).property('status').to.equal(201) // new entity created
expect(response).property('body').to.contain({
title: 'Cypress Test Runner',
})
// we don't know the exact post id - only that it will be > 100
// since JSONPlaceholder has built-in 100 posts
expect(response.body).property('id').to.be.a('number')
.and.to.be.gt(100)
// we don't know the user id here - since it was in above closure
// so in this test just confirm that the property is there
expect(response.body).property('userId').to.be.a('number')
})
})
it('cy.request() - save response in the shared test context', () => {
// https://on.cypress.io/variables-and-aliases
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
.its('body').its('0') // yields the first element of the returned list
.as('user') // saves the object in the test context
.then(function () {
// NOTE 👀
// By the time this callback runs the "as('user')" command
// has saved the user object in the test context.
// To access the test context we need to use
// the "function () { ... }" callback form,
// otherwise "this" points at a wrong or undefined object!
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
userId: this.user.id,
title: 'Cypress Test Runner',
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
})
.its('body').as('post') // save the new post from the response
})
.then(function () {
// When this callback runs, both "cy.request" API commands have finished
// and the test context has "user" and "post" objects set.
// Let's verify them.
expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id)
})
})
it('cy.intercept() - route responses to matching requests', () => {
// https://on.cypress.io/intercept
let message = 'whoa, this comment does not exist'
// Listen to GET to comments/1
cy.intercept('GET', '**/comments/*').as('getComment')
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.network-btn').click()
// https://on.cypress.io/wait
cy.wait('@getComment').its('response.statusCode').should('be.oneOf', [200, 304])
// Listen to POST to comments
cy.intercept('POST', '**/comments').as('postComment')
// we have code that posts a comment when
// the button is clicked in scripts.js
cy.get('.network-post').click()
cy.wait('@postComment').should(({request, response}) => {
expect(request.body).to.include('email')
expect(request.headers).to.have.property('content-type')
expect(response && response.body).to.have.property('name', 'Using POST in cy.intercept()')
})
// Stub a response to PUT comments/ ****
cy.intercept({
method: 'PUT',
url: '**/comments/*',
}, {
statusCode: 404,
body: {error: message},
headers: {'access-control-allow-origin': '*'},
delayMs: 500,
}).as('putComment')
// we have code that puts a comment when
// the button is clicked in scripts.js
cy.get('.network-put').click()
cy.wait('@putComment')
// our 404 statusCode logic in scripts.js executed
cy.get('.network-put-comment').should('contain', message)
})
})

View File

@@ -0,0 +1,114 @@
/// <reference types="cypress" />
context('Querying', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/querying')
})
// The most commonly used query is 'cy.get()', you can
// think of this like the '$' in jQuery
it('cy.get() - query DOM elements', () => {
// https://on.cypress.io/get
cy.get('#query-btn').should('contain', 'Button')
cy.get('.query-btn').should('contain', 'Button')
cy.get('#querying .well>button:first').should('contain', 'Button')
// ↲
// Use CSS selectors just like jQuery
cy.get('[data-test-id="test-example"]').should('have.class', 'example')
// 'cy.get()' yields jQuery object, you can get its attribute
// by invoking `.attr()` method
cy.get('[data-test-id="test-example"]')
.invoke('attr', 'data-test-id')
.should('equal', 'test-example')
// or you can get element's CSS property
cy.get('[data-test-id="test-example"]')
.invoke('css', 'position')
.should('equal', 'static')
// or use assertions directly during 'cy.get()'
// https://on.cypress.io/assertions
cy.get('[data-test-id="test-example"]')
.should('have.attr', 'data-test-id', 'test-example')
.and('have.css', 'position', 'static')
})
it('cy.contains() - query DOM elements with matching content', () => {
// https://on.cypress.io/contains
cy.get('.query-list')
.contains('bananas')
.should('have.class', 'third')
// we can pass a regexp to `.contains()`
cy.get('.query-list')
.contains(/^b\w+/)
.should('have.class', 'third')
cy.get('.query-list')
.contains('apples')
.should('have.class', 'first')
// passing a selector to contains will
// yield the selector containing the text
cy.get('#querying')
.contains('ul', 'oranges')
.should('have.class', 'query-list')
cy.get('.query-button')
.contains('Save Form')
.should('have.class', 'btn')
})
it('.within() - query DOM elements within a specific element', () => {
// https://on.cypress.io/within
cy.get('.query-form').within(() => {
cy.get('input:first').should('have.attr', 'placeholder', 'Email')
cy.get('input:last').should('have.attr', 'placeholder', 'Password')
})
})
it('cy.root() - query the root DOM element', () => {
// https://on.cypress.io/root
// By default, root is the document
cy.root().should('match', 'html')
cy.get('.query-ul').within(() => {
// In this within, the root is now the ul DOM element
cy.root().should('have.class', 'query-ul')
})
})
it('best practices - selecting elements', () => {
// https://on.cypress.io/best-practices#Selecting-Elements
cy.get('[data-cy=best-practices-selecting-elements]').within(() => {
// Worst - too generic, no context
cy.get('button').click()
// Bad. Coupled to styling. Highly subject to change.
cy.get('.btn.btn-large').click()
// Average. Coupled to the `name` attribute which has HTML semantics.
cy.get('[name=submission]').click()
// Better. But still coupled to styling or JS event listeners.
cy.get('#main').click()
// Slightly better. Uses an ID but also ensures the element
// has an ARIA role attribute
cy.get('#main[role=button]').click()
// Much better. But still coupled to text content that may change.
cy.contains('Submit').click()
// Best. Insulated from all changes.
cy.get('[data-cy=submit]').click()
})
})
})

View File

@@ -0,0 +1,206 @@
/// <reference types="cypress" />
// remove no check once Cypress.sinon is typed
// https://github.com/cypress-io/cypress/issues/6720
context('Spies, Stubs, and Clock', () => {
it('cy.spy() - wrap a method in a spy', () => {
// https://on.cypress.io/spy
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
const obj = {
foo() {
},
}
const spy = cy.spy(obj, 'foo').as('anyArgs')
obj.foo()
expect(spy).to.be.called
})
it('cy.spy() retries until assertions pass', () => {
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
const obj = {
/**
* Prints the argument passed
* @param x {any}
*/
foo(x) {
console.log('obj.foo called with', x)
},
}
cy.spy(obj, 'foo').as('foo')
setTimeout(() => {
obj.foo('first')
}, 500)
setTimeout(() => {
obj.foo('second')
}, 2500)
cy.get('@foo').should('have.been.calledTwice')
})
it('cy.stub() - create a stub and/or replace a function with stub', () => {
// https://on.cypress.io/stub
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
const obj = {
/**
* prints both arguments to the console
* @param a {string}
* @param b {string}
*/
foo(a, b) {
console.log('a', a, 'b', b)
},
}
const stub = cy.stub(obj, 'foo').as('foo')
obj.foo('foo', 'bar')
expect(stub).to.be.called
})
it('cy.clock() - control time in the browser', () => {
// https://on.cypress.io/clock
// create the date in UTC so its always the same
// no matter what local timezone the browser is running in
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
cy.clock(now)
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
cy.get('#clock-div').click()
.should('have.text', '1489449600')
})
it('cy.tick() - move time in the browser', () => {
// https://on.cypress.io/tick
// create the date in UTC so its always the same
// no matter what local timezone the browser is running in
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
cy.clock(now)
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
cy.get('#tick-div').click()
.should('have.text', '1489449600')
cy.tick(10000) // 10 seconds passed
cy.get('#tick-div').click()
.should('have.text', '1489449610')
})
it('cy.stub() matches depending on arguments', () => {
// see all possible matchers at
// https://sinonjs.org/releases/latest/matchers/
const greeter = {
/**
* Greets a person
* @param {string} name
*/
greet(name) {
return `Hello, ${name}!`
},
}
cy.stub(greeter, 'greet')
.callThrough() // if you want non-matched calls to call the real method
.withArgs(Cypress.sinon.match.string).returns('Hi')
.withArgs(Cypress.sinon.match.number).throws(new Error('Invalid name'))
expect(greeter.greet('World')).to.equal('Hi')
// @ts-ignore
expect(() => greeter.greet(42)).to.throw('Invalid name')
expect(greeter.greet).to.have.been.calledTwice
// non-matched calls goes the actual method
// @ts-ignore
expect(greeter.greet()).to.equal('Hello, undefined!')
})
it('matches call arguments using Sinon matchers', () => {
// see all possible matchers at
// https://sinonjs.org/releases/latest/matchers/
const calculator = {
/**
* returns the sum of two arguments
* @param a {number}
* @param b {number}
*/
add(a, b) {
return a + b
},
}
const spy = cy.spy(calculator, 'add').as('add')
expect(calculator.add(2, 3)).to.equal(5)
// if we want to assert the exact values used during the call
expect(spy).to.be.calledWith(2, 3)
// let's confirm "add" method was called with two numbers
expect(spy).to.be.calledWith(Cypress.sinon.match.number, Cypress.sinon.match.number)
// alternatively, provide the value to match
expect(spy).to.be.calledWith(Cypress.sinon.match(2), Cypress.sinon.match(3))
// match any value
expect(spy).to.be.calledWith(Cypress.sinon.match.any, 3)
// match any value from a list
expect(spy).to.be.calledWith(Cypress.sinon.match.in([1, 2, 3]), 3)
/**
* Returns true if the given number is event
* @param {number} x
*/
const isEven = (x) => x % 2 === 0
// expect the value to pass a custom predicate function
// the second argument to "sinon.match(predicate, message)" is
// shown if the predicate does not pass and assertion fails
expect(spy).to.be.calledWith(Cypress.sinon.match(isEven, 'isEven'), 3)
/**
* Returns a function that checks if a given number is larger than the limit
* @param {number} limit
* @returns {(x: number) => boolean}
*/
const isGreaterThan = (limit) => (x) => x > limit
/**
* Returns a function that checks if a given number is less than the limit
* @param {number} limit
* @returns {(x: number) => boolean}
*/
const isLessThan = (limit) => (x) => x < limit
// you can combine several matchers using "and", "or"
expect(spy).to.be.calledWith(
Cypress.sinon.match.number,
Cypress.sinon.match(isGreaterThan(2), '> 2').and(Cypress.sinon.match(isLessThan(4), '< 4')),
)
expect(spy).to.be.calledWith(
Cypress.sinon.match.number,
Cypress.sinon.match(isGreaterThan(200), '> 200').or(Cypress.sinon.match(3)),
)
// matchers can be used from BDD assertions
cy.get('@add').should('have.been.calledWith',
Cypress.sinon.match.number, Cypress.sinon.match(3))
// you can alias matchers for shorter test code
const {match: M} = Cypress.sinon
cy.get('@add').should('have.been.calledWith', M.number, M(3))
})
})

View File

@@ -0,0 +1,121 @@
/// <reference types="cypress" />
context('Traversal', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/traversal')
})
it('.children() - get child DOM elements', () => {
// https://on.cypress.io/children
cy.get('.traversal-breadcrumb')
.children('.active')
.should('contain', 'Data')
})
it('.closest() - get closest ancestor DOM element', () => {
// https://on.cypress.io/closest
cy.get('.traversal-badge')
.closest('ul')
.should('have.class', 'list-group')
})
it('.eq() - get a DOM element at a specific index', () => {
// https://on.cypress.io/eq
cy.get('.traversal-list>li')
.eq(1).should('contain', 'siamese')
})
it('.filter() - get DOM elements that match the selector', () => {
// https://on.cypress.io/filter
cy.get('.traversal-nav>li')
.filter('.active').should('contain', 'About')
})
it('.find() - get descendant DOM elements of the selector', () => {
// https://on.cypress.io/find
cy.get('.traversal-pagination')
.find('li').find('a')
.should('have.length', 7)
})
it('.first() - get first DOM element', () => {
// https://on.cypress.io/first
cy.get('.traversal-table td')
.first().should('contain', '1')
})
it('.last() - get last DOM element', () => {
// https://on.cypress.io/last
cy.get('.traversal-buttons .btn')
.last().should('contain', 'Submit')
})
it('.next() - get next sibling DOM element', () => {
// https://on.cypress.io/next
cy.get('.traversal-ul')
.contains('apples').next().should('contain', 'oranges')
})
it('.nextAll() - get all next sibling DOM elements', () => {
// https://on.cypress.io/nextall
cy.get('.traversal-next-all')
.contains('oranges')
.nextAll().should('have.length', 3)
})
it('.nextUntil() - get next sibling DOM elements until next el', () => {
// https://on.cypress.io/nextuntil
cy.get('#veggies')
.nextUntil('#nuts').should('have.length', 3)
})
it('.not() - remove DOM elements from set of DOM elements', () => {
// https://on.cypress.io/not
cy.get('.traversal-disabled .btn')
.not('[disabled]').should('not.contain', 'Disabled')
})
it('.parent() - get parent DOM element from DOM elements', () => {
// https://on.cypress.io/parent
cy.get('.traversal-mark')
.parent().should('contain', 'Morbi leo risus')
})
it('.parents() - get parent DOM elements from DOM elements', () => {
// https://on.cypress.io/parents
cy.get('.traversal-cite')
.parents().should('match', 'blockquote')
})
it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => {
// https://on.cypress.io/parentsuntil
cy.get('.clothes-nav')
.find('.active')
.parentsUntil('.clothes-nav')
.should('have.length', 2)
})
it('.prev() - get previous sibling DOM element', () => {
// https://on.cypress.io/prev
cy.get('.birds').find('.active')
.prev().should('contain', 'Lorikeets')
})
it('.prevAll() - get all previous sibling DOM elements', () => {
// https://on.cypress.io/prevall
cy.get('.fruits-list').find('.third')
.prevAll().should('have.length', 2)
})
it('.prevUntil() - get all previous sibling DOM elements until el', () => {
// https://on.cypress.io/prevuntil
cy.get('.foods-list').find('#nuts')
.prevUntil('#veggies').should('have.length', 3)
})
it('.siblings() - get all sibling DOM elements', () => {
// https://on.cypress.io/siblings
cy.get('.traversal-pills .active')
.siblings().should('have.length', 2)
})
})

View File

@@ -0,0 +1,110 @@
/// <reference types="cypress" />
context('Utilities', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/utilities')
})
it('Cypress._ - call a lodash method', () => {
// https://on.cypress.io/_
cy.request('https://jsonplaceholder.cypress.io/users')
.then((response) => {
let ids = Cypress._.chain(response.body).map('id').take(3).value()
expect(ids).to.deep.eq([1, 2, 3])
})
})
it('Cypress.$ - call a jQuery method', () => {
// https://on.cypress.io/$
let $li = Cypress.$('.utility-jquery li:first')
cy.wrap($li)
.should('not.have.class', 'active')
.click()
.should('have.class', 'active')
})
it('Cypress.Blob - blob utilities and base64 string conversion', () => {
// https://on.cypress.io/blob
cy.get('.utility-blob').then(($div) => {
// https://github.com/nolanlawson/blob-util#imgSrcToDataURL
// get the dataUrl string for the javascript-logo
return Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous')
.then((dataUrl) => {
// create an <img> element and set its src to the dataUrl
let img = Cypress.$('<img />', {src: dataUrl})
// need to explicitly return cy here since we are initially returning
// the Cypress.Blob.imgSrcToDataURL promise to our test
// append the image
$div.append(img)
cy.get('.utility-blob img').click()
.should('have.attr', 'src', dataUrl)
})
})
})
it('Cypress.minimatch - test out glob patterns against strings', () => {
// https://on.cypress.io/minimatch
let matching = Cypress.minimatch('/users/1/comments', '/users/*/comments', {
matchBase: true,
})
expect(matching, 'matching wildcard').to.be.true
matching = Cypress.minimatch('/users/1/comments/2', '/users/*/comments', {
matchBase: true,
})
expect(matching, 'comments').to.be.false
// ** matches against all downstream path segments
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/**', {
matchBase: true,
})
expect(matching, 'comments').to.be.true
// whereas * matches only the next path segment
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/*', {
matchBase: false,
})
expect(matching, 'comments').to.be.false
})
it('Cypress.Promise - instantiate a bluebird promise', () => {
// https://on.cypress.io/promise
let waited = false
/**
* @return Bluebird<string>
*/
function waitOneSecond() {
// return a promise that resolves after 1 second
// @ts-ignore TS2351 (new Cypress.Promise)
return new Cypress.Promise((resolve, reject) => {
setTimeout(() => {
// set waited to true
waited = true
// resolve with 'foo' string
resolve('foo')
}, 1000)
})
}
cy.then(() => {
// return a promise to cy.then() that
// is awaited until it resolves
// @ts-ignore TS7006
return waitOneSecond().then((str) => {
expect(str).to.eq('foo')
expect(waited).to.be.true
})
})
})
})

View File

@@ -0,0 +1,59 @@
/// <reference types="cypress" />
context('Viewport', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/viewport')
})
it('cy.viewport() - set the viewport size and dimension', () => {
// https://on.cypress.io/viewport
cy.get('#navbar').should('be.visible')
cy.viewport(320, 480)
// the navbar should have collapse since our screen is smaller
cy.get('#navbar').should('not.be.visible')
cy.get('.navbar-toggle').should('be.visible').click()
cy.get('.nav').find('a').should('be.visible')
// lets see what our app looks like on a super large screen
cy.viewport(2999, 2999)
// cy.viewport() accepts a set of preset sizes
// to easily set the screen to a device's width and height
// We added a cy.wait() between each viewport change so you can see
// the change otherwise it is a little too fast to see :)
cy.viewport('macbook-15')
cy.wait(200)
cy.viewport('macbook-13')
cy.wait(200)
cy.viewport('macbook-11')
cy.wait(200)
cy.viewport('ipad-2')
cy.wait(200)
cy.viewport('ipad-mini')
cy.wait(200)
cy.viewport('iphone-6+')
cy.wait(200)
cy.viewport('iphone-6')
cy.wait(200)
cy.viewport('iphone-5')
cy.wait(200)
cy.viewport('iphone-4')
cy.wait(200)
cy.viewport('iphone-3')
cy.wait(200)
// cy.viewport() accepts an orientation for all presets
// the default orientation is 'portrait'
cy.viewport('ipad-2', 'portrait')
cy.wait(200)
cy.viewport('iphone-4', 'landscape')
cy.wait(200)
// The viewport will be reset back to the default dimensions
// in between tests (the default can be set in cypress.json)
})
})

View File

@@ -0,0 +1,31 @@
/// <reference types="cypress" />
context('Waiting', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/waiting')
})
// BE CAREFUL of adding unnecessary wait times.
// https://on.cypress.io/best-practices#Unnecessary-Waiting
// https://on.cypress.io/wait
it('cy.wait() - wait for a specific amount of time', () => {
cy.get('.wait-input1').type('Wait 1000ms after typing')
cy.wait(1000)
cy.get('.wait-input2').type('Wait 1000ms after typing')
cy.wait(1000)
cy.get('.wait-input3').type('Wait 1000ms after typing')
cy.wait(1000)
})
it('cy.wait() - wait for a specific route', () => {
// Listen to GET to comments/1
cy.intercept('GET', '**/comments/*').as('getComment')
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.network-btn').click()
// wait for GET comments/1
cy.wait('@getComment').its('response.statusCode').should('be.oneOf', [200, 304])
})
})

View File

@@ -0,0 +1,22 @@
/// <reference types="cypress" />
context('Window', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/window')
})
it('cy.window() - get the global window object', () => {
// https://on.cypress.io/window
cy.window().should('have.property', 'top')
})
it('cy.document() - get the document object', () => {
// https://on.cypress.io/document
cy.document().should('have.property', 'charset').and('eq', 'UTF-8')
})
it('cy.title() - get the title', () => {
// https://on.cypress.io/title
cy.title().should('include', 'Kitchen Sink')
})
})

View File

@@ -1,23 +0,0 @@
/// <reference types="Cypress" />
const { FIREBASE_USERNAME, FIREBASE_PASSWORcD } = Cypress.env();
describe("Renders the General Page", () => {
beforeEach(() => {
cy.visit("/");
});
it("Renders Correctly", () => {});
it("Has the Slogan", () => {
cy.findByText("A whole x22new kind of shop management system.").should(
"exist"
);
/* ==== Generated with Cypress Studio ==== */
cy.get(
".ant-menu-item-active > .ant-menu-title-content > .header0-item-block"
).click();
cy.get("#email").clear();
cy.get("#email").type("patrick@imex.dev");
cy.get("#password").clear();
cy.get("#password").type("patrick123{enter}");
cy.get(".ant-form > .ant-btn").click();
/* ==== End Cypress Studio ==== */
});
});

View File

@@ -1,143 +0,0 @@
/// <reference types="cypress" />
// Welcome to Cypress!
//
// This spec file contains a variety of sample tests
// for a todo list app that are designed to demonstrate
// the power of writing tests in Cypress.
//
// To learn more about how Cypress works and
// what makes it such an awesome testing tool,
// please read our getting started guide:
// https://on.cypress.io/introduction-to-cypress
describe('example to-do app', () => {
beforeEach(() => {
// Cypress starts out with a blank slate for each test
// so we must tell it to visit our website with the `cy.visit()` command.
// Since we want to visit the same URL at the start of all our tests,
// we include it in our beforeEach function so that it runs before each test
cy.visit('https://example.cypress.io/todo')
})
it('displays two todo items by default', () => {
// We use the `cy.get()` command to get all elements that match the selector.
// Then, we use `should` to assert that there are two matched items,
// which are the two default items.
cy.get('.todo-list li').should('have.length', 2)
// We can go even further and check that the default todos each contain
// the correct text. We use the `first` and `last` functions
// to get just the first and last matched elements individually,
// and then perform an assertion with `should`.
cy.get('.todo-list li').first().should('have.text', 'Pay electric bill')
cy.get('.todo-list li').last().should('have.text', 'Walk the dog')
})
it('can add new todo items', () => {
// We'll store our item text in a variable so we can reuse it
const newItem = 'Feed the cat'
// Let's get the input element and use the `type` command to
// input our new list item. After typing the content of our item,
// we need to type the enter key as well in order to submit the input.
// This input has a data-test attribute so we'll use that to select the
// element in accordance with best practices:
// https://on.cypress.io/selecting-elements
cy.get('[data-test=new-todo]').type(`${newItem}{enter}`)
// Now that we've typed our new item, let's check that it actually was added to the list.
// Since it's the newest item, it should exist as the last element in the list.
// In addition, with the two default items, we should have a total of 3 elements in the list.
// Since assertions yield the element that was asserted on,
// we can chain both of these assertions together into a single statement.
cy.get('.todo-list li')
.should('have.length', 3)
.last()
.should('have.text', newItem)
})
it('can check off an item as completed', () => {
// In addition to using the `get` command to get an element by selector,
// we can also use the `contains` command to get an element by its contents.
// However, this will yield the <label>, which is lowest-level element that contains the text.
// In order to check the item, we'll find the <input> element for this <label>
// by traversing up the dom to the parent element. From there, we can `find`
// the child checkbox <input> element and use the `check` command to check it.
cy.contains('Pay electric bill')
.parent()
.find('input[type=checkbox]')
.check()
// Now that we've checked the button, we can go ahead and make sure
// that the list element is now marked as completed.
// Again we'll use `contains` to find the <label> element and then use the `parents` command
// to traverse multiple levels up the dom until we find the corresponding <li> element.
// Once we get that element, we can assert that it has the completed class.
cy.contains('Pay electric bill')
.parents('li')
.should('have.class', 'completed')
})
context('with a checked task', () => {
beforeEach(() => {
// We'll take the command we used above to check off an element
// Since we want to perform multiple tests that start with checking
// one element, we put it in the beforeEach hook
// so that it runs at the start of every test.
cy.contains('Pay electric bill')
.parent()
.find('input[type=checkbox]')
.check()
})
it('can filter for uncompleted tasks', () => {
// We'll click on the "active" button in order to
// display only incomplete items
cy.contains('Active').click()
// After filtering, we can assert that there is only the one
// incomplete item in the list.
cy.get('.todo-list li')
.should('have.length', 1)
.first()
.should('have.text', 'Walk the dog')
// For good measure, let's also assert that the task we checked off
// does not exist on the page.
cy.contains('Pay electric bill').should('not.exist')
})
it('can filter for completed tasks', () => {
// We can perform similar steps as the test above to ensure
// that only completed tasks are shown
cy.contains('Completed').click()
cy.get('.todo-list li')
.should('have.length', 1)
.first()
.should('have.text', 'Pay electric bill')
cy.contains('Walk the dog').should('not.exist')
})
it('can delete all completed tasks', () => {
// First, let's click the "Clear completed" button
// `contains` is actually serving two purposes here.
// First, it's ensuring that the button exists within the dom.
// This button only appears when at least one task is checked
// so this command is implicitly verifying that it does exist.
// Second, it selects the button so we can click it.
cy.contains('Clear completed').click()
// Then we can make sure that there is only one element
// in the list and our element does not exist
cy.get('.todo-list li')
.should('have.length', 1)
.should('not.have.text', 'Pay electric bill')
// Finally, make sure that the clear button no longer exists.
cy.contains('Clear completed').should('not.exist')
})
})
})

View File

@@ -1,299 +0,0 @@
/// <reference types="cypress" />
context('Actions', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/actions')
})
// https://on.cypress.io/interacting-with-elements
it('.type() - type into a DOM element', () => {
// https://on.cypress.io/type
cy.get('.action-email')
.type('fake@email.com').should('have.value', 'fake@email.com')
// .type() with special character sequences
.type('{leftarrow}{rightarrow}{uparrow}{downarrow}')
.type('{del}{selectall}{backspace}')
// .type() with key modifiers
.type('{alt}{option}') //these are equivalent
.type('{ctrl}{control}') //these are equivalent
.type('{meta}{command}{cmd}') //these are equivalent
.type('{shift}')
// Delay each keypress by 0.1 sec
.type('slow.typing@email.com', { delay: 100 })
.should('have.value', 'slow.typing@email.com')
cy.get('.action-disabled')
// Ignore error checking prior to type
// like whether the input is visible or disabled
.type('disabled error checking', { force: true })
.should('have.value', 'disabled error checking')
})
it('.focus() - focus on a DOM element', () => {
// https://on.cypress.io/focus
cy.get('.action-focus').focus()
.should('have.class', 'focus')
.prev().should('have.attr', 'style', 'color: orange;')
})
it('.blur() - blur off a DOM element', () => {
// https://on.cypress.io/blur
cy.get('.action-blur').type('About to blur').blur()
.should('have.class', 'error')
.prev().should('have.attr', 'style', 'color: red;')
})
it('.clear() - clears an input or textarea element', () => {
// https://on.cypress.io/clear
cy.get('.action-clear').type('Clear this text')
.should('have.value', 'Clear this text')
.clear()
.should('have.value', '')
})
it('.submit() - submit a form', () => {
// https://on.cypress.io/submit
cy.get('.action-form')
.find('[type="text"]').type('HALFOFF')
cy.get('.action-form').submit()
.next().should('contain', 'Your form has been submitted!')
})
it('.click() - click on a DOM element', () => {
// https://on.cypress.io/click
cy.get('.action-btn').click()
// You can click on 9 specific positions of an element:
// -----------------------------------
// | topLeft top topRight |
// | |
// | |
// | |
// | left center right |
// | |
// | |
// | |
// | bottomLeft bottom bottomRight |
// -----------------------------------
// clicking in the center of the element is the default
cy.get('#action-canvas').click()
cy.get('#action-canvas').click('topLeft')
cy.get('#action-canvas').click('top')
cy.get('#action-canvas').click('topRight')
cy.get('#action-canvas').click('left')
cy.get('#action-canvas').click('right')
cy.get('#action-canvas').click('bottomLeft')
cy.get('#action-canvas').click('bottom')
cy.get('#action-canvas').click('bottomRight')
// .click() accepts an x and y coordinate
// that controls where the click occurs :)
cy.get('#action-canvas')
.click(80, 75) // click 80px on x coord and 75px on y coord
.click(170, 75)
.click(80, 165)
.click(100, 185)
.click(125, 190)
.click(150, 185)
.click(170, 165)
// click multiple elements by passing multiple: true
cy.get('.action-labels>.label').click({ multiple: true })
// Ignore error checking prior to clicking
cy.get('.action-opacity>.btn').click({ force: true })
})
it('.dblclick() - double click on a DOM element', () => {
// https://on.cypress.io/dblclick
// Our app has a listener on 'dblclick' event in our 'scripts.js'
// that hides the div and shows an input on double click
cy.get('.action-div').dblclick().should('not.be.visible')
cy.get('.action-input-hidden').should('be.visible')
})
it('.rightclick() - right click on a DOM element', () => {
// https://on.cypress.io/rightclick
// Our app has a listener on 'contextmenu' event in our 'scripts.js'
// that hides the div and shows an input on right click
cy.get('.rightclick-action-div').rightclick().should('not.be.visible')
cy.get('.rightclick-action-input-hidden').should('be.visible')
})
it('.check() - check a checkbox or radio element', () => {
// https://on.cypress.io/check
// By default, .check() will check all
// matching checkbox or radio elements in succession, one after another
cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]')
.check().should('be.checked')
cy.get('.action-radios [type="radio"]').not('[disabled]')
.check().should('be.checked')
// .check() accepts a value argument
cy.get('.action-radios [type="radio"]')
.check('radio1').should('be.checked')
// .check() accepts an array of values
cy.get('.action-multiple-checkboxes [type="checkbox"]')
.check(['checkbox1', 'checkbox2']).should('be.checked')
// Ignore error checking prior to checking
cy.get('.action-checkboxes [disabled]')
.check({ force: true }).should('be.checked')
cy.get('.action-radios [type="radio"]')
.check('radio3', { force: true }).should('be.checked')
})
it('.uncheck() - uncheck a checkbox element', () => {
// https://on.cypress.io/uncheck
// By default, .uncheck() will uncheck all matching
// checkbox elements in succession, one after another
cy.get('.action-check [type="checkbox"]')
.not('[disabled]')
.uncheck().should('not.be.checked')
// .uncheck() accepts a value argument
cy.get('.action-check [type="checkbox"]')
.check('checkbox1')
.uncheck('checkbox1').should('not.be.checked')
// .uncheck() accepts an array of values
cy.get('.action-check [type="checkbox"]')
.check(['checkbox1', 'checkbox3'])
.uncheck(['checkbox1', 'checkbox3']).should('not.be.checked')
// Ignore error checking prior to unchecking
cy.get('.action-check [disabled]')
.uncheck({ force: true }).should('not.be.checked')
})
it('.select() - select an option in a <select> element', () => {
// https://on.cypress.io/select
// at first, no option should be selected
cy.get('.action-select')
.should('have.value', '--Select a fruit--')
// Select option(s) with matching text content
cy.get('.action-select').select('apples')
// confirm the apples were selected
// note that each value starts with "fr-" in our HTML
cy.get('.action-select').should('have.value', 'fr-apples')
cy.get('.action-select-multiple')
.select(['apples', 'oranges', 'bananas'])
// when getting multiple values, invoke "val" method first
.invoke('val')
.should('deep.equal', ['fr-apples', 'fr-oranges', 'fr-bananas'])
// Select option(s) with matching value
cy.get('.action-select').select('fr-bananas')
// can attach an assertion right away to the element
.should('have.value', 'fr-bananas')
cy.get('.action-select-multiple')
.select(['fr-apples', 'fr-oranges', 'fr-bananas'])
.invoke('val')
.should('deep.equal', ['fr-apples', 'fr-oranges', 'fr-bananas'])
// assert the selected values include oranges
cy.get('.action-select-multiple')
.invoke('val').should('include', 'fr-oranges')
})
it('.scrollIntoView() - scroll an element into view', () => {
// https://on.cypress.io/scrollintoview
// normally all of these buttons are hidden,
// because they're not within
// the viewable area of their parent
// (we need to scroll to see them)
cy.get('#scroll-horizontal button')
.should('not.be.visible')
// scroll the button into view, as if the user had scrolled
cy.get('#scroll-horizontal button').scrollIntoView()
.should('be.visible')
cy.get('#scroll-vertical button')
.should('not.be.visible')
// Cypress handles the scroll direction needed
cy.get('#scroll-vertical button').scrollIntoView()
.should('be.visible')
cy.get('#scroll-both button')
.should('not.be.visible')
// Cypress knows to scroll to the right and down
cy.get('#scroll-both button').scrollIntoView()
.should('be.visible')
})
it('.trigger() - trigger an event on a DOM element', () => {
// https://on.cypress.io/trigger
// To interact with a range input (slider)
// we need to set its value & trigger the
// event to signal it changed
// Here, we invoke jQuery's val() method to set
// the value and trigger the 'change' event
cy.get('.trigger-input-range')
.invoke('val', 25)
.trigger('change')
.get('input[type=range]').siblings('p')
.should('have.text', '25')
})
it('cy.scrollTo() - scroll the window or element to a position', () => {
// https://on.cypress.io/scrollto
// You can scroll to 9 specific positions of an element:
// -----------------------------------
// | topLeft top topRight |
// | |
// | |
// | |
// | left center right |
// | |
// | |
// | |
// | bottomLeft bottom bottomRight |
// -----------------------------------
// if you chain .scrollTo() off of cy, we will
// scroll the entire window
cy.scrollTo('bottom')
cy.get('#scrollable-horizontal').scrollTo('right')
// or you can scroll to a specific coordinate:
// (x axis, y axis) in pixels
cy.get('#scrollable-vertical').scrollTo(250, 250)
// or you can scroll to a specific percentage
// of the (width, height) of the element
cy.get('#scrollable-both').scrollTo('75%', '25%')
// control the easing of the scroll (default is 'swing')
cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' })
// control the duration of the scroll (in ms)
cy.get('#scrollable-both').scrollTo('center', { duration: 2000 })
})
})

View File

@@ -1,39 +0,0 @@
/// <reference types="cypress" />
context('Aliasing', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/aliasing')
})
it('.as() - alias a DOM element for later use', () => {
// https://on.cypress.io/as
// Alias a DOM element for use later
// We don't have to traverse to the element
// later in our code, we reference it with @
cy.get('.as-table').find('tbody>tr')
.first().find('td').first()
.find('button').as('firstBtn')
// when we reference the alias, we place an
// @ in front of its name
cy.get('@firstBtn').click()
cy.get('@firstBtn')
.should('have.class', 'btn-success')
.and('contain', 'Changed')
})
it('.as() - alias a route for later use', () => {
// Alias the route to wait for its response
cy.intercept('GET', '**/comments/*').as('getComment')
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.network-btn').click()
// https://on.cypress.io/wait
cy.wait('@getComment').its('response.statusCode').should('eq', 200)
})
})

View File

@@ -1,177 +0,0 @@
/// <reference types="cypress" />
context('Assertions', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/assertions')
})
describe('Implicit Assertions', () => {
it('.should() - make an assertion about the current subject', () => {
// https://on.cypress.io/should
cy.get('.assertion-table')
.find('tbody tr:last')
.should('have.class', 'success')
.find('td')
.first()
// checking the text of the <td> element in various ways
.should('have.text', 'Column content')
.should('contain', 'Column content')
.should('have.html', 'Column content')
// chai-jquery uses "is()" to check if element matches selector
.should('match', 'td')
// to match text content against a regular expression
// first need to invoke jQuery method text()
// and then match using regular expression
.invoke('text')
.should('match', /column content/i)
// a better way to check element's text content against a regular expression
// is to use "cy.contains"
// https://on.cypress.io/contains
cy.get('.assertion-table')
.find('tbody tr:last')
// finds first <td> element with text content matching regular expression
.contains('td', /column content/i)
.should('be.visible')
// for more information about asserting element's text
// see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-elements-text-contents
})
it('.and() - chain multiple assertions together', () => {
// https://on.cypress.io/and
cy.get('.assertions-link')
.should('have.class', 'active')
.and('have.attr', 'href')
.and('include', 'cypress.io')
})
})
describe('Explicit Assertions', () => {
// https://on.cypress.io/assertions
it('expect - make an assertion about a specified subject', () => {
// We can use Chai's BDD style assertions
expect(true).to.be.true
const o = { foo: 'bar' }
expect(o).to.equal(o)
expect(o).to.deep.equal({ foo: 'bar' })
// matching text using regular expression
expect('FooBar').to.match(/bar$/i)
})
it('pass your own callback function to should()', () => {
// Pass a function to should that can have any number
// of explicit assertions within it.
// The ".should(cb)" function will be retried
// automatically until it passes all your explicit assertions or times out.
cy.get('.assertions-p')
.find('p')
.should(($p) => {
// https://on.cypress.io/$
// return an array of texts from all of the p's
// @ts-ignore TS6133 unused variable
const texts = $p.map((i, el) => Cypress.$(el).text())
// jquery map returns jquery object
// and .get() convert this to simple array
const paragraphs = texts.get()
// array should have length of 3
expect(paragraphs, 'has 3 paragraphs').to.have.length(3)
// use second argument to expect(...) to provide clear
// message with each assertion
expect(paragraphs, 'has expected text in each paragraph').to.deep.eq([
'Some text from first p',
'More text from second p',
'And even more text from third p',
])
})
})
it('finds element by class name regex', () => {
cy.get('.docs-header')
.find('div')
// .should(cb) callback function will be retried
.should(($div) => {
expect($div).to.have.length(1)
const className = $div[0].className
expect(className).to.match(/heading-/)
})
// .then(cb) callback is not retried,
// it either passes or fails
.then(($div) => {
expect($div, 'text content').to.have.text('Introduction')
})
})
it('can throw any error', () => {
cy.get('.docs-header')
.find('div')
.should(($div) => {
if ($div.length !== 1) {
// you can throw your own errors
throw new Error('Did not find 1 element')
}
const className = $div[0].className
if (!className.match(/heading-/)) {
throw new Error(`Could not find class "heading-" in ${className}`)
}
})
})
it('matches unknown text between two elements', () => {
/**
* Text from the first element.
* @type {string}
*/
let text
/**
* Normalizes passed text,
* useful before comparing text with spaces and different capitalization.
* @param {string} s Text to normalize
*/
const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase()
cy.get('.two-elements')
.find('.first')
.then(($first) => {
// save text from the first element
text = normalizeText($first.text())
})
cy.get('.two-elements')
.find('.second')
.should(($div) => {
// we can massage text before comparing
const secondText = normalizeText($div.text())
expect(secondText, 'second text').to.equal(text)
})
})
it('assert - assert shape of an object', () => {
const person = {
name: 'Joe',
age: 20,
}
assert.isObject(person, 'value is object')
})
it('retries the should callback until assertions pass', () => {
cy.get('#random-number')
.should(($div) => {
const n = parseFloat($div.text())
expect(n).to.be.gte(1).and.be.lte(10)
})
})
})
})

View File

@@ -1,97 +0,0 @@
/// <reference types="cypress" />
context('Connectors', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/connectors')
})
it('.each() - iterate over an array of elements', () => {
// https://on.cypress.io/each
cy.get('.connectors-each-ul>li')
.each(($el, index, $list) => {
console.log($el, index, $list)
})
})
it('.its() - get properties on the current subject', () => {
// https://on.cypress.io/its
cy.get('.connectors-its-ul>li')
// calls the 'length' property yielding that value
.its('length')
.should('be.gt', 2)
})
it('.invoke() - invoke a function on the current subject', () => {
// our div is hidden in our script.js
// $('.connectors-div').hide()
// https://on.cypress.io/invoke
cy.get('.connectors-div').should('be.hidden')
// call the jquery method 'show' on the 'div.container'
.invoke('show')
.should('be.visible')
})
it('.spread() - spread an array as individual args to callback function', () => {
// https://on.cypress.io/spread
const arr = ['foo', 'bar', 'baz']
cy.wrap(arr).spread((foo, bar, baz) => {
expect(foo).to.eq('foo')
expect(bar).to.eq('bar')
expect(baz).to.eq('baz')
})
})
describe('.then()', () => {
it('invokes a callback function with the current subject', () => {
// https://on.cypress.io/then
cy.get('.connectors-list > li')
.then(($lis) => {
expect($lis, '3 items').to.have.length(3)
expect($lis.eq(0), 'first item').to.contain('Walk the dog')
expect($lis.eq(1), 'second item').to.contain('Feed the cat')
expect($lis.eq(2), 'third item').to.contain('Write JavaScript')
})
})
it('yields the returned value to the next command', () => {
cy.wrap(1)
.then((num) => {
expect(num).to.equal(1)
return 2
})
.then((num) => {
expect(num).to.equal(2)
})
})
it('yields the original subject without return', () => {
cy.wrap(1)
.then((num) => {
expect(num).to.equal(1)
// note that nothing is returned from this callback
})
.then((num) => {
// this callback receives the original unchanged value 1
expect(num).to.equal(1)
})
})
it('yields the value yielded by the last Cypress command inside', () => {
cy.wrap(1)
.then((num) => {
expect(num).to.equal(1)
// note how we run a Cypress command
// the result yielded by this Cypress command
// will be passed to the second ".then"
cy.wrap(2)
})
.then((num) => {
// this callback receives the value yielded by "cy.wrap(2)"
expect(num).to.equal(2)
})
})
})
})

View File

@@ -1,77 +0,0 @@
/// <reference types="cypress" />
context('Cookies', () => {
beforeEach(() => {
Cypress.Cookies.debug(true)
cy.visit('https://example.cypress.io/commands/cookies')
// clear cookies again after visiting to remove
// any 3rd party cookies picked up such as cloudflare
cy.clearCookies()
})
it('cy.getCookie() - get a browser cookie', () => {
// https://on.cypress.io/getcookie
cy.get('#getCookie .set-a-cookie').click()
// cy.getCookie() yields a cookie object
cy.getCookie('token').should('have.property', 'value', '123ABC')
})
it('cy.getCookies() - get browser cookies', () => {
// https://on.cypress.io/getcookies
cy.getCookies().should('be.empty')
cy.get('#getCookies .set-a-cookie').click()
// cy.getCookies() yields an array of cookies
cy.getCookies().should('have.length', 1).should((cookies) => {
// each cookie has these properties
expect(cookies[0]).to.have.property('name', 'token')
expect(cookies[0]).to.have.property('value', '123ABC')
expect(cookies[0]).to.have.property('httpOnly', false)
expect(cookies[0]).to.have.property('secure', false)
expect(cookies[0]).to.have.property('domain')
expect(cookies[0]).to.have.property('path')
})
})
it('cy.setCookie() - set a browser cookie', () => {
// https://on.cypress.io/setcookie
cy.getCookies().should('be.empty')
cy.setCookie('foo', 'bar')
// cy.getCookie() yields a cookie object
cy.getCookie('foo').should('have.property', 'value', 'bar')
})
it('cy.clearCookie() - clear a browser cookie', () => {
// https://on.cypress.io/clearcookie
cy.getCookie('token').should('be.null')
cy.get('#clearCookie .set-a-cookie').click()
cy.getCookie('token').should('have.property', 'value', '123ABC')
// cy.clearCookies() yields null
cy.clearCookie('token').should('be.null')
cy.getCookie('token').should('be.null')
})
it('cy.clearCookies() - clear browser cookies', () => {
// https://on.cypress.io/clearcookies
cy.getCookies().should('be.empty')
cy.get('#clearCookies .set-a-cookie').click()
cy.getCookies().should('have.length', 1)
// cy.clearCookies() yields null
cy.clearCookies()
cy.getCookies().should('be.empty')
})
})

View File

@@ -1,202 +0,0 @@
/// <reference types="cypress" />
context('Cypress.Commands', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
// https://on.cypress.io/custom-commands
it('.add() - create a custom command', () => {
Cypress.Commands.add('console', {
prevSubject: true,
}, (subject, method) => {
// the previous subject is automatically received
// and the commands arguments are shifted
// allow us to change the console method used
method = method || 'log'
// log the subject to the console
// @ts-ignore TS7017
console[method]('The subject is', subject)
// whatever we return becomes the new subject
// we don't want to change the subject so
// we return whatever was passed in
return subject
})
// @ts-ignore TS2339
cy.get('button').console('info').then(($button) => {
// subject is still $button
})
})
})
context('Cypress.Cookies', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
// https://on.cypress.io/cookies
it('.debug() - enable or disable debugging', () => {
Cypress.Cookies.debug(true)
// Cypress will now log in the console when
// cookies are set or cleared
cy.setCookie('fakeCookie', '123ABC')
cy.clearCookie('fakeCookie')
cy.setCookie('fakeCookie', '123ABC')
cy.clearCookie('fakeCookie')
cy.setCookie('fakeCookie', '123ABC')
})
it('.preserveOnce() - preserve cookies by key', () => {
// normally cookies are reset after each test
cy.getCookie('fakeCookie').should('not.be.ok')
// preserving a cookie will not clear it when
// the next test starts
cy.setCookie('lastCookie', '789XYZ')
Cypress.Cookies.preserveOnce('lastCookie')
})
it('.defaults() - set defaults for all cookies', () => {
// now any cookie with the name 'session_id' will
// not be cleared before each new test runs
Cypress.Cookies.defaults({
preserve: 'session_id',
})
})
})
context('Cypress.arch', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
it('Get CPU architecture name of underlying OS', () => {
// https://on.cypress.io/arch
expect(Cypress.arch).to.exist
})
})
context('Cypress.config()', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
it('Get and set configuration options', () => {
// https://on.cypress.io/config
let myConfig = Cypress.config()
expect(myConfig).to.have.property('animationDistanceThreshold', 5)
expect(myConfig).to.have.property('baseUrl', null)
expect(myConfig).to.have.property('defaultCommandTimeout', 4000)
expect(myConfig).to.have.property('requestTimeout', 5000)
expect(myConfig).to.have.property('responseTimeout', 30000)
expect(myConfig).to.have.property('viewportHeight', 660)
expect(myConfig).to.have.property('viewportWidth', 1000)
expect(myConfig).to.have.property('pageLoadTimeout', 60000)
expect(myConfig).to.have.property('waitForAnimations', true)
expect(Cypress.config('pageLoadTimeout')).to.eq(60000)
// this will change the config for the rest of your tests!
Cypress.config('pageLoadTimeout', 20000)
expect(Cypress.config('pageLoadTimeout')).to.eq(20000)
Cypress.config('pageLoadTimeout', 60000)
})
})
context('Cypress.dom', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
// https://on.cypress.io/dom
it('.isHidden() - determine if a DOM element is hidden', () => {
let hiddenP = Cypress.$('.dom-p p.hidden').get(0)
let visibleP = Cypress.$('.dom-p p.visible').get(0)
// our first paragraph has css class 'hidden'
expect(Cypress.dom.isHidden(hiddenP)).to.be.true
expect(Cypress.dom.isHidden(visibleP)).to.be.false
})
})
context('Cypress.env()', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
// We can set environment variables for highly dynamic values
// https://on.cypress.io/environment-variables
it('Get environment variables', () => {
// https://on.cypress.io/env
// set multiple environment variables
Cypress.env({
host: 'veronica.dev.local',
api_server: 'http://localhost:8888/v1/',
})
// get environment variable
expect(Cypress.env('host')).to.eq('veronica.dev.local')
// set environment variable
Cypress.env('api_server', 'http://localhost:8888/v2/')
expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/')
// get all environment variable
expect(Cypress.env()).to.have.property('host', 'veronica.dev.local')
expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/')
})
})
context('Cypress.log', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
it('Control what is printed to the Command Log', () => {
// https://on.cypress.io/cypress-log
})
})
context('Cypress.platform', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
it('Get underlying OS name', () => {
// https://on.cypress.io/platform
expect(Cypress.platform).to.be.exist
})
})
context('Cypress.version', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
it('Get current version of Cypress being run', () => {
// https://on.cypress.io/version
expect(Cypress.version).to.be.exist
})
})
context('Cypress.spec', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
it('Get current spec information', () => {
// https://on.cypress.io/spec
// wrap the object so we can inspect it easily by clicking in the command log
cy.wrap(Cypress.spec).should('include.keys', ['name', 'relative', 'absolute'])
})
})

View File

@@ -1,88 +0,0 @@
/// <reference types="cypress" />
/// JSON fixture file can be loaded directly using
// the built-in JavaScript bundler
// @ts-ignore
const requiredExample = require('../../fixtures/example')
context('Files', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/files')
})
beforeEach(() => {
// load example.json fixture file and store
// in the test context object
cy.fixture('example.json').as('example')
})
it('cy.fixture() - load a fixture', () => {
// https://on.cypress.io/fixture
// Instead of writing a response inline you can
// use a fixture file's content.
// when application makes an Ajax request matching "GET **/comments/*"
// Cypress will intercept it and reply with the object in `example.json` fixture
cy.intercept('GET', '**/comments/*', { fixture: 'example.json' }).as('getComment')
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.fixture-btn').click()
cy.wait('@getComment').its('response.body')
.should('have.property', 'name')
.and('include', 'Using fixtures to represent data')
})
it('cy.fixture() or require - load a fixture', function () {
// we are inside the "function () { ... }"
// callback and can use test context object "this"
// "this.example" was loaded in "beforeEach" function callback
expect(this.example, 'fixture in the test context')
.to.deep.equal(requiredExample)
// or use "cy.wrap" and "should('deep.equal', ...)" assertion
cy.wrap(this.example)
.should('deep.equal', requiredExample)
})
it('cy.readFile() - read file contents', () => {
// https://on.cypress.io/readfile
// You can read a file and yield its contents
// The filePath is relative to your project's root.
cy.readFile('cypress.json').then((json) => {
expect(json).to.be.an('object')
})
})
it('cy.writeFile() - write to a file', () => {
// https://on.cypress.io/writefile
// You can write to a file
// Use a response from a request to automatically
// generate a fixture file for use later
cy.request('https://jsonplaceholder.cypress.io/users')
.then((response) => {
cy.writeFile('cypress/fixtures/users.json', response.body)
})
cy.fixture('users').should((users) => {
expect(users[0].name).to.exist
})
// JavaScript arrays and objects are stringified
// and formatted into text.
cy.writeFile('cypress/fixtures/profile.json', {
id: 8739,
name: 'Jane',
email: 'jane@example.com',
})
cy.fixture('profile').should((profile) => {
expect(profile.name).to.eq('Jane')
})
})
})

View File

@@ -1,52 +0,0 @@
/// <reference types="cypress" />
context('Local Storage', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/local-storage')
})
// Although local storage is automatically cleared
// in between tests to maintain a clean state
// sometimes we need to clear the local storage manually
it('cy.clearLocalStorage() - clear all data in local storage', () => {
// https://on.cypress.io/clearlocalstorage
cy.get('.ls-btn').click().should(() => {
expect(localStorage.getItem('prop1')).to.eq('red')
expect(localStorage.getItem('prop2')).to.eq('blue')
expect(localStorage.getItem('prop3')).to.eq('magenta')
})
// clearLocalStorage() yields the localStorage object
cy.clearLocalStorage().should((ls) => {
expect(ls.getItem('prop1')).to.be.null
expect(ls.getItem('prop2')).to.be.null
expect(ls.getItem('prop3')).to.be.null
})
cy.get('.ls-btn').click().should(() => {
expect(localStorage.getItem('prop1')).to.eq('red')
expect(localStorage.getItem('prop2')).to.eq('blue')
expect(localStorage.getItem('prop3')).to.eq('magenta')
})
// Clear key matching string in Local Storage
cy.clearLocalStorage('prop1').should((ls) => {
expect(ls.getItem('prop1')).to.be.null
expect(ls.getItem('prop2')).to.eq('blue')
expect(ls.getItem('prop3')).to.eq('magenta')
})
cy.get('.ls-btn').click().should(() => {
expect(localStorage.getItem('prop1')).to.eq('red')
expect(localStorage.getItem('prop2')).to.eq('blue')
expect(localStorage.getItem('prop3')).to.eq('magenta')
})
// Clear keys matching regex in Local Storage
cy.clearLocalStorage(/prop1|2/).should((ls) => {
expect(ls.getItem('prop1')).to.be.null
expect(ls.getItem('prop2')).to.be.null
expect(ls.getItem('prop3')).to.eq('magenta')
})
})
})

View File

@@ -1,32 +0,0 @@
/// <reference types="cypress" />
context('Location', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/location')
})
it('cy.hash() - get the current URL hash', () => {
// https://on.cypress.io/hash
cy.hash().should('be.empty')
})
it('cy.location() - get window.location', () => {
// https://on.cypress.io/location
cy.location().should((location) => {
expect(location.hash).to.be.empty
expect(location.href).to.eq('https://example.cypress.io/commands/location')
expect(location.host).to.eq('example.cypress.io')
expect(location.hostname).to.eq('example.cypress.io')
expect(location.origin).to.eq('https://example.cypress.io')
expect(location.pathname).to.eq('/commands/location')
expect(location.port).to.eq('')
expect(location.protocol).to.eq('https:')
expect(location.search).to.be.empty
})
})
it('cy.url() - get the current URL', () => {
// https://on.cypress.io/url
cy.url().should('eq', 'https://example.cypress.io/commands/location')
})
})

View File

@@ -1,104 +0,0 @@
/// <reference types="cypress" />
context('Misc', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/misc')
})
it('.end() - end the command chain', () => {
// https://on.cypress.io/end
// cy.end is useful when you want to end a chain of commands
// and force Cypress to re-query from the root element
cy.get('.misc-table').within(() => {
// ends the current chain and yields null
cy.contains('Cheryl').click().end()
// queries the entire table again
cy.contains('Charles').click()
})
})
it('cy.exec() - execute a system command', () => {
// execute a system command.
// so you can take actions necessary for
// your test outside the scope of Cypress.
// https://on.cypress.io/exec
// we can use Cypress.platform string to
// select appropriate command
// https://on.cypress/io/platform
cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`)
// on CircleCI Windows build machines we have a failure to run bash shell
// https://github.com/cypress-io/cypress/issues/5169
// so skip some of the tests by passing flag "--env circle=true"
const isCircleOnWindows = Cypress.platform === 'win32' && Cypress.env('circle')
if (isCircleOnWindows) {
cy.log('Skipping test on CircleCI')
return
}
// cy.exec problem on Shippable CI
// https://github.com/cypress-io/cypress/issues/6718
const isShippable = Cypress.platform === 'linux' && Cypress.env('shippable')
if (isShippable) {
cy.log('Skipping test on ShippableCI')
return
}
cy.exec('echo Jane Lane')
.its('stdout').should('contain', 'Jane Lane')
if (Cypress.platform === 'win32') {
cy.exec('print cypress.json')
.its('stderr').should('be.empty')
} else {
cy.exec('cat cypress.json')
.its('stderr').should('be.empty')
cy.exec('pwd')
.its('code').should('eq', 0)
}
})
it('cy.focused() - get the DOM element that has focus', () => {
// https://on.cypress.io/focused
cy.get('.misc-form').find('#name').click()
cy.focused().should('have.id', 'name')
cy.get('.misc-form').find('#description').click()
cy.focused().should('have.id', 'description')
})
context('Cypress.Screenshot', function () {
it('cy.screenshot() - take a screenshot', () => {
// https://on.cypress.io/screenshot
cy.screenshot('my-image')
})
it('Cypress.Screenshot.defaults() - change default config of screenshots', function () {
Cypress.Screenshot.defaults({
blackout: ['.foo'],
capture: 'viewport',
clip: { x: 0, y: 0, width: 200, height: 200 },
scale: false,
disableTimersAndAnimations: true,
screenshotOnRunFailure: true,
onBeforeScreenshot () { },
onAfterScreenshot () { },
})
})
})
it('cy.wrap() - wrap an object', () => {
// https://on.cypress.io/wrap
cy.wrap({ foo: 'bar' })
.should('have.property', 'foo')
.and('include', 'bar')
})
})

View File

@@ -1,56 +0,0 @@
/// <reference types="cypress" />
context('Navigation', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io')
cy.get('.navbar-nav').contains('Commands').click()
cy.get('.dropdown-menu').contains('Navigation').click()
})
it('cy.go() - go back or forward in the browser\'s history', () => {
// https://on.cypress.io/go
cy.location('pathname').should('include', 'navigation')
cy.go('back')
cy.location('pathname').should('not.include', 'navigation')
cy.go('forward')
cy.location('pathname').should('include', 'navigation')
// clicking back
cy.go(-1)
cy.location('pathname').should('not.include', 'navigation')
// clicking forward
cy.go(1)
cy.location('pathname').should('include', 'navigation')
})
it('cy.reload() - reload the page', () => {
// https://on.cypress.io/reload
cy.reload()
// reload the page without using the cache
cy.reload(true)
})
it('cy.visit() - visit a remote url', () => {
// https://on.cypress.io/visit
// Visit any sub-domain of your current domain
// Pass options to the visit
cy.visit('https://example.cypress.io/commands/navigation', {
timeout: 50000, // increase total time for the visit to resolve
onBeforeLoad (contentWindow) {
// contentWindow is the remote page's window object
expect(typeof contentWindow === 'object').to.be.true
},
onLoad (contentWindow) {
// contentWindow is the remote page's window object
expect(typeof contentWindow === 'object').to.be.true
},
})
})
})

View File

@@ -1,163 +0,0 @@
/// <reference types="cypress" />
context('Network Requests', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/network-requests')
})
// Manage HTTP requests in your app
it('cy.request() - make an XHR request', () => {
// https://on.cypress.io/request
cy.request('https://jsonplaceholder.cypress.io/comments')
.should((response) => {
expect(response.status).to.eq(200)
// the server sometimes gets an extra comment posted from another machine
// which gets returned as 1 extra object
expect(response.body).to.have.property('length').and.be.oneOf([500, 501])
expect(response).to.have.property('headers')
expect(response).to.have.property('duration')
})
})
it('cy.request() - verify response using BDD syntax', () => {
cy.request('https://jsonplaceholder.cypress.io/comments')
.then((response) => {
// https://on.cypress.io/assertions
expect(response).property('status').to.equal(200)
expect(response).property('body').to.have.property('length').and.be.oneOf([500, 501])
expect(response).to.include.keys('headers', 'duration')
})
})
it('cy.request() with query parameters', () => {
// will execute request
// https://jsonplaceholder.cypress.io/comments?postId=1&id=3
cy.request({
url: 'https://jsonplaceholder.cypress.io/comments',
qs: {
postId: 1,
id: 3,
},
})
.its('body')
.should('be.an', 'array')
.and('have.length', 1)
.its('0') // yields first element of the array
.should('contain', {
postId: 1,
id: 3,
})
})
it('cy.request() - pass result to the second request', () => {
// first, let's find out the userId of the first user we have
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
.its('body') // yields the response object
.its('0') // yields the first element of the returned list
// the above two commands its('body').its('0')
// can be written as its('body.0')
// if you do not care about TypeScript checks
.then((user) => {
expect(user).property('id').to.be.a('number')
// make a new post on behalf of the user
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
userId: user.id,
title: 'Cypress Test Runner',
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
})
})
// note that the value here is the returned value of the 2nd request
// which is the new post object
.then((response) => {
expect(response).property('status').to.equal(201) // new entity created
expect(response).property('body').to.contain({
title: 'Cypress Test Runner',
})
// we don't know the exact post id - only that it will be > 100
// since JSONPlaceholder has built-in 100 posts
expect(response.body).property('id').to.be.a('number')
.and.to.be.gt(100)
// we don't know the user id here - since it was in above closure
// so in this test just confirm that the property is there
expect(response.body).property('userId').to.be.a('number')
})
})
it('cy.request() - save response in the shared test context', () => {
// https://on.cypress.io/variables-and-aliases
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
.its('body').its('0') // yields the first element of the returned list
.as('user') // saves the object in the test context
.then(function () {
// NOTE 👀
// By the time this callback runs the "as('user')" command
// has saved the user object in the test context.
// To access the test context we need to use
// the "function () { ... }" callback form,
// otherwise "this" points at a wrong or undefined object!
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
userId: this.user.id,
title: 'Cypress Test Runner',
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
})
.its('body').as('post') // save the new post from the response
})
.then(function () {
// When this callback runs, both "cy.request" API commands have finished
// and the test context has "user" and "post" objects set.
// Let's verify them.
expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id)
})
})
it('cy.intercept() - route responses to matching requests', () => {
// https://on.cypress.io/intercept
let message = 'whoa, this comment does not exist'
// Listen to GET to comments/1
cy.intercept('GET', '**/comments/*').as('getComment')
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.network-btn').click()
// https://on.cypress.io/wait
cy.wait('@getComment').its('response.statusCode').should('be.oneOf', [200, 304])
// Listen to POST to comments
cy.intercept('POST', '**/comments').as('postComment')
// we have code that posts a comment when
// the button is clicked in scripts.js
cy.get('.network-post').click()
cy.wait('@postComment').should(({ request, response }) => {
expect(request.body).to.include('email')
expect(request.headers).to.have.property('content-type')
expect(response && response.body).to.have.property('name', 'Using POST in cy.intercept()')
})
// Stub a response to PUT comments/ ****
cy.intercept({
method: 'PUT',
url: '**/comments/*',
}, {
statusCode: 404,
body: { error: message },
headers: { 'access-control-allow-origin': '*' },
delayMs: 500,
}).as('putComment')
// we have code that puts a comment when
// the button is clicked in scripts.js
cy.get('.network-put').click()
cy.wait('@putComment')
// our 404 statusCode logic in scripts.js executed
cy.get('.network-put-comment').should('contain', message)
})
})

View File

@@ -1,114 +0,0 @@
/// <reference types="cypress" />
context('Querying', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/querying')
})
// The most commonly used query is 'cy.get()', you can
// think of this like the '$' in jQuery
it('cy.get() - query DOM elements', () => {
// https://on.cypress.io/get
cy.get('#query-btn').should('contain', 'Button')
cy.get('.query-btn').should('contain', 'Button')
cy.get('#querying .well>button:first').should('contain', 'Button')
// ↲
// Use CSS selectors just like jQuery
cy.get('[data-test-id="test-example"]').should('have.class', 'example')
// 'cy.get()' yields jQuery object, you can get its attribute
// by invoking `.attr()` method
cy.get('[data-test-id="test-example"]')
.invoke('attr', 'data-test-id')
.should('equal', 'test-example')
// or you can get element's CSS property
cy.get('[data-test-id="test-example"]')
.invoke('css', 'position')
.should('equal', 'static')
// or use assertions directly during 'cy.get()'
// https://on.cypress.io/assertions
cy.get('[data-test-id="test-example"]')
.should('have.attr', 'data-test-id', 'test-example')
.and('have.css', 'position', 'static')
})
it('cy.contains() - query DOM elements with matching content', () => {
// https://on.cypress.io/contains
cy.get('.query-list')
.contains('bananas')
.should('have.class', 'third')
// we can pass a regexp to `.contains()`
cy.get('.query-list')
.contains(/^b\w+/)
.should('have.class', 'third')
cy.get('.query-list')
.contains('apples')
.should('have.class', 'first')
// passing a selector to contains will
// yield the selector containing the text
cy.get('#querying')
.contains('ul', 'oranges')
.should('have.class', 'query-list')
cy.get('.query-button')
.contains('Save Form')
.should('have.class', 'btn')
})
it('.within() - query DOM elements within a specific element', () => {
// https://on.cypress.io/within
cy.get('.query-form').within(() => {
cy.get('input:first').should('have.attr', 'placeholder', 'Email')
cy.get('input:last').should('have.attr', 'placeholder', 'Password')
})
})
it('cy.root() - query the root DOM element', () => {
// https://on.cypress.io/root
// By default, root is the document
cy.root().should('match', 'html')
cy.get('.query-ul').within(() => {
// In this within, the root is now the ul DOM element
cy.root().should('have.class', 'query-ul')
})
})
it('best practices - selecting elements', () => {
// https://on.cypress.io/best-practices#Selecting-Elements
cy.get('[data-cy=best-practices-selecting-elements]').within(() => {
// Worst - too generic, no context
cy.get('button').click()
// Bad. Coupled to styling. Highly subject to change.
cy.get('.btn.btn-large').click()
// Average. Coupled to the `name` attribute which has HTML semantics.
cy.get('[name=submission]').click()
// Better. But still coupled to styling or JS event listeners.
cy.get('#main').click()
// Slightly better. Uses an ID but also ensures the element
// has an ARIA role attribute
cy.get('#main[role=button]').click()
// Much better. But still coupled to text content that may change.
cy.contains('Submit').click()
// Best. Insulated from all changes.
cy.get('[data-cy=submit]').click()
})
})
})

View File

@@ -1,205 +0,0 @@
/// <reference types="cypress" />
// remove no check once Cypress.sinon is typed
// https://github.com/cypress-io/cypress/issues/6720
context('Spies, Stubs, and Clock', () => {
it('cy.spy() - wrap a method in a spy', () => {
// https://on.cypress.io/spy
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
const obj = {
foo () {},
}
const spy = cy.spy(obj, 'foo').as('anyArgs')
obj.foo()
expect(spy).to.be.called
})
it('cy.spy() retries until assertions pass', () => {
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
const obj = {
/**
* Prints the argument passed
* @param x {any}
*/
foo (x) {
console.log('obj.foo called with', x)
},
}
cy.spy(obj, 'foo').as('foo')
setTimeout(() => {
obj.foo('first')
}, 500)
setTimeout(() => {
obj.foo('second')
}, 2500)
cy.get('@foo').should('have.been.calledTwice')
})
it('cy.stub() - create a stub and/or replace a function with stub', () => {
// https://on.cypress.io/stub
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
const obj = {
/**
* prints both arguments to the console
* @param a {string}
* @param b {string}
*/
foo (a, b) {
console.log('a', a, 'b', b)
},
}
const stub = cy.stub(obj, 'foo').as('foo')
obj.foo('foo', 'bar')
expect(stub).to.be.called
})
it('cy.clock() - control time in the browser', () => {
// https://on.cypress.io/clock
// create the date in UTC so its always the same
// no matter what local timezone the browser is running in
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
cy.clock(now)
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
cy.get('#clock-div').click()
.should('have.text', '1489449600')
})
it('cy.tick() - move time in the browser', () => {
// https://on.cypress.io/tick
// create the date in UTC so its always the same
// no matter what local timezone the browser is running in
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
cy.clock(now)
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
cy.get('#tick-div').click()
.should('have.text', '1489449600')
cy.tick(10000) // 10 seconds passed
cy.get('#tick-div').click()
.should('have.text', '1489449610')
})
it('cy.stub() matches depending on arguments', () => {
// see all possible matchers at
// https://sinonjs.org/releases/latest/matchers/
const greeter = {
/**
* Greets a person
* @param {string} name
*/
greet (name) {
return `Hello, ${name}!`
},
}
cy.stub(greeter, 'greet')
.callThrough() // if you want non-matched calls to call the real method
.withArgs(Cypress.sinon.match.string).returns('Hi')
.withArgs(Cypress.sinon.match.number).throws(new Error('Invalid name'))
expect(greeter.greet('World')).to.equal('Hi')
// @ts-ignore
expect(() => greeter.greet(42)).to.throw('Invalid name')
expect(greeter.greet).to.have.been.calledTwice
// non-matched calls goes the actual method
// @ts-ignore
expect(greeter.greet()).to.equal('Hello, undefined!')
})
it('matches call arguments using Sinon matchers', () => {
// see all possible matchers at
// https://sinonjs.org/releases/latest/matchers/
const calculator = {
/**
* returns the sum of two arguments
* @param a {number}
* @param b {number}
*/
add (a, b) {
return a + b
},
}
const spy = cy.spy(calculator, 'add').as('add')
expect(calculator.add(2, 3)).to.equal(5)
// if we want to assert the exact values used during the call
expect(spy).to.be.calledWith(2, 3)
// let's confirm "add" method was called with two numbers
expect(spy).to.be.calledWith(Cypress.sinon.match.number, Cypress.sinon.match.number)
// alternatively, provide the value to match
expect(spy).to.be.calledWith(Cypress.sinon.match(2), Cypress.sinon.match(3))
// match any value
expect(spy).to.be.calledWith(Cypress.sinon.match.any, 3)
// match any value from a list
expect(spy).to.be.calledWith(Cypress.sinon.match.in([1, 2, 3]), 3)
/**
* Returns true if the given number is event
* @param {number} x
*/
const isEven = (x) => x % 2 === 0
// expect the value to pass a custom predicate function
// the second argument to "sinon.match(predicate, message)" is
// shown if the predicate does not pass and assertion fails
expect(spy).to.be.calledWith(Cypress.sinon.match(isEven, 'isEven'), 3)
/**
* Returns a function that checks if a given number is larger than the limit
* @param {number} limit
* @returns {(x: number) => boolean}
*/
const isGreaterThan = (limit) => (x) => x > limit
/**
* Returns a function that checks if a given number is less than the limit
* @param {number} limit
* @returns {(x: number) => boolean}
*/
const isLessThan = (limit) => (x) => x < limit
// you can combine several matchers using "and", "or"
expect(spy).to.be.calledWith(
Cypress.sinon.match.number,
Cypress.sinon.match(isGreaterThan(2), '> 2').and(Cypress.sinon.match(isLessThan(4), '< 4')),
)
expect(spy).to.be.calledWith(
Cypress.sinon.match.number,
Cypress.sinon.match(isGreaterThan(200), '> 200').or(Cypress.sinon.match(3)),
)
// matchers can be used from BDD assertions
cy.get('@add').should('have.been.calledWith',
Cypress.sinon.match.number, Cypress.sinon.match(3))
// you can alias matchers for shorter test code
const { match: M } = Cypress.sinon
cy.get('@add').should('have.been.calledWith', M.number, M(3))
})
})

View File

@@ -1,121 +0,0 @@
/// <reference types="cypress" />
context('Traversal', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/traversal')
})
it('.children() - get child DOM elements', () => {
// https://on.cypress.io/children
cy.get('.traversal-breadcrumb')
.children('.active')
.should('contain', 'Data')
})
it('.closest() - get closest ancestor DOM element', () => {
// https://on.cypress.io/closest
cy.get('.traversal-badge')
.closest('ul')
.should('have.class', 'list-group')
})
it('.eq() - get a DOM element at a specific index', () => {
// https://on.cypress.io/eq
cy.get('.traversal-list>li')
.eq(1).should('contain', 'siamese')
})
it('.filter() - get DOM elements that match the selector', () => {
// https://on.cypress.io/filter
cy.get('.traversal-nav>li')
.filter('.active').should('contain', 'About')
})
it('.find() - get descendant DOM elements of the selector', () => {
// https://on.cypress.io/find
cy.get('.traversal-pagination')
.find('li').find('a')
.should('have.length', 7)
})
it('.first() - get first DOM element', () => {
// https://on.cypress.io/first
cy.get('.traversal-table td')
.first().should('contain', '1')
})
it('.last() - get last DOM element', () => {
// https://on.cypress.io/last
cy.get('.traversal-buttons .btn')
.last().should('contain', 'Submit')
})
it('.next() - get next sibling DOM element', () => {
// https://on.cypress.io/next
cy.get('.traversal-ul')
.contains('apples').next().should('contain', 'oranges')
})
it('.nextAll() - get all next sibling DOM elements', () => {
// https://on.cypress.io/nextall
cy.get('.traversal-next-all')
.contains('oranges')
.nextAll().should('have.length', 3)
})
it('.nextUntil() - get next sibling DOM elements until next el', () => {
// https://on.cypress.io/nextuntil
cy.get('#veggies')
.nextUntil('#nuts').should('have.length', 3)
})
it('.not() - remove DOM elements from set of DOM elements', () => {
// https://on.cypress.io/not
cy.get('.traversal-disabled .btn')
.not('[disabled]').should('not.contain', 'Disabled')
})
it('.parent() - get parent DOM element from DOM elements', () => {
// https://on.cypress.io/parent
cy.get('.traversal-mark')
.parent().should('contain', 'Morbi leo risus')
})
it('.parents() - get parent DOM elements from DOM elements', () => {
// https://on.cypress.io/parents
cy.get('.traversal-cite')
.parents().should('match', 'blockquote')
})
it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => {
// https://on.cypress.io/parentsuntil
cy.get('.clothes-nav')
.find('.active')
.parentsUntil('.clothes-nav')
.should('have.length', 2)
})
it('.prev() - get previous sibling DOM element', () => {
// https://on.cypress.io/prev
cy.get('.birds').find('.active')
.prev().should('contain', 'Lorikeets')
})
it('.prevAll() - get all previous sibling DOM elements', () => {
// https://on.cypress.io/prevall
cy.get('.fruits-list').find('.third')
.prevAll().should('have.length', 2)
})
it('.prevUntil() - get all previous sibling DOM elements until el', () => {
// https://on.cypress.io/prevuntil
cy.get('.foods-list').find('#nuts')
.prevUntil('#veggies').should('have.length', 3)
})
it('.siblings() - get all sibling DOM elements', () => {
// https://on.cypress.io/siblings
cy.get('.traversal-pills .active')
.siblings().should('have.length', 2)
})
})

View File

@@ -1,110 +0,0 @@
/// <reference types="cypress" />
context('Utilities', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/utilities')
})
it('Cypress._ - call a lodash method', () => {
// https://on.cypress.io/_
cy.request('https://jsonplaceholder.cypress.io/users')
.then((response) => {
let ids = Cypress._.chain(response.body).map('id').take(3).value()
expect(ids).to.deep.eq([1, 2, 3])
})
})
it('Cypress.$ - call a jQuery method', () => {
// https://on.cypress.io/$
let $li = Cypress.$('.utility-jquery li:first')
cy.wrap($li)
.should('not.have.class', 'active')
.click()
.should('have.class', 'active')
})
it('Cypress.Blob - blob utilities and base64 string conversion', () => {
// https://on.cypress.io/blob
cy.get('.utility-blob').then(($div) => {
// https://github.com/nolanlawson/blob-util#imgSrcToDataURL
// get the dataUrl string for the javascript-logo
return Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous')
.then((dataUrl) => {
// create an <img> element and set its src to the dataUrl
let img = Cypress.$('<img />', { src: dataUrl })
// need to explicitly return cy here since we are initially returning
// the Cypress.Blob.imgSrcToDataURL promise to our test
// append the image
$div.append(img)
cy.get('.utility-blob img').click()
.should('have.attr', 'src', dataUrl)
})
})
})
it('Cypress.minimatch - test out glob patterns against strings', () => {
// https://on.cypress.io/minimatch
let matching = Cypress.minimatch('/users/1/comments', '/users/*/comments', {
matchBase: true,
})
expect(matching, 'matching wildcard').to.be.true
matching = Cypress.minimatch('/users/1/comments/2', '/users/*/comments', {
matchBase: true,
})
expect(matching, 'comments').to.be.false
// ** matches against all downstream path segments
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/**', {
matchBase: true,
})
expect(matching, 'comments').to.be.true
// whereas * matches only the next path segment
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/*', {
matchBase: false,
})
expect(matching, 'comments').to.be.false
})
it('Cypress.Promise - instantiate a bluebird promise', () => {
// https://on.cypress.io/promise
let waited = false
/**
* @return Bluebird<string>
*/
function waitOneSecond () {
// return a promise that resolves after 1 second
// @ts-ignore TS2351 (new Cypress.Promise)
return new Cypress.Promise((resolve, reject) => {
setTimeout(() => {
// set waited to true
waited = true
// resolve with 'foo' string
resolve('foo')
}, 1000)
})
}
cy.then(() => {
// return a promise to cy.then() that
// is awaited until it resolves
// @ts-ignore TS7006
return waitOneSecond().then((str) => {
expect(str).to.eq('foo')
expect(waited).to.be.true
})
})
})
})

View File

@@ -1,59 +0,0 @@
/// <reference types="cypress" />
context('Viewport', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/viewport')
})
it('cy.viewport() - set the viewport size and dimension', () => {
// https://on.cypress.io/viewport
cy.get('#navbar').should('be.visible')
cy.viewport(320, 480)
// the navbar should have collapse since our screen is smaller
cy.get('#navbar').should('not.be.visible')
cy.get('.navbar-toggle').should('be.visible').click()
cy.get('.nav').find('a').should('be.visible')
// lets see what our app looks like on a super large screen
cy.viewport(2999, 2999)
// cy.viewport() accepts a set of preset sizes
// to easily set the screen to a device's width and height
// We added a cy.wait() between each viewport change so you can see
// the change otherwise it is a little too fast to see :)
cy.viewport('macbook-15')
cy.wait(200)
cy.viewport('macbook-13')
cy.wait(200)
cy.viewport('macbook-11')
cy.wait(200)
cy.viewport('ipad-2')
cy.wait(200)
cy.viewport('ipad-mini')
cy.wait(200)
cy.viewport('iphone-6+')
cy.wait(200)
cy.viewport('iphone-6')
cy.wait(200)
cy.viewport('iphone-5')
cy.wait(200)
cy.viewport('iphone-4')
cy.wait(200)
cy.viewport('iphone-3')
cy.wait(200)
// cy.viewport() accepts an orientation for all presets
// the default orientation is 'portrait'
cy.viewport('ipad-2', 'portrait')
cy.wait(200)
cy.viewport('iphone-4', 'landscape')
cy.wait(200)
// The viewport will be reset back to the default dimensions
// in between tests (the default can be set in cypress.json)
})
})

View File

@@ -1,31 +0,0 @@
/// <reference types="cypress" />
context('Waiting', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/waiting')
})
// BE CAREFUL of adding unnecessary wait times.
// https://on.cypress.io/best-practices#Unnecessary-Waiting
// https://on.cypress.io/wait
it('cy.wait() - wait for a specific amount of time', () => {
cy.get('.wait-input1').type('Wait 1000ms after typing')
cy.wait(1000)
cy.get('.wait-input2').type('Wait 1000ms after typing')
cy.wait(1000)
cy.get('.wait-input3').type('Wait 1000ms after typing')
cy.wait(1000)
})
it('cy.wait() - wait for a specific route', () => {
// Listen to GET to comments/1
cy.intercept('GET', '**/comments/*').as('getComment')
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.network-btn').click()
// wait for GET comments/1
cy.wait('@getComment').its('response.statusCode').should('be.oneOf', [200, 304])
})
})

View File

@@ -1,22 +0,0 @@
/// <reference types="cypress" />
context('Window', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/window')
})
it('cy.window() - get the global window object', () => {
// https://on.cypress.io/window
cy.window().should('have.property', 'top')
})
it('cy.document() - get the document object', () => {
// https://on.cypress.io/document
cy.document().should('have.property', 'charset').and('eq', 'UTF-8')
})
it('cy.title() - get the title', () => {
// https://on.cypress.io/title
cy.title().should('include', 'Kitchen Sink')
})
})

View File

@@ -17,6 +17,6 @@
*/
// eslint-disable-next-line no-unused-vars
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}

View File

@@ -2,7 +2,11 @@
"compilerOptions": {
"allowJs": true,
"baseUrl": "../node_modules",
"types": ["cypress"]
"types": [
"cypress"
]
},
"include": ["**/*.*"]
"include": [
"**/*.*"
]
}

View File

@@ -8872,13 +8872,13 @@
│ ├─ email: luis@luisrudge.net
│ ├─ path: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-flexbugs-fixes
│ └─ licenseFile: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-flexbugs-fixes/LICENSE
├─ postcss-focus-visible@4.0.0
├─ postcss-focus-open@4.0.0
│ ├─ licenses: CC0-1.0
│ ├─ repository: https://github.com/jonathantneal/postcss-focus-visible
│ ├─ repository: https://github.com/jonathantneal/postcss-focus-open
│ ├─ publisher: Jonathan Neal
│ ├─ email: jonathantneal@hotmail.com
│ ├─ path: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-focus-visible
│ └─ licenseFile: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-focus-visible/LICENSE.md
│ ├─ path: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-focus-open
│ └─ licenseFile: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-focus-open/LICENSE.md
├─ postcss-focus-within@3.0.0
│ ├─ licenses: CC0-1.0
│ ├─ repository: https://github.com/jonathantneal/postcss-focus-within

16987
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,85 +4,86 @@
"private": true,
"proxy": "http://localhost:4000",
"dependencies": {
"@apollo/client": "^3.7.9",
"@ant-design/compatible": "^5.1.2",
"@ant-design/pro-layout": "^7.17.16",
"@apollo/client": "^3.8.10",
"@asseinfo/react-kanban": "^2.2.0",
"@craco/craco": "^7.0.0",
"@fingerprintjs/fingerprintjs": "^3.4.2",
"@craco/craco": "^7.1.0",
"@fingerprintjs/fingerprintjs": "^4.2.2",
"@jsreport/browser-client": "^3.1.0",
"@sentry/react": "^7.40.0",
"@sentry/tracing": "^7.40.0",
"@splitsoftware/splitio-react": "^1.8.1",
"@tanem/react-nprogress": "^5.0.8",
"antd": "^4.24.8",
"@reduxjs/toolkit": "^2.1.0",
"@sentry/cli": "^2.28.0",
"@sentry/react": "^7.100.0",
"@sentry/tracing": "^7.100.0",
"@splitsoftware/splitio-react": "^1.11.0",
"@tanem/react-nprogress": "^5.0.51",
"antd": "^5.14.0",
"apollo-link-logger": "^2.0.1",
"axios": "^1.3.4",
"craco-less": "^2.0.0",
"apollo-link-sentry": "^3.3.0",
"axios": "^1.6.7",
"craco-less": "^3.0.1",
"dayjs": "^1.11.10",
"dayjs-business-days2": "^1.2.2",
"dinero.js": "^1.9.1",
"dotenv": "^16.0.1",
"dotenv": "^16.4.1",
"enquire-js": "^0.2.1",
"env-cmd": "^10.1.0",
"exifr": "^7.1.3",
"firebase": "^9.17.1",
"firebase": "^10.8.0",
"graphql": "^16.6.0",
"i18next": "^22.4.10",
"i18next-browser-languagedetector": "^7.0.1",
"jsoneditor": "^9.9.0",
"i18next": "^23.8.2",
"i18next-browser-languagedetector": "^7.0.2",
"jsoneditor": "^10.0.0",
"jsreport-browser-client-dist": "^1.3.0",
"libphonenumber-js": "^1.10.21",
"logrocket": "^3.0.1",
"markerjs2": "^2.28.1",
"moment-business-days": "^1.2.0",
"moment-timezone": "^0.5.41",
"libphonenumber-js": "^1.10.55",
"logrocket": "^7.0.0",
"markerjs2": "^2.32.0",
"normalize-url": "^8.0.0",
"phone": "^3.1.35",
"phone": "^3.1.42",
"preval.macro": "^5.0.0",
"prop-types": "^15.8.1",
"query-string": "^7.1.3",
"query-string": "^8.2.0",
"rc-queue-anim": "^2.0.0",
"rc-scroll-anim": "^2.7.6",
"react": "^17.0.2",
"react-big-calendar": "^1.6.8",
"react": "^18.2.0",
"react-big-calendar": "^1.8.7",
"react-color": "^2.19.3",
"react-cookie": "^4.1.1",
"react-dom": "^17.0.2",
"react-drag-listview": "^0.2.1",
"react-cookie": "^7.0.2",
"react-dom": "^18.2.0",
"react-drag-listview": "^2.0.0",
"react-grid-gallery": "^1.0.0",
"react-grid-layout": "^1.3.4",
"react-i18next": "^12.2.0",
"react-icons": "^4.7.1",
"react-grid-layout": "1.3.4",
"react-i18next": "^14.0.4",
"react-icons": "^5.0.1",
"react-image-lightbox": "^5.1.4",
"react-intersection-observer": "^9.4.3",
"react-number-format": "^5.1.3",
"react-redux": "^8.0.5",
"react-resizable": "^3.0.4",
"react-router-dom": "^5.3.0",
"react-intersection-observer": "^9.7.0",
"react-markdown": "^9.0.1",
"react-number-format": "^5.1.4",
"react-redux": "^9.1.0",
"react-resizable": "^3.0.5",
"react-router-dom": "^6.22.0",
"react-scripts": "^5.0.1",
"react-sticky": "^6.0.3",
"react-sublime-video": "^0.2.5",
"react-virtualized": "^9.22.3",
"recharts": "^2.4.3",
"redux": "^4.2.1",
"react-virtualized": "^9.22.5",
"recharts": "^2.11.0",
"redux": "^5.0.1",
"redux-persist": "^6.0.0",
"redux-saga": "^1.2.2",
"redux-saga": "^1.3.0",
"redux-state-sync": "^3.1.4",
"reselect": "^4.1.7",
"sass": "^1.58.3",
"socket.io-client": "^4.6.1",
"styled-components": "^5.3.6",
"reselect": "^5.1.0",
"sass": "^1.70.0",
"socket.io-client": "^4.7.4",
"styled-components": "^6.1.8",
"subscriptions-transport-ws": "^0.11.0",
"web-vitals": "^2.1.4",
"workbox-background-sync": "^6.5.3",
"workbox-broadcast-update": "^6.5.3",
"workbox-cacheable-response": "^6.5.3",
"workbox-core": "^6.5.3",
"workbox-expiration": "^6.5.3",
"workbox-google-analytics": "^6.5.3",
"workbox-navigation-preload": "^6.5.3",
"workbox-precaching": "^6.5.3",
"workbox-range-requests": "^6.5.3",
"workbox-routing": "^6.5.3",
"workbox-strategies": "^6.5.3",
"workbox-streams": "^6.5.3",
"terser-webpack-plugin": "^5.3.10",
"web-vitals": "^3.5.2",
"workbox-core": "^7.0.0",
"workbox-expiration": "^7.0.0",
"workbox-navigation-preload": "^7.0.0",
"workbox-precaching": "^7.0.0",
"workbox-routing": "^7.0.0",
"workbox-strategies": "^7.0.0",
"yauzl": "^2.10.0"
},
"scripts": {
@@ -94,7 +95,9 @@
"buildcra": "REACT_APP_GIT_SHA=`git rev-parse --short HEAD` craco build",
"test": "cypress open",
"eject": "react-scripts eject",
"madge": "madge --image ./madge-graph.svg --extensions js,jsx,ts,tsx --circular ."
"madge": "madge --image ./madge-graph.svg --extensions js,jsx,ts,tsx --circular .",
"eulaize": "node src/utils/eulaize.js",
"sentry:sourcemaps": "sentry-cli sourcemaps inject --org imex --project imexonline ./build && sentry-cli sourcemaps upload --org imex --project imexonline ./build"
},
"eslintConfig": {
"extends": [
@@ -119,12 +122,13 @@
"react-error-overlay": "6.0.9"
},
"devDependencies": {
"@sentry/webpack-plugin": "^1.20.0",
"@testing-library/cypress": "^8.0.3",
"cypress": "^10.3.1",
"eslint-plugin-cypress": "^2.12.1",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@sentry/webpack-plugin": "^2.14.0",
"@testing-library/cypress": "^10.0.1",
"cypress": "^13.6.4",
"eslint-plugin-cypress": "^2.15.1",
"react-error-overlay": "6.0.11",
"redux-logger": "^3.0.6",
"source-map-explorer": "^2.5.2"
"source-map-explorer": "^2.5.3"
}
}

View File

@@ -190,7 +190,7 @@ This package contains the following license and notice below:
# @firebase/logger
This package serves as the base of all logging in the JS SDK. Any logging that
is intended to be visible to Firebase end developers should go through this
is intended to be open to Firebase end developers should go through this
module.
## Basic Usage
@@ -9375,7 +9375,7 @@ parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
to the extent that it includes a convenient and prominently open
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the

View File

@@ -1029,7 +1029,7 @@ The following NPM packages may be included in this product:
- postcss-dir-pseudo-class@5.0.0
- postcss-double-position-gradients@1.0.0
- postcss-env-function@2.0.2
- postcss-focus-visible@4.0.0
- postcss-focus-open@4.0.0
- postcss-focus-within@3.0.0
- postcss-gap-properties@2.0.0
- postcss-image-set-function@3.0.1
@@ -1699,7 +1699,7 @@ This package contains the following license and notice below:
# @firebase/logger
This package serves as the base of all logging in the JS SDK. Any logging that
is intended to be visible to Firebase end developers should go through this
is intended to be open to Firebase end developers should go through this
module.
## Basic Usage
@@ -24029,7 +24029,7 @@ parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
to the extent that it includes a convenient and prominently open
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the

View File

@@ -5,41 +5,52 @@ importScripts("https://www.gstatic.com/firebasejs/8.2.0/firebase-messaging.js");
// Initialize the Firebase app in the service worker by passing the generated config
let firebaseConfig;
switch (this.location.hostname) {
case "localhost":
firebaseConfig = {
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",
};
break;
case "test.imex.online":
firebaseConfig = {
apiKey: "AIzaSyBw7_GTy7GtQyfkIRPVrWHEGKfcqeyXw0c",
authDomain: "imex-test.firebaseapp.com",
projectId: "imex-test",
storageBucket: "imex-test.appspot.com",
messagingSenderId: "991923618608",
appId: "1:991923618608:web:633437569cdad78299bef5",
// measurementId: "${config.measurementId}",
};
break;
case "imex.online":
default:
firebaseConfig = {
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",
};
case "localhost":
firebaseConfig = {
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",
};
break;
case "test.imex.online":
firebaseConfig = {
apiKey: "AIzaSyBw7_GTy7GtQyfkIRPVrWHEGKfcqeyXw0c",
authDomain: "imex-test.firebaseapp.com",
projectId: "imex-test",
storageBucket: "imex-test.appspot.com",
messagingSenderId: "991923618608",
appId: "1:991923618608:web:633437569cdad78299bef5",
// measurementId: "${config.measurementId}",
};
break;
case "romeonline.io":
firebaseConfig = {
apiKey: "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE",
authDomain: "rome-prod-1.firebaseapp.com",
projectId: "rome-prod-1",
storageBucket: "rome-prod-1.appspot.com",
messagingSenderId: "147786367145",
appId: "1:147786367145:web:9d4cba68071c3f29a8a9b8",
measurementId: "G-G8Z9DRHTZS",
};
break;
case "imex.online":
default:
firebaseConfig = {
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",
};
}
firebase.initializeApp(firebaseConfig);
@@ -48,9 +59,9 @@ firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
messaging.onBackgroundMessage(function (payload) {
// Customize notification here
const channel = new BroadcastChannel("imex-sw-messages");
channel.postMessage(payload);
// Customize notification here
const channel = new BroadcastChannel("imex-sw-messages");
channel.postMessage(payload);
//self.registration.showNotification(notificationTitle, notificationOptions);
//self.registration.showNotification(notificationTitle, notificationOptions);
});

View File

@@ -1,73 +1,134 @@
<!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="#002366" />
<meta name="description" content="ImEX Online" />
<head>
<meta charset="utf-8"/>
<link href="%PUBLIC_URL%/ro-favicon.png" rel="icon"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<meta content="#002366" name="theme-color"/>
<meta content="Rome Online" name="description"/>
<!-- <link rel="apple-touch-icon" href="logo192.png" /> -->
<link rel="apple-touch-icon" href="logo192.png" />
<script type="text/javascript">
window.$crisp = [];
window.CRISP_WEBSITE_ID = "36724f62-2eb0-4b29-9cdd-9905fb99913e";
(function () {
d = document;
s = d.createElement("script");
s.src = "https://client.crisp.chat/l.js";
s.async = 1;
d.getElementsByTagName("head")[0].appendChild(s);
})();
</script>
<!--Use the below code snippet to provide real time updates to the live chat plugin without the need of copying and paste each time to your website when changes are made via PBX-->
<call-us-selector party="LiveChat528346" phonesystem-url=https://rometech.east.3cx.us:5001></call-us-selector>
<!--Incase you don't want real time updates to the live chat plugin when options are changed, use the below code snippet. Please note that each time you change the settings you will need to copy and paste the snippet code to your website-->
<!--<call-us
phonesystem-url=https://rometech.east.3cx.us:5001
style="position:fixed;font-size:16px;line-height:17px;z-index: 99999;right: 20px; bottom: 20px;"
id="wp-live-chat-by-3CX"
minimized="true"
animation-style="noanimation"
party="LiveChat528346"
minimized-style="bubbleright"
allow-call="true"
allow-video="false"
allow-soundnotifications="true"
enable-mute="true"
enable-onmobile="true"
offline-enabled="true"
enable="true"
ignore-queueownership="false"
authentication="both"
show-operator-actual-name="true"
aknowledge-received="true"
gdpr-enabled="false"
message-userinfo-format="name"
message-dateformat="both"
lang="browser"
button-icon-type="default"
greeting-visibility="none"
greeting-offline-visibility="none"
chat-delay="2000"
enable-direct-call="true"
enable-ga="false"
></call-us>-->
<script charset="utf-8" defer id="tcx-callus-js"
src=https://downloads-global.3cx.com/downloads/livechatandtalk/v1/callus.js></script>
<link href="logo192.png" rel="apple-touch-icon"/>
<script>
!(function () {
"use strict";
var e = [
"debug",
"destroy",
"do",
"help",
"identify",
"is",
"off",
"on",
"ready",
"render",
"reset",
"safe",
"set",
];
if (window.noticeable)
console.warn("Noticeable SDK code snippet loaded more than once");
else {
var n = (window.noticeable = window.noticeable || []);
function t(e) {
return function () {
var t = Array.prototype.slice.call(arguments);
return t.unshift(e), n.push(t), n;
};
}
!(function () {
for (var o = 0; o < e.length; o++) {
var r = e[o];
n[r] = t(r);
!(function () {
"use strict";
var e = [
"debug",
"destroy",
"do",
"help",
"identify",
"is",
"off",
"on",
"ready",
"render",
"reset",
"safe",
"set",
];
if (window.noticeable)
console.warn("Noticeable SDK code snippet loaded more than once");
else {
var n = (window.noticeable = window.noticeable || []);
function t(e) {
return function () {
var t = Array.prototype.slice.call(arguments);
return t.unshift(e), n.push(t), n;
};
}
!(function () {
for (var o = 0; o < e.length; o++) {
var r = e[o];
n[r] = t(r);
}
})(),
(function () {
var e = document.createElement("script");
(e.async = !0), (e.src = "https://sdk.noticeable.io/l.js");
var n = document.head;
n.insertBefore(e, n.firstChild);
})();
}
})(),
(function () {
var e = document.createElement("script");
(e.async = !0), (e.src = "https://sdk.noticeable.io/l.js");
var n = document.head;
n.insertBefore(e, n.firstChild);
})();
}
})();
})();
</script>
<!--
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" />
<link href="%PUBLIC_URL%/manifest.json" rel="manifest"/>
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
@@ -77,10 +138,10 @@
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</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
<title>Rome Online</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

View File

@@ -2,12 +2,12 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
xmlns="http://www.w3.org/2000/svg"
id="etuajo-oikeus"
width="450"
height="450">
<path d="M 0,225 L 225,0 L 450,225 L 225,450" fill="#000000" />
<path d="M 225,431.25 L 18.75,225 L 225,18.75 L 431.25,225" fill="#ffffff" />
<path d="M 56.25,225 L 225,56.25 L 393.75,225 L 225,393.75" fill="#000000" />
<path d="M 225,386.25 L 63.75,225 L 225,63.75 L 386.25,225" fill="#ffd90f" />
xmlns="http://www.w3.org/2000/svg"
id="etuajo-oikeus"
width="450"
height="450">
<path d="M 0,225 L 225,0 L 450,225 L 225,450" fill="#000000"/>
<path d="M 225,431.25 L 18.75,225 L 225,18.75 L 431.25,225" fill="#ffffff"/>
<path d="M 56.25,225 L 225,56.25 L 393.75,225 L 225,393.75" fill="#000000"/>
<path d="M 225,386.25 L 63.75,225 L 225,63.75 L 386.25,225" fill="#ffd90f"/>
</svg>

Before

Width:  |  Height:  |  Size: 552 B

After

Width:  |  Height:  |  Size: 572 B

View File

@@ -1,6 +1,6 @@
{
"short_name": "ImEX Online",
"name": "ImEX Online",
"short_name": "Rome Online",
"name": "Rome Online",
"description": "The ultimate bodyshop management system.",
"icons": [
{

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

View File

@@ -1,44 +1,53 @@
import { ApolloProvider } from "@apollo/client";
import { SplitFactory, SplitSdk } from "@splitsoftware/splitio-react";
import { ConfigProvider } from "antd";
import {ApolloProvider} from "@apollo/client";
import {SplitFactoryProvider, SplitSdk,} from '@splitsoftware/splitio-react';
import {ConfigProvider} from "antd";
import enLocale from "antd/es/locale/en_US";
import moment from "moment";
import dayjs from "../utils/day";
import 'dayjs/locale/en';
import React from "react";
import { useTranslation } from "react-i18next";
import {useTranslation} from "react-i18next";
import GlobalLoadingBar from "../components/global-loading-bar/global-loading-bar.component";
import client from "../utils/GraphQLClient";
import App from "./App";
import * as Sentry from "@sentry/react";
moment.locale("en-US");
import themeProvider from "./themeProvider";
export const factory = SplitSdk({
core: {
authorizationKey: process.env.REACT_APP_SPLIT_API,
key: "anon",
},
});
dayjs.locale("en");
export default function AppContainer() {
const { t } = useTranslation();
const config = {
core: {
authorizationKey: process.env.REACT_APP_SPLIT_API,
key: "anon",
},
};
export const factory = SplitSdk(config);
return (
<ApolloProvider client={client}>
<ConfigProvider
//componentSize="small"
input={{ autoComplete: "new-password" }}
locale={enLocale}
form={{
validateMessages: {
// eslint-disable-next-line no-template-curly-in-string
required: t("general.validation.required", { label: "${label}" }),
},
}}
>
<GlobalLoadingBar />
<SplitFactory factory={factory}>
<App />
</SplitFactory>
</ConfigProvider>
</ApolloProvider>
);
function AppContainer() {
const {t} = useTranslation();
return (
<ApolloProvider client={client}>
<ConfigProvider
//componentSize="small"
input={{autoComplete: "new-password"}}
locale={enLocale}
theme={themeProvider}
form={{
validateMessages: {
// eslint-disable-next-line no-template-curly-in-string
required: t("general.validation.required", {label: "${label}"}),
},
}}
>
<GlobalLoadingBar/>
<SplitFactoryProvider factory={factory}>
<App/>
</SplitFactoryProvider>
</ConfigProvider>
</ApolloProvider>
);
}
export default Sentry.withProfiler(AppContainer);

View File

@@ -1,161 +1,156 @@
import { useClient } from "@splitsoftware/splitio-react";
import { Button, Result } from "antd";
import {useSplitClient} from "@splitsoftware/splitio-react";
import {Button, Result} from "antd";
import LogRocket from "logrocket";
import React, { lazy, Suspense, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Route, Switch } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import React, {lazy, Suspense, useEffect, useState} from "react";
import {useTranslation} from "react-i18next";
import {connect} from "react-redux";
import {Route, Routes} from "react-router-dom";
import {createStructuredSelector} from "reselect";
import DocumentEditorContainer from "../components/document-editor/document-editor.container";
import ErrorBoundary from "../components/error-boundary/error-boundary.component";
//Component Imports
import LoadingSpinner from "../components/loading-spinner/loading-spinner.component";
import DisclaimerPage from "../pages/disclaimer/disclaimer.page";
import LandingPage from "../pages/landing/landing.page";
import TechPageContainer from "../pages/tech/tech.page.container";
import { setOnline } from "../redux/application/application.actions";
import { selectOnline } from "../redux/application/application.selectors";
import { checkUserSession } from "../redux/user/user.actions";
import {
selectBodyshop,
selectCurrentUser,
} from "../redux/user/user.selectors";
import PrivateRoute from "../utils/private-route";
import {setOnline} from "../redux/application/application.actions";
import {selectOnline} from "../redux/application/application.selectors";
import {checkUserSession} from "../redux/user/user.actions";
import {selectBodyshop, selectCurrentEula, selectCurrentUser,} from "../redux/user/user.selectors";
import PrivateRoute from "../components/PrivateRoute";
import "./App.styles.scss";
import handleBeta from "../utils/betaHandler";
import Eula from "../components/eula/eula.component";
const ResetPassword = lazy(() =>
import("../pages/reset-password/reset-password.component")
import("../pages/reset-password/reset-password.component")
);
const ManagePage = lazy(() => import("../pages/manage/manage.page.container"));
const SignInPage = lazy(() => import("../pages/sign-in/sign-in.page"));
const CsiPage = lazy(() => import("../pages/csi/csi.container.page"));
const MobilePaymentContainer = lazy(() =>
import("../pages/mobile-payment/mobile-payment.container")
import("../pages/mobile-payment/mobile-payment.container")
);
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
online: selectOnline,
bodyshop: selectBodyshop,
currentUser: selectCurrentUser,
online: selectOnline,
bodyshop: selectBodyshop,
currentEula: selectCurrentEula
});
const mapDispatchToProps = (dispatch) => ({
checkUserSession: () => dispatch(checkUserSession()),
setOnline: (isOnline) => dispatch(setOnline(isOnline)),
checkUserSession: () => dispatch(checkUserSession()),
setOnline: (isOnline) => dispatch(setOnline(isOnline)),
});
export function App({
bodyshop,
checkUserSession,
currentUser,
online,
setOnline,
}) {
const client = useClient();
export function App({bodyshop, checkUserSession, currentUser, online, setOnline, currentEula}) {
const client = useSplitClient().client;
const [listenersAdded, setListenersAdded] = useState(false)
const {t} = useTranslation();
useEffect(() => {
if (!navigator.onLine) {
setOnline(false);
}
checkUserSession();
}, [checkUserSession, setOnline]);
//const b = Grid.useBreakpoint();
// console.log("Breakpoints:", b);
const { t } = useTranslation();
window.addEventListener("offline", function (e) {
setOnline(false);
});
window.addEventListener("online", function (e) {
setOnline(true);
});
useEffect(() => {
if (currentUser.authorized && bodyshop) {
client.setAttribute("imexshopid", bodyshop.imexshopid);
if (client.getTreatment("LogRocket_Tracking") === "on") {
console.log("LR Start");
LogRocket.init("gvfvfw/bodyshopapp");
}
}
}, [bodyshop, client, currentUser.authorized]);
if (currentUser.authorized === null) {
return <LoadingSpinner message={t("general.labels.loggingin")} />;
}
if (!online)
return (
<Result
status="warning"
title={t("general.labels.nointernet")}
subTitle={t("general.labels.nointernet_sub")}
extra={
<Button
type="primary"
onClick={() => {
window.location.reload();
}}
>
{t("general.actions.refresh")}
</Button>
useEffect(() => {
if (!navigator.onLine) {
setOnline(false);
}
/>
);
return (
<Switch>
<Suspense fallback={<LoadingSpinner message="ImEX Online" />}>
<ErrorBoundary>
<Route exact path="/" component={LandingPage} />
</ErrorBoundary>
<ErrorBoundary>
<Route exact path="/signin" component={SignInPage} />
</ErrorBoundary>
<ErrorBoundary>
<Route exact path="/resetpassword" component={ResetPassword} />
</ErrorBoundary>
<ErrorBoundary>
<Route exact path="/csi/:surveyId" component={CsiPage} />
</ErrorBoundary>
<ErrorBoundary>
<Route exact path="/disclaimer" component={DisclaimerPage} />
</ErrorBoundary>
<ErrorBoundary>
<Route
exact
path="/mp/:paymentIs"
component={MobilePaymentContainer}
/>
</ErrorBoundary>
<ErrorBoundary>
<PrivateRoute
isAuthorized={currentUser.authorized}
path="/manage"
component={ManagePage}
/>
</ErrorBoundary>
<ErrorBoundary>
<PrivateRoute
isAuthorized={currentUser.authorized}
path="/tech"
component={TechPageContainer}
/>
</ErrorBoundary>
<ErrorBoundary>
<PrivateRoute
isAuthorized={currentUser.authorized}
path="/edit"
component={DocumentEditorContainer}
/>
</ErrorBoundary>
</Suspense>
</Switch>
);
checkUserSession();
}, [checkUserSession, setOnline]);
//const b = Grid.useBreakpoint();
// console.log("Breakpoints:", b);
// Associate event listeners, memoize to prevent multiple listeners being added
useEffect(() => {
const offlineListener = (e) => {
setOnline(false);
}
const onlineListener = (e) => {
setOnline(true);
}
if (!listenersAdded) {
console.log('Added events for offline and online');
window.addEventListener("offline", offlineListener);
window.addEventListener("online", onlineListener);
setListenersAdded(true);
}
return () => {
window.removeEventListener("offline", offlineListener);
window.removeEventListener("online", onlineListener);
}
}, [setOnline, listenersAdded]);
useEffect(() => {
if (currentUser.authorized && bodyshop) {
client.setAttribute("imexshopid", bodyshop.imexshopid);
if (
client.getTreatment("LogRocket_Tracking") === "on" ||
window.location.hostname === 'beta.romeonline.io'
) {
console.log("LR Start");
LogRocket.init("rome-online/rome-online");
}
}
}, [bodyshop, client, currentUser.authorized]);
if (currentUser.authorized === null) {
return <LoadingSpinner message={t("general.labels.loggingin")}/>;
}
handleBeta();
if (!online)
return (
<Result
status="warning"
title={t("general.labels.nointernet")}
subTitle={t("general.labels.nointernet_sub")}
extra={
<Button
type="primary"
onClick={() => {
window.location.reload();
}}
>
{t("general.actions.refresh")}
</Button>
}
/>
);
if (currentEula && !currentUser.eulaIsAccepted) {
return <Eula/>
}
// Any route that is not assigned and matched will default to the Landing Page component
return (
<Suspense fallback={<LoadingSpinner message="Rome Online"/>}>
<Routes>
<Route path="*" element={<ErrorBoundary><LandingPage/></ErrorBoundary>}/>
<Route path="/signin" element={<ErrorBoundary><SignInPage/></ErrorBoundary>}/>
<Route path="/resetpassword" element={<ErrorBoundary><ResetPassword/></ErrorBoundary>}/>
<Route path="/csi/:surveyId" element={<ErrorBoundary><CsiPage/></ErrorBoundary>}/>
<Route path="/disclaimer" element={<ErrorBoundary><DisclaimerPage/></ErrorBoundary>}/>
<Route path="/mp/:paymentIs" element={<ErrorBoundary><MobilePaymentContainer/></ErrorBoundary>}/>
<Route path="/manage/*"
element={<ErrorBoundary><PrivateRoute isAuthorized={currentUser.authorized}/></ErrorBoundary>}>
<Route path="*" element={<ManagePage/>}/>
</Route>
<Route path="/tech/*"
element={<ErrorBoundary><PrivateRoute isAuthorized={currentUser.authorized}/></ErrorBoundary>}>
<Route path="*" element={<TechPageContainer/>}/>
</Route>
<Route path="/edit/*" element={<PrivateRoute isAuthorized={currentUser.authorized}/>}>
<Route path="*" element={<DocumentEditorContainer/>}/>
</Route>
</Routes>
</Suspense>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(App);

View File

@@ -1,6 +1,10 @@
//Global Styles.
@import "react-big-calendar/lib/sass/styles";
.ant-menu-item-divider {
border-bottom: 1px solid #74695c !important;
}
.imex-table-header {
display: flex;
flex-wrap: wrap;
@@ -79,6 +83,7 @@
animation: alertBlinker 1s linear infinite;
color: blue;
}
@keyframes alertBlinker {
50% {
color: red;
@@ -95,6 +100,7 @@
color: rgba(255, 140, 0, 0.8);
font-weight: bold;
}
.production-completion-past {
color: rgba(255, 0, 0, 0.8);
font-weight: bold;
@@ -143,23 +149,11 @@
}
}
//Update row highlighting on production board.
.ant-table-tbody > tr.ant-table-row:hover > td {
background: #e7f3ff !important;
}
.ant-table-tbody > tr.ant-table-row-selected > td {
background: #e6f7ff !important;
}
.job-line-manual {
color: tomato;
font-style: italic;
}
td.ant-table-column-sort {
background-color: transparent;
}
.ant-table-tbody > tr.ant-table-row:nth-child(2n) > td {
background-color: #f4f4f4;

View File

@@ -0,0 +1,61 @@
import {defaultsDeep} from "lodash";
import {theme} from "antd";
const {defaultAlgorithm, darkAlgorithm} = theme;
let isDarkMode = false;
/**
* Default theme
* @type {{components: {Menu: {itemDividerBorderColor: string}}}}
*/
const defaultTheme = {
components: {
Table: {
rowHoverBg: '#e7f3ff',
rowSelectedBg: '#e6f7ff',
headerSortHoverBg: 'transparent',
},
Menu: {
darkItemHoverBg: '#1677ff',
itemHoverBg: '#1677ff',
horizontalItemHoverBg: '#1677ff',
}
},
token: {
colorPrimary: "#326ade",
colorInfo: "#326ade"
}
};
/**
* Development theme
* @type {{components: {Menu: {itemHoverBg: string, darkItemHoverBg: string, horizontalItemHoverBg: string}}, token: {colorPrimary: string}}}
*/
const devTheme = {
components: {
Menu: {
darkItemHoverBg: '#a51d1d',
itemHoverBg: '#a51d1d',
horizontalItemHoverBg: '#a51d1d',
}
},
token: {
colorPrimary: '#a51d1d'
}
};
/**
* Production theme
* @type {{components: {Menu: {itemHoverBg: string, darkItemHoverBg: string, horizontalItemHoverBg: string}}, token: {colorPrimary: string}}}
*/
const prodTheme = {};
const currentTheme = process.env.NODE_ENV === "development" ? devTheme
: prodTheme;
const finaltheme = {
algorithm: isDarkMode ? darkAlgorithm : defaultAlgorithm,
...defaultsDeep(currentTheme, defaultTheme)
}
export default finaltheme;

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 52 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 -256 1792 1792">
<g transform="matrix(1,0,0,-1,197.42373,1300.6102)">
<path d="M 1408,131 Q 1408,11 1335,-58.5 1262,-128 1141,-128 H 267 Q 146,-128 73,-58.5 0,11 0,131 0,184 3.5,234.5 7,285 17.5,343.5 28,402 44,452 q 16,50 43,97.5 27,47.5 62,81 35,33.5 85.5,53.5 50.5,20 111.5,20 9,0 42,-21.5 33,-21.5 74.5,-48 41.5,-26.5 108,-48 Q 637,565 704,565 q 67,0 133.5,21.5 66.5,21.5 108,48 41.5,26.5 74.5,48 33,21.5 42,21.5 61,0 111.5,-20 50.5,-20 85.5,-53.5 35,-33.5 62,-81 27,-47.5 43,-97.5 16,-50 26.5,-108.5 10.5,-58.5 14,-109 Q 1408,184 1408,131 z m -320,893 Q 1088,865 975.5,752.5 863,640 704,640 545,640 432.5,752.5 320,865 320,1024 320,1183 432.5,1295.5 545,1408 704,1408 863,1408 975.5,1295.5 1088,1183 1088,1024 z"/>
</g>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
viewBox="0 -256 1792 1792">
<g transform="matrix(1,0,0,-1,197.42373,1300.6102)">
<path d="M 1408,131 Q 1408,11 1335,-58.5 1262,-128 1141,-128 H 267 Q 146,-128 73,-58.5 0,11 0,131 0,184 3.5,234.5 7,285 17.5,343.5 28,402 44,452 q 16,50 43,97.5 27,47.5 62,81 35,33.5 85.5,53.5 50.5,20 111.5,20 9,0 42,-21.5 33,-21.5 74.5,-48 41.5,-26.5 108,-48 Q 637,565 704,565 q 67,0 133.5,21.5 66.5,21.5 108,48 41.5,26.5 74.5,48 33,21.5 42,21.5 61,0 111.5,-20 50.5,-20 85.5,-53.5 35,-33.5 62,-81 27,-47.5 43,-97.5 16,-50 26.5,-108.5 10.5,-58.5 14,-109 Q 1408,184 1408,131 z m -320,893 Q 1088,865 975.5,752.5 863,640 704,640 545,640 432.5,752.5 320,865 320,1024 320,1183 432.5,1295.5 545,1408 704,1408 863,1408 975.5,1295.5 1088,1183 1088,1024 z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 981 B

After

Width:  |  Height:  |  Size: 955 B

View File

@@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M23.5 7c.276 0 .5.224.5.5v.511c0 .793-.926.989-1.616.989l-1.086-2h2.202zm-1.441 3.506c.639 1.186.946 2.252.946 3.666 0 1.37-.397 2.533-1.005 3.981v1.847c0 .552-.448 1-1 1h-1.5c-.552 0-1-.448-1-1v-1h-13v1c0 .552-.448 1-1 1h-1.5c-.552 0-1-.448-1-1v-1.847c-.608-1.448-1.005-2.611-1.005-3.981 0-1.414.307-2.48.946-3.666.829-1.537 1.851-3.453 2.93-5.252.828-1.382 1.262-1.707 2.278-1.889 1.532-.275 2.918-.365 4.851-.365s3.319.09 4.851.365c1.016.182 1.45.507 2.278 1.889 1.079 1.799 2.101 3.715 2.93 5.252zm-16.059 2.994c0-.828-.672-1.5-1.5-1.5s-1.5.672-1.5 1.5.672 1.5 1.5 1.5 1.5-.672 1.5-1.5zm10 1c0-.276-.224-.5-.5-.5h-7c-.276 0-.5.224-.5.5s.224.5.5.5h7c.276 0 .5-.224.5-.5zm2.941-5.527s-.74-1.826-1.631-3.142c-.202-.298-.515-.502-.869-.566-1.511-.272-2.835-.359-4.441-.359s-2.93.087-4.441.359c-.354.063-.667.267-.869.566-.891 1.315-1.631 3.142-1.631 3.142 1.64.313 4.309.497 6.941.497s5.301-.184 6.941-.497zm2.059 4.527c0-.828-.672-1.5-1.5-1.5s-1.5.672-1.5 1.5.672 1.5 1.5 1.5 1.5-.672 1.5-1.5zm-18.298-6.5h-2.202c-.276 0-.5.224-.5.5v.511c0 .793.926.989 1.616.989l1.086-2z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M23.5 7c.276 0 .5.224.5.5v.511c0 .793-.926.989-1.616.989l-1.086-2h2.202zm-1.441 3.506c.639 1.186.946 2.252.946 3.666 0 1.37-.397 2.533-1.005 3.981v1.847c0 .552-.448 1-1 1h-1.5c-.552 0-1-.448-1-1v-1h-13v1c0 .552-.448 1-1 1h-1.5c-.552 0-1-.448-1-1v-1.847c-.608-1.448-1.005-2.611-1.005-3.981 0-1.414.307-2.48.946-3.666.829-1.537 1.851-3.453 2.93-5.252.828-1.382 1.262-1.707 2.278-1.889 1.532-.275 2.918-.365 4.851-.365s3.319.09 4.851.365c1.016.182 1.45.507 2.278 1.889 1.079 1.799 2.101 3.715 2.93 5.252zm-16.059 2.994c0-.828-.672-1.5-1.5-1.5s-1.5.672-1.5 1.5.672 1.5 1.5 1.5 1.5-.672 1.5-1.5zm10 1c0-.276-.224-.5-.5-.5h-7c-.276 0-.5.224-.5.5s.224.5.5.5h7c.276 0 .5-.224.5-.5zm2.941-5.527s-.74-1.826-1.631-3.142c-.202-.298-.515-.502-.869-.566-1.511-.272-2.835-.359-4.441-.359s-2.93.087-4.441.359c-.354.063-.667.267-.869.566-.891 1.315-1.631 3.142-1.631 3.142 1.64.313 4.309.497 6.941.497s5.301-.184 6.941-.497zm2.059 4.527c0-.828-.672-1.5-1.5-1.5s-1.5.672-1.5 1.5.672 1.5 1.5 1.5 1.5-.672 1.5-1.5zm-18.298-6.5h-2.202c-.276 0-.5.224-.5.5v.511c0 .793.926.989 1.616.989l1.086-2z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,5 +1,21 @@
<?xml version="1.0" ?><svg style="enable-background:new 0 0 128 128;" version="1.1" viewBox="0 0 128 128" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style type="text/css">
<?xml version="1.0" ?>
<svg style="enable-background:new 0 0 128 128;" version="1.1" viewBox="0 0 128 128" xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"><style type="text/css">
.st0{fill:none;stroke:#000000;stroke-width:8;stroke-miterlimit:10;}
.st1{display:none;}
.st2{display:inline;opacity:0.25;fill:#F45EFD;}
</style><g id="_x31_2_3D_Printing"/><g id="_x31_1_VR_Gear"/><g id="_x31_0_Virtual_reality"/><g id="_x39__Augmented_reality"/><g id="_x38__Teleport"/><g id="_x37__Glassess"/><g id="_x36__Folding_phone"/><g id="_x35__Drone"/><g id="_x34__Retina_scan"/><g id="_x33__Smartwatch"/><g id="_x32__Bionic_Arm"/><g id="_x31__Chip"><g><path d="M108,40c-5.2,0-9.6,3.3-11.3,8H84V32h-8V20h-8v12h-8V20h-8v12h-8v16H24v-8.7c4.7-1.7,8-6.1,8-11.3c0-6.6-5.4-12-12-12 S8,21.4,8,28c0,5.2,3.3,9.6,8,11.3V56h28v8H16v16.7c-4.7,1.7-8,6.1-8,11.3c0,6.6,5.4,12,12,12s12-5.4,12-12c0-5.2-3.3-9.6-8-11.3 V72h20v16h8v12h8V88h8v12h8V88h8V72h8v16.7c-4.7,1.7-8,6.1-8,11.3c0,6.6,5.4,12,12,12s12-5.4,12-12c0-5.2-3.3-9.6-8-11.3V64H84v-8 h12.7c1.7,4.7,6.1,8,11.3,8c6.6,0,12-5.4,12-12S114.6,40,108,40z M20,32c-2.2,0-4-1.8-4-4s1.8-4,4-4s4,1.8,4,4S22.2,32,20,32z M20,96c-2.2,0-4-1.8-4-4s1.8-4,4-4s4,1.8,4,4S22.2,96,20,96z M76,80H52V40h24V80z M96,96c2.2,0,4,1.8,4,4s-1.8,4-4,4s-4-1.8-4-4 S93.8,96,96,96z M108,56c-2.2,0-4-1.8-4-4s1.8-4,4-4s4,1.8,4,4S110.2,56,108,56z"/><rect height="8" width="8" x="56" y="64"/></g></g><g class="st1" id="Guide"><path class="st2" d="M120,8v112H8V8H120 M128,0H0v128h128V0L128,0z"/></g></svg>
</style>
<g id="_x31_2_3D_Printing"/>
<g id="_x31_1_VR_Gear"/>
<g id="_x31_0_Virtual_reality"/>
<g id="_x39__Augmented_reality"/>
<g id="_x38__Teleport"/>
<g id="_x37__Glassess"/>
<g id="_x36__Folding_phone"/>
<g id="_x35__Drone"/>
<g id="_x34__Retina_scan"/>
<g id="_x33__Smartwatch"/>
<g id="_x32__Bionic_Arm"/>
<g id="_x31__Chip"><g><path d="M108,40c-5.2,0-9.6,3.3-11.3,8H84V32h-8V20h-8v12h-8V20h-8v12h-8v16H24v-8.7c4.7-1.7,8-6.1,8-11.3c0-6.6-5.4-12-12-12 S8,21.4,8,28c0,5.2,3.3,9.6,8,11.3V56h28v8H16v16.7c-4.7,1.7-8,6.1-8,11.3c0,6.6,5.4,12,12,12s12-5.4,12-12c0-5.2-3.3-9.6-8-11.3 V72h20v16h8v12h8V88h8v12h8V88h8V72h8v16.7c-4.7,1.7-8,6.1-8,11.3c0,6.6,5.4,12,12,12s12-5.4,12-12c0-5.2-3.3-9.6-8-11.3V64H84v-8 h12.7c1.7,4.7,6.1,8,11.3,8c6.6,0,12-5.4,12-12S114.6,40,108,40z M20,32c-2.2,0-4-1.8-4-4s1.8-4,4-4s4,1.8,4,4S22.2,32,20,32z M20,96c-2.2,0-4-1.8-4-4s1.8-4,4-4s4,1.8,4,4S22.2,96,20,96z M76,80H52V40h24V80z M96,96c2.2,0,4,1.8,4,4s-1.8,4-4,4s-4-1.8-4-4 S93.8,96,96,96z M108,56c-2.2,0-4-1.8-4-4s1.8-4,4-4s4,1.8,4,4S110.2,56,108,56z"/><rect
height="8" width="8" x="56" y="64"/></g></g>
<g class="st1" id="Guide"><path class="st2" d="M120,8v112H8V8H120 M128,0H0v128h128V0L128,0z"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

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