Compare commits

...

782 commits

Author SHA1 Message Date
Ramon Gutierrez
630796df85 Merge branch '811-add-sealant-fee' into 'master'
Resolve "Add sealant fee"

Closes #811

See merge request jankstudio/resq!924
2024-12-08 14:35:58 +00:00
dedfb58a28 Fix issue of sealant and coolant fee not displaying in open edit form. #811 2024-12-05 01:48:39 -05:00
1b24e68f6b Add processing of sealant fee for tire repair service. #811 2024-12-04 02:51:50 -05:00
Ramon Gutierrez
dc4d5f90a7 Merge branch '808-add-form-validation-to-role' into 'master'
Validate role ID and name are not blank #808

Closes #808

See merge request jankstudio/resq!923
2024-10-02 05:58:32 +00:00
Ramon Gutierrez
0179a1b87e Validate role ID and name are not blank #808 2024-10-02 13:58:03 +08:00
Ramon Gutierrez
f1609b2273 Merge branch '807-disable-sms-for-certain-rejection-reasons' into 'master'
Resolve "Disable SMS for certain Rejection Reasons"

Closes #807 and #792

See merge request jankstudio/resq!922
2024-09-24 07:15:30 +00:00
22215ff9f6 Merge branch '807-disable-sms-for-certain-rejection-reasons' of gitlab.com:jankstudio/resq into 807-disable-sms-for-certain-rejection-reasons 2024-09-24 02:47:11 -04:00
Ramon Gutierrez
6994d69020 Merge branch '792-battery-facilitated-by-issue' into 'master'
Resolve "Battery Facilitated By issue"

Closes #792

See merge request jankstudio/resq!903
2024-09-24 02:45:43 -04:00
Ramon Gutierrez
83bdb5c626 Merge branch '792-battery-facilitated-by-issue' into 'master'
Resolve "Battery Facilitated By issue"

Closes #792

See merge request jankstudio/resq!903
2024-09-24 04:40:00 +00:00
Ramon Gutierrez
5a5113b166 Merge branch '803-fix-invoice-data-disappearing-on-open-edit-form' into 'master'
Fix invoice data on open edit form

Closes #803

See merge request jankstudio/resq!918
2024-09-24 04:23:02 +00:00
Ramon Gutierrez
629cc2afa1 Merge branch 'master' into 803-fix-invoice-data-disappearing-on-open-edit-form 2024-07-30 21:27:23 +08:00
Ramon Gutierrez
ad946247ba Merge branch '806-restore-inventory-counters-on-processing-form' into 'master'
Restore inventory retrieval on processing form #806

Closes #806

See merge request jankstudio/resq!921
2024-07-30 13:26:45 +00:00
Ramon Gutierrez
63902e5838 Restore inventory retrieval on processing form #806 2024-07-30 16:39:11 +08:00
Ramon Gutierrez
511aa5ec9b Merge branch 'master' into 803-fix-invoice-data-disappearing-on-open-edit-form 2024-07-18 16:34:59 +08:00
Ramon Gutierrez
2df53674c4 Merge branch '800-automatically-reject-jo-if-no-riders-or-inventory' into 'master'
Add hub selector filtering for available riders, refactor inventory filter to...

Closes #800

See merge request jankstudio/resq!920
2024-07-18 08:34:02 +00:00
Ramon Gutierrez
4ab6b0659d Merge branch 'master' into 800-automatically-reject-jo-if-no-riders-or-inventory 2024-07-18 16:30:10 +08:00
Ramon Gutierrez
a66d16a58b Restored hub filter area functionality #800 2024-07-16 16:10:29 +08:00
Ramon Gutierrez
5f2ed34d8c Disable round robin filter for emergency JOs #800 2024-07-12 14:17:59 +08:00
Ramon Gutierrez
e7d8af516e Temporarily disable hub filter area checks #800 2024-07-09 16:55:58 +08:00
Ramon Gutierrez
8da5381a1c Enable inventory retrieval if inventory checks are disabled #800 2024-07-05 15:54:14 +08:00
Ramon Gutierrez
f8d90cbdcd Fix typo on ResqJobOrderHandler properties #800 2024-07-04 17:06:46 +08:00
Ramon Gutierrez
6139e649fb Add logging for closest hubs selected #800 2024-07-04 16:10:02 +08:00
Ramon Gutierrez
e1103cf108 Move enabled filters list to env #800 2024-07-04 15:41:01 +08:00
Ramon Gutierrez
a10f58e425 Add filtering for JOs with VIP transaction origin #800 2024-07-04 12:57:27 +08:00
Ramon Gutierrez
23d814d1e9 Add extra logs to hub filtering #800 2024-07-03 23:41:44 +08:00
Ramon Gutierrez
9b63139957 Fix file logging format for hub filtering #800 2024-07-03 23:14:38 +08:00
Ramon Gutierrez
a335f84a13 Fix hub filter log location #800 2024-07-03 14:01:16 +08:00
Ramon Gutierrez
8992fdeec0 Add hub rejection log file #800 2024-07-03 13:56:27 +08:00
Ramon Gutierrez
57b4227da9 Add more requested JO rejection reasons #800 2024-06-30 11:47:23 +08:00
Ramon Gutierrez
bff1f7ff73 Add null check to battery inventory entries from motiv #800 2024-06-27 11:31:02 +08:00
Ramon Gutierrez
e8b14ff379 Fix available rider filter to also consider flag_active and current_job_order #800 2024-06-27 10:58:11 +08:00
Ramon Gutierrez
44b3753ece Skip hub filtering if hub list is alraedy empty #800 2024-06-26 10:02:04 +08:00
Ramon Gutierrez
a21ed66490 Move requested params to filters instead of hub selector #800 2024-06-26 09:59:29 +08:00
3fc04cd733 Fix trade-in issue for invoice. #803 2024-06-25 01:44:44 -04:00
Ramon Gutierrez
3b287236ec Add regional filter support for hub filters #800 2024-06-25 03:38:56 +08:00
Ramon Gutierrez
204c039fba Refactor hub selector to separate filters into individual classes #800 2024-06-25 03:19:10 +08:00
Ramon Gutierrez
b4057de938 Add hub filter exceptions to supported areas #800 2024-06-25 03:18:31 +08:00
2a30787dba Fix for issue with customer app JO request with trade in. #803 2024-06-24 06:00:01 -04:00
acee5f8f55 Populate invoice items array upon loading of form. #803 2024-06-21 05:37:04 -04:00
90628f0b54 Add trade in type to invoice item. #03 2024-06-21 05:24:58 -04:00
4ccdd29ae6 Changed the input for trade in items to battery size. #03 2024-06-21 03:39:44 -04:00
2f9ee4ec67 Add battery to criteria for battery replacement warranty. #803 2024-06-20 05:26:23 -04:00
4b5ad97225 Add battery size id to invoice item. Add saving of trade in items with battery size to invoice item. #803 2024-06-20 03:29:24 -04:00
Ramon Gutierrez
e83de164c1 Merge branch '804-add-checking-for-null-user-for-rejection-detail-report' into 'master'
Resolve "Add checking for null user for rejection detail report"

Closes #804

See merge request jankstudio/resq!917
2024-06-10 10:40:38 +00:00
8c886c4dbf Add check for null for user for hub rejection. #804 2024-06-10 02:20:28 -04:00
Ramon Gutierrez
10c44fbe64 Limit hub rejection SMS to one per JO/hub combo #800 2024-06-07 04:19:08 +08:00
Ramon Gutierrez
b5f169c14e Merge branch 'master' into 800-automatically-reject-jo-if-no-riders-or-inventory 2024-06-06 05:52:03 +08:00
Ramon Gutierrez
cec648f894 Merge branch '801-handle-failed-paymongo-payments' into 'master'
Attempt to re-enable paymongo webhook if found disabled #801

Closes #801

See merge request jankstudio/resq!916
2024-06-05 21:51:18 +00:00
Ramon Gutierrez
c4b0513386 Attempt to re-enable paymongo webhook if found disabled #801 2024-06-06 05:50:36 +08:00
Ramon Gutierrez
90838b004a Merge branch 'master' into 800-automatically-reject-jo-if-no-riders-or-inventory 2024-06-04 17:49:39 +08:00
Ramon Gutierrez
c60a39c13e Merge branch '802-fix-jos-being-able-to-proceed-after-cancellation' into 'master'
Add checks to rider app API for JO status and delivery status #802

Closes #802

See merge request jankstudio/resq!915
2024-06-04 09:47:46 +00:00
Ramon Gutierrez
792db080a1 Merge branch '801-handle-failed-paymongo-payments' into 'master'
Resolve "Handle failed PayMongo payments"

Closes #801

See merge request jankstudio/resq!914
2024-06-04 09:45:37 +00:00
Ramon Gutierrez
08084f682c Add force option to enable or disable webhook status checking, defaults to false #801 2024-05-31 18:51:55 +08:00
Ramon Gutierrez
3846ad5a43 Add checker for paymongo webhook status before running manual processing command #801 2024-05-31 18:45:16 +08:00
Ramon Gutierrez
191a02f4c4 Fix typo on getStatus call on entity listener #801 2024-05-31 12:28:43 +08:00
Ramon Gutierrez
e97cebd2b2 Fix typo in log message for new command #801 2024-05-31 12:11:13 +08:00
Ramon Gutierrez
952122a39e Prevent insurance applications from being flagged as paid more than once #801 2024-05-31 06:50:34 +08:00
Ramon Gutierrez
ad841a7e25 Prevent success handler from catching failed paymongo payment attempts #801 2024-05-31 06:49:55 +08:00
Ramon Gutierrez
75b2ada03f Add command for processing late pending paymongo transactions #801 2024-05-31 06:48:44 +08:00
Ramon Gutierrez
4b19cff996 Add checks to rider app API for JO status and delivery status #802 2024-05-30 17:15:47 +08:00
Ramon Gutierrez
2ebb6e040a Add placeholder debug logs #800 2024-05-30 16:06:55 +08:00
Ramon Gutierrez
404401d854 Fix erroneous delivery status IDs on collection #800 2024-05-30 16:06:04 +08:00
Ramon Gutierrez
6dfaeee799 Generate JO ID before hub selection on user app API, add additional params to HubCriteria for JORejection and SMS #800 2024-05-20 03:46:08 +08:00
Ramon Gutierrez
aae4aaa390 Enable inventory and rider hub filters for emergency JOs, disable for VIP customers #800 2024-05-18 15:21:32 +08:00
Ramon Gutierrez
b53aacb840 Update rejection messages to use battery name and model vs SKUs #800 2024-05-17 22:23:26 +08:00
Ramon Gutierrez
22683e1edf Add null check to user on detailed rejection report #800 2024-05-17 22:01:43 +08:00
Ramon Gutierrez
4be9134090 Update SMS message format for rejected hubs, add JO rejection entries for no inventory or no riders #800 2024-05-17 21:40:16 +08:00
Ramon Gutierrez
21c97df677 Set JO type regardless of area support on hub form initialization to trigger inventory filter #800 2024-05-16 21:46:02 +08:00
Ramon Gutierrez
5cf2c3619f Remove debug code from JO handler #800 2024-05-16 15:07:35 +08:00
Ramon Gutierrez
7b6afbb099 Modify inventory SMS message #800 2024-05-15 18:00:27 +08:00
Ramon Gutierrez
190ac88153 Enable inventory and rider filtering on CRM JO form hub lists #800 2024-05-15 18:00:07 +08:00
Ramon Gutierrez
aed31f2a33 Rearrange flow logic on hub selector, save inventory counts upon retrieval if enabled #800 2024-05-15 17:59:27 +08:00
Ramon Gutierrez
76496ed6fe Fix issues with inventory filter flow #800 2024-05-14 17:51:00 +08:00
Ramon Gutierrez
89e5dd799f Update hub rejection SMS translations #800 2024-05-14 17:49:34 +08:00
Ramon Gutierrez
0bd6a89840 Fix missing keys on NameValue class #800 2024-05-14 17:49:14 +08:00
Ramon Gutierrez
be0e69db89 Add blacklist support to base NameValue class, for hiding options when getting entire collection #800 2024-05-14 14:45:51 +08:00
Ramon Gutierrez
d52402a2ef Enable inventory and rider checks on hub criteria on user app and TAPI #800 2024-05-14 04:18:37 +08:00
Ramon Gutierrez
a45c3dd65c Add hub selector filtering for available riders, refactor inventory filter to send a single batch call instead #800 2024-05-14 03:39:45 +08:00
Ramon Gutierrez
b19d9c203a Merge branch '783-rider-app-trade-in-support' into 'master'
Resolve "Rider app trade-in support"

Closes #783

See merge request jankstudio/resq!912
2024-04-23 13:11:51 +00:00
Ramon Gutierrez
a64557ffcd Fix API roles permissions list to properly display the correct ACL group #783 2024-04-06 14:56:16 +08:00
Ramon Gutierrez
d7909f7941 Merge branch '796-price-display-issue-with-price-tier' into '783-rider-app-trade-in-support'
Resolve "Price display issue with price tier"

See merge request jankstudio/resq!908
2024-04-05 10:59:32 +00:00
Ramon Gutierrez
8e383fd23f Merge branch '794-capi-calls-for-pullout-form-system' into '783-rider-app-trade-in-support'
Resolve "CAPI calls for Pullout Form System"

See merge request jankstudio/resq!906
2024-04-05 10:57:13 +00:00
Ramon Gutierrez
86889b3147 Merge branch '798-motolite-user-jumpstart-fee' into '783-rider-app-trade-in-support'
Resolve "Motolite user jumpstart fee"

See merge request jankstudio/resq!910
2024-04-02 21:08:35 +00:00
6a804c11df Add sql file to update service offering table. #798 2024-04-02 01:21:23 -04:00
c8e2c02be1 Add a separate service fee for motolite users for jumpstart. #798 2024-04-02 01:11:32 -04:00
Ramon Gutierrez
06dc8eae7b Merge branch '795-jumpstart-service-fee-for-motolite-users' into '783-rider-app-trade-in-support'
Resolve "Jumpstart service fee for motolite users"

See merge request jankstudio/resq!907
2024-04-01 13:19:07 +00:00
Ramon Gutierrez
f97f287f5b Merge branch '797-resq-dispatch-display-issue' into '783-rider-app-trade-in-support'
Resolve "Resq Dispatch Display Issue"

See merge request jankstudio/resq!909
2024-04-01 13:17:25 +00:00
6f2fca292e Add use statement. #797 2024-04-01 06:55:23 -04:00
b80ece9084 Fix display issue for invoice. #796 2024-03-26 01:41:48 -04:00
90aada4bf3 ADd service offering for motolite users for jumpstart warranty. Add sql file to add new service offering. #795 2024-03-25 04:51:40 -04:00
93c313f111 Fix issues found during testing. #794 2024-03-24 23:38:08 -04:00
Ramon Gutierrez
25e0931f6f Revert warranty serial check for now #783 2024-03-23 04:03:00 +08:00
Ramon Gutierrez
5af3a3cb5e Add check for if serial is present before registering warranty #783 2024-03-23 04:01:16 +08:00
bf0d1f664b Add CAPI calls for hub list and job order details. #794 2024-03-22 05:35:06 -04:00
Ramon Gutierrez
07b459e7a3 Add pycache and test insurance banner to gitignore #783 2024-03-19 19:16:34 +08:00
Ramon Gutierrez
c4e03f861d Exclude cancelled JOs on rider app API #783 2024-03-19 17:33:13 +08:00
Ramon Gutierrez
cd21e41d2f Merge branch '793-prevent-jo-progression-on-rider-app-after-cancellation' into '783-rider-app-trade-in-support'
Rename JO progression check method #793

See merge request jankstudio/resq!905
2024-03-19 08:36:23 +00:00
Ramon Gutierrez
1a6af00399 Rename JO progression check method #793 2024-03-19 16:35:51 +08:00
Ramon Gutierrez
c03025748f Merge branch '793-prevent-jo-progression-on-rider-app-after-cancellation' into '783-rider-app-trade-in-support'
Resolve "Prevent JO progression on rider app after cancellation"

See merge request jankstudio/resq!904
2024-03-19 08:33:43 +00:00
Ramon Gutierrez
ca513355fe Switch parameters of allowJOProgress to fix error #793 2024-03-19 15:25:32 +08:00
Ramon Gutierrez
9152370300 Add checks to prevent JO progression if cancelled #793 2024-03-19 15:22:34 +08:00
Ramon Gutierrez
bff89a6817 Add regional pricing support to job order updates on rider app #783 2024-03-15 16:24:09 +08:00
Ramon Gutierrez
a59aa0f66d Make insurance body types a namevalue class #783 2024-03-14 13:40:37 +08:00
Ramon Gutierrez
69218aecf4 Update insurance application paid call to use external transaction id #783 2024-03-13 14:33:29 +08:00
Ramon Gutierrez
47dcd92474 Refactor insurance, paymongo connector logging logic #783 2024-03-13 07:09:56 +08:00
Ramon Gutierrez
9f4c16b149 Add debug code for insurance api #783 2024-03-12 16:34:21 +08:00
Ramon Gutierrez
175ac92765 Fix syntax error on rider api controller #783 2024-03-11 23:50:44 +08:00
Ramon Gutierrez
801a274e8c Disable serial number requirement on rider api to allow old rider app to work for now #783 2024-03-11 23:45:05 +08:00
Ramon Gutierrez
d603934d93 Update the correct MQTT client with latest changes #783 2024-03-07 23:41:21 +08:00
Ramon Gutierrez
a4b883b7ea Fix rider assign MQTT event for new rider app #783 2024-03-07 23:39:57 +08:00
Ramon Gutierrez
a2cd86b48c Merge branch '780-regional-pricing' into 783-rider-app-trade-in-support
# Conflicts:
#	src/Controller/CAPI/RiderAppController.php
#	src/InvoiceRule/BatterySales.php
2024-03-07 09:42:42 +08:00
5ddebcd95f Add saving of facilitated hub data when reassigning hub. Fix display of dropdown for facilitated hubs. #792 2024-03-04 22:45:57 -05:00
Ramon Gutierrez
ef5e629358 Merge branch '791-support-for-insurance-premiums-banner' into 780-regional-pricing 2024-02-23 18:40:10 +08:00
Ramon Gutierrez
4dd8efd95a Fix returned format of body types endpoint #791 2024-02-23 18:39:21 +08:00
34adefb798 Merge branch '791-support-for-insurance-premiums-banner' of gitlab.com:jankstudio/resq into 780-regional-pricing 2024-02-23 04:01:58 -05:00
Ramon Gutierrez
78a43ae85c Add insurance body types endpoint #791 2024-02-23 16:53:04 +08:00
7ed9f90945 Merge branch '791-support-for-insurance-premiums-banner' of gitlab.com:jankstudio/resq into 780-regional-pricing 2024-02-22 19:42:15 -05:00
Ramon Gutierrez
0a4f78559c Merge branch '791-support-for-insurance-premiums-banner' into 783-rider-app-trade-in-support 2024-02-22 16:51:55 +08:00
Ramon Gutierrez
270a4cfb10 Add endpoint for insurance premiums banner #791 2024-02-22 16:51:26 +08:00
Ramon Gutierrez
7a5583d840 Include trade in type and container size to battery info rider api call #783 2024-02-22 16:08:36 +08:00
4d89e7420f Add checking for location and price tier when getting list of compatible batteries. #780 2024-02-20 02:09:57 -05:00
010bdca458 Add updating of other fields when updating job order. Fix issue found during testing in invoice rule. #783 2024-02-12 06:19:00 -05:00
abf4bbfe22 Add checking for promo. #783 2024-02-12 03:46:26 -05:00
Ramon Gutierrez
eebd1d93c4 Fix battery info endpoint to work with warranty serials instead #783 2024-02-08 23:17:32 +08:00
Ramon Gutierrez
ba09e6ac7b Merge branch '782-invoice-and-jo-modifications-for-regional-pricing' into '780-regional-pricing'
Resolve "Invoice and JO modifications for regional pricing"

See merge request jankstudio/resq!894
2024-02-08 06:21:40 +00:00
Ramon Gutierrez
8860796db2 Add endpoint for rider app trade-in types #783 2024-02-07 15:02:47 +08:00
Ramon Gutierrez
3254527653 Merge branch 'master' into '782-invoice-and-jo-modifications-for-regional-pricing'
Master

See merge request jankstudio/resq!901
2024-02-06 08:16:28 +00:00
8ca7292a25 Add processing of trade in items from rider app. #783 2024-02-05 03:06:06 -05:00
c9057b9617 Add API call to update invoice. #783 2024-02-02 04:50:03 -05:00
86744afde3 Add serial as a parameter when rider fulfills a job order. #783 2024-02-01 04:24:09 -05:00
ae46d64f5b Add API call to return battery data given a serial. #783 2024-02-01 03:10:16 -05:00
Ramon Gutierrez
a5340fbfd6 Merge branch '788-remove-geofence-message-from-view-jo' into 'master'
Resolve "Remove geofence message from View JO"

Closes #788

See merge request jankstudio/resq!900
2024-02-01 06:46:29 +00:00
0e5365a015 Comment out geofence message when viewing JO. Initialize branch_codes array. #788 2024-01-31 20:13:41 -05:00
Ramon Gutierrez
313dc74eb0 Merge branch '784-transaction-origin-additional-fields' into 'master'
Fix transaction origin list to replace existing facebook and hotline with manila entries #784

Closes #784

See merge request jankstudio/resq!899
2024-01-31 14:06:05 +00:00
Ramon Gutierrez
33eaf9bbff Fix transaction origin list to replace existing facebook and hotline with manila entries #784 2024-01-31 22:05:42 +08:00
Ramon Gutierrez
8ee1809a99 Merge branch '787-update-geofence-message-in-app' into 'master'
Resolve "Update geofence message in app"

Closes #787

See merge request jankstudio/resq!898
2024-01-30 07:25:15 +00:00
5717eddaa0 Update geofence message in the app. #787 2024-01-30 02:24:08 -05:00
Ramon Gutierrez
35b3b23e55 Merge branch '786-remove-geofence-message-in-crm' into 'master'
Resolve "Remove geofence message in CRM"

Closes #786

See merge request jankstudio/resq!897
2024-01-30 07:14:34 +00:00
f7c8034538 Comment out the geofence call for admin panel. #786 2024-01-30 02:12:08 -05:00
Ramon Gutierrez
ba8ac73c9d Merge branch '785-no-sms-notification-for-discount' into 'master'
Resolve "No SMS notification for discount"

Closes #785

See merge request jankstudio/resq!896
2024-01-30 07:03:47 +00:00
9b52d4578f Add checking for discount rejection reason. #785 2024-01-30 02:02:24 -05:00
Ramon Gutierrez
b033e5674d Merge branch '784-transaction-origin-additional-fields' into 'master'
Resolve "Transaction Origin additional fields"

Closes #784

See merge request jankstudio/resq!895
2024-01-30 06:33:05 +00:00
0e2afaa400 Add new fields for transaction origin. #784 2024-01-30 01:30:09 -05:00
Ramon Gutierrez
b123be25cc Add battery sizes endpoint to rider api #783 2024-01-30 03:42:05 +08:00
d4eae00902 Add sql for item types. #782 2024-01-28 22:21:34 -05:00
20f5bb08e0 Add checking for longitude and latitude when calling getEstimate. #782 2024-01-26 04:50:54 -05:00
213171f4b7 Add price tiering for Resq 2 App and TAPI. #782 2024-01-26 04:44:18 -05:00
c136b0666b Fix issues found during testing. #782 2024-01-25 03:08:00 -05:00
57fd7fe5ac Fix issues found during testing. #782 2024-01-25 02:23:47 -05:00
bc6364ace5 Add price tier to invoice rules. #782 2024-01-25 02:11:05 -05:00
c5b395d720 Add price tier for battery replacement warranty. #782 2024-01-24 04:02:14 -05:00
b6763bfd3e Add price tier checking for battery sales. #782 2024-01-24 02:24:13 -05:00
29ad8d57a4 Add processing of battery entries and invoice item titles. #782 2024-01-22 04:24:41 -05:00
root
70ee7fdd89 Add invoice rule for price tier. #782 2024-01-19 04:14:06 -05:00
Korina Cordero
ee033ddd55 Fix issues found during testing. #780 2024-01-17 15:31:26 +08:00
Korina Cordero
a83fecf224 Merge branch 'master' of gitlab.com:jankstudio/resq into 780-regional-pricing 2024-01-17 14:50:50 +08:00
Korina Cordero
9de6fa7999 Fix issues found during saving of item prices. #780 2024-01-17 14:25:28 +08:00
Korina Cordero
6d7c8c5b53 Add saving of item prices for price tier. #780 2024-01-16 16:28:26 +08:00
Korina Cordero
022336ad8f Add saving of prices. #780 2024-01-15 17:21:31 +08:00
Korina Cordero
bfe7a5fbf6 Fix display of item prices per tier. #780 2024-01-15 15:23:07 +08:00
Korina Cordero
b592390554 Add response when displaying item prices. #780 2024-01-11 16:48:23 +08:00
Korina Cordero
7f4675a8a2 Add item type dropdown to form. #780 2024-01-10 17:23:15 +08:00
Korina Cordero
f65ca19010 Load service offering into Item Pricing page. #780 2024-01-09 17:39:29 +08:00
c17be92f0a Fix errors for item query. #780 2023-12-31 00:46:12 -05:00
80b9f90324 Rename ItemPriceController to ItemController. #780 2023-12-30 23:09:27 -05:00
01e4baa8c4 Add item price controller. #780 2023-12-28 20:41:44 -05:00
e4ffcc0c9d Add controller for item pricing. #780 2023-12-27 22:15:44 -05:00
Ramon Gutierrez
9c081b416e Merge branch '781-fix-character-length-for-motolite-events-title' into 'master'
Increase motolite event name field size to 255 #781

Closes #781

See merge request jankstudio/resq!893
2023-12-22 07:30:47 +00:00
Ramon Gutierrez
5ee41dab32 Increase motolite event name field size to 255 #781 2023-12-22 15:30:11 +08:00
root
58f46fd5bf Add route and CRUD for item type. #780 2023-12-21 23:23:46 -05:00
Korina Cordero
8c810bf27a Add validation and deletion for price tier. #780 2023-12-21 16:24:37 +08:00
Korina Cordero
fa3cf12be1 Add controller for price tier. #780 2023-12-20 18:15:17 +08:00
Korina Cordero
9447f64312 Create item price, price tier, and item type entities for regional pricing. #780 2023-12-19 17:30:38 +08:00
Ramon Gutierrez
b51160e9d0 Merge branch '779-fix-battery-recommendations-still-including-inactive-batteries' into 'master'
Display inactive batteries on edit vehicle form, exclude inactive batteries on...

Closes #779

See merge request jankstudio/resq!891
2023-12-18 09:18:17 +00:00
Ramon Gutierrez
d8bd2803e0 Display inactive batteries on edit vehicle form, exclude inactive batteries on battery recommendations API endpoint #779 2023-12-18 17:17:40 +08:00
Ramon Gutierrez
a7c7b03d06 Merge branch '746-resq-2-0-final' into 'master'
Add source to invoice criteria. Modify invoice rules to get service fees from...

See merge request jankstudio/resq!890
2023-11-22 08:54:47 +00:00
Ramon Gutierrez
ebfa3495a7 Merge branch '778-add-in-app-support-for-battery-trade-ins' into '746-resq-2-0-final'
Resolve "Add in-app support for battery trade-ins"

See merge request jankstudio/resq!889
2023-11-22 08:50:51 +00:00
Ramon Gutierrez
7c09dcac65 Merge branch '746-resq-2-0-final' into 778-add-in-app-support-for-battery-trade-ins
# Conflicts:
#	config/routes/apiv2.yaml
#	src/Controller/CustomerAppAPI/VehicleController.php
2023-11-18 04:36:57 +08:00
Ramon Gutierrez
fb2ca0bbd8 Merge branch '761-add-paramount-insurance-and-paymongo-support-for-resq2-api' into '746-resq-2-0-final'
Resolve "Add Paramount insurance and PayMongo support for RESQ2 API"

See merge request jankstudio/resq!888
2023-11-17 20:28:02 +00:00
Ramon Gutierrez
9bc9b13055 Merge branch '765-change-fax-to-alternative-phone-number' into '746-resq-2-0-final'
Resolve "Change Fax to Alternative Phone Number"

See merge request jankstudio/resq!879
2023-11-17 08:43:21 +00:00
Ramon Gutierrez
4773d6c08c Add trade-in support to invoice generation and JO creation for app #778 2023-11-17 06:30:07 +08:00
Ramon Gutierrez
fd0c9ede26 Merge branch '746-resq-2-0-final' into 778-add-in-app-support-for-battery-trade-ins 2023-11-14 19:25:54 +08:00
Ramon Gutierrez
ef10f7c7b9 Add endpoint for getting estimated trade-in value #778 2023-11-14 19:25:05 +08:00
Ramon Gutierrez
6d4614f634 Merge branch '772-remove-list-of-car-club-members-checkboxes-from-jo' into '746-resq-2-0-final'
Resolve "Remove list of car club members checkboxes from JO"

See merge request jankstudio/resq!886
2023-11-14 07:18:19 +00:00
Korina Cordero
cf5da6ea7b Comment out customer car club code. #772 2023-11-14 14:56:32 +08:00
Ramon Gutierrez
2e5ce7e28b Merge branch '770-add-another-module-for-all-resq-transactions' into '746-resq-2-0-final'
Resolve "Add another module for all RESQ transactions"

See merge request jankstudio/resq!885
2023-11-14 04:49:04 +00:00
Korina Cordero
deb26d3aa8 Remove debug message. #770 2023-11-13 18:30:07 +08:00
Korina Cordero
1dbfd2e3d1 Rename the menu item for Resq view all. #770 2023-11-13 18:29:24 +08:00
Korina Cordero
6cf94bb193 Add the new columns to the Resq View All page. #770 2023-11-13 18:27:01 +08:00
Korina Cordero
14d62d044f Make new page to view all Resq app job orders. #770 2023-11-13 15:20:46 +08:00
Ramon Gutierrez
fba077d4d3 Merge branch '773-add-a-dropdown-box-in-customer-information-to-indicate-if-customer-is-new-old' into '746-resq-2-0-final'
Resolve "Add a dropdown box in Customer Information to indicate if customer is new/old"

See merge request jankstudio/resq!883
2023-11-10 05:47:05 +00:00
Korina Cordero
c7b2502f0a Merge branch '746-resq-2-0-final' of gitlab.com:jankstudio/resq into 773-add-a-dropdown-box-in-customer-information-to-indicate-if-customer-is-new-old 2023-11-10 13:46:07 +08:00
Ramon Gutierrez
0ded3cea83 Merge branch '767-enable-viewing-of-jos-locked-to-another-agent' into '746-resq-2-0-final'
Resolve "Enable viewing of JOs locked to another agent"

See merge request jankstudio/resq!880
2023-11-10 05:45:32 +00:00
Korina Cordero
1ce284578d Merge branch '746-resq-2-0-final' of gitlab.com:jankstudio/resq into 767-enable-viewing-of-jos-locked-to-another-agent 2023-11-10 13:40:52 +08:00
Korina Cordero
24332c0f9b Merge branch '746-resq-2-0-final' of gitlab.com:jankstudio/resq into 773-add-a-dropdown-box-in-customer-information-to-indicate-if-customer-is-new-old 2023-11-10 13:39:12 +08:00
Korina Cordero
91edfa6ef0 Fix issues found during testing. #773 2023-11-10 13:35:49 +08:00
Korina Cordero
005f891057 Fix issues found during testing. #773 2023-11-10 13:29:52 +08:00
Korina Cordero
c77591fe01 Fix issues during testing. #773 2023-11-09 18:08:59 +08:00
Korina Cordero
fd28be75d1 Add command to update flag_cust_new for existing job orders. Rename flag for consistency. #773 2023-11-09 18:03:17 +08:00
Korina Cordero
806418db52 Fix checking for customer job orders. #773 2023-11-09 16:30:57 +08:00
Korina Cordero
35456cfb19 Add new field for job order for new customers. Add saving of new field for job orders from admin panel and third party API. #773 2023-11-09 12:07:26 +08:00
Ramon Gutierrez
58c3d1c64a Merge branch '768-add-timer-in-jo-list-to-show-real-time-dispatch-time' into '746-resq-2-0-final'
Add dispatch timer to list of all JOs view #768

See merge request jankstudio/resq!884
2023-11-08 22:17:00 +00:00
Ramon Gutierrez
e070d6df18 Merge branch '746-resq-2-0-final' into 768-add-timer-in-jo-list-to-show-real-time-dispatch-time
# Conflicts:
#	templates/job-order/list.all.html.twig
2023-11-09 06:16:24 +08:00
Ramon Gutierrez
ac5683f7f1 Add dispatch timer to list of all JOs view #768 2023-11-09 06:10:51 +08:00
Ramon Gutierrez
0ba63cc106 Merge branch '769-add-transaction-type-for-view-all-header' into '746-resq-2-0-final'
Resolve "Add Transaction Type for View All header"

See merge request jankstudio/resq!882
2023-11-08 07:19:54 +00:00
Korina Cordero
8ed1434353 Add service type to View All page. Replace Battery Facilitated By to Assigned Hub in View All Page. #769 2023-11-08 15:17:32 +08:00
Ramon Gutierrez
b20371cd1f Merge branch '774-add-late-documentation-tickbox-and-reason-field-in-new-ticket-ticket-creation' into '746-resq-2-0-final'
Add source to invoice criteria. Modify invoice rules to get service fees from...

See merge request jankstudio/resq!881
2023-11-06 20:04:50 +00:00
Ramon Gutierrez
2344ec716b Add documentation time column to ticket list #774 2023-11-07 04:02:57 +08:00
Ramon Gutierrez
d44323c097 Add late documentation fields to ticket form #774 2023-11-07 04:02:33 +08:00
Ramon Gutierrez
561a280647 Add late documentation fields to ticket table #774 2023-11-07 03:34:56 +08:00
Korina Cordero
20a6029671 Add view only form for job order. #767 2023-10-27 17:53:10 +08:00
Ramon Gutierrez
ff753d5452 Remove initial 0 from mobile number passed to paymongo checkout api #761 2023-10-23 12:42:09 +08:00
Ramon Gutierrez
2432a08c4d Add support for transient status between making a payment and receiving the webhook #761 2023-10-23 01:17:05 +08:00
Korina Cordero
a29c31d3de Change Fax to Alternative Phone. #765 2023-10-20 13:45:42 +08:00
Ramon Gutierrez
b1ff62d9ec Add back insurance status to vehicle list so latest status can be displayed #761 2023-10-17 14:43:06 +08:00
Ramon Gutierrez
ac2cf864f2 Handle expiry date from insurance completed callback #761 2023-10-13 17:38:03 +08:00
Ramon Gutierrez
708e9a67cc Update insurance callback handler to expect formdata #761 2023-10-13 14:13:57 +08:00
Ramon Gutierrez
38262151e8 Add dates to vehicle info insurance info #761 2023-10-11 17:06:37 +08:00
Ramon Gutierrez
502e9a11cd Add customer vehicle id to insurance FCM notifications #761 2023-10-11 15:39:07 +08:00
Ramon Gutierrez
da87b386a3 Add changelog to insurance info on vehicle endpoint #761 2023-10-09 17:02:23 +08:00
Ramon Gutierrez
d3054760d3 Add external transaction id to vehicle info endpoint #761 2023-10-09 16:56:41 +08:00
Ramon Gutierrez
c332757a53 Fix paymongo handler not checking for the correct payload parameter on validation #761 2023-10-09 16:35:06 +08:00
Ramon Gutierrez
516fbcfcba Add missing dependency to insurance callback handler #761 2023-10-09 15:51:33 +08:00
Ramon Gutierrez
c0c6fe26f7 Fix wrong parameter being checked for invalid insurance callback #761 2023-10-09 15:50:28 +08:00
Ramon Gutierrez
cbe84d1cc8 Set insurance callback handler to process raw json body #761 2023-10-09 15:48:05 +08:00
Ramon Gutierrez
e3a79361bd Remove auth from insurance listener. Fail silently if invalid callback given #761 2023-10-09 14:05:25 +08:00
Ramon Gutierrez
9b616cf398 Handle insurance callbacks, add support for non-JO related FCM notifications #761 2023-10-09 01:15:12 +08:00
Ramon Gutierrez
dd9c9dd0ec Add endpoint for getting individual vehicle info #761 2023-09-26 04:53:13 +08:00
Ramon Gutierrez
38023bdb00 Add insurance information to customer vehicle endpoint #761 2023-09-20 20:40:00 +08:00
Ramon Gutierrez
a002da6aad Add entity null check for paymongo webhooks #761 2023-09-20 06:14:22 +08:00
Ramon Gutierrez
ee021da453 Handle paymongo webhooks #761 2023-09-20 06:08:00 +08:00
Ramon Gutierrez
78956de357 Merge branch '763-add-shopify-to-transaction-origin' into '746-resq-2-0-final'
Resolve "Add Shopify to Transaction Origin"

See merge request jankstudio/resq!877
2023-09-12 13:02:19 +00:00
Ramon Gutierrez
c5a8bda95a Return premium amount on insurance application endpoint #761 2023-09-09 00:42:42 +08:00
Korina Cordero
4dbd2377f4 Add Shopify to TransactionOrigin. #763 2023-09-08 15:31:58 +08:00
Ramon Gutierrez
95f771c252 Update field requirements for is_public and vehicle_use_type #761 2023-09-07 06:54:30 +08:00
Ramon Gutierrez
db75e7becd Add insurance endpoints, insurance and paymongo connectors #761 2023-09-06 04:05:15 +08:00
Ramon Gutierrez
8c11ec9e8f
Merge branch '759-add-inventory-column-to-job-order-details-report' into '746-resq-2-0-final'
Resolve "Add inventory column to Job Order Details Report"

See merge request jankstudio/resq!873
2023-09-05 20:00:36 +00:00
Ramon Gutierrez
f94cec4bfa
Merge branch '760-jumpstart-fee-for-hotline' into '746-resq-2-0-final'
Resolve "Jumpstart fee for Hotline"

See merge request jankstudio/resq!875
2023-09-04 07:58:51 +00:00
Korina Cordero
041248ae0c Set jumpstart fee for motolite users, depending on JO source. #760 2023-09-04 15:36:44 +08:00
Korina Cordero
d00b211363 Merge branch '746-resq-2-0-final' of gitlab.com:jankstudio/resq into 759-add-inventory-column-to-job-order-details-report 2023-08-29 10:15:09 +08:00
Ramon Gutierrez
32f3f957be Merge branch '758-make-service-fees-dynamic' into '746-resq-2-0-final'
Fix issue of jumpstart for motolite user. #758

See merge request jankstudio/resq!874
2023-08-25 06:00:04 +00:00
Korina Cordero
fc95f781d8 Fix issue of jumpstart for motolite user. #758 2023-08-25 09:42:42 +08:00
Korina Cordero
f98b3e170c Merge branch '746-resq-2-0-final' of gitlab.com:jankstudio/resq into 759-add-inventory-column-to-job-order-details-report 2023-08-25 00:25:28 +00:00
Ramon Gutierrez
555e79ab68 Merge branch '758-make-service-fees-dynamic' into '746-resq-2-0-final'
Resolve "Make service fees dynamic"

See merge request jankstudio/resq!872
2023-08-24 10:02:59 +00:00
Korina Cordero
80c762d463 Add inventory to the Job Order Details report. #759 2023-08-24 09:04:40 +00:00
Korina Cordero
4f13114649 Add inventory count to job order. Add saving of inventory count when assigning hub. #759 2023-08-24 07:29:06 +00:00
Korina Cordero
cfa77bf2e1 Add source to invoice criteria. Modify invoice rules to get service fees from database. Modify call to invoice to include source. #758 2023-08-23 07:51:43 +00:00
Korina Cordero
e9631b437f Add sql file to populate the ServiceOffering table. #758 2023-08-22 10:53:18 +00:00
Korina Cordero
3af04a922a Fix input type for fee. #758 2023-08-22 10:34:01 +00:00
Korina Cordero
8f196000a8 Add permisssions, menu, forms, entity, for ServiceOffering. #758 2023-08-22 08:36:51 +00:00
Ramon Gutierrez
236819d951 Merge branch '757-fix-display-of-database-menu-items' into '746-resq-2-0-final'
Resolve "Fix display of Database menu items"

See merge request jankstudio/resq!871
2023-08-18 09:07:50 +00:00
Korina Cordero
70047d4ea0 Resolve "Fix display of Database menu items" 2023-08-18 09:07:50 +00:00
Ramon Gutierrez
f481af3694 Merge branch '756-update-jumpstart-service-fee' into '746-resq-2-0-final'
Resolve "Update jumpstart service fee"

See merge request jankstudio/resq!870
2023-08-16 07:55:14 +00:00
Korina Cordero
acf7ce0d4d Update the service fee for jumpstart. #756 2023-08-16 07:51:53 +00:00
Ramon Gutierrez
de5f55ac0e Use friendlier error message for invalid confirmation code #746 2023-08-14 07:22:41 +08:00
Ramon Gutierrez
3137d39a9a Add customer account validation and response spoofing to account deletion resend code method #746 2023-08-14 05:22:26 +08:00
Ramon Gutierrez
b3b81e4e27 Add transparent check if number is valid before storing new deletion request #746 2023-08-14 00:28:27 +08:00
Ramon Gutierrez
18c295f2b1 Fix customer record association when submitting a delete request #746 2023-08-13 17:36:33 +08:00
Ramon Gutierrez
9ad1f0d9b2 Add account deletion api endpoints #746 2023-08-11 07:26:49 +08:00
Ramon Gutierrez
73738b7a18 Fix checking of test app store numbers #746 2023-08-10 12:49:06 +08:00
Ramon Gutierrez
e3af21f741 Add mfg id to exported vehicle list, fix default sorting of vehicle results #746 2023-08-09 06:01:24 +08:00
Ramon Gutierrez
4516566d56 Add vehicle make and manufacturer CSV export functionality #746 2023-08-09 05:49:26 +08:00
Ramon Gutierrez
26824713da Remove authentication from version check endpoint #746 2023-08-04 18:00:35 +08:00
Ramon Gutierrez
f3992f05fc Update apiv2 app version check to include OS #746 2023-08-02 16:39:30 +08:00
Ramon Gutierrez
e212e2d29a Merge branch '755-resq-2-fix-display-of-discount-type' into '746-resq-2-0-final'
Resolve "RESQ 2: Fix display of discount type"

See merge request jankstudio/resq!869
2023-07-28 09:27:23 +00:00
Korina Cordero
458a34c6a8 Fix setting of promo for invoice. #755 2023-07-28 05:58:03 +00:00
Ramon Gutierrez
1704235bbd Add image for premium excel battery #746 2023-07-26 17:05:50 +08:00
Ramon Gutierrez
0708ebdca9 Fix vertical centering on battery images #746 2023-07-24 16:01:31 +08:00
Ramon Gutierrez
00eb5d1a9d Fix aspect ratio of stock battery images #746 2023-07-24 15:46:12 +08:00
Ramon Gutierrez
570d405347 Update temp static battery images with new ones, handle spaces in image path #746 2023-07-24 15:36:49 +08:00
Ramon Gutierrez
18c893cc6e Merge branch '753-resq-2-set-invoice-criteria-correctly-in-getestimate' into '746-resq-2-0-final'
Resolve "RESQ 2: Set invoice criteria correctly in getEstimate"

See merge request jankstudio/resq!868
2023-07-21 06:34:40 +00:00
Korina Cordero
7b16738709 Fix typo. #753 2023-07-21 06:28:40 +00:00
Korina Cordero
da419dd257 Fix setting of invoice criteria for vat computations and battery entries. #753 2023-07-21 06:25:48 +00:00
Ramon Gutierrez
49ff4b604b Merge branch '752-resq-2-fix-return-values-for-invoice-data' into '746-resq-2-0-final'
Resolve "RESQ 2: Fix return values for invoice data"

See merge request jankstudio/resq!867
2023-07-20 02:30:51 +00:00
Korina Cordero
fc33668a46 Typecast the invoice fields to float. Fix the namespace for APIResponse for TAPI controllers. #752 2023-07-20 02:19:13 +00:00
Ramon Gutierrez
9b75993d3d Merge branch '751-resq-2-test-fix-for-fcm-notification-priority' into '746-resq-2-0-final'
Change dependency for fcm to forked lib with high priority set #751

See merge request jankstudio/resq!866
2023-07-19 10:04:54 +00:00
Ramon Gutierrez
6d6662611d Change dependency for fcm to forked lib with high priority set #751 2023-07-19 17:57:05 +08:00
Ramon Gutierrez
0eef2449e8 Fix duplicate fcm notification issue #746 2023-07-19 16:14:49 +08:00
Ramon Gutierrez
c2ff927f1f Merge branch '750-resq-2-fix-computation-issue-for-jo-from-resq-1-app' into '746-resq-2-0-final'
Fix the same issue in resq 2 app. #750

See merge request jankstudio/resq!865
2023-07-19 07:43:33 +00:00
Korina Cordero
4f70fc437c Fix the same issue in resq 2 app. #750 2023-07-19 07:41:48 +00:00
Ramon Gutierrez
bc47873ed1 Merge branch '750-resq-2-fix-computation-issue-for-jo-from-resq-1-app' into '746-resq-2-0-final'
Resolve "RESQ 2: Fix computation issue for JO from Resq 1 app"

See merge request jankstudio/resq!864
2023-07-19 07:18:09 +00:00
Korina Cordero
8427b3fb3d Fix adding of battery to invoice criteria for new JOs created from app. #750 2023-07-19 07:17:03 +00:00
Ramon Gutierrez
a78c08b7a2 Merge branch '749-resq-2-fix-api-responses-in-capi-calls' into '746-resq-2-0-final'
Resolve "RESQ 2: Fix API responses in CAPI calls"

See merge request jankstudio/resq!863
2023-07-18 06:20:55 +00:00
Korina Cordero
976acc26ad Change APIResponse namespace for CAPI controllers. #749 2023-07-18 06:16:41 +00:00
Ramon Gutierrez
11355f3eb2 Fix case issue on class name for api controller #746 2023-07-18 09:35:48 +08:00
Ramon Gutierrez
20301b6b98 Merge branch '748-fuel-price-update-for-resq-2' into '746-resq-2-0-final'
Resolve "Fuel Price Update for Resq 2"

See merge request jankstudio/resq!862
2023-07-13 13:43:27 +00:00
Korina Cordero
97917cf49b Updated fuel prices. #748 2023-07-12 07:49:30 +00:00
Ramon Gutierrez
f26d6284f3 Merge branch '744-new-invoice-service' into '746-resq-2-0-final'
Resolve "New invoice service"

See merge request jankstudio/resq!860
2023-07-10 12:48:30 +00:00
Korina Cordero
12ebe3538c Set taxable for the invoice criteria. #744 2023-07-07 09:36:22 +00:00
Korina Cordero
37ce74f07d Merge branch '746-resq-2-0-final' of gitlab.com:jankstudio/resq into 744-new-invoice-service 2023-07-06 05:39:07 -04:00
Korina Cordero
17e0fd6dcf Merge branch 'master' of gitlab.com:jankstudio/resq into 744-new-invoice-service 2023-07-06 05:25:22 -04:00
Korina Cordero
54c49eb8c5 Add comment on return value for compute. #744 2023-07-05 01:38:31 -04:00
Korina Cordero
2f3a77e96d Fix issues found during testing. #744 2023-07-05 01:36:44 -04:00
Korina Cordero
b4bcc06e42 Modify the invoice manager to be more generic. #744 2023-07-04 06:05:34 -04:00
Ramon Gutierrez
7beeef104c Update table names of role and user to match master #746 2023-06-23 13:14:41 +08:00
Ramon Gutierrez
87f77c9b9c Merge branch '730-resq-2-0' into 746-resq-2-0-final 2023-06-22 12:35:28 +08:00
Ramon Gutierrez
abc4e31d96 Initial commit for insurance listener only #730 2023-06-22 12:34:31 +08:00
Korina Cordero
783c26facc Add setting of taxable for invoice criteria. #744 2023-06-19 00:14:34 -04:00
Korina Cordero
822bc59c6c Set taxable for invoice criteria when app requests a job order. #744 2023-06-18 23:40:09 -04:00
Korina Cordero
9840ecf633 Use interface for the invoice manager. #744 2023-06-18 23:23:29 -04:00
ee9031a8f3 Merge branch '745-make-required-initial-concern-of-customer-and-notes-on-initial-concern-of-customer' into 'master'
Resolve "Make required Initial Concern of Customer and Notes on Initial Concern of Customer"

Closes #745

See merge request jankstudio/resq!859
2023-06-18 23:54:01 +00:00
Korina Cordero
f9800d8da3 Make required the initial concern and notes on initial concern fields. #745 2023-06-16 02:09:35 -04:00
Ramon Gutierrez
b81b10840b Pass jo status with each notification #730 2023-06-14 17:36:31 +08:00
Ramon Gutierrez
c2418b117e Attach jo_id to all fcm notifications #730 2023-06-14 17:14:59 +08:00
Ramon Gutierrez
31c0f4a102 Fix customer user not being properly associated with session #730 2023-06-14 16:49:04 +08:00
Ramon Gutierrez
c4878a9e6d Increase os_version size to 200 #730 2023-06-14 16:38:30 +08:00
Ramon Gutierrez
5540084416 Fix translation locations #730 2023-06-14 15:33:29 +08:00
Ramon Gutierrez
4990a3dc9d Add inital support for FCM push notifications 2023-06-13 20:33:58 +08:00
Korina Cordero
282760fe5a Remove debug message. #744 2023-06-07 05:33:59 -04:00
Korina Cordero
05073f3a0c Add frontend elements for testing JO saving. #744 2023-06-07 05:30:37 -04:00
Korina Cordero
fa514ef26c Remove debug messages. Add TODO task for front-end. #744 2023-06-05 21:51:19 -04:00
Korina Cordero
e9f18ed184 Modify the admin panel to use the new invoice engine when creating a new JO. #744 2023-06-05 21:34:15 -04:00
Korina Cordero
4ebbd8cfd3 Finish adding the test cases. #744 2023-06-05 20:13:37 -04:00
Korina Cordero
fe5121cf71 Add methods to process generateInvoice ajax call. Add test cases. #744 2023-06-05 01:55:04 -04:00
Korina Cordero
a986d7835b Add function to let the JO service call the new invoice manager. #744 2023-06-02 05:50:39 -04:00
Korina Cordero
77c2763f53 Fix typo. #744 2023-06-01 04:39:38 -04:00
Korina Cordero
f760b2c02a Add discount type rule and test cases. #744 2023-06-01 03:22:24 -04:00
Korina Cordero
725704e951 Add test cases for no tax. Fix issues found when computing the total if no tax. #744 2023-05-31 06:09:54 -04:00
Korina Cordero
49317188c9 Fix issues found during testing of tax computation. #744 2023-05-31 03:57:30 -04:00
Korina Cordero
f598e4f426 Add tax rule. #744 2023-05-30 05:54:16 -04:00
Korina Cordero
9bac6df2df Add rules for trade in and other service types. Add test scenarios. #744 2023-05-29 06:05:59 -04:00
Ramon Gutierrez
82065bda93 Fix review tag endpoints #730 2023-05-29 15:49:55 +08:00
Korina Cordero
e3ec6148df Add command to test invoice manager. #744 2023-05-26 05:54:22 -04:00
Korina Cordero
15830924e2 Add function to process the criteria entries. #744 2023-05-25 06:06:15 -04:00
Korina Cordero
0063f10f93 Add function to check what rules to use. #744 2023-05-24 06:16:44 -04:00
Korina Cordero
0bb32f47b5 Modify invoice engine. #744 2023-05-23 07:52:14 -04:00
Ramon Gutierrez
ed037428b3 Fix missing rider object from jo info #730 2023-05-23 14:41:43 +08:00
Ramon Gutierrez
0b3b5eb0bb Add review info to jo info endpoint #730 2023-05-23 14:32:46 +08:00
Korina Cordero
1c02138f52 Add services for the new invoice generator. #744 2023-05-22 06:06:12 -04:00
Ramon Gutierrez
562e96e32d Add review tag management views #730 2023-05-22 14:42:21 +08:00
Ramon Gutierrez
e235026197 Add review tags api #730 2023-05-22 14:12:33 +08:00
Ramon Gutierrez
a821c42f0d Add rider average rating to jo info #730 2023-05-22 13:18:01 +08:00
Ramon Gutierrez
33e6994aaa Add rider rating average computation #730 2023-05-22 13:00:54 +08:00
Ramon Gutierrez
c2c4be8b7b Fix missing entity dependency for rider reviews #730 2023-05-22 12:48:01 +08:00
Ramon Gutierrez
f2233d6680 Remove unnecessary entitymanager dependency on motolite events controller #730 2023-05-17 01:29:53 +08:00
Ramon Gutierrez
9afa2dfc6c Add CRM support for upcoming motolite events #730 2023-05-17 00:30:13 +08:00
Ramon Gutierrez
059bda9bf6 Add limit clause to motolite events endpoint #730 2023-05-16 13:30:12 +08:00
Ramon Gutierrez
9b7e0e55a7 Add missing getter method to motolite events #730 2023-05-16 12:20:05 +08:00
Ramon Gutierrez
24bd64d6e0 Fix events endpoint not returning any rows #730 2023-05-16 12:15:39 +08:00
Ramon Gutierrez
202b2d740e Fix case types on motolite event type namevalue #730 2023-05-16 12:12:01 +08:00
Ramon Gutierrez
8241dc5630 Fix order clause for upcoming events #730 2023-05-16 12:06:15 +08:00
Ramon Gutierrez
58eafabdcf Add api support for motolite events #730 2023-05-16 06:12:05 +08:00
Ramon Gutierrez
9c36baa3d3 Fix jo id null on outlet_assign #730 2023-05-12 15:32:02 +08:00
Ramon Gutierrez
551a39a236 Append JO ID and debug code to outlet_assign event #730 2023-05-12 15:21:15 +08:00
Ramon Gutierrez
8d7556c732 Remove in_transit mqtt event #730 2023-05-12 15:15:14 +08:00
Ramon Gutierrez
b90fc2f8dd Move in_transit event to pre hub departure #730 2023-05-12 15:10:08 +08:00
Ramon Gutierrez
c32b7d68c7 Add in_transit mqtt event for new app #730 2023-05-12 15:05:21 +08:00
Ramon Gutierrez
63526d65f2 Fix typo for Search in menu translation keys #730 2023-05-12 03:27:17 +08:00
Ramon Gutierrez
ea60fa081c Fix missing param for new mqtt client on assigning hub and rider #730 2023-05-11 19:13:56 +08:00
Ramon Gutierrez
4f06c02bd4 Restore legacy MQTTClient, add new MQTTClientApiv2 class for new customer api #730 2023-05-11 18:34:02 +08:00
Ramon Gutierrez
1d278beb35 Fix label for jumpstart service #730 2023-05-11 16:11:39 +08:00
Ramon Gutierrez
0afc1a04b0 Fix partner reviews not working with new customer session type #730 2023-05-11 16:11:17 +08:00
Ramon Gutierrez
fa3998d47f Separate apiv2 user provider #730 2023-05-11 01:39:38 +08:00
Ramon Gutierrez
a52267ca76 Initial implementation of insurance connector #730 2023-05-06 03:24:45 +08:00
Ramon Gutierrez
3861a9bf93 Keep legacy mqtt payload the same #730 2023-05-06 01:51:06 +08:00
Ramon Gutierrez
ddde274fdc Additional fix using sess array as object on mqtt connector #730 2023-05-06 01:37:07 +08:00
Ramon Gutierrez
82578fb346 Fix using sess array as object on mqtt connector #730 2023-05-06 01:36:21 +08:00
Ramon Gutierrez
e24174e59e Use different mqtt channel for apiv2 sessions #730 2023-05-06 01:33:16 +08:00
Ramon Gutierrez
5f4e6b1ad9 Fix mapping for customer user to session #730 2023-05-04 18:26:57 +08:00
Ramon Gutierrez
8e53a3bb19 Add debug code for mqtt sending #730 2023-05-04 18:08:50 +08:00
Ramon Gutierrez
219ab513b5 Remove truncation of first two digits on customer creation for new API #730 2023-05-04 18:07:38 +08:00
Ramon Gutierrez
87702f0e4c Revert use of isEmpty on arraycollection on mqtt connector #730 2023-05-04 17:41:19 +08:00
Ramon Gutierrez
df6a4ad292 Fix array merge issue on refactoring mqtt client #730 2023-05-04 17:38:10 +08:00
Ramon Gutierrez
13531171d7 Update MQTT client to send to both legacy and new customer sessions #730 2023-05-03 11:03:25 +08:00
Ramon Gutierrez
1ed25d0a26 Remove debug code from review entity #730 2023-04-28 18:14:54 +08:00
Ramon Gutierrez
1261fc1d20 Add support for new customer sessions on partner reviews #730 2023-04-28 18:08:23 +08:00
Ramon Gutierrez
3bf350ceaf Add icon id to service list #730 2023-04-28 17:47:58 +08:00
Ramon Gutierrez
4182e44607 Add date_schedule to JO info generation #730 2023-04-24 17:02:58 +08:00
Ramon Gutierrez
fed0b655f5 Make landmark field optional for now #730 2023-04-24 15:11:09 +08:00
Ramon Gutierrez
68fe13de46 Add missing dependency for warranty #730 2023-04-12 22:52:27 +08:00
Ramon Gutierrez
403de63251 Add missing dependency for warranty serial, replace request input api_key instances with session_key #730 2023-04-12 06:37:15 +08:00
Ramon Gutierrez
bddddf1970 Fix missing dependency on warranty check #730 2023-04-04 11:49:10 +08:00
da03f13f75 Merge branch '743-fix-for-hub-filter-for-emergency-jo-from-re-assign-hub' into 'master'
Resolve "Fix for hub filter for emergency JO from Re-assign Hub"

Closes #743

See merge request jankstudio/resq!857
2023-03-31 10:29:58 +00:00
Korina Cordero
2535498db9 Add TODO for emergency distance limit. #743 2023-03-31 10:29:22 +00:00
Korina Cordero
f6436cd421 Add limit distance for emergencies when assigning hub from Open page. #743 2023-03-31 10:04:16 +00:00
Ramon Gutierrez
46104bc395 Replace doctrine spatial lib with forked version #730 2023-03-28 11:36:32 +08:00
Ramon Gutierrez
cb11849489 Add support for customer credits, add credit manager #730 2023-03-27 04:40:14 +08:00
Ramon Gutierrez
6d416ee5f1 Fix issues encountered during v2 app creation #730 2023-03-26 00:43:45 +08:00
Ramon Gutierrez
c7fc06ef50 Fix routes and acl for apiv2 #730 2023-03-26 00:43:08 +08:00
bc7a91c01d Merge branch '740-filter-sms-hub-rejection-by-servie-type' into 'master'
Resolve "Filter SMS Hub Rejection by Service Type"

Closes #740

See merge request jankstudio/resq!855
2023-03-08 01:01:27 +00:00
Korina Cordero
92abe703d3 Add checking for JO service type. #740 2023-03-07 02:30:57 +00:00
e2498beca7 Merge branch '739-add-customer-location-to-jo' into 'master'
Resolve "Add customer location to JO"

Closes #739

See merge request jankstudio/resq!854
2023-02-28 10:14:33 +00:00
f6a858cc28 Merge branch '738-filter-sms-hub-rejection' into 'master'
Resolve "Filter SMS Hub Rejection"

Closes #738

See merge request jankstudio/resq!853
2023-02-28 10:14:20 +00:00
Korina Cordero
674a862586 Remove else condition. #738 2023-02-28 08:04:19 +00:00
Korina Cordero
e102766961 Move checking for phone number and rejection reason. #738 2023-02-28 08:02:11 +00:00
Korina Cordero
a594bef863 Add sql script to insert the requested customer locations. #739 2023-02-23 08:07:40 +00:00
Korina Cordero
2aef8e64e7 Add blank option for customer location dropdown. Add checking for blank option. #739 2023-02-23 08:02:37 +00:00
Korina Cordero
4717d7d925 Add customer location dropdown to JO form. #739 2023-02-23 07:13:48 +00:00
Korina Cordero
f57c9f5f4f Add CRUD for customer locations. #739 2023-02-23 03:08:17 +00:00
Ramon Gutierrez
d59ac805f7 Update rider app to use correct api response class #730 2023-02-18 23:28:04 +08:00
Ramon Gutierrez
95b5c59db2 Fix customer user not being associated with customer record #730 2023-02-18 15:43:20 +08:00
Ramon Gutierrez
202b984aa2 Fix typo on customer user getter #730 2023-02-18 15:43:02 +08:00
Ramon Gutierrez
f7f182e062 Fix old dependency for customer endpoints on rider app api #730 2023-02-16 05:56:24 +08:00
Ramon Gutierrez
0947b12e99 Add resend code endpoint to creds whitelist #730 2023-02-16 05:54:39 +08:00
Ramon Gutierrez
2f7e493fab Separate routes for old and new apis #730 2023-02-16 05:54:14 +08:00
Korina Cordero
5dc4d9f3f8 Add checking if reason is administrative. #738 2023-02-13 02:05:18 +00:00
Ramon Gutierrez
81d4f46930 Fix existing customer user association #730 2023-02-10 15:10:24 +08:00
87846040b6 Merge branch 'staging' into 'master'
Staging

See merge request jankstudio/resq!852
2023-02-09 10:19:33 +00:00
71ee183813 Merge branch '734-add-columns-to-nearest-hubs-in-dispatch-page' into 'staging'
Add flag_active to query for riders. #734

See merge request jankstudio/resq!851
2023-02-09 03:14:29 +00:00
Korina Cordero
b87855e0a6 Add flag_active to query for riders. #734 2023-02-08 06:28:02 +00:00
2c6b39acb6 Merge branch '736-rejection-notification-to-hub-via-sms' into 'staging'
Add sending of SMS notification to hub when rejected. #736

See merge request jankstudio/resq!850
2023-02-08 03:32:25 +00:00
8cdf33014e Merge branch '734-add-columns-to-nearest-hubs-in-dispatch-page' into 'staging'
Add rider count columns to Nearest Hubs table in Dispatch page. #734

See merge request jankstudio/resq!848
2023-02-08 03:31:46 +00:00
0331fb605a Merge branch '733-add-capability-to-deactivate-a-battery' into 'staging'
"Add capability to deactivate a battery"

See merge request jankstudio/resq!847
2023-02-08 03:31:13 +00:00
Ramon Gutierrez
e3be92b63e Rename register return value from session_id to session_key #730 2023-02-08 07:45:01 +08:00
Ramon Gutierrez
f62ce78ac7 Fix base api user usage, fix customer user registration logic on number confirm #730 2023-02-08 07:42:51 +08:00
1ecd69b959 Fix typo in ApiUser entity #730 2023-02-08 02:45:20 +08:00
af39b6d6ca Add ApiUser to replace the old catalyst api user #730 2023-02-08 02:44:15 +08:00
Ramon Gutierrez
efec5c4b84 Add proper config for api acl #730 2023-02-08 02:24:25 +08:00
Ramon Gutierrez
693ee7cd9b Update api user provider on security policy #730 2023-02-07 18:19:55 +08:00
Ramon Gutierrez
e0029d8ab5 Remove debug code for register endpoint, add customer api user entity #730 2023-02-07 18:17:35 +08:00
Korina Cordero
879c80f7be Add sending of SMS notification to hub when rejected. #736 2023-02-07 07:15:43 +00:00
Ramon Gutierrez
98705f99d4 Remove guard on api routes, move all returns to base accessed methods #730 2023-02-07 09:11:17 +08:00
Ramon Gutierrez
9876165af5 Adjust new customer api method groupings, add routes #730 2023-02-07 08:25:07 +08:00
Ramon Gutierrez
b3301fdbac Add new customer app API logic #730 2023-02-07 07:58:57 +08:00
Korina Cordero
ab2d6be08e Add getActiveBatteries function. #733 2023-02-06 10:42:01 +00:00
Korina Cordero
765b3a99b9 Add getActiveBatteries function. #733 2023-02-06 10:39:30 +00:00
51a2111552 Merge branch '735-add-rider-status-to-rider-assignment-table-in-assignment-form' into 'staging'
Add rider status to rider assignment table. #735

See merge request jankstudio/resq!849
2023-02-06 10:30:47 +00:00
Korina Cordero
0e7a955a91 Improve checking for rider status. #735 2023-02-06 10:01:36 +00:00
Korina Cordero
63b02a7c21 Add rider status to rider assignment table. #735 2023-02-06 07:35:06 +00:00
Ramon Gutierrez
2a0ca3b9ea Update auth table names to new standard, fix model association config for acl #730 2023-02-06 05:14:08 +08:00
Korina Cordero
4c4a8da7e6 Add rider count columns to Nearest Hubs table in Dispatch page. #734 2023-02-03 08:36:43 +00:00
Ramon Gutierrez
876722ebe7 Switch over to newer catalyst libs, update service configs #730 2023-02-03 14:52:44 +08:00
Korina Cordero
6e9e56b1be Add filtering for inactive batteries. #733 2023-02-02 09:09:44 +00:00
Korina Cordero
72fc6ee9b0 Fix error. #733 2023-02-02 06:57:07 +00:00
Korina Cordero
cbf5d12d96 Modify queries to only get active batteries. #733 2023-02-02 03:59:21 +00:00
Korina Cordero
c478a4d0bf Add flag_active to Battery entity. Add flag_active to forms. #733 2023-02-02 02:50:22 +00:00
935dc15101 Merge branch '729-fuel-price-updates' into 'master'
Resolve "Fuel price updates"

Closes #729

See merge request jankstudio/resq!844
2023-01-27 13:30:38 +00:00
Korina Cordero
fd2a1b35bc Update fuel prices. #729 2023-01-27 06:02:25 +00:00
c8d22a0dfb Merge branch '726-add-sales-invoice-number-field-to-warranty' into 'master'
Resolve "Add sales invoice number field to warranty"

Closes #726

See merge request jankstudio/resq!841
2023-01-19 07:58:38 +00:00
Korina Cordero
7cd8dcf725 Add sales invoice number field to warranty creation in admin panel. #726 2022-12-26 02:15:43 +00:00
08ecd2ebea Merge branch '725-add-fields-for-warranty-creation-from-admin-panel' into 'master'
Resolve "Add fields for warranty creation from admin panel"

Closes #725

See merge request jankstudio/resq!840
2022-12-20 08:12:53 +00:00
Korina Cordero
54b5d0deef Fix layout of form. #725 2022-12-19 10:09:19 +00:00
d5245844ac Merge branch '724-fuel-price-changes' into 'master'
Resolve "Fuel price changes"

Closes #724

See merge request jankstudio/resq!839
2022-12-19 09:09:58 +00:00
Korina Cordero
7c95f1ff0d Add new fields to warranty creation in admin panel. #725 2022-12-19 06:37:21 +00:00
Korina Cordero
79caebf1f9 Modify fuel prices. #724 2022-12-19 03:28:30 +00:00
31b246fca0 Merge branch '723-fix-issue-with-raffle-reports-2' into 'master'
Resolve "Fix issue with raffle reports"

Closes #723

See merge request jankstudio/resq!838
2022-12-16 11:19:58 +00:00
Korina Cordero
6d6c855feb Fixed setting of time for date time for query. #723 2022-12-16 08:02:47 +00:00
524d99db08 Merge branch '720-create-service-to-filter-warranty-entries-for-warranty-raffle-report' into 'master'
Resolve "Create service to filter warranty entries for warranty raffle report"

Closes #720

See merge request jankstudio/resq!835
2022-11-22 07:42:16 +00:00
Korina Cordero
bec964ffa4 Add criteria to warranty raffle filter. #720 2022-11-22 07:39:45 +00:00
Korina Cordero
907bee0d70 Add service to filter warranty raffle entries. #720 2022-11-21 07:37:27 +00:00
Korina Cordero
5b6b090257 Add mobile number from mobile session to warranty raffle report. #719 2022-11-21 07:01:55 +00:00
8776d69a92 Merge branch '718-warranty-raffle-report-changes' into 'master'
Resolve "Warranty Raffle Report Changes"

Closes #718

See merge request jankstudio/resq!833
2022-11-16 10:42:42 +00:00
Korina Cordero
c70dbd3b52 Add action to report. Modify transaction id in report. #718 2022-11-16 10:41:35 +00:00
f0d14b7d77 Merge branch '717-log-warranty-activities-from-app' into 'master'
Resolve "Log warranty activities from app"

Closes #717

See merge request jankstudio/resq!832
2022-11-14 12:43:39 +00:00
Korina Cordero
8d9c02ae72 Merge branch '716-jo-raffle-report' of gitlab.com:jankstudio/resq into 717-log-warranty-activities-from-app
Conflicts:
	config/acl.yaml
	config/routes/report.yaml
	src/Controller/ReportController.php
2022-11-14 11:58:25 +00:00
Korina Cordero
29468c629b Add warranty raffle report. #717 2022-11-14 08:11:49 +00:00
Korina Cordero
f2a661f696 Add logging for raffle when doing a serial check, creating and updating a warranty. #717 2022-11-14 06:32:24 +00:00
Korina Cordero
b1d7777726 Add log for warranty from app. #717 2022-11-11 08:33:35 +00:00
Korina Cordero
2317bfee4d Fix formatting of csv output. #716 2022-11-11 03:28:23 +00:00
Korina Cordero
b9159b7f4a Add Raffle Number column. #716 2022-11-11 01:12:21 +00:00
Korina Cordero
1b3d8d86a0 Add JO raffle report. #716 2022-11-10 09:29:01 +00:00
36ad7a28c2 Merge branch '708-warranty-serial-upload-improvements' into 'master'
Resolve "Warranty Serial Upload Improvements"

Closes #708

See merge request jankstudio/resq!824
2022-11-10 06:45:46 +00:00
a5640914bf Merge branch '715-modify-number-of-days-for-sending-warranty-sms-expiry-notification' into 'master'
Resolve "Modify number of days for sending warranty sms expiry notification"

Closes #715

See merge request jankstudio/resq!830
2022-10-27 12:56:34 +00:00
Korina Cordero
0ece8b5864 Change time of warranty sms notification from one month to 45 days. #715 2022-10-25 02:55:38 +00:00
9f2027fcc1 Merge branch '714-fuel-price-update' into 'master'
Resolve "Fuel price update"

Closes #714

See merge request jankstudio/resq!829
2022-10-20 14:22:20 +00:00
Korina Cordero
ab77cb6260 Update fuel prices. #714 2022-10-19 01:11:09 +00:00
337b98f655 Merge branch '713-tapi-changes' into 'master'
Resolve "TAPI Changes"

Closes #713

See merge request jankstudio/resq!828
2022-10-11 07:24:55 +00:00
Korina Cordero
9112bf55f1 Fix formatting for floats. #713 2022-10-11 07:06:58 +00:00
Korina Cordero
36cf10871e Comment debug logs. #713 2022-10-11 05:37:24 +00:00
Korina Cordero
474298a42b Add a break when service type is set to jumpstart_warranty. #713 2022-10-11 05:23:23 +00:00
5e22dc5de1 Merge branch '712-fuel-price-changes' into 'master'
Resolve "Fuel price changes"

Closes #712

See merge request jankstudio/resq!827
2022-10-11 03:56:22 +00:00
Korina Cordero
49df3fc976 Change fuel prices. #712 2022-10-11 03:55:26 +00:00
e08a4ed803 Merge branch '711-fuel-price-changes' into 'master'
Resolve "Fuel price changes"

Closes #711

See merge request jankstudio/resq!826
2022-10-07 07:36:31 +00:00
Korina Cordero
1c3032b9e7 Change fuel prices. #711 2022-10-07 07:11:32 +00:00
9130d41a96 Merge branch '710-disable-stripping-qr-prefix' into 'master'
Resolve "Disable stripping QR prefix"

Closes #710

See merge request jankstudio/resq!825
2022-09-30 13:40:48 +00:00
Korina Cordero
a3be1434a0 Disable removal of QR prefix. #710 2022-09-30 07:51:25 +00:00
Korina Cordero
b3678168da Comment debug logs. #708 2022-09-30 04:57:54 +00:00
Korina Cordero
b4a6e233f1 Delete csv file and directory after processing file. #708 2022-09-29 07:04:53 +00:00
Korina Cordero
6794db5f6a Add checking if any file was processed. #708 2022-09-29 05:50:46 +00:00
Korina Cordero
97d058c3d3 Modify the load warranty serial command to process one file. Add a command to get the number of pending files. Add bash script to call the load warranty serial command. #708 2022-09-28 09:43:04 +00:00
Korina Cordero
815c25a894 Add locking and unlocking for warranty serial queue table when deleting an entry. #708 2022-09-28 06:19:41 +00:00
Korina Cordero
21231358d6 Delete entry from warranty_serial_queue when done processing. #708 2022-09-28 02:43:27 +00:00
c1ef75b8f5 Merge branch '707-add-checking-for-warranty-serial-length' into 'master'
Resolve "Add checking for warranty serial length"

Closes #707

See merge request jankstudio/resq!823
2022-09-27 01:11:39 +00:00
Korina Cordero
b8c0fa9932 Add checking for serial length. #707 2022-09-26 06:46:45 +00:00
72dab63503 Merge branch '704-capi-call-for-warranty-serial' into 'master'
Resolve "CAPI call for warranty serial"

Closes #704

See merge request jankstudio/resq!821
2022-09-23 03:14:27 +00:00
Korina Cordero
c077094044 Merge branch 'master' of gitlab.com:jankstudio/resq into 704-capi-call-for-warranty-serial 2022-09-22 01:25:16 +00:00
53d4d28716 Merge branch '705-fuel-changes' into 'master'
Resolve "Fuel changes"

Closes #705

See merge request jankstudio/resq!822
2022-09-21 13:23:34 +00:00
Korina Cordero
6ee6a7d9a1 Comment debug logs. #704 2022-09-21 05:36:39 +00:00
Korina Cordero
9efe73e8b2 Add validation for invalid number of fields. #704 2022-09-21 04:54:21 +00:00
Korina Cordero
f40155e1f5 Change the logging of serial. #704 2022-09-20 08:19:43 +00:00
Korina Cordero
2bbb83c43e Adjust fuel prices. #705 2022-09-20 06:12:34 +00:00
Korina Cordero
6314b4097d Add test capi endpoint. #704 2022-09-20 04:20:36 +00:00
Korina Cordero
138c60a61b Comment out sending to callback URL. #704 2022-09-20 02:38:32 +00:00
Korina Cordero
f8910860a6 Fix json output for command. #704 2022-09-19 09:28:12 +00:00
Korina Cordero
fc15b514bf Add file id. #704 2022-09-19 08:21:29 +00:00
Korina Cordero
0ffbf10879 Fix conflict. #704 2022-09-19 07:15:55 +00:00
Korina Cordero
c42d2973f4 Merge branch 'master' of gitlab.com:jankstudio/resq into 704-capi-call-for-warranty-serial
Conflicts:
	config/api_acl.yaml
	src/Controller/APIUserController.php
2022-09-19 07:14:04 +00:00
7416be8425 Merge branch '686-move-apicontroller-methods-into-capi' into 'master'
Resolve "Move APIController methods into CAPI"

Closes #686

See merge request jankstudio/resq!800
2022-09-19 06:39:38 +00:00
Korina Cordero
35d6e34128 Merge branch 'master' of gitlab.com:jankstudio/resq into 686-move-apicontroller-methods-into-capi
Conflicts:
	src/Ramcar/TransactionOrigin.php
2022-09-19 06:35:16 +00:00
Korina Cordero
d9aaea928c Add call to curl to command. #704 2022-09-19 06:27:03 +00:00
Korina Cordero
70e9b933d9 Add output to command. #704 2022-09-16 05:22:14 +00:00
Korina Cordero
cbc0b290ad Add processing for output. #704 2022-09-15 09:51:07 +00:00
Korina Cordero
32720ba9e7 Fix issues for the load command. #704 2022-09-15 07:38:33 +00:00
Korina Cordero
5b848a7f10 Fix issue when creating API user that's not a rider. Fix issues when uploading a file. #704 2022-09-15 05:56:43 +00:00
Korina Cordero
a3e9c45ec3 Separate the uploading of files and the processing of files. #704 2022-09-14 09:33:05 +00:00
Korina Cordero
3c9bdc8152 Add WarrantySerialQueue entity. #704 2022-09-14 08:02:51 +00:00
Korina Cordero
7d65b1eb77 Add CAPI call to upload warranty serial CSV file. #704 2022-09-14 07:33:51 +00:00
c2adf8f082 Merge branch '703-add-credit-card-amex-to-payment-mode' into 'master'
Resolve "Add Credit Card - AMEX to payment mode"

Closes #703

See merge request jankstudio/resq!820
2022-08-31 13:23:02 +00:00
Korina Cordero
dae8fe7051 Add credit card amex to mode of payment. #703 2022-08-31 04:57:27 +00:00
5352f16b83 Merge branch '702-modify-fuel-prices' into 'master'
Resolve "Modify fuel prices"

Closes #702

See merge request jankstudio/resq!819
2022-08-30 04:50:49 +00:00
Korina Cordero
f51ec9112d Modify fuel prices. #702 2022-08-30 04:38:22 +00:00
c1dbc8abf6 Merge branch '701-modify-motiv-endpoint-info-for-warranty-serial' into 'master'
Resolve "Modify motiv endpoint info for warranty serial"

Closes #701

See merge request jankstudio/resq!818
2022-08-30 04:30:12 +00:00
Korina Cordero
6231db2467 Update the token for the motiv blob. #701 2022-08-30 04:29:16 +00:00
4b887adcd2 Merge branch '695-yokohama-add-new-ticket-types-and-subticket-types' into 'master'
Resolve "YOKOHAMA Add new ticket types and subticket types"

Closes #695

See merge request jankstudio/resq!811
2022-08-23 09:34:56 +00:00
5d6eb443a7 Merge branch '694-yokohama-add-new-transactionorigin-types' into 'master'
Resolve "YOKOHAMA Add new TransactionOrigin types"

Closes #694

See merge request jankstudio/resq!810
2022-08-23 09:34:25 +00:00
eb769f736f Merge branch '696-ownership-dropdown-in-jo-form' into 'master'
Add sql file for ownership types. #696

Closes #696

See merge request jankstudio/resq!817
2022-08-16 08:07:27 +00:00
Korina Cordero
34accc1a0c Add sql file for ownership types. #696 2022-08-16 08:05:02 +00:00
091da71cc1 Merge branch '700-fuel-price-changes' into 'master'
Resolve "Fuel price changes"

Closes #700

See merge request jankstudio/resq!816
2022-08-16 07:55:38 +00:00
Korina Cordero
1feef7484e Adjust fuel charges. #700 2022-08-16 07:44:36 +00:00
52545c8a4f Merge branch '696-ownership-dropdown-in-jo-form' into 'master'
Resolve "Ownership Dropdown in JO form"

Closes #696

See merge request jankstudio/resq!812
2022-08-15 08:39:28 +00:00
Korina Cordero
a4338c8f61 Add ownership type dropdown to JO form. #696 2022-08-15 08:28:23 +00:00
Korina Cordero
837a3a2ec5 Add ownership type CRUD. #696 2022-08-15 07:10:15 +00:00
Korina Cordero
c1e33fb5dd Add new ticket and new subticket types. #695 2022-08-12 10:39:08 +00:00
Korina Cordero
5f94f252bc Add new transaction origin types for Yokohama. #694 2022-08-12 08:36:21 +00:00
a08f988a54 Merge branch '693-fuel-price-change-and-geofence-message-change' into 'master'
Resolve "Fuel price change and geofence message change"

Closes #693

See merge request jankstudio/resq!809
2022-08-05 14:22:29 +00:00
80d4063238 Change error message for geofence #693 2022-08-05 22:21:49 +08:00
774599a01b Change prices for refuel #693 2022-08-05 22:10:12 +08:00
d27d54f7da Fix motiv being down for getInventory 2022-07-16 19:22:59 +08:00
a327f070aa Merge branch '692-filter-plate-number-for-warranty-check-and-submission' into 'master'
Clean plate number before warranty registering for mobile API

Closes #692

See merge request jankstudio/resq!808
2022-07-12 16:50:38 +00:00
559d4bbc01 Clean plate number before warranty registering for mobile API 2022-07-13 00:45:58 +08:00
ae9b7ce061 Merge branch '690-warranty-creation-issue-in-warrantyhandler' into 'master'
Resolve "Warranty creation issue in WarrantyHandler"

Closes #690

See merge request jankstudio/resq!806
2022-06-28 13:25:38 +00:00
Korina Cordero
270867f86f Redo the warranty creation. #690 2022-06-28 13:21:47 +00:00
Korina Cordero
48aa0b024f Fix warranty creation issue. #690 2022-06-28 12:47:42 +00:00
0ea02ae04d Merge branch '684-move-the-blob-and-sas-token-for-warranty-serial-download-to-env' into 'master'
Resolve "Move the blob and sas token for warranty serial download to .env"

Closes #684

See merge request jankstudio/resq!798
2022-06-24 13:15:05 +00:00
Korina Cordero
ce160c506c Add a process date for the output filename when loading serials. Change the write method to append. #684 2022-06-24 07:13:09 +00:00
Korina Cordero
3910db88f0 Fix parameter issue for getJobOrderInfo. #686 2022-06-23 09:39:25 +00:00
Korina Cordero
ee44dfb44e Fix cleaning of mobile number. #686 2022-06-23 09:02:56 +00:00
Korina Cordero
06a2a887ef Fix cleaning of mobile number. #686 2022-06-23 08:46:50 +00:00
Korina Cordero
470dd47195 Add DeliveryStatus to JobOrderController. #686 2022-06-23 08:23:34 +00:00
Korina Cordero
accd6fd0f6 Add validation for model year. #686 2022-06-23 07:57:24 +00:00
Korina Cordero
7995706dd3 Add another date to bulk script. #684 2022-06-23 03:07:12 +00:00
Korina Cordero
a669159513 Merge branch 'master' of gitlab.com:jankstudio/resq into 684-move-the-blob-and-sas-token-for-warranty-serial-download-to-env 2022-06-23 03:05:45 +00:00
c2d556b1b6 Merge branch '682-add-code-to-emergency-types' into 'master'
Fixed the sql with emergency type code. #682

Closes #682

See merge request jankstudio/resq!804
2022-06-22 02:11:33 +00:00
Korina Cordero
873bf80154 Fixed the sql with emergency type code. #682 2022-06-22 02:09:28 +00:00
4e728fd59a Merge branch '688-disable-motiv' into 'master'
Add check to see if motiv reply is valid #688

Closes #688

See merge request jankstudio/resq!803
2022-06-22 01:37:04 +00:00
Korina Cordero
3ce12df214 Add another date to the bulk script. #684 2022-06-22 01:14:49 +00:00
b4def3c1a7 Add check to see if motiv reply is valid #688 2022-06-21 21:51:31 +08:00
Korina Cordero
bbb562d366 Comment out scheduleOptionStatus. #686 2022-06-21 10:16:48 +00:00
Korina Cordero
fd77f1ef62 Add route for getNearestHubAndSlots. Modify getNearestHubAndSlots. #686 2022-06-21 10:08:58 +00:00
Korina Cordero
2112edd4f0 Remove getJOHistory. Add route for locationSupport. Modify responses of locationSupport. #686 2022-06-21 09:43:19 +00:00
Korina Cordero
144afae551 Add route for getJobOrderInfo. Modify the responses for getJobOrderInfo. #686 2022-06-21 09:10:23 +00:00
Korina Cordero
4e613e3c01 Add route for cancelJobOrder. Modify cancelJobOrder responses. #686 2022-06-21 08:54:09 +00:00
Korina Cordero
3e73bc0513 Add route for getJOInvoice. Modify getJOInvoice responses. #686 2022-06-21 08:32:19 +00:00
Korina Cordero
f486a1b5a0 Add route for getEstimate. Modify getEstimate for third party api. #686 2022-06-21 07:55:25 +00:00
Korina Cordero
7985ec8f34 Rename validateRequest to validateJORequest. Modify required parameters for getEstimate. #686 2022-06-21 03:57:16 +00:00
Korina Cordero
ce6b1f8049 Fix responses. Add routes for promo. #686 2022-06-21 03:20:30 +00:00
7b01e7bc0d Merge branch '687-change-fuel-charges' into 'master'
Resolve "Change fuel charges"

Closes #687

See merge request jankstudio/resq!801
2022-06-20 14:57:28 +00:00
Korina Cordero
5b32349437 Fix the responses for the api calls for vehicle and battery. #686 2022-06-20 10:20:42 +00:00
Korina Cordero
fb91d462ff Add path to tapi calls. Add more required parameters for new job order. #686 2022-06-20 09:00:56 +00:00
Korina Cordero
2ca7f86829 Add another day to batch script. #684 2022-06-20 06:59:37 +00:00
Korina Cordero
fb766eb99f Change diesel fuel fee. #687 2022-06-20 06:56:48 +00:00
Korina Cordero
08050416bb Add route for job order creation using third party API. #686 2022-06-20 06:50:06 +00:00
Korina Cordero
db65c6d623 Add more dates to bulk script. #684 2022-06-17 10:44:28 +00:00
Korina Cordero
c8a8bc53af Start processing of request data. #686 2022-06-17 08:47:55 +00:00
Korina Cordero
89cd852db8 Merge branch '684-move-the-blob-and-sas-token-for-warranty-serial-download-to-env' of gitlab.com:jankstudio/resq into 686-move-apicontroller-methods-into-capi 2022-06-17 04:03:23 +00:00
Korina Cordero
16fb2cf0da Add bulk load serial script. Modify bulk script for loading serials. #684 2022-06-16 08:24:05 +00:00
Korina Cordero
c885033934 Change URL and token for downloading warranty serials. #684 2022-06-16 06:35:06 +00:00
Korina Cordero
44b9679a2e Move third party api controllers to a more descriptive directory. #686 2022-06-16 04:26:27 +00:00
Korina Cordero
60f401e26e Add permissions for another third party api. Copied the methods from APIController into CAPI third party conrtrollers. #686 2022-06-15 08:22:36 +00:00
54f065d30f Merge branch '668-remove-error_logs' into 'master'
Resolve "Remove error_logs"

Closes #668

See merge request jankstudio/resq!783
2022-06-13 02:09:24 +00:00
0734f315ac Merge branch '682-add-code-to-emergency-types' into 'master'
Resolve "Add code to emergency types"

Closes #682

See merge request jankstudio/resq!796
2022-06-12 05:40:06 +00:00
b68d722013 Merge branch '683-use-gettickettypetext-when-returning-ticket-type-for-ticket-list' into 'master'
Resolve "Use getTicketTypeText when returning ticket type for ticket list"

Closes #683

See merge request jankstudio/resq!797
2022-06-12 05:40:00 +00:00
11432f9742 Merge branch '681-mark-orange-in-dispatch-page-jos-that-are-marked-rush' into 'master'
Resolve "Mark orange in Dispatch page JOs that are marked Rush"

Closes #681

See merge request jankstudio/resq!795
2022-06-12 05:38:39 +00:00
Korina Cordero
a9a5760444 Use getTicketTypeText to display ticket type. #683 2022-06-10 08:39:41 +00:00
Korina Cordero
200f4bca22 Add code to emergency type. #682 2022-06-10 08:32:46 +00:00
Korina Cordero
f8e3e7df2d Add rush request JOs to be marked the same color as emergency. #681 2022-06-10 08:00:18 +00:00
4eb35364ca Merge branch '680-add-code-to-ticket-and-subticket-types' into 'master'
Resolve "Add code to ticket and subticket types"

Closes #680

See merge request jankstudio/resq!794
2022-06-10 07:38:32 +00:00
f90badd331 Merge branch '679-separate-screen-for-resq-transations' into 'master'
Resolve "Separate screen for RESQ transations"

Closes #679

See merge request jankstudio/resq!793
2022-06-10 07:25:49 +00:00
9150db3c20 Merge branch '677-dropdown-menu-for-specific-emergency-scenarios' into 'master'
Resolve "Dropdown Menu for specific Emergency Scenarios"

Closes #677

See merge request jankstudio/resq!791
2022-06-10 07:23:40 +00:00
Korina Cordero
cf97c74ea6 Fix display of ticket types when listing tickets in ticket list, ticket list in job order and ticket list in customer. #680 2022-06-10 07:20:24 +00:00
Korina Cordero
c63b9ffe43 Add code to ticket and subticket types. #680 2022-06-10 06:46:14 +00:00
Korina Cordero
3af014c7cf Remove JOs from mobile app in the Dispatch page. #679 2022-06-08 03:43:44 +00:00
Korina Cordero
d2591a3ffb Fix the routes for JOs coming from the Resq Dispatch page. #679 2022-06-08 03:07:12 +00:00
Korina Cordero
feade62c18 Add query parameter for the return urls when unlocking and editing/dispatching a JO. #679 2022-06-07 10:07:20 +00:00
Korina Cordero
86ab8edb74 Add a separate menu item for dispatch for JOs from mobile app. #679 2022-06-07 07:28:27 +00:00
50ce917a1a Merge branch '678-fix-color-coding-issues' into 'master'
Resolve "Fix color coding issues"

Closes #678

See merge request jankstudio/resq!792
2022-06-07 03:14:58 +00:00
Korina Cordero
61c7774da0 Fix color coding issue. #678 2022-06-07 03:08:02 +00:00
Korina Cordero
1a290436cb Modify length limit for name. Add table dump for emergency type. #677 2022-06-06 08:55:58 +00:00
Korina Cordero
70d917a585 Add emergency type to job order. #677 2022-06-06 08:40:26 +00:00
Korina Cordero
a847cba9b9 Add create, list, update, and delete for emergency type. #677 2022-06-06 06:44:55 +00:00
80e61bbc92 Merge branch '676-new-ticket-types' into 'master'
Resolve "New ticket types"

Closes #676

See merge request jankstudio/resq!790
2022-06-06 03:42:17 +00:00
Korina Cordero
3b80fee75f Add mysqldumps for ticket types and subticket types. #676 2022-06-03 09:55:44 +00:00
Korina Cordero
d89f67bc76 Add the new ticket fields into the ticket form. #676 2022-06-03 08:34:16 +00:00
Korina Cordero
96ce1f81fa Add saving of ticket type for subticket type. #676 2022-06-02 13:12:23 +00:00
Korina Cordero
efd402acb1 Add list, create, update, delete for subticket type. #676 2022-06-02 07:18:37 +00:00
Korina Cordero
5840aba2a9 Add list, create, update, delete for ticket types. #676 2022-06-02 06:44:51 +00:00
16e0d8448f Merge branch '674-color-code-jos-in-dispatch-page' into 'master'
Resolve "Color code JOs in dispatch page"

Closes #674

See merge request jankstudio/resq!788
2022-06-01 11:11:07 +00:00
Korina Cordero
a7f52fc139 Merge branch 'master' of gitlab.com:jankstudio/resq into 674-color-code-jos-in-dispatch-page
Conflicts:
	src/Service/JobOrderHandler/ResqJobOrderHandler.php
2022-06-01 08:06:06 +00:00
79f2686404 Merge branch '675-set-rider-s-current-jo-id-to-null-if-jo-s-hub-is-reassigned-and-jo-has-been-rider-assigned' into 'master'
Resolve "Set rider's current jo id to null if JO's hub is reassigned and JO has been rider assigned"

Closes #675

See merge request jankstudio/resq!789
2022-06-01 08:04:07 +00:00
Korina Cordero
e2bdf91f1c Add checking for current job order that current jo is the selected jo. #675 2022-06-01 08:01:39 +00:00
Korina Cordero
c3ecf51468 Add checking for current job order. #675 2022-06-01 07:44:02 +00:00
Korina Cordero
e36523528d Merge branch 'master' of gitlab.com:jankstudio/resq into 675-set-rider-s-current-jo-id-to-null-if-jo-s-hub-is-reassigned-and-jo-has-been-rider-assigned 2022-06-01 07:32:04 +00:00
744e80a9e5 Merge branch '673-add-classification-of-caller-to-job-order' into 'master'
Resolve "Add classification of caller to job order"

Closes #673

See merge request jankstudio/resq!787
2022-06-01 07:29:10 +00:00
Korina Cordero
6098858332 Fix issue of rider assignment not working after hub reassignment. #675 2022-06-01 06:04:04 +00:00
Korina Cordero
174acddc91 Add default values. #673 2022-06-01 04:08:08 +00:00
ee65a75ec2 Merge branch '672-add-gender-of-caller-to-jo' into 'master'
Resolve "Add gender of caller to JO"

Closes #672

See merge request jankstudio/resq!786
2022-06-01 03:43:31 +00:00
Korina Cordero
a67ec1ec11 Fixed setting of colors for special JO rows. #674 2022-06-01 03:40:16 +00:00
Korina Cordero
fe0243a4cc Add color coding for JOs that are for VIP customers or emergencies. #673 2022-05-31 09:37:29 +00:00
Korina Cordero
4580228628 Add caller classification to job order. #673 2022-05-31 07:25:49 +00:00
Korina Cordero
da20713f0f Add gender to job order. #672 2022-05-31 06:33:19 +00:00
9ac0c1613d Merge branch '671-yokohama-add-new-field-initial-concern-of-the-customer' into 'master'
Resolve "YOKOHAMA : add new field Initial Concern of the Customer"

Closes #671

See merge request jankstudio/resq!785
2022-05-31 02:39:14 +00:00
Korina Cordero
70cbecb481 Add initial concern of customer and text area to job order. #671 2022-05-26 03:47:51 +00:00
3b23c7b913 Merge branch '670-refuel-service-charge-increase' into 'master'
Resolve "Refuel service charge increase"

Closes #670

See merge request jankstudio/resq!784
2022-05-25 15:24:32 +00:00
Korina Cordero
b56787e637 Adjust fuel prices. #670 2022-05-25 06:52:18 +00:00
Korina Cordero
ff1f5bc7c6 Commented out the debug logs. #668 2022-05-20 06:59:51 +00:00
cc41ac4290 Merge branch '654-script-to-fulflll-job-orders' into 'master'
Resolve "Script to fulflll job orders"

Closes #654

See merge request jankstudio/resq!782
2022-05-19 06:03:07 +00:00
Korina Cordero
ba87fe61c5 Set flag_activated to false. #654 2022-05-19 05:44:23 +00:00
Korina Cordero
941f59ab6e Change jo event creation. #654 2022-05-18 09:34:15 +00:00
Korina Cordero
c8208df0f3 Modify warranty creation to be done by load data infile. #654 2022-05-18 08:46:13 +00:00
Korina Cordero
31e2088b6a Add log for processing. #654 2022-05-18 05:55:46 +00:00
Korina Cordero
1778af3f9f Fix issue on batch updates and inserts. #654 2022-05-18 05:53:38 +00:00
Korina Cordero
a7d1bb6a90 Add batch insert for JO event. #654 2022-05-17 12:01:15 +00:00
Korina Cordero
fa02cd1a67 Merge branch 'master' of gitlab.com:jankstudio/resq into 654-script-to-fulflll-job-orders 2022-05-17 01:58:16 +00:00
b343d00dfc Merge branch '660-add-customer-and-customer-vehicle-in-warranty-upload' into 'master'
Add sap code to warranty creation when battery exists. #660

Closes #660

See merge request jankstudio/resq!781
2022-05-16 08:48:48 +00:00
Korina Cordero
232b962c2e Add sap code to warranty creation when battery exists. #660 2022-05-16 08:38:41 +00:00
41c25ed1f5 Merge branch '660-add-customer-and-customer-vehicle-in-warranty-upload' into 'master'
Resolve "Add customer and customer vehicle in warranty upload"

Closes #660

See merge request jankstudio/resq!780
2022-05-16 07:44:13 +00:00
Korina Cordero
4803152fb1 Add checking for sap battery in hash. #660 2022-05-16 06:16:23 +00:00
Korina Cordero
3f9fd88729 Add sap battery hash. #660 2022-05-13 10:44:34 +00:00
Korina Cordero
c099ffd5fd Optimize sql selects. #654 2022-05-13 09:24:20 +00:00
Korina Cordero
f89e8548a9 Add checking for sap code for warranty creation. #654 2022-05-13 07:22:10 +00:00
Korina Cordero
b0e743b6e7 Merge branch 'master' of gitlab.com:jankstudio/resq into 654-script-to-fulflll-job-orders 2022-05-13 05:32:57 +00:00
1c22b8b96f Merge branch '660-add-customer-and-customer-vehicle-in-warranty-upload' into 'master'
Remove checking of entries. #660

Closes #660

See merge request jankstudio/resq!779
2022-05-12 08:19:39 +00:00
Korina Cordero
938d6ff848 Rename field total. #660 2022-05-12 08:10:44 +00:00
Korina Cordero
4afa21f51e Add row number to output. Add checking for correct number of fields. #660 2022-05-12 08:06:36 +00:00
Korina Cordero
559a61bb13 Add checking for null rider ids. #654 2022-05-12 07:04:52 +00:00
Korina Cordero
9318b37077 Remove checking of entries. #660 2022-05-12 06:08:50 +00:00
Korina Cordero
0dda309a76 Add insert command for warranty creation. #654 2022-05-12 04:08:28 +00:00
Korina Cordero
d9de5cd519 Redo the command to fulfill all open job orders. #654 2022-05-11 10:08:41 +00:00
Korina Cordero
1a7d53ca01 Merge branch 'master' of gitlab.com:jankstudio/resq into 654-script-to-fulflll-job-orders 2022-05-11 03:04:42 +00:00
3a00a46b73 Merge branch '660-add-customer-and-customer-vehicle-in-warranty-upload' into 'master'
Resolve "Add customer and customer vehicle in warranty upload"

Closes #660

See merge request jankstudio/resq!773
2022-05-10 06:58:44 +00:00
Korina Cordero
8401eeb0da Move the bulk warranty upload to its own service. #660 2022-05-10 06:28:28 +00:00
Korina Cordero
e8670e4b60 Add index for serial. Add additional checks for serial in warranty. #660 2022-05-06 10:17:27 +00:00
Korina Cordero
86ef1ec646 Fix issues found during testing of bulk upload. #660 2022-05-06 09:03:22 +00:00
Korina Cordero
ecff27524a Create test command for bulk warranty upload optimization. #660 2022-05-05 11:27:35 +00:00
Korina Cordero
39be9e94ed Merge branch 'master' of gitlab.com:jankstudio/resq into 660-add-customer-and-customer-vehicle-in-warranty-upload 2022-05-04 09:26:50 +00:00
Korina Cordero
a9cb98912c Merge branch 'master' of gitlab.com:jankstudio/resq into 654-script-to-fulflll-job-orders 2022-05-04 09:02:18 +00:00
413d963348 Merge branch '663-update-refuel-charges' into 'master'
Resolve "Update refuel charges"

Closes #663

See merge request jankstudio/resq!777
2022-05-02 06:56:56 +00:00
Korina Cordero
5adbc79363 Merge branch 'master' of gitlab.com:jankstudio/resq into 663-update-refuel-charges 2022-05-02 06:40:09 +00:00
102f0962bf Merge branch '662-fuel-type-and-status-condition-of-customer-vehicle-not-saved-correctly-via-app' into 'master'
Resolve "Fuel type and status condition of customer vehicle not saved correctly via app"

Closes #662

See merge request jankstudio/resq!776
2022-05-02 06:39:26 +00:00
Korina Cordero
0ea329655f Rename function to normalizeString. #662 2022-05-02 06:22:17 +00:00
Korina Cordero
19d12d9264 Modify hardcoded refuel charges. #663 2022-05-02 06:20:30 +00:00
Korina Cordero
3e61bdb89c Fix typo for call to normalize text. #662 2022-05-02 06:14:53 +00:00
Korina Cordero
4fb28174c5 Normalize fuel type and status condition of vehicle when adding customer vehicle via app. #662 2022-05-02 02:45:38 +00:00
4c67d59b22 Merge branch '661-yokohama-add-source-of-awareness-dropdown-and-related-remarks-field-to-ticket-and-jo' into 'master'
Add Referral to source of awareness dropdown. #661

Closes #661

See merge request jankstudio/resq!775
2022-04-29 05:05:08 +00:00
Korina Cordero
e44d8d3b06 Add Referral to source of awareness dropdown. #661 2022-04-29 05:03:17 +00:00
ca4c59f59e Merge branch '661-yokohama-add-source-of-awareness-dropdown-and-related-remarks-field-to-ticket-and-jo' into 'master'
Resolve "YOKOHAMA: Add Source of Awareness dropdown and related Remarks field to ticket and JO"

Closes #661

See merge request jankstudio/resq!774
2022-04-29 00:33:43 +00:00
Korina Cordero
ebaef97333 Add Source of Awareness and Remarks to job order form. #661 2022-04-27 06:45:54 +00:00
Korina Cordero
bbea317cf1 Add Source of Awareness and Remarks to Ticket and ticket form. #661 2022-04-27 05:56:15 +00:00
Korina Cordero
0dee028045 Find customer and customer vehicle before warranty creation for warranty upload. #660 2022-04-25 08:42:43 +00:00
4a93a2d482 Merge branch '659-post-cert-renewal-script' into 'master'
Resolve "Post cert renewal script"

Closes #659

See merge request jankstudio/resq!772
2022-04-22 09:25:20 +00:00
Korina Cordero
4d07f350bb Add comments on how to install the script. #695 2022-04-22 09:24:39 +00:00
Korina Cordero
cea8df1a2c Add script to copy the new certificates to vernemq folder and restart the needed services 2022-04-22 08:26:13 +00:00
19a757f48d Merge branch '658-check-numbers-sent-to-rising-tide' into 'master'
Fix bugs found when testing with app. #658

Closes #658

See merge request jankstudio/resq!771
2022-04-12 11:03:24 +00:00
Korina Cordero
dad3caecf3 Fix bugs found when testing with app. #658 2022-04-12 11:00:43 +00:00
2caa286f12 Merge branch '658-check-numbers-sent-to-rising-tide' into 'master'
Resolve "Check numbers sent to Rising Tide"

Closes #658

See merge request jankstudio/resq!770
2022-04-12 10:08:48 +00:00
Korina Cordero
9bc1f44ca2 Clean up code. #658 2022-04-12 10:08:13 +00:00
Korina Cordero
b712b35a97 Fix checking for return. #658 2022-04-12 10:01:14 +00:00
Korina Cordero
6fff162c0e Improve error message and return value. #658 2022-04-12 09:59:35 +00:00
Korina Cordero
a6add363bd Refine the cleaning of mobile number. #658 2022-04-12 09:53:01 +00:00
Korina Cordero
466d6c124f Prepend country code to mobile numbers for SMS messaging. #658 2022-04-12 09:30:00 +00:00
ab2ca02227 Merge branch '655-import-yokohama-vehicle-battery-compatibility' into 'master'
Modify script to create vehicle if vehicle does not exist. Modify length of make in Vehicle. #655

Closes #655

See merge request jankstudio/resq!769
2022-04-11 03:06:51 +00:00
Korina Cordero
688b890fd7 Modify script to create vehicle if vehicle does not exist. Modify length of make in Vehicle. #655 2022-04-11 03:04:43 +00:00
d0d26e01e4 Merge branch '655-import-yokohama-vehicle-battery-compatibility' into 'master'
Resolve "Import Yokohama vehicle battery compatibility"

Closes #655

See merge request jankstudio/resq!767
2022-04-08 12:23:03 +00:00
Korina Cordero
bc1c6110e8 Fix issues found during testing. #655 2022-04-08 09:06:55 +00:00
7433fd5153 Merge branch '656-add-motiv-inventory-to-initializehubform' into 'master'
Resolve "Add motiv inventory to initializeHubForm"

Closes #656

See merge request jankstudio/resq!768
2022-04-07 10:32:42 +00:00
Korina Cordero
928257ccdc Add motiv call to initializeOpenHubForm. #656 2022-04-07 09:58:17 +00:00
Korina Cordero
a50d591160 Redo warranty flow. #654 2022-04-07 09:32:23 +00:00
Korina Cordero
6cc9cddf1f Add command to import vehicle battery compatibility for Yokohama. #655 2022-04-06 11:01:27 +00:00
Korina Cordero
b831deacfb Add fixes. 2022-04-06 03:09:46 +00:00
Korina Cordero
789c919179 Redo command to include open job orders. 2022-04-05 10:30:49 +00:00
9b50efc9d0 Merge branch '654-script-to-fulflll-job-orders' into 'master'
Resolve "Script to fulflll job orders"

Closes #654

See merge request jankstudio/resq!766
2022-04-01 10:38:29 +00:00
Korina Cordero
4e1613540d Add date argument to command. #654 2022-03-31 06:45:40 +00:00
Korina Cordero
618769ab5d Remove clearing of entitymanager. #654 2022-03-31 02:10:10 +00:00
Korina Cordero
3315565000 Create command to fulfill assigned job orders. #654 2022-03-30 10:56:09 +00:00
b4f28a3b17 Merge branch '652-make-command-to-test-getclosestopenhubs' into 'master'
Resolve "Make command to test getClosestOpenHubs"

Closes #652

See merge request jankstudio/resq!764
2022-03-24 08:20:52 +00:00
Korina Cordero
3e238347be Add hub output with distance. #652 2022-03-24 08:19:44 +00:00
f9647f3337 Merge branch '653-modify-message-when-no-hubs-are-found' into 'master'
Resolve "Modify message when no hubs are found"

Closes #653

See merge request jankstudio/resq!765
2022-03-24 08:10:57 +00:00
Korina Cordero
c8629692e9 Change message when no hubs are found. Add checking for null if no hubs are found. #653 2022-03-24 07:44:03 +00:00
Korina Cordero
85be728bf6 Create command to test getClosestOpenHubs. #652 2022-03-24 07:32:06 +00:00
b7159c127c Merge branch '651-fix-nearest-hub-issue' into 'master'
Resolve "Fix nearest hub issue"

Closes #651

See merge request jankstudio/resq!763
2022-03-24 06:35:40 +00:00
Korina Cordero
73f0e69b9a Fix issues found while testing. #651 2022-03-24 05:50:02 +00:00
Korina Cordero
e80ce9db66 Fix issues found while testing. #651 2022-03-24 05:38:18 +00:00
Korina Cordero
457bbece2b Fix issues found while testing. #651 2022-03-24 05:28:15 +00:00
Korina Cordero
b7c5f5dafe Add checking for hub slots. #651 2022-03-24 05:07:26 +00:00
Korina Cordero
d8f5b7833d Add flag for unavailable slots. #651 2022-03-23 09:48:37 +00:00
b16e58cf35 Merge branch '650-improve-performance-for-capi-call-for-vehicles' into 'master'
Resolve "Improve performance for capi call for vehicles"

Closes #650

See merge request jankstudio/resq!762
2022-03-15 09:07:06 +00:00
Korina Cordero
8c685536d3 Change query for vehicle manufacturers and vehicles to use raw sql. #650 2022-03-15 09:01:53 +00:00
1d627025eb Merge branch '649-move-hardcoded-text-into-translations-file' into 'master'
Resolve "Move hardcoded text into translations file"

Closes #649

See merge request jankstudio/resq!761
2022-03-15 07:59:25 +00:00
Korina Cordero
a5a30ec7f9 Change hardcoded messages into entries in messages file. #649 2022-03-15 07:51:58 +00:00
Korina Cordero
ae477ea440 Move hardcoded labels to messages file. #649 2022-03-15 06:37:22 +00:00
5686923a04 Merge branch '647-update-fuel-prices' into 'master'
Resolve "Update fuel prices"

Closes #647

See merge request jankstudio/resq!759
2022-03-09 08:57:13 +00:00
Korina Cordero
4765c34be8 Update fuel prices for gas and diesel. #647 2022-03-09 03:44:16 +00:00
e986d07f70 Merge branch '644-fix-app-warranty-api' into 'master'
Add QR prefix removal to app api for warranty #644

Closes #644

See merge request jankstudio/resq!756
2022-02-02 14:32:32 +00:00
5b36e0d8d7 Add QR prefix removal to app api for warranty #644 2022-02-02 22:27:58 +08:00
c9fe5ffce5 Merge branch '643-have-capi-call-for-warranty-get-remove-qr-prefix-from-serial' into 'master'
Resolve "Have CAPI call for warranty get remove 'QR' prefix from serial"

Closes #643

See merge request jankstudio/resq!755
2022-01-20 17:04:13 +00:00
b1150d6c93 Add clean serial functionality for QR prefix in CAPI customer warranty #643 2022-01-21 01:02:55 +08:00
aa529e7411 Merge branch '641-create-capi-call-to-verify-if-resq-user' into 'master-fix'
Resolve "Create capi call to verify if resq user"

See merge request jankstudio/resq!753
2021-12-03 05:57:12 +00:00
a5f5ac861d Merge branch '640-new-rider-api-call-to-return-customer-hash' into 'master-fix'
Resolve "New rider api call to return customer hash"

See merge request jankstudio/resq!752
2021-12-03 05:56:57 +00:00
255395bb38 Merge branch '632-resq-1-5-changes' into 'master-fix'
Resolve "Resq 1.5 changes"

See merge request jankstudio/resq!745
2021-12-03 05:54:22 +00:00
Korina Cordero
8c057c216e Add mobile number to response. #641 2021-11-25 02:28:49 +00:00
Korina Cordero
5c03ccb1fb Add checking in hash service for invalid hashes. Add capi call to verify if hash belongs to customer. #641 2021-11-24 08:23:48 +00:00
Korina Cordero
b0de01ae1b Add get customer hash to api. #640 2021-11-23 05:29:51 +00:00
Korina Cordero
2e428378c6 Merge branch '632-resq-1-5-changes' of gitlab.com:jankstudio/resq into 640-new-rider-api-call-to-return-customer-hash 2021-11-23 03:12:00 +00:00
Korina Cordero
3dd2bf5de4 Remove modifications. #640 2021-11-23 03:02:03 +00:00
Korina Cordero
9c73a18b2e Add customer information to latest job order. #632 2021-11-23 02:50:49 +00:00
Korina Cordero
680a12e52a Add call to get customer hash. #640 2021-11-23 02:48:24 +00:00
Korina Cordero
0e5824af29 Add the hash generator and command to test hash generator. #640 2021-11-23 02:10:31 +00:00
Korina Cordero
ca21fcd5c9 Add landmark to response for latest jo. #632 2021-11-22 10:13:24 +00:00
Korina Cordero
1030b1934e Fix the response when no latest jo. #632 2021-11-22 08:10:12 +00:00
Korina Cordero
65c0ad1c56 Add call to get latest job order. #632 2021-11-22 06:02:50 +00:00
Korina Cordero
280a7c9c8f Fix issue found during testing. #632 2021-11-18 07:06:29 +00:00
Korina Cordero
c108647222 Add comment to response for getJOHistory. #632 2021-11-18 06:49:00 +00:00
ee07c9cc84 Fix decline in rider api to always return true, so rider app can get out of decline / accept screen 2021-11-08 18:45:36 +08:00
cc12e150f4 Merge branch '630-rider-app-timeout' into 'master-fix'
Resolve "Rider app timeout"

See merge request jankstudio/resq!743
2021-11-08 10:09:01 +00:00
11c323f39a Merge branch '637-set-up-24-7-ordering-using-app' into 'master-fix'
Resolve "Set up 24/7 ordering using app"

See merge request jankstudio/resq!750
2021-11-08 10:08:10 +00:00
Korina Cordero
09405d16ce Add setting of date_assign when JO is auto assigned. Add sql script to update date_assign of JOs. #630 2021-11-08 08:23:38 +00:00
Korina Cordero
05d50e28f7 Comment out debug log. #630 2021-11-08 07:45:31 +00:00
Korina Cordero
a7d6f20cc4 Commented out time check for schedule options. #637 2021-11-08 07:17:24 +00:00
Korina Cordero
f9de11ccb5 Fix the command to update unaccepted job orders. Add more checking before updating rider's availability. #630 2021-11-08 05:36:59 +00:00
Korina Cordero
8d5b67b020 Fix setting of landmark if no landmark is received. #632 2021-11-03 07:18:57 +00:00
Korina Cordero
12c85e5cbb Fix issue when fulfiling a JO in admin panel. #632 2021-11-03 07:02:26 +00:00
Korina Cordero
4ce09e9671 Change return response for locationSupport. #632 2021-11-03 06:27:36 +00:00
Korina Cordero
acf5d964cf Merge branch '636-fix-timing-of-vat-computation' of gitlab.com:jankstudio/resq into 632-resq-1-5-changes 2021-11-02 04:54:28 +00:00
4d66345ae3 Merge branch '636-fix-timing-of-vat-computation' into 'master-fix'
Revert VAT tax computation. #636

See merge request jankstudio/resq!749
2021-11-02 04:52:50 +00:00
Korina Cordero
0dce53beaa Revert VAT tax computation. #636 2021-11-02 04:46:30 +00:00
Korina Cordero
5c61e5ebea Add saving of landmark, if provided. #632 2021-10-29 08:24:42 +00:00
Korina Cordero
4a1ae91b78 Comment out call for completed job orders. Modify getJOHistory to only retrieve cancelled and fulfilled job orders. #632 2021-10-29 06:07:34 +00:00
Korina Cordero
918c06725e Add call to get completed job orders. #632 2021-10-29 05:51:12 +00:00
Korina Cordero
1f6162cb47 Fix sorting for ongoing job orders. #632 2021-10-28 09:43:07 +00:00
Korina Cordero
1d93c63da7 Add null checking for jo rating even if flag for rider rating is true. #632 2021-10-28 08:39:12 +00:00
Korina Cordero
8ebb123064 Add average rating for partners in response for closest partners. #632 2021-10-28 07:19:32 +00:00
Korina Cordero
158d05d822 Add rating and rider rating to JO history response. Fix associations between rider rating and customer, job order, and rider. #632 2021-10-28 06:31:27 +00:00
Korina Cordero
16c944899f Add rider rating for jo in job order history. #632 2021-10-28 03:05:05 +00:00
Korina Cordero
f7def95cdd Merge branch 'master-fix' of gitlab.com:jankstudio/resq into 632-resq-1-5-changes 2021-10-28 02:23:00 +00:00
07f7457937 Merge branch '636-fix-timing-of-vat-computation' into 'master-fix'
Fix response for vat ex price . #636

See merge request jankstudio/resq!748
2021-10-28 02:12:23 +00:00
Korina Cordero
b14007e276 Fix response for vat ex price . #636 2021-10-28 02:10:59 +00:00
Korina Cordero
7001d6a0ed Fix get locations response. #632 2021-10-27 09:39:28 +00:00
Korina Cordero
84844046f1 Add limit to number of locations to be stored. #632 2021-10-27 08:26:19 +00:00
Korina Cordero
c54ee5d7d8 Add landmark to location details. #632 2021-10-27 07:50:02 +00:00
Korina Cordero
e4e412fd14 Fix response to get locations. #632 2021-10-27 07:27:15 +00:00
Korina Cordero
3f7075f26d Merge branch 'master-fix' of gitlab.com:jankstudio/resq into 632-resq-1-5-changes 2021-10-27 07:15:13 +00:00
Korina Cordero
48aaeddadd Add call to remove a vehicle from customer's list of vehicles. #632 2021-10-27 06:35:40 +00:00
Korina Cordero
ca3fbc21c8 Add route for customer vehicle removal. Add call to get locations. #632 2021-10-27 02:54:34 +00:00
Korina Cordero
61b897d883 Add call to add location for customer. #632 2021-10-26 09:18:13 +00:00
Korina Cordero
a8eaad2a82 Add call to get ongoing job order count. #632 2021-10-26 07:49:45 +00:00
Korina Cordero
9c31a573c6 Add checking if hub_id is -1. Add call to get all ongoing job orders. #632 2021-10-26 07:26:11 +00:00
764c9e690c Merge branch '636-fix-timing-of-vat-computation' into 'master-fix'
Resolve "Fix timing of vat computation"

See merge request jankstudio/resq!747
2021-10-26 05:20:02 +00:00
Korina Cordero
0fe66f4719 Fix display of VAT. #636 2021-10-25 08:50:15 +00:00
Korina Cordero
44611915e5 Fix VAT computation when trade ins and discounts are present. #636 2021-10-25 08:37:19 +00:00
97070ded9a Merge branch '633-refuel-fee-changes' into 'master-fix'
Resolve "Refuel fee changes"

See merge request jankstudio/resq!746
2021-10-22 10:44:01 +00:00
Korina Cordero
50c67d7088 Modify the fuel charges for gas and diesel. #633 2021-10-22 10:19:37 +00:00
Korina Cordero
9f5493c125 Remove debug logs. Update rider's current job order when JO is requeued. #630 2021-10-22 06:59:55 +00:00
Korina Cordero
6fe63050c6 Merge branch 'master-fix' of gitlab.com:jankstudio/resq into 630-rider-app-timeout 2021-10-22 06:29:12 +00:00
Korina Cordero
b9fdcbbbbb Sort the job orders for job order history from latest to oldest. #632 2021-10-22 05:49:05 +00:00
1f067dd2ef Merge branch '631-change-dealer-information-for-selected-warranties' into 'master-fix'
Resolve "Change dealer information for selected warranties"

See merge request jankstudio/resq!744
2021-10-21 04:10:31 +00:00
Korina Cordero
46ea41f034 Add command to update dealer information for warranties. #631 2021-10-21 03:21:09 +00:00
Korina Cordero
e9fa25dada Fix sending of rider event when JO is requeued. #630 2021-10-20 06:45:12 +00:00
Korina Cordero
c955516acf Fix testing issues found. #630 2021-10-20 06:28:31 +00:00
Korina Cordero
f8ebe0d97a Set rider's availability after JOs are requeued. #630 2021-10-20 06:19:59 +00:00
Korina Cordero
9b7852d248 Remove rider id from command. #630 2021-10-20 05:42:05 +00:00
Korina Cordero
d366106381 Add sending of mqtt events. #630 2021-10-20 05:34:43 +00:00
Korina Cordero
c2066b86c9 Add retrieval of job orders to be updated. #630 2021-10-19 09:19:27 +00:00
Korina Cordero
0065bc94ef Add index for status for job order. Add command to update the status and rider for unaccepted job orders. #630 2021-10-19 06:41:53 +00:00
94f2cc75a7 Merge branch '628-sort-the-compatible-batteries-by-price-descending' into 'master-fix'
Resolve "Sort the compatible batteries by price descending"

See merge request jankstudio/resq!741
2021-10-12 08:06:11 +00:00
Korina Cordero
d750c6b8ba Add sorting to Vehicle's getBatteries. #628 2021-10-12 07:53:17 +00:00
8056cb6d29 Merge branch '626-improve-loading-for-jo-for-dispatch' into 'master-fix'
Resolve "Improve loading for JO for Dispatch"

See merge request jankstudio/resq!740
2021-10-08 12:36:07 +00:00
Korina Cordero
840cbe2463 Fix setting of hub jo count. #626 2021-10-08 12:34:55 +00:00
Korina Cordero
e6d3043556 Set hub jo count to redis jo count. #626 2021-10-08 12:21:57 +00:00
Korina Cordero
fe15385613 Use the redis job order count to display number of assigned job orders to hub. #626 2021-10-08 12:09:46 +00:00
38ce447b0a Merge branch '625-new-rider-cannot-log-in-to-app' into 'master-fix'
Resolve "New rider cannot log in to app"

See merge request jankstudio/resq!739
2021-10-06 04:14:23 +00:00
Korina Cordero
c6654bd3c6 Add creation of rider api user when rider is created. #625 2021-10-06 03:52:37 +00:00
697fa20071 Merge branch '624-app-error-when-customer-requests-tire-assistance' into 'master-fix'
Resolve "App error when customer requests tire assistance"

See merge request jankstudio/resq!738
2021-09-29 07:03:50 +00:00
Korina Cordero
21cf667b47 Add check for battery. #624 2021-09-29 06:44:04 +00:00
1db04374ec Merge branch '622-arrive-button-does-not-show-up-when-jo-is-auto-assigned' into 'master-fix'
Resolve "Arrive button does not show up when JO is auto assigned"

See merge request jankstudio/resq!736
2021-09-09 10:53:22 +00:00
Korina Cordero
f43d2f10fe Change QoS level to 1 when publishing messages. #622 2021-09-09 10:42:31 +00:00
0ababa77c2 Merge branch '621-check-for-null-current-job-order-when-re-assigning-rider-to-jo' into 'master-fix'
Resolve "Check for null current job order when re-assigning rider to JO"

See merge request jankstudio/resq!735
2021-09-09 03:52:47 +00:00
Korina Cordero
8dd06b2d5e Add null check for previous rider when re-assigning rider. #621 2021-09-09 03:40:53 +00:00
8ef2617f87 Merge branch '620-add-new-shift-to-rider-optimization' into 'master-fix'
Add new hour shifts to script. #620

See merge request jankstudio/resq!734
2021-09-08 03:06:40 +00:00
Korina Cordero
89370b4bd0 Add new hour shifts to script. #620 2021-09-08 03:04:31 +00:00
4ea21f7004 Merge branch '620-add-new-shift-to-rider-optimization' into 'master-fix'
Resolve "Add new shift to rider optimization"

See merge request jankstudio/resq!733
2021-09-08 02:23:13 +00:00
Korina Cordero
e820051d0e Add 6 AM-10 PM and 6AM - 12 AM shifts. #620 2021-09-02 09:19:10 +00:00
Korina Cordero
93d4282257 Add 6 AM-7 PM shift schedule. #620 2021-09-01 09:04:31 +00:00
326 changed files with 39681 additions and 3743 deletions

3
.gitignore vendored
View file

@ -12,3 +12,6 @@
*.swp
/public/warranty_uploads/*
.vscode
*__pycache__
/public/assets/images/insurance-premiums.png

View file

@ -1,9 +0,0 @@
<?php
namespace Catalyst\APIBundle\Access;
use Catalyst\AuthBundle\Service\ACLGenerator as BaseGenerator;
class Generator extends BaseGenerator
{
}

View file

@ -1,10 +0,0 @@
<?php
namespace Catalyst\APIBundle\Access;
use Catalyst\AuthBundle\Service\ACLVoter as BaseVoter;
class Voter extends BaseVoter
{
}

View file

@ -1,9 +0,0 @@
<?php
namespace Catalyst\APIBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class CatalystAPIBundle extends Bundle
{
}

View file

@ -1,155 +0,0 @@
<?php
namespace Catalyst\APIBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Catalyst\APIBundle\Connector\Client as APIClient;
class TestAPICommand extends Command
{
protected function configure()
{
$this->setName('api:test-connector-all')
->setDescription('Test API connector with all commands.')
->setHelp('Test API Connector with all commands.')
->addArgument('protocol', InputArgument::REQUIRED, 'protocol')
->addArgument('server', InputArgument::REQUIRED, 'server')
->addArgument('api_key', InputArgument::REQUIRED, 'api_key')
->addArgument('secret_key', InputArgument::REQUIRED, 'secret_key');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$protocol = $input->getArgument('protocol');
$server = $input->getArgument('server');
$api_key = $input->getArgument('api_key');
$secret_key = $input->getArgument('secret_key');
// api client
$api = new APIClient($server, $api_key, $secret_key);
$api->setProtocol($protocol);
// test
$api->get('/capi/test');
// TODO: shift this out of the bundle, since it's project specific
// warranty register
$serial = 'AJ34LJADR12134LKJL5';
$plate_num = 'XEN918';
$params = [
'serial' => $serial,
'plate_number' => $plate_num,
'warranty_class' => 'private',
'sku' => 'WMEB24CB-CPN00-LX',
'date_purchase' => '20181001',
'date_expire' => '20191001',
'first_name' => 'First',
'last_name' => 'Last',
'mobile_number' => '09231234567',
];
//$api->post('/capi/warranties', $params);
// get all warranties
$params = [
'order' => 'DESC',
'limit' => '5',
'start' => '1',
];
//$api->get('/capi/warranties', $params);
// warranty find
//$api->get('/capi/warranties/' . $serial);
// warranty update
$id = 86811;
$params = [
'serial' => $serial,
'plate_number' => $plate_num,
'warranty_class' => 'private',
'sku' => 'WMEB24CB-CPN00-LX',
'date_purchase' => '20181001',
'date_expire' => '20191001',
'first_name' => 'First',
'last_name' => 'Last',
'mobile_number' => '123456789111',
];
//$api->post('/capi/warranties/'. $id, $params);
// warranty set privacy policy
$id = 86811;
$policy_id = 2;
$params = [
'privacy_policy_id' => $policy_id,
];
//$api->post('/capi/warranties/' . $id .'/privacypolicy', $params);
// warranty claim
$id = 86811;
$serial = 'AJ34LJADR12134LKJL5';
$params = [
'serial' => $serial,
];
//$api->post('/capi/warranties/' . $id . '/claim', $params);
// warranty cancel
$id = 86811;
//$api->get('/capi/warranties/' . $id . '/cancel');
// plate warranty
//$api->get('/capi/plates/' . $plate_num . '/warranties');
// warranty delete
$id = 86811;
//$api->post('/capi/warranties/' . $id . '/delete');
// battery
//$api->get('/capi/battery_brands');
//$api->get('/capi/battery_sizes');
//$api->get('/capi/batteries');
// vehicle
//$api->get('/capi/vehicle_manufacturers');
//$api->get('/capi/vehicles');
// privacy policy
$privacy_policy_id = 2;
//$api->get('/capi/privacy_policy/' . $privacy_policy_id );
// register new customer
$params = [
'first_name' => 'Krispups',
'last_name' =>'Porzindog',
'mobile_number' => '9221111111',
'v_make_id' => '22241',
'v_model_year' => '2018',
'v_plate_number' => 'KPP1234',
'v_color' => 'White',
'v_condition' => 'new',
'v_fuel_type' => 'gas',
];
//$api->post('/capi/quick_registration', $params);
// get warranties given list of serial numbers
$serial_list = [
'AJ34LJADR12134LKJM4',
'AJ34LJADR12134LKJL5',
'test',
];
$params = [
'serial_list' => $serial_list,
];
$api->post('/capi/warranties_list', $params);
}
}

View file

@ -1,104 +0,0 @@
<?php
namespace Catalyst\APIBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Catalyst\APIBundle\Connector\Client as APIClient;
class TestCommand extends Command
{
protected function configure()
{
$this->setName('api:test-connector')
->setDescription('Test API connector.')
->setHelp('Test API Connector.')
->addArgument('protocol', InputArgument::REQUIRED, 'protocol')
->addArgument('server', InputArgument::REQUIRED, 'server')
->addArgument('api_key', InputArgument::REQUIRED, 'api_key')
->addArgument('secret_key', InputArgument::REQUIRED, 'secret_key');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$protocol = $input->getArgument('protocol');
$server = $input->getArgument('server');
$api_key = $input->getArgument('api_key');
$secret_key = $input->getArgument('secret_key');
// api client
$api = new APIClient($server, $api_key, $secret_key);
$api->setProtocol($protocol);
// test
$api->get('/capi/test');
// TODO: shift this out of the bundle, since it's project specific
// warranty register
$serial = 'AJ34LJADR12134LKJL5';
$plate_num = 'XEN918';
$params = [
'serial' => $serial,
'plate_number' => $plate_num,
'warranty_class' => 'private',
'sku' => 'WMEB24CB-CPN00-LX',
'date_purchase' => '20181001',
'date_expire' => '20191001',
'first_name' => 'First',
'last_name' => 'Last',
'mobile_number' => '12345678910',
];
$api->post('/capi/warranties', $params);
// get all warranties
$api->get('/capi/warranties');
/*
// warranty find
$api->get('/capi/warranties/' . $serial);
*/
// warranty claim
$id = 86811;
$serial = 'AJ34LJADR12134LKJL';
$params = [
'serial' => $serial,
];
$api->post('/capi/warranties/' . $id . '/claim', $params);
// add battery
$sku = 'WZMB31QT-CPP00-S';
$brand_id = '4';
$size_id = '1';
$params = [
'sku' => $sku,
'brand_id' => $brand_id,
'size_id' => $size_id,
];
$api->post('/capi/batteries', $params);
/*
// plate warranty
$api->get('/capi/plates/' . $plate_num . '/warranties');
// battery
$api->get('/capi/battery_brands');
$api->get('/capi/battery_sizes');
$api->get('/capi/batteries');
// vehicle
// $api->get('/capi/vehicle_manufacturers');
// $api->get('/capi/vehicles');
*/
}
}

View file

@ -1,49 +0,0 @@
<?php
namespace Catalyst\APIBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Entity\User;
class UserCreateCommand extends Command
{
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
parent::__construct();
}
protected function configure()
{
$this->setName('api:user-create')
->setDescription('Create new API user.')
->setHelp('Creates new API user and saves to database.')
->addArgument('name', InputArgument::REQUIRED, 'name');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$name = $input->getArgument('name');
$user = new User();
$user->setName($name);
$this->em->persist($user);
$this->em->flush();
$output->write('API Key - ' . $user->getAPIKey() . "\n");
$output->write('Secret Key - ' . $user->getSecretKey() . "\n");
}
}

View file

@ -1,151 +0,0 @@
<?php
namespace Catalyst\APIBundle\Connector;
use DateTime;
class Client
{
const HEADER_API_KEY = 'X-Cata-API-Key';
const HEADER_SIGNATURE = 'X-Cata-Signature';
const HEADER_DATE = 'X-Cata-Date';
const DATE_FORMAT = 'D, d M Y H:i:s T';
const USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36';
protected $protocol;
protected $server;
protected $port;
protected $api_key;
protected $secret_key;
protected $curl;
public function __construct($server, $api_key, $secret_key)
{
$this->protocol = 'https';
$this->port = null;
$this->server = $server;
$this->api_key = $api_key;
$this->secret_key = $secret_key;
$this->curl = curl_init();
}
public function __destruct()
{
curl_close($this->curl);
}
public function setProtocol($protocol)
{
if ($protocol != 'http' && $protocol != 'https')
return $this;
$this->protocol = $protocol;
return $this;
}
protected function getDateString()
{
$date = new DateTime();
return $date->format(self::DATE_FORMAT);
}
public function get($url, $params = [])
{
curl_reset($this->curl);
$date_string = $this->getDateString();
$headers = $this->generateHeaders('GET', $url, $date_string);
// build query string
if (count($params) > 0)
$query_string = '?' . http_build_query($params);
else
$query_string = '';
// build url
if ($this->port == null)
$full_url = $this->protocol . '://' . $this->server . $url . $query_string;
else
$full_url = $this->protocol . '://' . $this->server . ':' . $this->port . $url . $query_string;
error_log($full_url);
// curl
// curl_setopt($this->curl, CURLOPT_VERBOSE, true);
curl_setopt($this->curl, CURLOPT_URL, $full_url);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($this->curl, CURLOPT_USERAGENT, self::USER_AGENT);
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->curl, CURLOPT_TIMEOUT, 0);
$res = curl_exec($this->curl);
error_log($res);
}
public function post($url, $params = [])
{
curl_reset($this->curl);
$date_string = $this->getDateString();
$headers = $this->generateHeaders('POST', $url, $date_string);
// build query string
$query_string = http_build_query($params);
// build url
if ($this->port == null)
$full_url = $this->protocol . '://' . $this->server . $url;
else
$full_url = $this->protocol . '://' . $this->server . ':' . $this->port . $url;
error_log($full_url);
// curl
// curl_setopt($this->curl, CURLOPT_VERBOSE, true);
curl_setopt($this->curl, CURLOPT_URL, $full_url);
curl_setopt($this->curl, CURLOPT_POST, true);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $query_string);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($this->curl, CURLOPT_USERAGENT, self::USER_AGENT);
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->curl, CURLOPT_TIMEOUT, 0);
$res = curl_exec($this->curl);
error_log($res);
}
protected function generateSignature($method, $url, $date_string)
{
$creds = [
$method,
$url,
$date_string,
$this->secret_key,
];
$sig_source = implode('|', $creds);
error_log('SIG SOURCE - ' . $sig_source);
$raw_sig = hash_hmac('sha1', $sig_source, $this->secret_key, true);
$enc_sig = base64_encode($raw_sig);
return $enc_sig;
}
protected function generateHeaders($method, $url, $date_string)
{
$sig = $this->generateSignature($method, $url, $date_string);
$headers = [
self::HEADER_API_KEY . ': ' . $this->api_key,
self::HEADER_SIGNATURE . ': ' . $sig,
self::HEADER_DATE . ': ' . $date_string,
];
return $headers;
}
}

View file

@ -1,42 +0,0 @@
<?php
namespace Catalyst\APIBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
abstract class APIController extends Controller
{
protected function checkRequiredParameters(Request $req, $params = [])
{
$missing = [];
// check if parameters are there
foreach ($params as $param)
{
if ($req->getMethod() == 'GET')
{
$check = $req->query->get($param);
if (empty($check))
$missing[] = $param;
}
// else if ($req->getMethod() == 'POST')
else
{
$check = $req->request->get($param);
//if (empty($check))
if (!isset($check))
$missing[] = $param;
}
}
// check missing parameters
if (count($missing) > 0)
{
$miss_string = implode(', ', $missing);
return 'Missing required parameter(s): ' . $miss_string;
}
return false;
}
}

View file

@ -1,20 +0,0 @@
<?php
namespace Catalyst\APIBundle\DataFixtures;
use Catalyst\APIBundle\Entity\Role;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
class APIRoleFixtures extends Fixture
{
public function load(ObjectManager $em)
{
// setup super user account
$role = new Role();
$role->setID(Role::SUPER_ADMIN)
->setName('Super Administrator');
$em->persist($role);
$em->flush();
}
}

View file

@ -1,28 +0,0 @@
<?php
namespace Catalyst\APIBundle\Entity;
use Catalyst\AuthBundle\Entity\Role as BaseRole;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity
* @ORM\Table(name="api_role")
* @UniqueEntity("id")
* @UniqueEntity("name")
*/
class Role extends BaseRole
{
/**
* @ORM\ManyToMany(targetEntity="User", mappedBy="roles", fetch="EXTRA_LAZY")
*/
protected $users;
public function __construct()
{
parent::__construct();
}
}

View file

@ -1,186 +0,0 @@
<?php
namespace Catalyst\APIBundle\Entity;
use Catalyst\AuthBundle\Entity\User as BaseUser;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\Common\Collections\ArrayCollection;
use DateTime;
/**
* @ORM\Entity
* @ORM\Table(name="api_user")
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// api key
/**
* @ORM\Column(type="string", length=32)
*/
protected $api_key;
// secret key
/**
* @ORM\Column(type="string", length=32)
*/
protected $secret_key;
/**
* @ORM\Column(type="string", length=80)
*/
protected $name;
// date created
/**
* @ORM\Column(type="datetime")
*/
protected $date_create;
// roles
/**
* @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
* @ORM\JoinTable(name="api_user_role")
*/
protected $roles;
// rider linked to user
// NOTE: we're directly linking this only because we don't have to care about other apps using this library
/**
* @ORM\OneToOne(targetEntity="App\Entity\Rider", mappedBy="api_user")
*/
protected $rider;
/**
* @ORM\Column(type="json")
*/
protected $metadata;
public function __construct()
{
parent::__construct();
// generate keys
$this->setAPIKey($this->generateAPIKey())
->setSecretKey($this->generateSecretKey());
// set date created
$this->date_create = new DateTime();
$this->metadata = [];
}
public function getID()
{
return $this->id;
}
public function setAPIKey($api_key)
{
$this->api_key = $api_key;
return $this;
}
public function getAPIKey()
{
return $this->api_key;
}
public function setSecretKey($key)
{
$this->secret_key = $key;
return $this;
}
public function getSecretKey()
{
return $this->secret_key;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
public function getDateCreate()
{
return $this->date_create;
}
public function getPassword()
{
// we don't need this for API
return 'notneeded';
}
public function getSalt()
{
return null;
}
public function getUsername()
{
// since it's an api, the api key IS the username
return $this->api_key;
}
public function eraseCredentials()
{
return;
}
public function generateAPIKey()
{
return $this->generateKey('api');
}
public function generateSecretKey()
{
return $this->generateKey('secret');
}
public function setMetadata($meta)
{
$this->metadata = $meta;
return $this;
}
public function getMetadata()
{
if ($this->metadata == null)
return [];
return $this->metadata;
}
protected function generateKey($prefix = '')
{
return md5(uniqid($prefix, true));
}
public function setRider($rider)
{
$this->rider = $rider;
return $this;
}
public function getRider()
{
return $this->rider;
}
}

View file

@ -1,20 +0,0 @@
<?php
namespace Catalyst\APIBundle\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
class APIResponse extends JsonResponse
{
public function __construct($success = true, $message = '', $data = null, $status = 200, $headers = [])
{
$data = [
'success' => (bool) $success,
'message' => (string) $message,
'data' => $data,
];
parent::__construct($data, $status, $headers);
}
}

View file

@ -1,160 +0,0 @@
<?php
namespace Catalyst\APIBundle\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Doctrine\ORM\EntityManagerInterface;
use DateTime;
class APIKeyAuthenticator implements SimplePreAuthenticatorInterface, AuthenticationFailureHandlerInterface
{
const HEADER_API_KEY = 'X-Cata-API-Key';
const HEADER_SIGNATURE = 'X-Cata-Signature';
const HEADER_DATE = 'X-Cata-Date';
const DATE_FORMAT = 'D, d M Y H:i:s T';
// 30 minute time limit
const TIME_LIMIT = 1800;
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
protected function validateSignature($creds, $secret_key)
{
$elements = [
$creds['method'],
$creds['uri'],
$creds['date'],
$secret_key,
];
$sig_source = implode('|', $elements);
error_log($sig_source);
// generate signature
$raw_sig = hash_hmac('sha1', $sig_source, $secret_key, true);
$enc_sig = base64_encode($raw_sig);
error_log($enc_sig);
if ($enc_sig != trim($creds['signature']))
throw new CustomUserMessageAuthenticationException('Invalid signature.');
}
public function createToken(Request $req, $provider_key)
{
// api key header
$api_key = $req->headers->get(self::HEADER_API_KEY);
if ($api_key == null)
throw new BadCredentialsException('No API key sent.');
// check date from headers
$hdate_string = $req->headers->get(self::HEADER_DATE);
if ($hdate_string == null)
throw new BadCredentialsException('No date specified.');
$hdate = DateTime::createFromFormat(self::DATE_FORMAT, $hdate_string);
if ($hdate == null)
throw new BadCredentialsException('Invalid date specified.');
// get number of seconds difference
$date_now = new DateTime();
$date_diff = abs($date_now->getTimestamp() - $hdate->getTimestamp());
// time difference is too much
if ($date_diff > self::TIME_LIMIT)
throw new BadCredentialsException('Clock synchronization error.');
// signature header
$sig = $req->headers->get(self::HEADER_SIGNATURE);
if ($sig == null)
throw new BadCredentialsException('No signature sent.');
// credentials
$creds = [
'api_key' => $api_key,
'date' => $hdate_string,
'signature' => $sig,
'method' => $req->getRealMethod(),
'uri' => $req->getPathInfo(),
];
return new PreAuthenticatedToken(
'anonymous',
$creds,
$provider_key
);
}
public function supportsToken(TokenInterface $token, $provider_key)
{
return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $provider_key;
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $user_provider, $provider_key)
{
if (!$user_provider instanceof APIKeyUserProvider)
{
throw new \InvalidArgumentException(
sprintf(
'The user provider must be an instance of APIKeyUserProvider (%s was given).',
get_class($user_provider)
)
);
}
$creds = $token->getCredentials();
$api_key = $creds['api_key'];
$user = $user_provider->getUserByAPIKey($api_key);
// check if api key is valid
if (!$user)
throw new CustomUserMessageAuthenticationException('Invalid API Key');
// check if signature is valid
$this->validateSignature($creds, $user->getSecretKey());
// check if user is enabled
if (!$user->isEnabled())
{
throw new CustomUserMessageAuthenticationException('User account is disabled');
}
// $user = $user_provider->loadUserByUsername($username);
return new PreAuthenticatedToken(
$user,
$api_key,
$provider_key,
$user->getRoles()
);
}
public function onAuthenticationFailure(Request $req, AuthenticationException $exception)
{
$data = [
'success' => false,
'error' => [
'message' => $exception->getMessage(),
],
];
return new JsonResponse($data, 401);
}
}

View file

@ -1,62 +0,0 @@
<?php
namespace Catalyst\APIBundle\Security;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Entity\User;
class APIKeyUserProvider implements UserProviderInterface
{
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function getUserByAPIKey($api_key)
{
$user = $this->em->getRepository(User::class)->findOneBy(array('api_key' => $api_key));
return $user;
}
public function getUsernameForAPIKey($apiKey)
{
// Look up the username based on the token in the database, via
// an API call, or do something entirely different
$username = 'test';
return $username;
}
public function loadUserByUsername($username)
{
return new User(
$username,
null,
// the roles for the user - you may choose to determine
// these dynamically somehow based on the user
array('ROLE_API')
);
}
public function refreshUser(UserInterface $user)
{
// this is used for storing authentication in the session
// but in this example, the token is sent in each request,
// so authentication can be stateless. Throwing this exception
// is proper to make things stateless
throw new UnsupportedUserException();
}
public function supportsClass($class)
{
return User::class === $class;
}
}

View file

@ -1,18 +0,0 @@
<?php
namespace Catalyst\APIBundle\Service;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
class AccessDeniedHandler implements AccessDeniedHandlerInterface
{
public function handle(Request $req, AccessDeniedException $exception)
{
$content = $exception->getMessage();
return new Response($content, 403);
}
}

View file

@ -2,18 +2,43 @@
"type": "project",
"license": "proprietary",
"repositories": [
{ "type": "vcs", "url": "git@gitlab.com:jankstudio-catalyst/auth-bundle.git" },
{ "type": "vcs", "url": "git@gitlab.com:jankstudio-catalyst/menu-bundle.git" }
{
"type": "vcs",
"url": "https://github.com/jankstudio/doctrine2-spatial.git"
},
{
"type": "vcs",
"url": "git@gitlab.com:jankstudio1/catalyst-2/api-bundle.git"
},
{
"type": "vcs",
"url": "git@gitlab.com:jankstudio1/catalyst-2/auth-bundle.git"
},
{
"type": "vcs",
"url": "git@gitlab.com:jankstudio1/catalyst-2/menu-bundle.git"
},
{
"type": "vcs",
"url": "https://github.com/arcticzero/php-fcm.git"
}
],
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"catalyst/auth-bundle": "dev-master",
"catalyst/menu-bundle": "dev-master",
"creof/doctrine2-spatial": "^1.2",
"composer/package-versions-deprecated": "1.11.99.4",
"data-dog/audit-bundle": "^0.1.10",
"edwinhoksberg/php-fcm": "^1.0",
"doctrine/common": "^2",
"doctrine/doctrine-bundle": "^2",
"doctrine/doctrine-migrations-bundle": "^2",
"doctrine/orm": "^2",
"edwinhoksberg/php-fcm": "dev-notif-priority-hotfix",
"guzzlehttp/guzzle": "^6.3",
"hashids/hashids": "^4.1",
"jankstudio/catalyst-api-bundle": "dev-master",
"jankstudio/catalyst-auth-bundle": "dev-master",
"jankstudio/catalyst-menu-bundle": "dev-master",
"jankstudio/doctrine-spatial": "dev-master",
"microsoft/azure-storage-blob": "^1.5",
"predis/predis": "^1.1",
"sensio/framework-extra-bundle": "^5.1",
@ -26,9 +51,7 @@
"symfony/framework-bundle": "^4.0",
"symfony/maker-bundle": "^1.0",
"symfony/monolog-bundle": "^3.7",
"symfony/orm-pack": "^1.0",
"symfony/process": "^4.0",
"symfony/profiler-pack": "^1.0",
"symfony/security-bundle": "^4.0",
"symfony/translation": "^4.0",
"symfony/twig-bundle": "^4.0",
@ -38,18 +61,24 @@
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.0",
"symfony/dotenv": "^4.0",
"symfony/thanks": "^1.0"
"symfony/stopwatch": "^4.0",
"symfony/thanks": "^1.0",
"symfony/web-profiler-bundle": "^4.0"
},
"config": {
"preferred-install": {
"*": "dist"
},
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"composer/package-versions-deprecated": true,
"symfony/flex": true,
"symfony/thanks": true
}
},
"autoload": {
"psr-4": {
"App\\": "src/",
"Catalyst\\APIBundle\\": "catalyst/api-bundle/"
"App\\": "src/"
}
},
"autoload-dev": {

2083
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -272,6 +272,8 @@ access_keys:
label: Hub View
- id: jo_cancel.fulfill
label: Fulfill Cancelled JO
- id: jo_resq_proc.list
label: RESQ Dispatch
- id: support
label: Customer Support Access
@ -346,6 +348,10 @@ access_keys:
label: Customer Source Report
- id: report.hub.filter
label: Hub Filter Report
- id: report.warranty.raffle
label: Warranty Raffle Report
- id: report.jo.raffle
label: JO Raffle Report
- id: service
label: Other Services
@ -518,3 +524,79 @@ access_keys:
label: Update
- id: dealer.delete
label: Delete
- id: database
label: Database Access
acls:
- id: database.menu
label: Menu
- id: ticket_type
label: Ticket Type Access
acls:
- id: ticket_type.menu
label: Menu
- id: ticket_type.list
label: List
- id: ticket_type.add
label: Add
- id: ticket_type.update
label: Update
- id: ticket_type.delete
label: Delete
- id: subticket_type
label: Sub Ticket Type Access
acls:
- id: subticket_type.menu
label: Menu
- id: subticket_type.list
label: List
- id: subticket_type.add
label: Add
- id: subticket_type.update
label: Update
- id: subticket_type.delete
label: Delete
- id: emergency_type
label: Emergency Type Access
acls:
- id: emergency_type.menu
label: Menu
- id: emergency_type.list
label: List
- id: emergency_type.add
label: Add
- id: emergency_type.update
label: Update
- id: emergency_type.delete
label: Delete
- id: ownership_type
label: Ownership Type Access
acls:
- id: ownership_type.menu
label: Menu
- id: ownership_type.list
label: List
- id: ownership_type.add
label: Add
- id: ownership_type.update
label: Update
- id: ownership_type.delete
label: Delete
- id: customer_location
label: Customer Location Access
acls:
- id: cust_location.menu
label: Menu
- id: cust_location.list
label: List
- id: cust_location.add
label: Add
- id: cust_location.update
label: Update
- id: cust_location.delete
label: Delete

View file

@ -57,6 +57,8 @@ access_keys:
acls:
- id: customer.register
label: Register Customer
- id: customer.verify
label: Verify Customer
- id: municipality
label: Municipality
acls:
@ -67,3 +69,56 @@ access_keys:
acls:
- id: dealer.list
label: List
- id: warrantyserial
label: Warranty Serial
acls:
- id: warrantyserial.upload
label: Upload
- id: tapi_vmanufacturer
label: Third Party Vehicle Manufacturer Access
acls:
- id: tapi_vmanufacturer.list
label: List Third Party Vehicle Manufacturers
- id: tapi_vehicle
label: Third Party Vehicle Make Access
acls:
- id: tapi_vehicle.list
label: List Third Party Vehicles
- id: tapi_promo
label: Third Party Promo Access
acls:
- id: tapi_promo.list
label: List Third Party Promos
- id: tapi_battery
label: Third Party Battery Access
acls:
- id: tapi_battery_compatible.list
label: List Third Party Compatible Batteries
- id: tapi_jo
label: Third Party Job Order Access
acls:
- id: tapi_jo.request
label: Third Party Request Job Order
- id: tapi_jo.get.estimate
label: Third Party Get Estimate
- id: tapi_jo.get.ongoing
label: Third Party Get Ongoing Job Order
- id: tapi_jo.cancel
label: Third Party Cancel Job Order
- id: tapi_jo.get.invoice
label: Third Party Get Job Order Invoice
- id: tapi_jo.location.support
label: Third Party Check Location Support
- id: tapi_jo.nearest_hub.get
label: Third Party Get Nearest Hub and Slots
- id: tapi_jo.schedule_option.status
label: Third Party Schedule Option Status
- id: tapi_jo.get.info
label: Third Party Get Job Order Info
- id: tapi_service
label: Third Party Service Access
acls:
- id: tapi_service.list
label: List Third Party Services

View file

@ -2,7 +2,6 @@
return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class => ['all' => true],
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
@ -11,8 +10,8 @@ return [
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
Catalyst\APIBundle\CatalystAPIBundle::class => ['all' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
Catalyst\ApiBundle\CatalystApiBundle::class => ['all' => true],
Catalyst\AuthBundle\CatalystAuthBundle::class => ['all' => true],
Catalyst\MenuBundle\CatalystMenuBundle::class => ['all' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
];

View file

@ -42,20 +42,6 @@ services:
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
Catalyst\AuthBundle\Service\ACLGenerator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
$acl_file: "%app_acl_file%"
Catalyst\AuthBundle\Service\ACLVoter:
arguments:
$user_class: "App\\Entity\\User"
tags: ['security.voter']
Catalyst\AuthBundle\Service\UserChecker:
App\Service\FileUploader:
arguments:
$target_dir: '%image_upload_directory%'
@ -114,50 +100,6 @@ services:
arguments:
$redis_client: "@App\\Service\\RedisClientProvider"
Catalyst\APIBundle\Security\APIKeyUserProvider:
arguments:
$em: "@doctrine.orm.entity_manager"
Catalyst\APIBundle\Security\APIKeyAuthenticator:
arguments:
$em: "@doctrine.orm.entity_manager"
Catalyst\APIBundle\Command\UserCreateCommand:
arguments:
$em: "@doctrine.orm.entity_manager"
tags: ['console.command']
Catalyst\APIBundle\Command\TestCommand:
tags: ['console.command']
Catalyst\APIBundle\Command\TestAPICommand:
tags: ['console.command']
Catalyst\APIBundle\Access\Voter:
arguments:
$acl_gen: "@Catalyst\\APIBundle\\Access\\Generator"
$user_class: "Catalyst\\APIBundle\\Entity\\User"
tags: ['security.voter']
Catalyst\APIBundle\Access\Generator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
$acl_file: "%api_acl_file%"
Catalyst\MenuBundle\Menu\Generator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
Catalyst\MenuBundle\Listener\MenuAnnotationListener:
arguments:
$menu_name: "main_menu"
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
# invoice generator
App\Service\InvoiceGenerator\CMBInvoiceGenerator: ~

View file

@ -132,6 +132,10 @@ main_menu:
acl: jo_proc.list
label: Dispatch
parent: joborder
- id: jo_resq_proc
acl: jo_resq_proc.list
label: RESQ Dispatch
parent: joborder
- id: jo_assign
acl: jo_assign.list
label: Rider Assignment
@ -224,3 +228,28 @@ main_menu:
acl: analytics.forecast
label: Forecasting
parent: analytics
- id: database
acl: database.menu
label: Database
icon: fa fa-database
- id: ticket_type_list
acl: ticket_type.menu
label: Ticket Types
parent: database
- id: subticket_type_list
acl: subticket_type.menu
label: Sub Ticket Types
parent: database
- id: emergency_type_list
acl: emergency_type.menu
label: Emergency Types
parent: database
- id: ownership_type_list
acl: ownership_type.menu
label: Ownership Types
parent: database
- id: customer_location_list
acl: cust_location.menu
label: Customer Locations
parent: database

View file

@ -0,0 +1,944 @@
catalyst_auth:
main:
user_entity: "App\\Entity\\User"
acl_data:
- id: dashboard
label: Dashboard Access
acls:
- id: dashboard.menu
label: Menu
- id: user
label: User Access
acls:
- id: user.menu
label: Menu
- id: user.list
label: List
- id: user.add
label: Add
- id: user.update
label: Update
- id: user.delete
label: Delete
- id: user.role.sadmin
label: Super Admin Role
- id: user.profile
label: User Profile
- id: role
label: Role Access
acls:
- id: role.menu
label: Menu
- id: role.list
label: List
- id: role.add
label: Add
- id: role.update
label: Update
- id: role.delete
label: Delete
- id: apiuser
label: API User Access
acls:
- id: apiuser.menu
label: Menu
- id: apiuser.list
label: List
- id: apiuser.add
label: Add
- id: apiuser.update
label: Update
- id: apiuser.delete
label: Delete
- id: apirole
label: API Role Access
acls:
- id: apirole.menu
label: Menu
- id: apirole.list
label: List
- id: apirole.add
label: Add
- id: apirole.update
label: Update
- id: apirole.delete
label: Delete
- id: logistics
label: Logistics Access
acls:
- id: logistics.menu
label: Menu
- id: battery
label: Battery Access
acls:
- id: battery.menu
label: Menu
- id: battery.list
label: List
- id: battery.add
label: Add
- id: battery.update
label: Update
- id: battery.delete
label: Delete
- id: bmfg
label: Battery Manufacturer Access
acls:
- id: bmfg.menu
label: Menu
- id: bmfg.list
label: List
- id: bmfg.add
label: Add
- id: bmfg.update
label: Update
- id: bmfg.delete
label: Delete
- id: bmodel
label: Battery Model Access
acls:
- id: bmodel.menu
label: Menu
- id: bmodel.list
label: List
- id: bmodel.add
label: Add
- id: bmodel.update
label: Update
- id: bmodel.delete
label: Delete
- id: bsize
label: Battery Size Access
acls:
- id: bsize.menu
label: Menu
- id: bsize.list
label: List
- id: bsize.add
label: Add
- id: bsize.update
label: Update
- id: bsize.delete
label: Delete
- id: vehicle
label: Vehicle Access
acls:
- id: vehicle.menu
label: Menu
- id: vehicle.list
label: List
- id: vehicle.add
label: Add
- id: vehicle.update
label: Update
- id: vehicle.delete
label: Delete
- id: vmfg
label: Vehicle Manufacturer Access
acls:
- id: vmfg.menu
label: Menu
- id: vmfg.list
label: List
- id: vmfg.add
label: Add
- id: vmfg.update
label: Update
- id: vmfg.delete
label: Delete
- id: customer
label: Customer Access
acls:
- id: customer.menu
label: Menu
- id: customer.list
label: List
- id: customer.add
label: Add
- id: customer.update
label: Update
- id: customer.delete
label: Delete
- id: customer.dpa
label: Display DPA
- id: location
label: Location Access
acls:
- id: location.menu
label: Menu
- id: outlet
label: Outlet Access
acls:
- id: outlet.menu
label: Menu
- id: outlet.list
label: List
- id: outlet.add
label: Add
- id: outlet.update
label: Update
- id: outlet.delete
label: Delete
- id: hub
label: Hub Access
acls:
- id: hub.menu
label: Menu
- id: hub.list
label: List
- id: hub.add
label: Add
- id: hub.update
label: Update
- id: hub.delete
label: Delete
- id: geofence
label: Geofence
acls:
- id: geofence.menu
label: Menu
- id: geofence.list
label: List
- id: geofence.add
label: Add
- id: geofence.delete
label: Delete
- id: rider
label: Rider Access
acls:
- id: rider.menu
label: Menu
- id: rider.list
label: List
- id: rider.add
label: Add
- id: rider.update
label: Update
- id: rider.delete
label: Delete
- id: servicecharge
label: Service Charge
acls:
- id: service_charge.menu
label: Menu
- id: service_charge.list
label: List
- id: service_charge.add
label: Add
- id: service_charge.update
label: Update
- id: service_charge.delete
label: Delete
- id: joborder
label: Job Order
acls:
- id: joborder.menu
label: Menu
- id: jo_in.list
label: Incoming
- id: jo_proc.list
label: Dispatch
- id: jo_proc.unlock
label: Dispatch Unlock
- id: jo_assign.list
label: Rider Assignment
- id: jo_assign.unlock
label: Rider Assignment Unlock
- id: jo_fulfill.list
label: Fulfillment
- id: jo_open.list
label: Open
- id: jo_all.list
label: View All
- id: jo_pdf.list
label: PDF
- id: jo_open.edit
label: Edit
- id: joborder.cancel
label: Cancel
- id: jo_onestep.form
label: One-step Process
- id: jo_onestep.edit
label: One-step Process Edit
- id: jo_walkin.form
label: Walk-in
- id: jo_walkin.edit
label: Walk-in Edit
- id: jo_autoassign.test
label: Autoassign Test
- id: jo_hub.list
label: Hub View
- id: jo_cancel.fulfill
label: Fulfill Cancelled JO
- id: jo_resq_proc.list
label: RESQ Dispatch
- id: jo_resq_all.list
label: RESQ All
- id: support
label: Customer Support Access
acls:
- id: support.menu
label: Menu
- id: general.search
label: Search
- id: warranty.search
label: Customer Battery Search
- id: warranty.upload
label: Warranty Upload
- id: ticket
label: Ticket Access
acls:
- id: ticket.menu
label: Menu
- id: ticket.list
label: List
- id: ticket.add
label: Add
- id: ticket.update
label: Update
- id: ticket.delete
label: Delete
- id: promo
label: Promo Access
acls:
- id: promo.menu
label: Menu
- id: promo.list
label: List
- id: promo.add
label: Add
- id: promo.update
label: Update
- id: promo.delete
label: Delete
- id: report
label: Reports
acls:
- id: report.menu
label: Menu
- id: report.reject
label: Rejection Report
- id: report.battery.conflict
label: Battery Conflict Report
- id: report.popapp.comparison
label: Popapp Comparison Report
- id: report.meh.customer
label: RESQ MEH Customer Report
- id: report.warranty.class
label: Warranty Class Report
- id: report.vehicle.battery.compatibility
label: Vehicle Battery Compatibility Report
- id: report.warranty.details
label: Warranty Details Report
- id: report.jo.details
label: Job Order Details Report
- id: report.jo_events
label: Job Order Events Report
- id: report.sms_messages
label: SMS Messages Report
- id: report.jo.auto_assign
label: Auto Assigned Job Order Report
- id: report.jo.advance_order
label: Advance Order Job Order Report
- id: report.customer.source
label: Customer Source Report
- id: report.hub.filter
label: Hub Filter Report
- id: report.warranty.raffle
label: Warranty Raffle Report
- id: report.jo.raffle
label: JO Raffle Report
- id: service
label: Other Services
acls:
- id: service.menu
label: Menu
- id: service.list
label: List
- id: service.add
label: Add
- id: service.update
label: Update
- id: service.delete
label: Delete
- id: partner
label: Partners
acls:
- id: partner.menu
label: Menu
- id: partner.list
label: List
- id: partner.add
label: Add
- id: partner.update
label: Update
- id: partner.delete
label: Delete
- id: motolite_event
label: Motolite Events
acls:
- id: motolite_event.menu
label: Menu
- id: motolite_event.list
label: List
- id: motolite_event.add
label: Add
- id: motolite_event.update
label: Update
- id: motolite_event.delete
label: Delete
- id: review
label: Reviews
acls:
- id: review.menu
label: Menu
- id: review.list
label: List
- id: review.view
label: View
- id: review.delete
label: Delete
- id: privacypolicy
label: Privacy Policy
acls:
- id: privacy_policy.menu
label: Menu
- id: privacy_policy.list
label: List
- id: privacy_policy.add
label: Add
- id: privacy_policy.update
label: Update
- id: privacy_policy.delete
label: Delete
- id: warranty
label: Warranty
acls:
- id: warranty.menu
label: Menu
- id: warranty.list
label: List
- id: warranty.add
label: Add
- id: warranty.update
label: Update
- id: staticcontent
label: Static Content
acls:
- id: static_content.menu
label: Menu
- id: static_content.list
label: List
- id: static_content.add
label: Add
- id: static_content.update
label: Update
- id: static_content.delete
label: Delete
- id: analytics
label: Analytics
acls:
- id: analytics.menu
label: Menu
- id: analytics.forecast
label: Forecasting
- id: sap_battery
label: SAP Battery Access
acls:
- id: sap_battery.menu
label: Menu
- id: sap_battery.list
label: List
- id: sap_battery.add
label: Add
- id: sap_battery.update
label: Update
- id: sap_battery.delete
label: Delete
- id: sap_brand
label: SAP Battery Brand Access
acls:
- id: sap_brand.menu
label: Menu
- id: sap_brand.list
label: List
- id: sap_brand.add
label: Add
- id: sap_brand.update
label: Update
- id: sap_brand.delete
label: Delete
- id: sap_bsize
label: SAP Battery Size Access
acls:
- id: sap_bsize.menu
label: Menu
- id: sap_bsize.list
label: List
- id: sap_bsize.add
label: Add
- id: sap_bsize.update
label: Update
- id: sap_bsize.delete
label: Delete
- id: sap_csize
label: SAP Battery Container Size Access
acls:
- id: sap_csize.menu
label: Menu
- id: sap_csize.list
label: List
- id: sap_csize.add
label: Add
- id: sap_csize.update
label: Update
- id: sap_csize.delete
label: Delete
- id: customer_tag
label: Customer Tags Access
acls:
- id: customer_tag.menu
label: Menu
- id: customer_tag.list
label: List
- id: customer_tag.add
label: Add
- id: customer_tag.update
label: Update
- id: customer_tag.delete
label: Delete
- id: review_tag
label: Review Tags Access
acls:
- id: review_tag.menu
label: Menu
- id: review_tag.list
label: List
- id: review_tag.add
label: Add
- id: review_tag.update
label: Update
- id: review_tag.delete
label: Delete
- id: dealer
label: Dealer Access
acls:
- id: dealer.menu
label: Menu
- id: dealer.list
label: List
- id: dealer.add
label: Add
- id: dealer.update
label: Update
- id: dealer.delete
label: Delete
- id: database
label: Database Access
acls:
- id: database.menu
label: Menu
- id: ticket_type
label: Ticket Type Access
acls:
- id: ticket_type.menu
label: Menu
- id: ticket_type.list
label: List
- id: ticket_type.add
label: Add
- id: ticket_type.update
label: Update
- id: ticket_type.delete
label: Delete
- id: subticket_type
label: Sub Ticket Type Access
acls:
- id: subticket_type.menu
label: Menu
- id: subticket_type.list
label: List
- id: subticket_type.add
label: Add
- id: subticket_type.update
label: Update
- id: subticket_type.delete
label: Delete
- id: emergency_type
label: Emergency Type Access
acls:
- id: emergency_type.menu
label: Menu
- id: emergency_type.list
label: List
- id: emergency_type.add
label: Add
- id: emergency_type.update
label: Update
- id: emergency_type.delete
label: Delete
- id: ownership_type
label: Ownership Type Access
acls:
- id: ownership_type.menu
label: Menu
- id: ownership_type.list
label: List
- id: ownership_type.add
label: Add
- id: ownership_type.update
label: Update
- id: ownership_type.delete
label: Delete
- id: service_offering
label: Service Offering Access
acls:
- id: service_offering.menu
label: Menu
- id: service_offering.list
label: List
- id: service_offering.add
label: Add
- id: service_offering.update
label: Update
- id: service_offering.delete
label: Delete
- id: price_tier
label: Price Tier
acls:
- id: price_tier.menu
label: Menu
- id: price_tier.list
label: List
- id: price_tier.add
label: Add
- id: price_tier.update
label: Update
- id: price_tier.delete
label: Delete
- id: item_type
label: Item Type
acls:
- id: item_type.menu
label: Menu
- id: item_type.list
label: List
- id: item_type.add
label: Add
- id: item_type.update
label: Update
- id: item_type.delete
label: Delete
- id: item
label: Item
acls:
- id: item.menu
label: Menu
- id: item_pricing
label: Item Pricing
acls:
- id: item_pricing.update
label: Update
api:
user_entity: "App\\Entity\\ApiUser"
acl_data:
- id: warranty
label: Warranty Access
acls:
- id: warranty.list
label: List
- id: warranty.find.serial
label: Find by Serial
- id: warranty.find.platenumber
label: Find by Plate Number
- id: warranty.register.battery
label: Register Battery
- id: warranty.claim
label: Claim
- id: warranty.update
label: Update
- id: warranty.cancel
label: Cancel
- id: warranty.delete
label: Delete
- id: warranty.set.privacypolicy
label: Set Privacy Policy
- id: warranty.list.serial
label: List by Serial
- id: batterybrand
label: Battery Brand Access
acls:
- id: batterybrand.list
label: List
- id: batterysize
label: Battery Size Access
acls:
- id: batterysize.list
label: List
- id: battery
label: Battery Access
acls:
- id: battery.list
label: List
- id: vmanufacturer
label: Vehicle Manufacturer Access
acls:
- id: vmanufacturer.list
label: List
- id: vehicle
label: Vehicle Access
acls:
- id: vehicle.list
label: List
- id: privacypolicy
label: Privacy Policy
acls:
- id: privacypolicy.find
label: Find Privacy Policy
- id: customer
label: Customer
acls:
- id: customer.register
label: Register Customer
- id: customer.verify
label: Verify Customer
- id: municipality
label: Municipality
acls:
- id: municipality.list
label: List
- id: dealer
label: Dealer
acls:
- id: dealer.list
label: List
- id: warrantyserial
label: Warranty Serial
acls:
- id: warrantyserial.upload
label: Upload
- id: hub
label: Hub Access
acls:
- id: hub.list
label: List
- id: joborder
label: Job Order Access
acls:
- id: joborder.find
label: Find Job Order
- id: tapi_vmanufacturer
label: Third Party Vehicle Manufacturer Access
acls:
- id: tapi_vmanufacturer.list
label: List Third Party Vehicle Manufacturers
- id: tapi_vehicle
label: Third Party Vehicle Make Access
acls:
- id: tapi_vehicle.list
label: List Third Party Vehicles
- id: tapi_promo
label: Third Party Promo Access
acls:
- id: tapi_promo.list
label: List Third Party Promos
- id: tapi_battery
label: Third Party Battery Access
acls:
- id: tapi_battery_compatible.list
label: List Third Party Compatible Batteries
- id: tapi_jo
label: Third Party Job Order Access
acls:
- id: tapi_jo.request
label: Third Party Request Job Order
- id: tapi_jo.get.estimate
label: Third Party Get Estimate
- id: tapi_jo.get.ongoing
label: Third Party Get Ongoing Job Order
- id: tapi_jo.cancel
label: Third Party Cancel Job Order
- id: tapi_jo.get.invoice
label: Third Party Get Job Order Invoice
- id: tapi_jo.location.support
label: Third Party Check Location Support
- id: tapi_jo.nearest_hub.get
label: Third Party Get Nearest Hub and Slots
- id: tapi_jo.schedule_option.status
label: Third Party Schedule Option Status
- id: tapi_jo.get.info
label: Third Party Get Job Order Info
- id: tapi_service
label: Third Party Service Access
acls:
- id: tapi_service.list
label: List Third Party Services
cust_api_v2:
user_entity: "App\\Entity\\CustomerUser"
acl_data:
- id: cust_api_v2.auth
label: Authentication
acls:
- id: cust_api_v2.auth.register
label: Register
- id: cust_api_v2.auth.confirm
label: Confirm Number
- id: cust_api_v2.auth.validate
label: Validate Code
- id: cust_api_v2.auth.resend_code
label: Resend Code
- id: cust_api_v2.customer
label: Customer
acls:
- id: cust_api_v2.customer.info
label: Info
- id: cust_api_v2.customer.update
label: Update
- id: cust_api_v2.customer.status
label: Status
- id: cust_api_v2.customer.hash
label: Hash
- id: cust_api_v2.device
label: Device
acls:
- id: cust_api_v2.device.id
label: Update
- id: cust_api_v2.invoice
label: Invoice
acls:
- id: cust_api_v2.invoice.estimate
label: Estimate
- id: cust_api_v2.jo
label: Job Order
acls:
- id: cust_api_v2.jo.ongoing
label: List Ongoing
- id: cust_api_v2.jo.invoice
label: Get Invoice
- id: cust_api_v2.jo.cancel
label: Cancel
- id: cust_api_v2.jo.info
label: Info
- id: cust_api_v2.jo.history
label: History
- id: cust_api_v2.jo.latest
label: Latest
- id: cust_api_v2.jo.all_ongoing
label: List All Ongoing
- id: cust_api_v2.jo.ongoing_count
label: List Ongoing Count
- id: cust_api_v2.jo.create
label: Create
- id: cust_api_v2.jo.request
label: Request
- id: cust_api_v2.jo.completed
label: List Completed
- id: cust_api_v2.location
label: Location
acls:
- id: cust_api_v2.location.support
label: Get Support Status
- id: cust_api_v2.location.nearest_hub_and_slots
label: List Nearest Hub and Slots
- id: cust_api_v2.location.create
label: Create
- id: cust_api_v2.location.list
label: List
- id: cust_api_v2.partner
label: Partner
acls:
- id: cust_api_v2.partner.info
label: Info
- id: cust_api_v2.partner.closest
label: List Closest Partners
- id: cust_api_v2.partner.review
label: Review
- id: cust_api_v2.privacy
label: Privacy
acls:
- id: cust_api_v2.privacy.settings
label: Get Privacy Settings
- id: cust_api_v2.promo
label: Promo
acls:
- id: cust_api_v2.promo.list
label: Get Promos
- id: cust_api_v2.rider
label: Rider
acls:
- id: cust_api_v2.rider.status
label: Status
- id: cust_api_v2.rider.rating
label: Rate
- id: cust_api_v2.schedule
label: Schedule
acls:
- id: cust_api_v2.schedule.status
label: Get Schedule Option Status
- id: cust_api_v2.service
label: Service
acls:
- id: cust_api_v2.service.list
label: List
- id: cust_api_v2.vehicle
label: Vehicle
acls:
- id: cust_api_v2.vehicle.mfgs
label: List Manufacturers
- id: cust_api_v2.vehicle.makes
label: List Makes
- id: cust_api_v2.vehicle.create
label: Add
- id: cust_api_v2.vehicle.update
label: Update
- id: cust_api_v2.vehicle.list
label: List
- id: cust_api_v2.vehicle.batteries
label: Compatible Batteries
- id: cust_api_v2.vehicle.delete
label: Delete
- id: cust_api_v2.warranty
label: Warranty
acls:
- id: cust_api_v2.warranty.activate
label: Activate
- id: cust_api_v2.warranty.check
label: Check Status
- id: cust_api_v2.warranty.register
label: Register

View file

@ -0,0 +1,308 @@
catalyst_menu:
main:
- id: home
acl: dashboard.menu
label: '[menu.dashboard]'
icon: flaticon-line-graph
order: 1
- id: user
acl: user.menu
label: '[menu.user]'
icon: flaticon-users
order: 2
- id: user_list
acl: user.list
label: '[menu.user.users]'
parent: user
- id: role_list
acl: role.list
label: '[menu.user.roles]'
parent: user
- id: apiuser
acl: apiuser.menu
label: '[menu.apiuser]'
icon: flaticon-users
order: 3
- id: api_user_list
acl: apiuser.list
label: '[menu.apiuser.users]'
parent: apiuser
- id: api_role_list
acl: apirole.list
label: '[menu.apiuser.roles]'
parent: apiuser
- id: logistics
acl: logistics.menu
label: '[menu.logistics]'
icon: fa fa-truck
order: 4
- id: rider_list
acl: rider.list
label: '[menu.logistics.riders]'
parent: logistics
- id: battery
acl: battery.menu
label: '[menu.battery]'
icon: fa fa-battery-3
order: 5
- id: battery_list
acl: battery.list
label: '[menu.battery.batteries]'
parent: battery
- id: bmfg_list
acl: bmfg.list
label: '[menu.battery.manufacturers]'
parent: battery
- id: bmodel_list
acl: bmodel.list
label: '[menu.battery.models]'
parent: battery
- id: bsize_list
acl: bsize.list
label: '[menu.battery.sizes]'
parent: battery
- id: promo_list
acl: promo.list
label: '[menu.battery.promos]'
parent: battery
- id: sapbattery
acl: sap_battery.menu
label: '[menu.sapbattery]'
icon: fa fa-battery
order: 6
- id: sapbattery_list
acl: sap_battery.list
label: '[menu.sapbattery.batteries]'
parent: sapbattery
- id: sapbrand_list
acl: sap_brand.list
label: '[menu.sapbattery.brands]'
parent: sapbattery
- id: sapbsize_list
acl: sap_bsize.list
label: '[menu.sapbattery.sizes]'
parent: sapbattery
- id: sapcsize_list
acl: sap_csize.list
label: '[menu.sapbattery.csizes]'
parent: sapbattery
- id: vehicle
acl: vehicle.menu
label: '[menu.vehicle]'
icon: fa fa-car
order: 7
- id: vehicle_list
acl: vehicle.list
label: '[menu.vehicle.vehicles]'
parent: vehicle
- id: vmfg_list
acl: vmfg.list
label: '[menu.vehicle.manufacturers]'
parent: vehicle
- id: location
acl: location.menu
label: '[menu.location]'
icon: fa fa-home
order: 8
- id: outlet_list
acl: outlet.menu
label: '[menu.location.outlets]'
parent: location
- id: hub_list
acl: hub.menu
label: '[menu.location.hubs]'
parent: location
- id: dealer_list
acl: dealer.list
label: '[menu.location.dealers]'
parent: location
- id: geofence_list
acl: geofence.menu
label: '[menu.location.geofence]'
parent: location
- id: joborder
acl: joborder.menu
label: '[menu.joborder]'
icon: flaticon-calendar-3
order: 9
- id: jo_in
acl: jo_in.list
label: '[menu.joborder.incoming]'
parent: joborder
- id: jo_proc
acl: jo_proc.list
label: '[menu.joborder.dispatch]'
parent: joborder
- id: jo_resq_proc
acl: jo_resq_proc.list
label: '[menu.joborder.resqdispatch]'
parent: joborder
- id: jo_assign
acl: jo_assign.list
label: '[menu.joborder.assignment]'
parent: joborder
- id: jo_fulfill
acl: jo_fulfill.list
label: '[menu.joborder.fulfillment]'
parent: joborder
- id: jo_open
acl: jo_open.list
label: '[menu.joborder.open]'
parent: joborder
- id: jo_all
acl: jo_all.list
label: '[menu.joborder.viewall]'
parent: joborder
- id: jo_hub_view
acl: jo_hub.list
label: '[menu.joborder.hubview]'
parent: joborder
- id: jo_resq_all
acl: jo_resq_all.list
label: '[menu.joborder.resqall]'
parent: joborder
- id: support
acl: support.menu
label: '[menu.support]'
icon: flaticon-support
order: 11
- id: customer_list
acl: customer.list
label: '[menu.support.customers]'
parent: support
- id: ticket_list
acl: ticket.list
label: '[menu.support.tickets]'
parent: support
- id: general_search
acl: general.search
label: '[menu.support.search]'
parent: support
- id: warranty_search
acl: warranty.search
label: '[menu.support.warrantysearch]'
parent: support
- id: privacy_policy_list
acl: privacy_policy.list
label: '[menu.support.privacypolicy]'
parent: support
- id: warranty_list
acl: warranty.list
label: '[menu.support.warranty]'
parent: support
- id: warranty_upload
acl: warranty.upload
label: '[menu.support.warrantyupload]'
parent: support
- id: static_content_list
acl: static_content.list
label: '[menu.support.staticcontent]'
parent: support
- id: customertag_list
acl: customer_tag.list
label: '[menu.support.customertags]'
parent: support
- id: reviewtag_list
acl: review_tag.list
label: '[menu.support.reviewtags]'
parent: support
- id: service
acl: service.menu
label: '[menu.service]'
icon: flaticon-squares
order: 12
- id: service_list
acl: service.list
label: '[menu.service.services]'
parent: service
- id: partner
acl: partner.menu
label: '[menu.partner]'
icon: flaticon-network
order: 13
- id: partner_list
acl: partner.list
label: '[menu.partner.partners]'
parent: partner
- id: review_list
acl: review.list
label: '[menu.partner.reviews]'
parent: partner
- id: motolite_event
acl: motolite_event.menu
label: '[menu.motolite_event]'
icon: flaticon-event-calendar-symbol
order: 14
- id: motolite_event_list
acl: motolite_event.list
label: '[menu.motolite_event.events]'
parent: motolite_event
- id: analytics
acl: analytics.menu
label: '[menu.analytics]'
icon: flaticon-graphic
order: 15
- id: analytics_forecast_form
acl: analytics.forecast
label: '[menu.analytics.forecasting]'
parent: analytics
- id: database
acl: database.menu
label: '[menu.database]'
icon: fa fa-database
order: 16
- id: ticket_type_list
acl: ticket_type.menu
label: '[menu.database.tickettypes]'
parent: database
- id: subticket_type_list
acl: subticket_type.menu
label: '[menu.database.subtickettypes]'
parent: database
- id: emergency_type_list
acl: emergency_type.menu
label: '[menu.database.emergencytypes]'
parent: database
- id: ownership_type_list
acl: ownership_type.menu
label: '[menu.database.ownershiptypes]'
parent: database
- id: service_offering_list
acl: service_offering.menu
label: '[menu.database.serviceofferings]'
parent: database
- id: item_type_list
acl: item_type.menu
label: '[menu.database.itemtypes]'
parent: database
- id: item
acl: item.menu
label: Item Management
icon: fa fa-boxes
order: 10
- id: price_tier_list
acl: price_tier.list
label: Price Tiers
parent: item
- id: item_pricing
acl: item_pricing.update
label: Item Pricing
parent: item

View file

@ -11,6 +11,8 @@ doctrine:
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
options:
!php/const PDO::MYSQL_ATTR_LOCAL_INFILE: true
# With Symfony 3.3, remove the `resolve:` prefix
url: '%env(resolve:DATABASE_URL)%'

View file

@ -9,8 +9,14 @@ security:
entity:
class: App\Entity\User
property: username
api_key_user_provider:
id: Catalyst\APIBundle\Security\APIKeyUserProvider
api_provider:
entity:
class: App\Entity\ApiUser
property: api_key
api_v2_provider:
entity:
class: App\Entity\CustomerUser
property: api_key
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
@ -43,21 +49,57 @@ security:
pattern: ^\/rapi\/
security: false
test_capi:
pattern: ^\/test_capi\/
security: false
insurance:
pattern: ^\/insurance\/
security: false
paymongo:
pattern: ^\/paymongo\/
security: false
cust_api_v2:
pattern: ^\/apiv2\/(?!register|register\/|number_confirm|number_confirm\/|code_validate|code_validate\/|resend_code|resend_code\/|version_check|version_check\/|account|account\/|account_code_validate|account_code_validate\/|account_resend_code|account_resend_code\/)
provider: api_v2_provider
access_denied_handler: Catalyst\ApiBundle\Service\AccessDeniedHandler
stateless: true
guard:
authenticators:
- Catalyst\ApiBundle\Security\Authenticator
cust_api_v2_guest:
pattern: ^\/apiv2\/(register|register\/|number_confirm|number_confirm\/|code_validate|code_validate\/|resend_code|resend_code\/|version_check|version_check\/|account|account\/|account_code_validate|account_code_validate\/|account_resend_code|account_resend_code\/)
security: false
warranty_api:
pattern: ^\/capi\/
provider: api_provider
access_denied_handler: Catalyst\ApiBundle\Service\AccessDeniedHandler
stateless: true
simple_preauth:
authenticator: Catalyst\APIBundle\Security\APIKeyAuthenticator
provider: api_key_user_provider
user_checker: Catalyst\AuthBundle\Service\UserChecker
guard:
authenticators:
- Catalyst\ApiBundle\Security\Authenticator
new_rider_api:
pattern: ^\/rider_api\/
provider: api_provider
access_denied_handler: Catalyst\ApiBundle\Service\AccessDeniedHandler
stateless: true
simple_preauth:
authenticator: Catalyst\APIBundle\Security\APIKeyAuthenticator
provider: api_key_user_provider
user_checker: Catalyst\AuthBundle\Service\UserChecker
guard:
authenticators:
- Catalyst\ApiBundle\Security\Authenticator
third_party_api:
pattern: ^\/tapi\/
provider: api_provider
access_denied_handler: Catalyst\ApiBundle\Service\AccessDeniedHandler
stateless: true
guard:
authenticators:
- Catalyst\ApiBundle\Security\Authenticator
main:
provider: user_provider
@ -72,6 +114,7 @@ security:
lifetime: 604800
path: /
user_checker: Catalyst\AuthBundle\Service\UserChecker
switch_user: { role: ROLE_SUPER_ADMIN }
# activate different ways to authenticate

View file

@ -43,20 +43,6 @@ services:
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
Catalyst\AuthBundle\Service\ACLGenerator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
$acl_file: "%app_acl_file%"
Catalyst\AuthBundle\Service\ACLVoter:
arguments:
$user_class: "App\\Entity\\User"
tags: ['security.voter']
Catalyst\AuthBundle\Service\UserChecker:
App\Service\FileUploader:
arguments:
$target_dir: '%image_upload_directory%'
@ -115,50 +101,6 @@ services:
arguments:
$redis_client: "@App\\Service\\RedisClientProvider"
Catalyst\APIBundle\Security\APIKeyUserProvider:
arguments:
$em: "@doctrine.orm.entity_manager"
Catalyst\APIBundle\Security\APIKeyAuthenticator:
arguments:
$em: "@doctrine.orm.entity_manager"
Catalyst\APIBundle\Command\UserCreateCommand:
arguments:
$em: "@doctrine.orm.entity_manager"
tags: ['console.command']
Catalyst\APIBundle\Command\TestCommand:
tags: ['console.command']
Catalyst\APIBundle\Command\TestAPICommand:
tags: ['console.command']
Catalyst\APIBundle\Access\Voter:
arguments:
$acl_gen: "@Catalyst\\APIBundle\\Access\\Generator"
$user_class: "Catalyst\\APIBundle\\Entity\\User"
tags: ['security.voter']
Catalyst\APIBundle\Access\Generator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
$acl_file: "%api_acl_file%"
Catalyst\MenuBundle\Menu\Generator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
Catalyst\MenuBundle\Listener\MenuAnnotationListener:
arguments:
$menu_name: "main_menu"
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
# invoice generator
App\Service\InvoiceGenerator\ResqInvoiceGenerator: ~

View file

@ -185,3 +185,43 @@ api_jo_info:
path: /api/job_order/{id}/info
controller: App\Controller\APIController::getJobOrderInfo
methods: [GET]
api_ongoing_job_orders:
path: /api/job_orders/ongoing
controller: App\Controller\APIController::getAllOngoingJobOrders
methods: [GET]
api_ongoing_jo_count:
path: /api/job_orders/ongoing/count
controller: App\Controller\APIController::getOngoingJobOrderCount
methods: [GET]
api_new_location:
path: /api/new_location
controller: App\Controller\APIController::addLocation
methods: [POST]
api_locations:
path: /api/locations
controller: App\Controller\APIController::getLocations
methods: [GET]
api_cust_vehicle_remove:
path: /api/vehicles/{id}/remove
controller: App\Controller\APIController::removeVehicle
methods: [POST]
api_latest_job_order:
path: /api/job_order/latest
controller: App\Controller\APIController::getLatestJobOrder
methods: [GET]
api_customer_hash_get:
path: /api/customer_hash
controller: App\Controller\APIController::getCustomerHash
methods: [GET]
#api_completed_job_orders:
# path: /api/job_orders/completed
# controller: App\Controller\APIController::getCompletedJobOrders
# methods: [GET]

315
config/routes/apiv2.yaml Normal file
View file

@ -0,0 +1,315 @@
# api
apiv2_register:
path: /apiv2/register
controller: App\Controller\CustomerAppAPI\AuthController::register
methods: [POST]
apiv2_confirm:
path: /apiv2/number_confirm
controller: App\Controller\CustomerAppAPI\AuthController::confirmNumber
methods: [POST]
apiv2_validate:
path: /apiv2/code_validate
controller: App\Controller\CustomerAppAPI\AuthController::validateCode
methods: [POST]
apiv2_info_get:
path: /apiv2/info
controller: App\Controller\CustomerAppAPI\CustomerController::getInfo
methods: [GET]
apiv2_info_update:
path: /apiv2/info
controller: App\Controller\CustomerAppAPI\CustomerController::updateInfo
methods: [POST]
apiv2_status:
path: /apiv2/status
controller: App\Controller\CustomerAppAPI\CustomerController::getStatus
methods: [GET]
apiv2_vehicle_mfg_list:
path: /apiv2/vehicle/mfgs
controller: App\Controller\CustomerAppAPI\VehicleController::listVehicleManufacturers
methods: [GET]
apiv2_vehicle_make_list:
path: /apiv2/vehicle/mfgs/{mfg_id}/makes
controller: App\Controller\CustomerAppAPI\VehicleController::listVehicleMakes
methods: [GET]
apiv2_cust_vehicle_add:
path: /apiv2/vehicles
controller: App\Controller\CustomerAppAPI\VehicleController::addVehicle
methods: [POST]
apiv2_cust_vehicle_info:
path: /apiv2/vehicles/{id}
controller: App\Controller\CustomerAppAPI\VehicleController::getVehicle
methods: [GET]
apiv2_cust_vehicle_update:
path: /apiv2/vehicles/{id}
controller: App\Controller\CustomerAppAPI\VehicleController::updateVehicle
methods: [POST]
apiv2_cust_vehicle_list:
path: /apiv2/vehicles
controller: App\Controller\CustomerAppAPI\VehicleController::listVehicles
methods: [GET]
apiv2_promo_list:
path: /apiv2/promos
controller: App\Controller\CustomerAppAPI\PromoController::listPromos
methods: [GET]
apiv2_battery_list:
path: /apiv2/vehicles/{vid}/compatible_batteries
controller: App\Controller\CustomerAppAPI\VehicleController::getCompatibleBatteries
methods: [GET]
apiv2_jo_request:
path: /apiv2/job_order
controller: App\Controller\CustomerAppAPI\JobOrderController::requestJobOrder
methods: [POST]
apiv2_estimate:
path: /apiv2/estimate
controller: App\Controller\CustomerAppAPI\InvoiceController::getEstimate
methods: [POST]
apiv2_ongoing:
path: /apiv2/job_order/ongoing
controller: App\Controller\CustomerAppAPI\JobOrderController::getOngoing
methods: [GET]
apiv2_rider_status:
path: /apiv2/rider
controller: App\Controller\CustomerAppAPI\RiderController::getRiderStatus
methods: [GET]
apiv2_rider_rating_add:
path: /apiv2/rider_rating
controller: App\Controller\CustomerAppAPI\RiderController::addRiderRating
methods: [POST]
apiv2_jo_cancel:
path: /apiv2/job_order/cancel
controller: App\Controller\CustomerAppAPI\JobOrderController:cancelJobOrder
methods: [POST]
apiv2_jo_history:
path: /apiv2/job_order/history
controller: App\Controller\CustomerAppAPI\JobOrderController:getJOHistory
methods: [GET]
apiv2_jo_invoice:
path: /apiv2/job_order/invoice
controller: App\Controller\CustomerAppAPI\JobOrderController:getJOInvoice
methods: [GET]
apiv2_device_id:
path: /apiv2/device_id
controller: App\Controller\CustomerAppAPI\DeviceController:updateDeviceID
methods: [POST]
apiv2_privacy:
path: /apiv2/privacy
controller: App\Controller\CustomerAppAPI\PrivacyController:privacySettings
methods: [POST]
apiv2_resend_code:
path: /apiv2/resend_code
controller: App\Controller\CustomerAppAPI\AuthController:resendCode
methods: [POST]
apiv2_location_support:
path: /apiv2/location_support
controller: App\Controller\CustomerAppAPI\LocationController:locationSupport
methods: [GET]
apiv2_activate_warranty:
path: /apiv2/activate_warranty
controller: App\Controller\CustomerAppAPI\WarrantyController:activateWarranty
methods: [POST]
apiv2_service_list:
path: /apiv2/services
controller: App\Controller\CustomerAppAPI\ServiceController:listServices
methods: [GET]
apiv2_partner_info:
path: /apiv2/partners/{pid}
controller: App\Controller\CustomerAppAPI\PartnerController:getPartnerInformation
methods: [GET]
apiv2_partner:
path: /apiv2/partners
controller: App\Controller\CustomerAppAPI\PartnerController:getClosestPartners
methods: [GET]
apiv2_partner_review:
path: /apiv2/partners/{pid}/review
controller: App\Controller\CustomerAppAPI\PartnerController:reviewPartner
methods: [POST]
apiv2_nearest_hub_slots:
path: /apiv2/hub_slots
controller: App\Controller\CustomerAppAPI\LocationController::getNearestHubAndSlots
methods: [GET]
apiv2_new_jo_request:
path: /apiv2/new_job_order
controller: App\Controller\CustomerAppAPI\JobOrderController::newRequestJobOrder
methods: [POST]
apiv2_version_check:
path: /apiv2/version_check
controller: App\Controller\CustomerAppAPI\AppController::versionCheck
methods: [GET]
apiv2_schedule_option_status:
path: /apiv2/schedule_option_status
controller: App\Controller\CustomerAppAPI\ScheduleController::scheduleOptionStatus
methods: [GET]
# paperless warranty / qr code
apiv2_warr_serial_check:
path: /apiv2/warranty/{serial}
controller: App\Controller\CustomerAppAPI\WarrantyController::warrantyCheck
methods: [GET]
apiv2_warr_serial_register:
path: /apiv2/warranty/{serial}
controller: App\Controller\CustomerAppAPI\WarrantyController::warrantyRegister
methods: [POST]
apiv2_jo_info:
path: /apiv2/job_order/{id}/info
controller: App\Controller\CustomerAppAPI\JobOrderController::getJobOrderInfo
methods: [GET]
apiv2_ongoing_job_orders:
path: /apiv2/job_orders/ongoing
controller: App\Controller\CustomerAppAPI\JobOrderController::getAllOngoingJobOrders
methods: [GET]
apiv2_ongoing_jo_count:
path: /apiv2/job_orders/ongoing/count
controller: App\Controller\CustomerAppAPI\JobOrderController::getOngoingJobOrderCount
methods: [GET]
apiv2_new_location:
path: /apiv2/new_location
controller: App\Controller\CustomerAppAPI\LocationController::addLocation
methods: [POST]
apiv2_locations:
path: /apiv2/locations
controller: App\Controller\CustomerAppAPI\LocationController::getLocations
methods: [GET]
apiv2_location_remove:
path: /apiv2/locations/{id}/remove
controller: App\Controller\CustomerAppAPI\LocationController::removeLocation
methods: [POST]
apiv2_cust_vehicle_remove:
path: /apiv2/vehicles/{id}/remove
controller: App\Controller\CustomerAppAPI\VehicleController::removeVehicle
methods: [POST]
apiv2_latest_job_order:
path: /apiv2/job_order/latest
controller: App\Controller\CustomerAppAPI\JobOrderController::getLatestJobOrder
methods: [GET]
apiv2_customer_hash_get:
path: /apiv2/customer_hash
controller: App\Controller\CustomerAppAPI\CustomerController::getCustomerHash
methods: [GET]
#apiv2_completed_job_orders:
# path: /apiv2/job_orders/completed
# controller: App\Controller\CustomerAppAPI\JobOrderController::getCompletedJobOrders
# methods: [GET]
# motolite events
apiv2_motolite_events:
path: /apiv2/motolite_events
controller: App\Controller\CustomerAppAPI\MotoliteEventController::getEvents
methods: [GET]
# review tags
apiv2_partner_review_tags:
path: /apiv2/review_tags/partner
controller: App\Controller\CustomerAppAPI\ReviewTagController::getPartnerReviewTags
apiv2_rider_review_tags:
path: /apiv2/review_tags/rider
controller: App\Controller\CustomerAppAPI\ReviewTagController::getRiderReviewTags
# account deletion
apiv2_account_delete:
path: /apiv2/account_delete
controller: App\Controller\CustomerAppAPI\AccountController::deleteAccount
methods: [POST]
apiv2_account_delete_resend_code:
path: /apiv2/account_delete_resend_code
controller: App\Controller\CustomerAppAPI\AccountController:resendCode
methods: [POST]
apiv2_account_delete_code_validate:
path: /apiv2/account_delete_code_validate
controller: App\Controller\CustomerAppAPI\AccountController::validateDeleteCode
methods: [POST]
# trade-in support
apiv2_cust_vehicle_trade_in_estimate:
path: /apiv2/vehicles/{id}/trade_in_estimate
controller: App\Controller\CustomerAppAPI\VehicleController::getTradeInEstimate
methods: [GET]
# insurance
apiv2_insurance_vehicle_maker_list:
path: /apiv2/insurance/vehicles/makers
controller: App\Controller\CustomerAppAPI\InsuranceController::getVehicleMakers
methods: [GET]
apiv2_insurance_vehicle_model_list:
path: /apiv2/insurance/vehicles/models/{maker_id}
controller: App\Controller\CustomerAppAPI\InsuranceController::getVehicleModels
methods: [GET]
apiv2_insurance_vehicle_trim_list:
path: /apiv2/insurance/vehicles/trims/{model_id}
controller: App\Controller\CustomerAppAPI\InsuranceController::getVehicleTrims
methods: [GET]
apiv2_insurance_vehicle_mv_type_list:
path: /apiv2/insurance/mvtypes
controller: App\Controller\CustomerAppAPI\InsuranceController::getMVTypes
methods: [GET]
apiv2_insurance_vehicle_client_type_list:
path: /apiv2/insurance/clienttypes
controller: App\Controller\CustomerAppAPI\InsuranceController::getClientTypes
methods: [GET]
apiv2_insurance_application_create:
path: /apiv2/insurance/application
controller: App\Controller\CustomerAppAPI\InsuranceController::createApplication
methods: [POST]
apiv2_insurance_premiums_banner:
path: /apiv2/insurance/premiums_banner
controller: App\Controller\CustomerAppAPI\InsuranceController::getPremiumsBanner
methods: [GET]
apiv2_insurance_body_types:
path: /apiv2/insurance/body_types
controller: App\Controller\CustomerAppAPI\InsuranceController::getBodyTypes
methods: [GET]

View file

@ -3,6 +3,10 @@ capi_test:
path: /capi/test
controller: App\Controller\CAPI\TestController::test
capi_test_warranty_serial:
path: /test_capi/test/warranty_serial
controller: App\Controller\CAPI\TestController::warrantySerial
# battery api
@ -155,6 +159,12 @@ capi_customer_register:
controller: App\Controller\CAPI\CustomerController::register
methods: [POST]
# verify if resq customer
capi_customer_verify:
path: /capi/customer/{customer_hash}
controller: App\Controller\CAPI\CustomerController::verifyCustomer
methods: [GET]
# customer warranty api
capi_cwarr_check:
path: /capi/customer_warranty/{serial}
@ -178,3 +188,22 @@ capi_dealer_list:
path: /capi/dealers
controller: App\Controller\CAPI\DealerController::getAll
methods: [GET]
# warranty serial api
capi_warranty_serial_upload:
path: /capi/warranty_serial/upload
controller: App\Controller\CAPI\WarrantySerialController::uploadWarrantySerialFile
methods: [POST]
# pullout form system
# hub
capi_hub_list:
path: /capi/hubs
controller: App\Controller\CAPI\HubController::getAll
methods: [GET]
# job order details
capi_job_order:
path: /capi/job_order/{id}
controller: App\Controller\CAPI\JobOrderController::getJobOrder
methods: [GET]

View file

@ -95,3 +95,23 @@ capi_rider_jo_start:
controller: App\Controller\CAPI\RiderAppController::startJobOrder
methods: [POST]
# trade-ins
capi_rider_battery_sizes:
path: /rider_api/battery_sizes
controller: App\Controller\CAPI\RiderAppController::getBatterySizes
methods: [GET]
capi_rider_trade_in_types:
path: /rider_api/trade_in_types
controller: App\Controller\CAPI\RiderAppController::getTradeInTypes
methods: [GET]
capi_rider_battery_info:
path: /rider_api/battery/{serial}
controller: App\Controller\CAPI\RiderAppController::getBatteryInfo
methods: [GET]
capi_rider_update_jo:
path: /rider_api/job_order/update
controller: App\Controller\CAPI\RiderAppController::updateJobOrder
methods: [POST]

View file

@ -0,0 +1,227 @@
# api
cust_api_register:
path: /apiv2/register
controller: App\Controller\CustomerAppAPI\AuthController::register
methods: [POST]
cust_api_confirm:
path: /apiv2/number_confirm
controller: App\Controller\CustomerAppAPI\AuthController::confirmNumber
methods: [POST]
cust_api_validate:
path: /apiv2/code_validate
controller: App\Controller\CustomerAppAPI\AuthController::validateCode
methods: [POST]
cust_api_info_get:
path: /apiv2/info
controller: App\Controller\CustomerAppAPI\CustomerController::getInfo
methods: [GET]
cust_api_info_update:
path: /apiv2/info
controller: App\Controller\CustomerAppAPI\CustomerController::updateInfo
methods: [POST]
cust_api_status:
path: /apiv2/status
controller: App\Controller\CustomerAppAPI\CustomerController::getStatus
methods: [GET]
cust_api_vehicle_mfg_list:
path: /apiv2/vehicle/mfgs
controller: App\Controller\CustomerAppAPI\VehicleController::listVehicleManufacturers
methods: [GET]
cust_api_vehicle_make_list:
path: /apiv2/vehicle/mfgs/{mfg_id}/makes
controller: App\Controller\CustomerAppAPI\VehicleController::listVehicleMakes
methods: [GET]
cust_api_cust_vehicle_add:
path: /apiv2/vehicles
controller: App\Controller\CustomerAppAPI\VehicleController::addVehicle
methods: [POST]
cust_api_cust_vehicle_update:
path: /apiv2/vehicles/{id}
controller: App\Controller\CustomerAppAPI\VehicleController::updateVehicle
methods: [POST]
cust_api_cust_vehicle_list:
path: /apiv2/vehicles
controller: App\Controller\CustomerAppAPI\VehicleController::listVehicles
methods: [GET]
cust_api_promo_list:
path: /apiv2/promos
controller: App\Controller\CustomerAppAPI\PromoController::listPromos
methods: [GET]
cust_api_battery_list:
path: /apiv2/vehicles/{vid}/compatible_batteries
controller: App\Controller\CustomerAppAPI\VehicleController::getCompatibleBatteries
methods: [GET]
cust_api_jo_request:
path: /apiv2/job_order
controller: App\Controller\CustomerAppAPI\JobOrderController::requestJobOrder
methods: [POST]
cust_api_estimate:
path: /apiv2/estimate
controller: App\Controller\CustomerAppAPI\EstimateController::getEstimate
methods: [POST]
cust_api_ongoing:
path: /apiv2/job_order/ongoing
controller: App\Controller\CustomerAppAPI\JobOrderController::getOngoing
methods: [GET]
cust_api_rider_status:
path: /apiv2/rider
controller: App\Controller\CustomerAppAPI\RiderController::getRiderStatus
methods: [GET]
cust_api_rider_rating_add:
path: /apiv2/rider_rating
controller: App\Controller\CustomerAppAPI\RiderController::addRiderRating
methods: [POST]
cust_api_jo_cancel:
path: /apiv2/job_order/cancel
controller: App\Controller\CustomerAppAPI\JobOrderController:cancelJobOrder
methods: [POST]
cust_api_jo_history:
path: /apiv2/job_order/history
controller: App\Controller\CustomerAppAPI\JobOrderController:getJOHistory
methods: [GET]
cust_api_jo_invoice:
path: /apiv2/job_order/invoice
controller: App\Controller\CustomerAppAPI\JobOrderController:getJOInvoice
methods: [GET]
cust_api_device_id:
path: /apiv2/device_id
controller: App\Controller\CustomerAppAPI\DeviceController:updateDeviceID
methods: [POST]
cust_api_privacy:
path: /apiv2/privacy
controller: App\Controller\CustomerAppAPI\PrivacyController:privacySettings
methods: [POST]
cust_api_resend_code:
path: /apiv2/resend_code
controller: App\Controller\CustomerAppAPI\AuthController:resendCode
methods: [POST]
cust_api_location_support:
path: /apiv2/location_support
controller: App\Controller\CustomerAppAPI\LocationController:locationSupport
methods: [GET]
cust_api_activate_warranty:
path: /apiv2/activate_warranty
controller: App\Controller\CustomerAppAPI\WarrantyController:activateWarranty
methods: [POST]
cust_api_service_list:
path: /apiv2/services
controller: App\Controller\CustomerAppAPI\ServiceController:listServices
methods: [GET]
cust_api_partner_info:
path: /apiv2/partners/{pid}
controller: App\Controller\CustomerAppAPI\PartnerController:getPartnerInformation
methods: [GET]
cust_api_partner:
path: /apiv2/partners
controller: App\Controller\CustomerAppAPI\PartnerController:getClosestPartners
methods: [GET]
cust_api_partner_review:
path: /apiv2/partners/{pid}/review
controller: App\Controller\CustomerAppAPI\PartnerController:reviewPartner
methods: [POST]
cust_api_nearest_hub_slots:
path: /apiv2/hub_slots
controller: App\Controller\CustomerAppAPI\LocationController::getNearestHubAndSlots
methods: [GET]
cust_api_new_jo_request:
path: /apiv2/new_job_order
controller: App\Controller\CustomerAppAPI\JobOrderController::newRequestJobOrder
methods: [POST]
cust_api_version_check:
path: /apiv2/version_check
controller: App\Controller\CustomerAppAPI\AppController::versionCheck
methods: [GET]
cust_api_schedule_option_status:
path: /apiv2/schedule_option_status
controller: App\Controller\CustomerAppAPI\ScheduleController::scheduleOptionStatus
methods: [GET]
# paperless warranty / qr code
cust_api_warr_serial_check:
path: /apiv2/warranty/{serial}
controller: App\Controller\CustomerAppAPI\WarrantyController::warrantyCheck
methods: [GET]
cust_api_warr_serial_register:
path: /apiv2/warranty/{serial}
controller: App\Controller\CustomerAppAPI\WarrantyController::warrantyRegister
methods: [POST]
cust_api_jo_info:
path: /apiv2/job_order/{id}/info
controller: App\Controller\CustomerAppAPI\JobOrderController::getJobOrderInfo
methods: [GET]
cust_api_ongoing_job_orders:
path: /apiv2/job_orders/ongoing
controller: App\Controller\CustomerAppAPI\JobOrderController::getAllOngoingJobOrders
methods: [GET]
cust_api_ongoing_jo_count:
path: /apiv2/job_orders/ongoing/count
controller: App\Controller\CustomerAppAPI\JobOrderController::getOngoingJobOrderCount
methods: [GET]
cust_api_new_location:
path: /apiv2/new_location
controller: App\Controller\CustomerAppAPI\LocationController::addLocation
methods: [POST]
cust_api_locations:
path: /apiv2/locations
controller: App\Controller\CustomerAppAPI\LocationController::getLocations
methods: [GET]
cust_api_cust_vehicle_remove:
path: /apiv2/vehicles/{id}/remove
controller: App\Controller\CustomerAppAPI\VehicleController::removeVehicle
methods: [POST]
cust_api_latest_job_order:
path: /apiv2/job_order/latest
controller: App\Controller\CustomerAppAPI\JobOrderController::getLatestJobOrder
methods: [GET]
cust_api_customer_hash_get:
path: /apiv2/customer_hash
controller: App\Controller\CustomerAppAPI\CustomerController::getCustomerHash
methods: [GET]
#cust_api_completed_job_orders:
# path: /apiv2/job_orders/completed
# controller: App\Controller\CustomerAppAPI\JobOrderController::getCompletedJobOrders
# methods: [GET]

View file

@ -0,0 +1,35 @@
customer_location_list:
path: /customer-locations
controller: App\Controller\CustomerLocationController::index
methods: [GET]
customer_location_rows:
path: /customer-locations/rowdata
controller: App\Controller\CustomerLocationController::datatableRows
methods: [POST]
customer_location_add_form:
path: /customer-locations/newform
controller: App\Controller\CustomerLocationController::addForm
methods: [GET]
customer_location_add_submit:
path: /customer-locations
controller: App\Controller\CustomerLocationController::addSubmit
methods: [POST]
customer_location_update_form:
path: /customer-locations/{id}
controller: App\Controller\CustomerLocationController::updateForm
methods: [GET]
customer_location_update_submit:
path: /customer-locations/{id}
controller: App\Controller\CustomerLocationController::updateSubmit
methods: [POST]
customer_location_delete:
path: /customer-locations/{id}
controller: App\Controller\CustomerLocationController::deleteSubmit
methods: [DELETE]

View file

@ -0,0 +1,34 @@
emergency_type_list:
path: /emergency-types
controller: App\Controller\EmergencyTypeController::index
methods: [GET]
emergency_type_rows:
path: /emergency-types/rowdata
controller: App\Controller\EmergencyTypeController::datatableRows
methods: [POST]
emergency_type_add_form:
path: /emergency-types/newform
controller: App\Controller\EmergencyTypeController::addForm
methods: [GET]
emergency_type_add_submit:
path: /emergency-types
controller: App\Controller\EmergencyTypeController::addSubmit
methods: [POST]
emergency_type_update_form:
path: /emergency-types/{id}
controller: App\Controller\EmergencyTypeController::updateForm
methods: [GET]
emergency_type_update_submit:
path: /emergency-types/{id}
controller: App\Controller\EmergencyTypeController::updateSubmit
methods: [POST]
emergency_type_delete:
path: /emergency-types/{id}
controller: App\Controller\EmergencyTypeController::deleteSubmit
methods: [DELETE]

View file

@ -0,0 +1,6 @@
# insurance
insurance_listener:
path: /insurance/listen
controller: App\Controller\InsuranceController::listen
methods: [POST]

View file

@ -0,0 +1,14 @@
item_pricing:
path: /item-pricing
controller: App\Controller\ItemPricingController::index
methods: [GET]
item_pricing_update:
path: /item-pricing
controller: App\Controller\ItemPricingController::formSubmit
methods: [POST]
item_pricing_prices:
path: /item-pricing/{pt_id}/{it_id}/prices
controller: App\Controller\ItemPricingController::itemPrices
methods: [GET]

View file

@ -0,0 +1,34 @@
item_type_list:
path: /item-types
controller: App\Controller\ItemTypeController::index
methods: [GET]
item_type_rows:
path: /item-types/rowdata
controller: App\Controller\ItemTypeController::datatableRows
methods: [POST]
item_type_add_form:
path: /item-types/newform
controller: App\Controller\ItemTypeController::addForm
methods: [GET]
item_type_add_submit:
path: /item-types
controller: App\Controller\ItemTypeController::addSubmit
methods: [POST]
item_type_update_form:
path: /item-types/{id}
controller: App\Controller\ItemTypeController::updateForm
methods: [GET]
item_type_update_submit:
path: /item-types/{id}
controller: App\Controller\ItemTypeController::updateSubmit
methods: [POST]
item_type_delete:
path: /item-types/{id}
controller: App\Controller\ItemTypeController::deleteSubmit
methods: [DELETE]

View file

@ -267,3 +267,8 @@ jo_geofence:
path: /ajax/job-order/geofence
controller: App\Controller\JobOrderController::checkGeofence
methods: [GET]
jo_all_view_form:
path: /job-order/all/view/{id}
controller: App\Controller\JobOrderController::allViewForm
methods: [GET]

View file

@ -0,0 +1,38 @@
motolite_event_list:
path: /motolite_events
controller: App\Controller\MotoliteEventController::index
motolite_event_rows:
path: /motolite_events/rows
controller: App\Controller\MotoliteEventController::rows
methods: [POST]
motolite_event_create:
path: /motolite_events/create
controller: App\Controller\MotoliteEventController::addForm
methods: [GET]
motolite_event_create_submit:
path: /motolite_events/create
controller: App\Controller\MotoliteEventController::addSubmit
methods: [POST]
motolite_event_upload_image:
path: /motolite_events/upload
controller: App\Controller\MotoliteEventController::uploadImage
methods: [POST]
motolite_event_update:
path: /motolite_events/{id}
controller: App\Controller\MotoliteEventController::updateForm
methods: [GET]
motolite_event_update_submit:
path: /motolite_events/{id}
controller: App\Controller\MotoliteEventController::updateSubmit
methods: [POST]
motolite_event_delete:
path: /motolite_events/{id}
controller: App\Controller\MotoliteEventController::destroy
methods: [DELETE]

View file

@ -0,0 +1,35 @@
ownership_type_list:
path: /ownership-types
controller: App\Controller\OwnershipTypeController::index
methods: [GET]
ownership_type_rows:
path: /ownership-types/rowdata
controller: App\Controller\OwnershipTypeController::datatableRows
methods: [POST]
ownership_type_add_form:
path: /ownership-types/newform
controller: App\Controller\OwnershipTypeController::addForm
methods: [GET]
ownership_type_add_submit:
path: /ownership-types
controller: App\Controller\OwnershipTypeController::addSubmit
methods: [POST]
ownership_type_update_form:
path: /ownership-types/{id}
controller: App\Controller\OwnershipTypeController::updateForm
methods: [GET]
ownership_type_update_submit:
path: /ownership-types/{id}
controller: App\Controller\OwnershipTypeController::updateSubmit
methods: [POST]
ownership_type_delete:
path: /ownership-types/{id}
controller: App\Controller\OwnershipTypeController::deleteSubmit
methods: [DELETE]

View file

@ -0,0 +1,16 @@
# paymongo
paymongo_listener:
path: /paymongo/listen
controller: App\Controller\PayMongoController::listen
methods: [POST]
paymongo_payment_success:
path: /paymongo/success
controller: App\Controller\PayMongoController::paymentSuccess
methods: [GET]
paymongo_payment_cancelled:
path: /paymongo/cancelled
controller: App\Controller\PayMongoController::paymentCancelled
methods: [GET]

View file

@ -0,0 +1,34 @@
price_tier_list:
path: /price-tiers
controller: App\Controller\PriceTierController::index
methods: [GET]
price_tier_rows:
path: /price-tiers/rows
controller: App\Controller\PriceTierController::datatableRows
methods: [POST]
price_tier_add_form:
path: /price-tiers/newform
controller: App\Controller\PriceTierController::addForm
methods: [GET]
price_tier_add_submit:
path: /price-tiers
controller: App\Controller\PriceTierController::addSubmit
methods: [POST]
price_tier_update_form:
path: /price-tiers/{id}
controller: App\Controller\PriceTierController::updateForm
methods: [GET]
price_tier_update_submit:
path: /price-tiers/{id}
controller: App\Controller\PriceTierController::updateSubmit
methods: [POST]
price_tier_delete:
path: /price-tiers/{id}
controller: App\Controller\PriceTierController::deleteSubmit
methods: [DELETE]

View file

@ -147,3 +147,23 @@ rep_hub_filter_submit:
path: /report/hub_filter_report
controller: App\Controller\ReportController::hubFilterSubmit
methods: [POST]
rep_warranty_raffle_form:
path: /report/warranty_raffle_report
controller: App\Controller\ReportController::warrantyRaffleForm
methods: [GET]
rep_warranty_raffle_submit:
path: /report/warranty_raffle_report
controller: App\Controller\ReportController::warrantyRaffleSubmit
methods: [POST]
rep_jo_raffle_form:
path: /report/jo_raffle_report
controller: App\Controller\ReportController::joRaffleForm
methods: [GET]
rep_jo_raffle_submit:
path: /report/jo_raffle_report
controller: App\Controller\ReportController::joRaffleSubmit
methods: [POST]

View file

@ -0,0 +1,23 @@
jo_resq_proc:
path: /resq-job-order/processing
controller: App\Controller\ResqJobOrderController::listProcessing
methods: [GET]
jo_resq_proc_rows:
path: /resq-job-order/processing-rows
controller: App\Controller\ResqJobOrderController::datatableRows
methods: [POST]
defaults:
tier: "proc"
jo_resq_all:
path: /resq-job-order/all
controller: App\Controller\ResqJobOrderController::listAll
methods: [GET]
jo_resq_all_rows:
path: /resq-job-orer/all
controller: App\Controller\ResqJobOrderController::datatableRows
methods: [POST]
defaults:
tier: "all"

View file

@ -0,0 +1,33 @@
reviewtag_list:
path: /review_tags
controller: App\Controller\ReviewTagController::index
reviewtag_rows:
path: /review_tags/rows
controller: App\Controller\ReviewTagController::rows
methods: [POST]
reviewtag_create:
path: /review_tags/create
controller: App\Controller\ReviewTagController::addForm
methods: [GET]
reviewtag_create_submit:
path: /review_tags/create
controller: App\Controller\ReviewTagController::addSubmit
methods: [POST]
reviewtag_update:
path: /review_tags/{id}
controller: App\Controller\ReviewTagController::updateForm
methods: [GET]
reviewtag_update_submit:
path: /review_tags/{id}
controller: App\Controller\ReviewTagController::updateSubmit
methods: [POST]
reviewtag_delete:
path: /review_tags/{id}
controller: App\Controller\ReviewTagController::destroy
methods: [DELETE]

View file

@ -0,0 +1,34 @@
service_offering_list:
path: /service-offerings
controller: App\Controller\ServiceOfferingController::index
methods: [GET]
service_offering_rows:
path: /service-offerings/rowdata
controller: App\Controller\ServiceOfferingController::datatableRows
methods: [POST]
service_offering_add_form:
path: /service-offerings/newform
controller: App\Controller\ServiceOfferingController::addForm
methods: [GET]
service_offering_add_submit:
path: /service-offerings
controller: App\Controller\ServiceOfferingController::addSubmit
methods: [POST]
service_offering_update_form:
path: /service-offerings/{id}
controller: App\Controller\ServiceOfferingController::updateForm
methods: [GET]
service_offering_update_submit:
path: /service-offerings/{id}
controller: App\Controller\ServiceOfferingController::updateSubmit
methods: [POST]
service_offering_delete:
path: /service-offerings/{id}
controller: App\Controller\ServiceOfferingController::deleteSubmit
methods: [DELETE]

View file

@ -0,0 +1,35 @@
subticket_type_list:
path: /subticket-types
controller: App\Controller\SubTicketTypeController::index
methods: [GET]
subticket_type_rows:
path: /subticket-types/rowdata
controller: App\Controller\SubTicketTypeController::datatableRows
methods: [POST]
subticket_type_add_form:
path: /subticket-types/newform
controller: App\Controller\SubTicketTypeController::addForm
methods: [GET]
subticket_type_add_submit:
path: /subticket-types
controller: App\Controller\SubTicketTypeController::addSubmit
methods: [POST]
subticket_type_update_form:
path: /subticket-types/{id}
controller: App\Controller\SubTicketTypeController::updateForm
methods: [GET]
subticket_type_update_submit:
path: /subticket-types/{id}
controller: App\Controller\SubTicketTypeController::updateSubmit
methods: [POST]
subticket_type_delete:
path: /subticket-types/{id}
controller: App\Controller\SubTicketTypeController::deleteSubmit
methods: [DELETE]

60
config/routes/tapi.yaml Normal file
View file

@ -0,0 +1,60 @@
# third party api
# job order
tapi_jo_request:
path: /tapi/job_order
controller: App\Controller\TAPI\JobOrderController::requestJobOrder
methods: [POST]
tapi_estimate:
path: /tapi/estimate
controller: App\Controller\TAPI\JobOrderController::getEstimate
methods: [POST]
tapi_jo_invoice:
path: /tapi/job_order/invoice/{jo_id}
controller: App\Controller\TAPI\JobOrderController:getJOInvoice
methods: [GET]
tapi_jo_cancel:
path: /tapi/job_order/cancel
controller: App\Controller\TAPI\JobOrderController:cancelJobOrder
methods: [POST]
tapi_jo_info:
path: /tapi/job_order/{jo_id}/info
controller: App\Controller\TAPI\JobOrderController::getJobOrderInfo
methods: [GET]
tapi_location_support:
path: /tapi/location_support
controller: App\Controller\TAPI\JobOrderController:locationSupport
methods: [POST]
tapi_nearest_hub_slots:
path: /tapi/hub_slots
controller: App\Controller\TAPI\JobOrderController::getNearestHubAndSlots
methods: [POST]
# vehicle manufacturer and vehicle
tapi_vehicle_mfg_list:
path: /tapi/vehicle/mfgs
controller: App\Controller\TAPI\VehicleController::listVehicleManufacturers
methods: [GET]
tapi_vehicle_make_list:
path: /tapi/vehicle/mfgs/{mfg_id}/makes
controller: App\Controller\TAPI\VehicleController::listVehicleMakes
methods: [GET]
# battery
tapi_battery_list:
path: /tapi/vehicles/{vid}/compatible_batteries
controller: App\Controller\TAPI\BatteryController::getCompatibleBatteries
methods: [POST]
# promos
tapi_promo_list:
path: /tapi/promos
controller: App\Controller\TAPI\PromoController::listPromos
methods: [GET]

View file

@ -0,0 +1,35 @@
ticket_type_list:
path: /ticket-types
controller: App\Controller\TicketTypeController::index
methods: [GET]
ticket_type_rows:
path: /ticket-types/rowdata
controller: App\Controller\TicketTypeController::datatableRows
methods: [POST]
ticket_type_add_form:
path: /ticket-types/newform
controller: App\Controller\TicketTypeController::addForm
methods: [GET]
ticket_type_add_submit:
path: /ticket-types
controller: App\Controller\TicketTypeController::addSubmit
methods: [POST]
ticket_type_update_form:
path: /ticket-types/{id}
controller: App\Controller\TicketTypeController::updateForm
methods: [GET]
ticket_type_update_submit:
path: /ticket-types/{id}
controller: App\Controller\TicketTypeController::updateSubmit
methods: [POST]
ticket_type_delete:
path: /ticket-types/{id}
controller: App\Controller\TicketTypeController::deleteSubmit
methods: [DELETE]

View file

@ -13,6 +13,10 @@ parameters:
cvu_brand_id: "%env(CVU_BRAND_ID)%"
country_code: "%env(COUNTRY_CODE)%"
api_version: "%env(API_VERSION)%"
android_app_version: "%env(ANDROID_APP_VERSION)%"
ios_app_version: "%env(IOS_APP_VERSION)%"
insurance_premiums_banner_url: "%env(INSURANCE_PREMIUMS_BANNER_URL)%"
enabled_hub_filters: "%env(ENABLED_HUB_FILTERS)%"
services:
# default configuration for services in *this* file
@ -43,20 +47,6 @@ services:
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
Catalyst\AuthBundle\Service\ACLGenerator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
$acl_file: "%app_acl_file%"
Catalyst\AuthBundle\Service\ACLVoter:
arguments:
$user_class: "App\\Entity\\User"
tags: ['security.voter']
Catalyst\AuthBundle\Service\UserChecker:
App\Service\FileUploader:
arguments:
$target_dir: '%image_upload_directory%'
@ -81,6 +71,11 @@ services:
$redis_client: "@App\\Service\\RedisClientProvider"
$key: "mqtt_events"
App\Service\MQTTClientApiv2:
arguments:
$redis_client: "@App\\Service\\RedisClientProvider"
$key: "mqtt_events"
App\Service\APNSClient:
arguments:
$redis_client: "@App\\Service\\RedisClientProvider"
@ -111,60 +106,29 @@ services:
$cvu_mfg_id: "%env(CVU_MFG_ID)%"
$cvu_brand_id: "%env(CVU_BRAND_ID)%"
App\Command\LoadWarrantySerialCommand:
arguments:
$callback_url: "%env(WARRANTY_SERIAL_CALLBACK_URL)%"
App\Command\ProcessLatePaymongoTransactionsCommand:
arguments:
$em: "@doctrine.orm.entity_manager"
$paymongo: "@App\\Service\\PayMongoConnector"
$webhook_id: "%env(PAYMONGO_WEBHOOK_ID)%"
# rider tracker service
App\Service\RiderTracker:
arguments:
$redis_client: "@App\\Service\\RedisClientProvider"
Catalyst\APIBundle\Security\APIKeyUserProvider:
arguments:
$em: "@doctrine.orm.entity_manager"
Catalyst\APIBundle\Security\APIKeyAuthenticator:
arguments:
$em: "@doctrine.orm.entity_manager"
Catalyst\APIBundle\Command\UserCreateCommand:
arguments:
$em: "@doctrine.orm.entity_manager"
tags: ['console.command']
Catalyst\APIBundle\Command\TestCommand:
tags: ['console.command']
Catalyst\APIBundle\Command\TestAPICommand:
tags: ['console.command']
Catalyst\APIBundle\Access\Voter:
arguments:
$acl_gen: "@Catalyst\\APIBundle\\Access\\Generator"
$user_class: "Catalyst\\APIBundle\\Entity\\User"
tags: ['security.voter']
Catalyst\APIBundle\Access\Generator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
$acl_file: "%api_acl_file%"
Catalyst\MenuBundle\Menu\Generator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
Catalyst\MenuBundle\Listener\MenuAnnotationListener:
arguments:
$menu_name: "main_menu"
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
# invoice generator
App\Service\InvoiceGenerator\ResqInvoiceGenerator: ~
# invoice generator interface
App\Service\InvoiceGeneratorInterface: "@App\\Service\\InvoiceGenerator\\ResqInvoiceGenerator"
App\Service\InvoiceGeneratorInterface: "@App\\Service\\InvoiceManager"
# invoice manager
App\Service\InvoiceManager: ~
# job order generator
App\Service\JobOrderHandler\ResqJobOrderHandler:
@ -253,6 +217,30 @@ services:
$sub_key: "%env(MOTIV_KEY)%"
$token: "%env(MOTIV_TOKEN)%"
# insurance connector
App\Service\InsuranceConnector:
arguments:
$base_url: "%env(INSURANCE_BASE_URL)%"
$username: "%env(INSURANCE_USERNAME)%"
$password: "%env(INSURANCE_PASSWORD)%"
# entity listener for gateway transactions
App\EntityListener\GatewayTransactionListener:
arguments:
$em: "@doctrine.orm.entity_manager"
$ic: "@App\\Service\\InsuranceConnector"
tags:
- name: doctrine.orm.entity_listener
event: 'postUpdate'
entity: 'App\Entity\GatewayTransaction'
# paymongo connector
App\Service\PayMongoConnector:
arguments:
$base_url: "%env(PAYMONGO_BASE_URL)%"
$public_key: "%env(PAYMONGO_PUBLIC_KEY)%"
$secret_key: "%env(PAYMONGO_SECRET_KEY)%"
# entity listener for customer vehicle warranty code history
App\EntityListener\CustomerVehicleSerialListener:
arguments:
@ -273,6 +261,14 @@ services:
arguments:
$em: "@doctrine.orm.entity_manager"
# warranty logger for raffle
App\Service\WarrantyRaffleLogger:
arguments:
$em: "@doctrine.orm.entity_manager"
# warranty raffle filter
App\Service\WarrantyRaffleFilter: ~
# promo logger
App\Service\PromoLogger:
arguments:
@ -301,3 +297,62 @@ services:
App\Service\HubFilteringGeoChecker:
arguments:
$geofence_flag: "%env(HUB_GEOFENCE_ENABLE)%"
# bulk warranty uploader
App\Service\WarrantyBulkUploader:
arguments:
$em: "@doctrine.orm.entity_manager"
# warranty serial file logger
App\Service\WarrantySerialUploadLogger:
arguments:
$em: "@doctrine.orm.entity_manager"
# warranty serial load logger
App\Service\WarrantySerialLoadLogger:
arguments:
$em: "@doctrine.orm.entity_manager"
# FCM sender
App\Service\FCMSender:
arguments:
$server_key: "%env(FCM_SERVER_KEY)%"
$sender_id: "%env(FCM_SENDER_ID)%"
# price tier manager
App\Service\PriceTierManager:
arguments:
$em: "@doctrine.orm.entity_manager"
# hub filters
App\Service\HubFilter\BaseHubFilter:
arguments:
$hub_filter_logger: "@App\\Service\\HubFilterLogger"
$em: "@doctrine.orm.entity_manager"
$rt: "@App\\Service\\RisingTideGateway"
$trans: "@Symfony\\Contracts\\Translation\\TranslatorInterface"
App\Service\HubFilter\Filters\DateAndTimeHubFilter:
public: true
App\Service\HubFilter\Filters\JoTypeHubFilter:
public: true
App\Service\HubFilter\Filters\MaxResultsHubFilter:
public: true
App\Service\HubFilter\Filters\PaymentMethodHubFilter:
public: true
App\Service\HubFilter\Filters\RiderAvailabilityHubFilter:
public: true
App\Service\HubFilter\Filters\InventoryHubFilter:
public: true
arguments:
$im: "@App\\Service\\InventoryManager"
App\Service\HubFilter\Filters\RoundRobinHubFilter:
public: true
arguments:
$hub_distributor: "@App\\Service\\HubDistributor"

View file

@ -155,6 +155,30 @@ span.has-danger,
color: #fff !important;
}
.m-table__row--is_vip td {
background-color: #ffff00 !important;
color: #414a4c !important;
}
.m-table__row--is_vip td > span,
.m-table__row--is_vip td > span a,
.m-table__row--is_vip td > span a i {
color: #414a4c !important;
}
.m-table__row--is_emergency td {
background-color: #ffa500 !important;
color: #fff !important;
}
.m-table__row--is_emergency td > span,
.m-table__row--is_emergency td > span a,
.m-table__row--is_emergency td > span a i {
color: #fff !important;
}
.m-datatable.m-datatable--default > .m-datatable__table {
min-height: 0 !important;
}
@ -358,4 +382,4 @@ span.has-danger,
.map-info .m-badge {
border-radius: 0;
}
}

BIN
public/assets/images/image.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -0,0 +1,74 @@
$(function() {
// export table to csv
$(document).on('click', '[data-export-csv]', async function(e) {
const el = e.target.closest('[data-export-csv]');
const oldLabel = el.innerHTML;
// set loading status
el.disabled = true;
el.innerHTML = 'Exporting...';
const formData = new FormData();
formData.append('datatable[pagination][page]', 1);
formData.append('datatable[pagination][perpage]', 10000000);
// get all rows
const response = await fetch(el.dataset.url, {
method: el.dataset.method,
body: formData,
});
const result = await response.json();
if (response.status === 200) {
// empty set returned
if (parseInt(result.meta.total) === 0) {
swal({
title: 'Whoops',
html: 'No data to export!',
type: 'warning',
});
}
// build csv data
const csvRows = [];
const fieldList = el.dataset.fields.split(',');
csvRows.push(el.dataset.headers);
result.data.forEach((row) => {
const fieldData = [];
fieldList.forEach((field) => {
fieldData.push('"' + row[field] + '"');
});
csvRows.push(fieldData.join(','));
});
const csvData = csvRows.join('\n');
// build the csv file
const csvFile = new Blob([csvData], {
type: 'text/csv',
});
// create a link to the file and download it
const url = window.URL.createObjectURL(csvFile);
const a = document.createElement('a');
a.href = url;
a.download = el.dataset.filename + '.csv';
a.click();
} else {
// something went wrong on the server
swal({
title: 'Whoops',
html: 'An error has occurred while retrieving data.',
type: 'error',
});
}
// remove loading status
el.disabled = false;
el.innerHTML = oldLabel;
});
});

BIN
public/battery/enduro_mobile.jpg Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

BIN
public/battery/excel_mobile.jpg Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

BIN
public/battery/gold_mobile.jpg Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,54 @@
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\WarrantySerialQueue;
class CountTotalPendingWarrantySerialFilesCommand extends Command
{
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
parent::__construct();
}
protected function configure()
{
$this->setName('warrantyserial:count')
->setDescription('Count number of pending warranty serial files.')
->setHelp('Count number of pending warranty serial files.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->em;
$status = 'pending';
$db = $em->getConnection();
$ws_query_sql = 'SELECT COUNT(*) AS total FROM warranty_serial_queue
WHERE status = :status';
$ws_query_stmt = $db->prepare($ws_query_sql);
$ws_query_stmt->bindValue('status', $status);
$ws_results = $ws_query_stmt->executeQuery();
$results = $ws_results->fetchAssociative();
$output->write($results['total']);
return 0;
}
}

View file

@ -10,8 +10,8 @@ use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Entity\User as APIUser;
use Catalyst\APIBundle\Entity\Role as APIRole;
use App\Entity\ApiUser as APIUser;
use Catalyst\ApiBundle\Entity\Role as APIRole;
use App\Entity\Rider;

View file

@ -0,0 +1,529 @@
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\JobOrder;
use App\Entity\JOEvent;
use App\Entity\User;
use App\Entity\Warranty;
use App\Entity\SAPBattery;
use App\Ramcar\JOStatus;
use App\Ramcar\JOEventType;
use App\Ramcar\DeliveryStatus;
use App\Ramcar\WarrantyClass;
use App\Ramcar\ServiceType;
use App\Ramcar\WarrantySource;
use App\Ramcar\WarrantyStatus;
use DateTime;
use DateInterval;
class FulfillOpenJobOrderCommand extends Command
{
const DEFAULT_SAP_WARRANTY = 12;
const JO_BATCH_CTR = 200;
protected $em;
protected $batt_hash;
protected $sap_batt_hash;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
parent::__construct();
}
protected function configure()
{
$this->setName('joborder:fulfillopenjosnosms')
->setDescription('Fulfill open job orders without sending an SMS message.')
->setHelp('Mark open job orders as fulfilled and should not send a SMS message. Date format: YYYY-MM-DD')
->addArgument('end_date', InputArgument::REQUIRED, 'End date. Format: YYYY-MM-DD');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// load batteries into hash
$this->populateBatteryIndex();
// load sap batteries into hash
$this->populateSAPBatteryIndex();
// get the input date
$str_date_end = $input->getArgument('end_date');
// append the 23:59:59 to end date
$str_date_end = $str_date_end . ' ' . '23:59:59';
// starting time to count is date schedule
$date_end = new DateTime($str_date_end);
// get current date and convert to string
$current_date = new DateTime();
$str_current_date = $current_date->format('Y-m-d H:i:s');
// find all open job orders starting from input date and before
// need to get customer id, customer vehicle id, service type, warranty class
$conn = $this->em->getConnection();
$jo_sql = 'SELECT jo.id AS jo_id, c.id AS c_id, cv.id AS cv_id,
jo.service_type, jo.warranty_class, jo.rider_id, jo.date_schedule
FROM job_order jo, customer c, customer_vehicle cv
WHERE jo.customer_id = c.id AND jo.cvehicle_id = cv.id
AND jo.status IN (\'pending\', \'rider_assign\', \'assigned\', \'in_transit\', \'in_progress\')
AND jo.date_schedule <= :date_end';
$stmt = $conn->prepare($jo_sql);
$stmt->execute([
'date_end' => $str_date_end]);
$jo_results = $stmt->fetchAll();
error_log('JOs found ' . count($jo_results));
$total_jos = count($jo_results);
$jo_ctr = 0;
$update_jo_ctr = 0;
$update_wheres = [];
$w_data = [];
$jo_evt_data = [];
foreach ($jo_results as $jo_row)
{
// get the data first
$jo_id = $jo_row['jo_id'];
$cust_id = $jo_row['c_id'];
$cv_id = $jo_row['cv_id'];
$service_type = $jo_row['service_type'];
$warranty_class = $jo_row['warranty_class'];
$rider_id = $jo_row['rider_id'];
$str_date_schedule = $jo_row['date_schedule'];
$jo_ctr++;
// fulfill JO
$this->fulfillJO($conn, $jo_id, $update_jo_ctr, $update_wheres, $jo_ctr, $total_jos);
// create JO event
$jo_evt_data[] = $this->createJOEvent($conn, $jo_id, $str_current_date, $rider_id);
// error_log($jo_ctr . ' Processing JO ' . $jo_id);
// check service type
if ($service_type == ServiceType::BATTERY_REPLACEMENT_NEW)
{
// new battery so we need to create warranty so we need to get battery id from invoice
$batt_id = $this->getBatteryInformation($conn, $jo_id);
if (($batt_id != null) && (isset($this->batt_hash[$batt_id])))
$w_data[] = $this->createWarrantyForJO($conn, $current_date, $str_date_schedule, $cust_id, $cv_id, $warranty_class, $batt_id);
}
}
// load data file for jo event
$this->createLoadDataFileForJOEvent($jo_evt_data);
// load data file for warranty
$this->createLoadDataFileForWarranty($w_data);
return 0;
}
protected function fulfillJO($conn, $jo_id, &$update_jo_ctr, &$update_wheres, $jo_ctr, $total_jos)
{
$update_wheres[] = 'id = ' . $jo_id;
// update db when we reach max # of JOs or when we reach total number of jos
if (($update_jo_ctr == self::JO_BATCH_CTR) ||
($jo_ctr == $total_jos))
{
error_log('Processing ' . $update_jo_ctr . ' job orders...');
$update_where_string = implode(' OR ' , $update_wheres);
// update job order
$fulfill_jo_sql = 'UPDATE job_order SET status = :fulfilled, delivery_status = :del_fulfilled WHERE ' . $update_where_string;
// error_log($fulfill_jo_sql);
$fulfill_jo_stmt = $conn->prepare($fulfill_jo_sql);
$fulfill_jo_stmt->execute([
'fulfilled' => JOStatus::FULFILLED,
'del_fulfilled' => DeliveryStatus::FULFILLED,
]);
// reset the wheres string
$update_wheres = [];
// reset the update jo counter
$update_jo_ctr = 0;
}
else
$update_jo_ctr++;
}
protected function createJOEvent($conn, $jo_id, $str_current_date, $rider_id)
{
// create jo event
// set user to admin that has id of 1
$user_id = 1;
$r_id = '\N';
// check if rider is null
if ($rider_id != NULL)
$r_id = $rider_id;
// create array for the jo event
$data = [
$user_id,
$jo_id,
$str_current_date,
$str_current_date,
JOEventType::FULFILL,
$r_id,
];
return $data;
}
protected function getBatteryInformation($conn, $jo_id)
{
// break this down into two sql calls
// get the invoice for job order
$i_sql = 'SELECT i.id FROM invoice i
WHERE i.job_order_id = :jo_id';
$i_stmt = $conn->prepare($i_sql);
$i_stmt->execute([
'jo_id' => $jo_id,
]);
$i_result = $i_stmt->fetch();
// check if invoice exists
if (empty($i_result))
return null;
$invoice_id = $i_result['id'];
// get the battery id from invoice item
$ii_sql = 'SELECT ii.battery_id FROM invoice_item ii
WHERE ii.invoice_id = :invoice_id
AND ii.battery_id IS NOT NULL';
$ii_stmt = $conn->prepare($ii_sql);
$ii_stmt->execute([
'invoice_id' => $invoice_id,
]);
$ii_result = $ii_stmt->fetch();
// checking for result
if (empty($ii_result))
return null;
$batt_id = $ii_result['battery_id'];
return $batt_id;
}
protected function createWarrantyForJO($conn, $current_date, $str_date_schedule, $cust_id, $cv_id, $warranty_class, $batt_id)
{
// convert current date to string since we use this for date_create
$str_current_date = $current_date->format('Y-m-d H:i:s');
// get the warranty period based on warranty class from battery hash
$warranty_period = $this->getWarrantyPeriod($batt_id, $warranty_class);
// compute date expiry.
// convert to DateTime date schedule
$date_schedule = DateTime::createFromFormat('Y-m-d H:i:s', $str_date_schedule);
$date_expire = $this->computeDateExpire($date_schedule, $warranty_period);
// convert to string the expiry date
$str_date_expire = $date_expire->format('Y-m-d');
// convert date schedule to just date
$str_date_purchase = $date_schedule->format('Y-m-d');
// check if date_expire is after or equal to the current date
// if so, set warranty status to active
$warranty_status = WarrantyStatus::EXPIRED;
if ($date_expire >= $current_date)
$warranty_status = WarrantyStatus::ACTIVE;
// get customer
$cust_info = $this->getCustomerInfo($conn, $cust_id);
// get customer vehicle
$cv_info = $this->getCustomerVehicleInfo($conn, $cv_id);
// customer info
$first_name = addslashes($cust_info['first_name']);
$last_name = addslashes($cust_info['last_name']);
$mobile = addslashes($cust_info['mobile']);
// customer vehicle info
$plate_number = $cv_info['plate_number'];
$vehicle_id = $cv_info['vehicle_id'];
// battery info
$model_id = $this->batt_hash[$batt_id]['model_id'];
$size_id = $this->batt_hash[$batt_id]['size_id'];
// need to confirm that sap_code exists in sap_battery
if (isset($this->sap_batt_hash['sap_code']))
$sap_code = $this->batt_hash[$batt_id]['sap_code'];
else
$sap_code = '\N';
// set flag_activated to false since that's the default in Warranty's constructor
$flag_activated = false;
// create array for the infile
$warranty_data = [
$model_id,
$size_id,
$sap_code,
$warranty_class,
$plate_number,
$warranty_status,
$str_current_date,
$str_date_purchase,
$str_date_expire,
$first_name,
$last_name,
$mobile,
$flag_activated,
$vehicle_id,
$cust_id,
WarrantySource::ADMIN_PANEL,
];
return $warranty_data;
}
protected function createLoadDataFileForWarranty($warranty_data)
{
// cache directory
$cache_dir = __DIR__ . '/../../var/cache';
$file = $cache_dir . '/warranty_data.tab';
error_log('opening file for warranty - ' . $file);
$fp = fopen($file, 'w');
if ($fp === false)
{
error_log('could not open file for load data infile - ' . $file);
}
else
{
foreach ($warranty_data as $key => $data)
{
$line = implode('|', $data) . "\r\n";
fwrite($fp, $line);
}
}
fclose($fp);
error_log('Loading warranty data');
$conn = $this->em->getConnection();
$stmt = $conn->prepare('LOAD DATA LOCAL INFILE \'' . $file . '\' INTO TABLE warranty FIELDS TERMINATED BY \'|\' LINES TERMINATED BY \'\\r\\n\' (bty_model_id,bty_size_id,sap_bty_id,warranty_class,plate_number,status,date_create,date_purchase,date_expire,first_name,last_name,mobile_number,flag_activated,vehicle_id,customer_id, create_source)');
$result = $stmt->execute();
if (!$result)
error_log('Failed loading data.');
// TODO: delete file?
}
protected function createLoadDataFileForJOEvent($jo_evt_data)
{
// cache directory
$cache_dir = __DIR__ . '/../../var/cache';
$file = $cache_dir . '/jo_event_data.tab';
error_log('opening file for jo_event - ' . $file);
$fp = fopen($file, 'w');
if ($fp === false)
{
error_log('could not open file for load data infile - ' . $file);
}
else
{
foreach ($jo_evt_data as $key => $data)
{
$line = implode('|', $data) . "\r\n";
fwrite($fp, $line);
}
}
fclose($fp);
error_log('Loading jo event data');
$conn = $this->em->getConnection();
$stmt = $conn->prepare('LOAD DATA LOCAL INFILE \'' . $file . '\' INTO TABLE jo_event FIELDS TERMINATED BY \'|\' LINES TERMINATED BY \'\\r\\n\' (create_user_id, job_order_id, date_create, date_happen, type_id, rider_id)');
$result = $stmt->execute();
if (!$result)
error_log('Failed loading data.');
// TODO: delete file?
}
protected function getCustomerInfo($conn, $id)
{
$cust_info = [];
$cust_sql = 'SELECT c.first_name, c.last_name, c.phone_mobile
FROM customer c
WHERE c.id = :id';
$cust_stmt = $conn->prepare($cust_sql);
$cust_stmt->execute([
'id' => $id,
]);
$cust_result = $cust_stmt->fetch();
$cust_info = [
'first_name' => $cust_result['first_name'],
'last_name' => $cust_result['last_name'],
'mobile' => $cust_result['phone_mobile'],
];
return $cust_info;
}
protected function getCustomerVehicleInfo($conn, $id)
{
$cv_info = [];
$cv_sql = 'SELECT cv.plate_number, cv.vehicle_id
FROM customer_vehicle cv
WHERE cv.id = :id';
$cv_stmt = $conn->prepare($cv_sql);
$cv_stmt->execute([
'id' => $id,
]);
$cv_result = $cv_stmt->fetch();
$plate_number = $cv_result['plate_number'];
$clean_plate = $this->cleanPlateNumber($plate_number);
$cv_info = [
'plate_number' => $clean_plate,
'vehicle_id' => $cv_result['vehicle_id'],
];
return $cv_info;
}
protected function getWarrantyPeriod($batt_id, $warranty_class)
{
// set default period to that of private
$period = $this->batt_hash[$batt_id]['warr_private'];
if ($warranty_class == WarrantyClass::WTY_PRIVATE)
{
$period = $this->batt_hash[$batt_id]['warr_private'];
return $period;
}
if ($warranty_class == WarrantyClass::WTY_COMMERCIAL)
{
$period = $this->batt_hash[$batt_id]['warr_commercial'];
return $period;
}
if ($warranty_class == WarrantyClass::WTY_TNV)
{
$period = $this->batt_hash[$batt_id]['warr_tnv'];
return $period;
}
return $period;
}
protected function computeDateExpire($purchase_date, $warranty_period)
{
$expire_date = clone $purchase_date;
$expire_date->add(new DateInterval('P'.$warranty_period.'M'));
return $expire_date;
}
protected function cleanPlateNumber($plate)
{
// trim plate number down to 20 characters
$trim_plate = str_replace(' ','', $plate);
// truncate plate number down to 20 (max length)
$trunc_plate = substr($trim_plate, 0, 20);
return strtoupper($trunc_plate);
}
protected function populateBatteryIndex()
{
$conn = $this->em->getConnection();
// get all the batteries
$sql = 'SELECT b.id, b.model_id, b.size_id, b.sap_code, b.warr_private, b.warr_commercial, b.warr_tnv
FROM battery b';
$stmt = $conn->prepare($sql);
$stmt->execute();
$results = $stmt->fetchAll();
// go through the rows
foreach ($results as $row)
{
// breaking this down for clarity
$battery_id = $row['id'];
$model_id = $row['model_id'];
$size_id = $row['size_id'];
$sap_code = trim($row['sap_code']);
$warr_private = $row['warr_private'];
$warr_commercial = $row['warr_commercial'];
$warr_tnv = $row['warr_tnv'];
$this->batt_hash[$battery_id] = [
'sap_code' => $sap_code,
'model_id' => $model_id,
'size_id' => $size_id,
'warr_private' => $warr_private,
'warr_commercial' => $warr_commercial,
'warr_tnv' => $warr_tnv,
];
}
}
protected function populateSAPBatteryIndex()
{
$conn = $this->em->getConnection();
// get all the sap batteries
$sql = 'SELECT sap.id, sap.brand_id, sap.size_id FROM sap_battery sap';
$stmt = $conn->prepare($sql);
$stmt->execute();
$results = $stmt->fetchAll();
// go through the rows
foreach ($results as $row)
{
// set warranty period to default warranty period for SAP batteries
$this->sap_batt_hash[$row['id']] = [
'sap_brand' => $row['brand_id'],
'sap_size' => $row['size_id'],
'warranty' => self::DEFAULT_SAP_WARRANTY,
];
}
}
}

View file

@ -43,7 +43,7 @@ class GenerateBatteryCompatibilityCommand extends Command
$vehicles = $vm->getVehicles();
foreach ($vehicles as $vehicle)
{
$batteries = $vehicle->getBatteries();
$batteries = $vehicle->getActiveBatteries();
$comp_batt = [];
foreach ($batteries as $battery)
{

View file

@ -0,0 +1,463 @@
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use CrEOF\Spatial\PHP\Types\Geometry\Point;
use DateTime;
use App\Entity\VehicleManufacturer;
use App\Entity\Vehicle;
use App\Entity\Battery;
use App\Entity\BatteryManufacturer;
use App\Entity\BatteryModel;
use App\Entity\BatterySize;
class ImportYokohamaVehicleBatteryCompatibilityCommand extends Command
{
const F_V_BRAND = 0;
const F_V_MAKE = 1;
const F_V_MODEL_YEAR = 2;
const F_B_SIZE = 7;
const F_B_MODEL = 8;
//const F_B_ALT_PREM_MF = 10;
//const F_B_ALT_PREM_LM = 11;
//const F_B_ALT_SUPER_PREM_MF = 12;
//const F_B_ALT_SUPREME_MF = 13;
//const F_B_ALT_PLATINUM_MF = 14;
// the rest of the fields are irrelevant
protected $em;
protected $vmfg_index;
protected $v_index;
protected $batt_index;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
$this->vmfg_index = [];
$this->v_index = [];
$this->batt_index = [];
parent::__construct();
}
protected function configure()
{
$this->setName('yokohamavehicle:import')
->setDescription('Import Yokohama data CSV file with vehicles and batteries.')
->setHelp('Creates vehicles and batteries based on imported Yokohama CSV.')
->addArgument('input_file', InputArgument::REQUIRED, 'Path to the CSV file.')
->addArgument('output_file', InputArgument::REQUIRED, 'Path to output file.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$csv_file = $input->getArgument('input_file');
$output_file = $input->getArgument('output_file');
$this->populateVehicleManufacturerIndex();
$this->populateVehicleIndex();
$this->populateBatteryIndex();
// attempt to open file
try
{
$fh = fopen($csv_file, "r");
}
catch (Exception $e)
{
throw new Exception('The file "' . $csv_file . '" could be read.');
}
// get entity manager
$em = $this->em;
$vbrands = [];
$output_info = [];
// loop through rows
$row_num = 1;
$prem_mf_name = '';
$prem_lm_name = '';
$super_prem_mf_name = '';
$supreme_mf_name = '';
$platinum_mf_name = '';
while (($fields = fgetcsv($fh)) !== false)
{
$output->writeln("Parsing row " . $row_num . "...");
// alternate brands are not in file, so we just comment out
// get the alternate battery brand header names
/*
if ($row_num == 2)
{
$prem_mf_name = $this->normalizeName($fields[SELF::F_B_ALT_PREM_MF]);
$prem_lm_name = $this->normalizeName($fields[SELF::F_B_ALT_PREM_LM]);
$super_prem_mf_name = $this->normalizeName($fields[SELF::F_B_ALT_SUPER_PREM_MF]);
$supreme_mf_name = $this->normalizeName($fields[SELF::F_B_ALT_SUPREME_MF]);
$platinum_mf_name = $this->normalizeName($fields[SELF::F_B_ALT_PLATINUM_MF]);
}
*/
// process row
$output_info[] = $this->processRow($fields, $vbrands, $row_num, $prem_mf_name, $prem_lm_name,
$super_prem_mf_name, $supreme_mf_name, $platinum_mf_name);
$row_num++;
}
// save to db the valid ones
foreach ($vbrands as $brand_name => $vbrand)
{
// vehicles
foreach ($vbrand['vehicles'] as $row_num => $vdata)
{
$model = $vdata['model'];
if ($model == 'NONE')
{
$m_year_from = 0;
$m_year_to = 0;
}
else
{
$ex_model = explode('-', $model);
$m_year_from = trim($ex_model[0]);
if (isset($ex_model[1]))
$m_year_to = trim($ex_model[1]);
else
$m_year_to = 0;
}
$vehicle = $this->v_index[$brand_name][$vdata['make'] . '|' . intval($m_year_from) . '|' . intval($m_year_to)];
// recommended battery
$vdata['battery']->addVehicle($vehicle);
// alt_batteries
// alternate brands are not in file, so we just comment out
/*
if (isset($vdata['alt_battery_prem_mf']))
$vdata['alt_battery_prem_mf']->addVehicle($vehicle);
if (isset($vdata['alt_battery_prem_lm']))
$vdata['alt_battery_prem_lm']->addVehicle($vehicle);
if (isset($vdata['alt_battery_super_prem_mf']))
$vdata['alt_battery_super_prem_mf']->addVehicle($vehicle);
if (isset($vdata['alt_battery_supreme_mf']))
$vdata['alt_battery_supreme_mf']->addVehicle($vehicle);
if (isset($vdata['alt_battery_platinum_mf']))
$vdata['alt_battery_platinum_mf']->addVehicle($vehicle);
*/
}
}
$em->flush();
// write to output file
// error_log(print_r($output_info, true));
$this->outputVehicleBatteryInfo($output_file, $output_info);
fclose($fh);
return 0;
}
protected function processRow($fields, &$vbrands, $row_num, $prem_mf_name, $prem_lm_name,
$super_prem_mf_name, $supreme_mf_name, $platinum_mf_nam)
{
$output_info = [];
$brand = $this->normalizeName($fields[0]);
$make = $this->normalizeName($fields[1]);
$model = trim($fields[2]);
$bsize = $this->normalizeName($fields[self::F_B_SIZE]);
$bmodel = $this->normalizeName($fields[self::F_B_MODEL]);
// checking for valid vehicles and batteries should be done here so that only valid entries
// go into the vbrands array
$output_info = $this->validateManufacturerVehicle($fields, $brand, $make, $model, $bsize, $bmodel);
if (!empty($output_info))
return $output_info;
if (!isset($vbrands[$brand]))
{
// build array
$vbrands[$brand] = [
'vehicles' => [],
];
}
if (empty($model))
$model = 'NONE';
$vbrands[$brand]['vehicles'][$row_num] = [
'make' => $make,
'model' => $model,
];
// at this point we are sure we have battery
$batt_key = $this->getBatteryKey($bsize, $bmodel);
$vbrands[$brand]['vehicles'][$row_num]['battery'] = $this->batt_index[$batt_key];
// alternate brands are not in file, so we just comment out
// need to check alternate brands if battery exists
// go through the alternate fields, look for 'P'. Not kidding. It's what is in the csv file.
/*
if ($this->normalizeName($fields[SELF::F_B_ALT_PREM_MF]) == 'P')
{
// check if we have battery for name + size combo
$alt_batt_key = $this->getBatteryKey($field_bsize, $prem_mf_name);
if (isset($this->batt_index[$alt_batt_key]))
{
$vbrands[$brand]['vehicles'][$row_num]['alt_battery_prem_mf'] = $this->batt_index[$alt_batt_key];
}
}
if ($this->normalizeName($fields[SELF::F_B_ALT_PREM_LM]) == 'P')
{
// check if we have battery for name + size combo
$alt_batt_key = $this->getBatteryKey($field_bsize, $prem_lm_name);
if (isset($this->batt_index[$alt_batt_key]))
{
$vbrands[$brand]['vehicles'][$row_num]['alt_battery_prem_lm'] = $this->batt_index[$alt_batt_key];
}
}
if ($this->normalizeName($fields[SELF::F_B_ALT_SUPER_PREM_MF]) == 'P')
{
// check if we have battery for name + size combo
$alt_batt_key = $this->getBatteryKey($field_bsize, $super_prem_mf_name);
if (isset($this->batt_index[$alt_batt_key]))
{
$vbrands[$brand]['vehicles'][$row_num]['alt_battery_super_prem_mf'] = $this->batt_index[$alt_batt_key];
}
}
if ($this->normalizeName($fields[SELF::F_B_ALT_SUPREME_MF]) == 'P')
{
// check if we have battery for name + size combo
$alt_batt_key = $this->getBatteryKey($field_bsize, $supreme_mf_name);
if (isset($this->batt_index[$alt_batt_key]))
{
$vbrands[$brand]['vehicles'][$row_num]['alt_battery_supreme_mf'] = $this->batt_index[$alt_batt_key];
}
}
if ($this->normalizeName($fields[SELF::F_B_ALT_PLATINUM_MF]) == 'P')
{
// check if we have battery for name + size combo
$alt_batt_key = $this->getBatteryKey($field_bsize, $platinum_mf_name);
if (isset($this->batt_index[$alt_batt_key]))
{
$vbrands[$brand]['vehicles'][$row_num]['alt_battery_platinum_mf'] = $this->batt_index[$alt_batt_key];
}
}
*/
}
protected function validateManufacturerVehicle($fields, $brand, $make, $model, $bsize, $bmodel)
{
$output_info = [];
// check if manufacturer is blank
if (empty($brand))
{
$message = 'No manufacturer provided.';
$output_info = $this->setOutputInfo($fields, 'NOT ADDED', $message);
return $output_info;
}
// check if make is blank
if (empty($make))
{
$message = 'No make provided.';
$output_info = $this->setOutputInfo($fields, 'NOT ADDED', $message);
return $output_info;
}
// process model year data
if ($model == 'NONE')
{
$m_year_from = 0;
$m_year_to = 0;
}
else
{
$ex_model = explode('-', $model);
$m_year_from = trim($ex_model[0]);
if (isset($ex_model[1]))
$m_year_to = trim($ex_model[1]);
else
$m_year_to = 0;
}
// get manufacturer or make one
if (!isset($this->vmfg_index[$brand]))
{
// manufacturer
$mfg = new VehicleManufacturer();
$mfg->setName($brand);
$this->em->persist($mfg);
}
else
{
$mfg = $this->vmfg_index[$brand];
}
if (!isset($this->v_index[$brand][$make . '|' . intval($m_year_from) . '|' . intval($m_year_to)]))
{
// vehicle
$vehicle = new Vehicle();
$vehicle->setManufacturer($mfg)
->setMake($make)
->setModelYearFrom($m_year_from)
->setModelYearTo($m_year_to);
$this->em->persist($vehicle);
}
else
{
$vehicle = $this->v_index[$brand][$make . '|' . intval($m_year_from) . '|' . intval($m_year_to)];
}
// save to db new manufacturer and vehicle
$this->em->flush();
// add the vehicle manufacturer to hash
$this->vmfg_index[$brand] = $mfg;
// add the new vehicle to hash
$this->v_index[$brand][$make . '|' . $m_year_from . '|' . $m_year_to] = $vehicle;
// recommended battery
$batt_key = $this->getBatteryKey($bsize, $bmodel);
if (!isset($this->batt_index[$batt_key]))
{
$message = 'Could not find battery - ' . $bsize . ' - ' . $bmodel;
$output_info = $this->setOutputInfo($fields, 'NOT ADDED', $message);
return $output_info;
}
return $output_info;
}
protected function setOutputInfo($fields, $status, $reason)
{
$mfg_name = trim($fields[SELF::F_V_BRAND]);
$model_name = trim($fields[SELF::F_V_MAKE]);
$model_year = trim($fields[SELF::F_V_MODEL_YEAR]);
$bsize = trim($fields[SELF::F_B_SIZE]);
$bmodel = trim($fields[SELF::F_B_MODEL]);
// alternate brands are not in file, so we just comment out
/*
$alt_prem_mf = trim($fields[SELF::F_B_ALT_PREM_MF]);
$alt_prem_lm = trim($fields[SELF::F_B_ALT_PREM_LM]);
$alt_super_prem_mf = trim($fields[SELF::F_B_ALT_SUPER_PREM_MF]);
$alt_supreme_mf = trim($fields[SELF::F_B_ALT_SUPREME_MF]);
$alt_platinum_mf = trim($fields[SELF::F_B_ALT_PLATINUM_MF]);
*/
return [
$mfg_name,
$model_name,
$model_year,
$bsize,
$bmodel,
$status,
$reason
];
}
protected function outputVehicleBatteryInfo($output_file, $entries)
{
try
{
$fh = fopen($output_file, "w");
}
catch (Exception $e)
{
throw new Exception('The file "' . $report_file . '" could be opened.');
}
// write the headers
fputcsv($fh, [
'Manufacturer',
'Vehicle Model',
'Year Model',
'Battery Size',
'Battery Model',
'Status',
'Reason',
]);
foreach($entries as $row)
{
if ($row != null)
fputcsv($fh, $row);
}
fclose($fh);
}
protected function populateVehicleManufacturerIndex()
{
$vmfgs = $this->em->getRepository(VehicleManufacturer::class)->findAll();
$this->vmfg_index = [];
foreach ($vmfgs as $vmfg)
{
$mfg_name = $this->normalizeName($vmfg->getName());
$this->vmfg_index[$mfg_name] = $vmfg;
}
}
protected function populateVehicleIndex()
{
$vs = $this->em->getRepository(Vehicle::class)->findAll();
$this->v_index = [];
foreach ($vs as $v)
{
$mfg_name = $this->normalizeName($v->getManufacturer()->getName());
if (!isset($this->v_index[$mfg_name]))
$this->v_index[$mfg_name] = [];
$this->v_index[$mfg_name][$this->normalizeName($v->getMake()) . '|' . $v->getModelYearFrom() . '|' . $v->getModelYearTo()] = $v;
}
}
protected function populateBatteryIndex()
{
$bs = $this->em->getRepository(Battery::class)->findAll();
$this->batt_index = [];
foreach ($bs as $b)
{
// get the battery size
$bsize = $b->getSize()->getName();
$key = $this->getBatteryKey($bsize, $b->getModel()->getName());
$this->batt_index[$key] = $b;
}
}
protected function getBatteryKey($size_name, $model_name)
{
return $this->normalizeName(str_replace(' ', '', $size_name)) .
'|' .
$this->normalizeName(str_replace(' ', '', $model_name));
}
protected function normalizeName($name)
{
$normalized_key = trim(strtoupper($name));
return $normalized_key;
}
}

View file

@ -0,0 +1,469 @@
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Filesystem\Filesystem;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\WarrantySerial;
use App\Entity\WarrantySerialQueue;
use App\Entity\WarrantySerialUploadLog;
use App\Entity\WarrantySerialLoadLog;
use App\Service\WarrantySerialUploadLogger;
use App\Service\WarrantySerialLoadLogger;
use PDO;
use DateTime;
class LoadWarrantySerialCommand extends Command
{
const FIELD_COUNT = 7;
const SERIAL_LENGTH = 20;
protected $em;
protected $upload_logger;
protected $load_logger;
protected $project_dir;
protected $callback_url;
protected $log_data;
protected $filesystem;
public function __construct(EntityManagerInterface $em, WarrantySerialUploadLogger $upload_logger,
WarrantySerialLoadLogger $load_logger, KernelInterface $kernel, $callback_url,
FileSystem $filesystem)
{
$this->em = $em;
$this->upload_logger = $upload_logger;
$this->load_logger = $load_logger;
$this->project_dir = $kernel->getProjectDir();
$this->callback_url = $callback_url;
$this->filesystem = $filesystem;
parent::__construct();
}
protected function configure()
{
$this->setName('warrantyserial:load')
->setDescription('Load warranty serials from file.')
->setHelp('Load warranty serials from file.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->em;
$this->log_data = [];
$status = 'pending';
// get the filenames from the queue table with status pending
$db = $em->getConnection();
$ws_query_sql = 'SELECT id, file_serial, file_id, api_user, orig_file_serial FROM warranty_serial_queue
WHERE status = :status ORDER BY id LIMIT 1';
$ws_query_stmt = $db->prepare($ws_query_sql);
$ws_query_stmt->bindValue('status', $status);
$ws_results = $ws_query_stmt->executeQuery();
$output_info = [];
while ($row = $ws_results->fetchAssociative())
{
$filename = $row['file_serial'];
$user_id = $row['api_user'];
$id = $row['id'];
$file_id = $row['file_id'];
$orig_filename = $row['orig_file_serial'];
$output_info[] = $this->processWarrantySerialFile($filename, $user_id, $file_id, $orig_filename);
// remove entry from queue table
$this->updateWarrantySerialQueue($id);
// delete the uploaded csv file and directory
$this->deleteDirectoryAndFile($file_id);
}
if (count($output_info) > 0)
{
// error_log(print_r($this->log_data, true));
// load log data into db
$this->load_logger->logWarrantySerialLoadInfo($this->log_data);
// send results back to third party
$this->sendResults($output_info);
}
return 0;
}
protected function processWarrantySerialFile($filename, $user_id, $file_id, $orig_filename)
{
$csv_file = $this->project_dir . '/public/warranty_serial_uploads/' . $filename;
$output_info = [];
// attempt to open file
try
{
$fh = fopen($csv_file, "r");
}
catch (Exception $e)
{
$error = 'The file ' . $csv_file . 'could not be read.';
$log_data = [
'user_id' => $user_id,
'is_uploaded' => false,
'error' => $error,
];
$this->upload_logger->logWarrantySerialUploadInfo($log_data);
$output_info = $this->setOutputInfo($filename, $file_id, true, $error, $data, $orig_filename);
return $output_info;
}
$data = [];
while(($row = fgetcsv($fh)) !== false)
{
$validation_result = $this->validateRow($row, $user_id);
if (!empty($validation_result))
{
$data[] = $validation_result;
continue;
}
// valid entry, we parse and insert
$serial = trim(strtoupper($row[0]));
// error_log('Processing ' . $serial);
$sku = trim(strtoupper($row[1]));
$dispatch_status = trim($row[2]);
$str_date_create = trim($row[3]);
$inventory_status = trim($row[4]);
$cat_id = trim($row[5]);
$cat_name = trim(strtoupper($row[6]));
// we are sure that this is a valid date at this point
$created_date = $this->convertDateCreate($str_date_create);
$meta_info = [
'dispatch_status' => $dispatch_status,
'inventory_status' => $inventory_status,
'category_id' => $cat_id,
'category_name' => $cat_name,
];
$info = json_encode($meta_info);
// prepare the data
$source = 'motiv';
if ($sku == 'N/A')
$sku = null;
// prepared statement
$db = $this->em->getConnection();
$insert_stmt = $db->prepare('INSERT INTO warranty_serial (id, sku, date_create, source, meta_info)
VALUES (:serial, :sku, :date_create, :source, :meta_info)');
$res = $insert_stmt->execute([
':serial' => $serial,
':sku' => $sku,
':date_create' => $created_date,
':source' => $source,
':meta_info' => $info,
]);
if (!$res)
{
// log the not successful insert
$err = $insert_stmt->errorInfo();
$error = $err[2];
$this->logLoadInfo($user_id, false, $serial, $error);
$data[] = [
'serial' => $serial,
'status' => 'error',
'has_error' => true,
'error_message' => $error,
];
}
else
{
// log the successful insert
$this->logLoadInfo($user_id, true, $serial, '');
$data[] = [
'serial' => $serial,
'status' => 'success',
'has_error' => false,
'error_message' => '',
];
}
}
// form what we output
$output_info = $this->setOutputInfo($filename, $file_id, false, '', $data, $orig_filename, $orig_filename);
return $output_info;
}
protected function validateRow($row, $user_id)
{
$data = [];
// possible lines:
// (1) header in csv file - ignore
// SerialNumber,Sku,DispatchStatus,CreatedDate,InventoryStatus,CategoryID,CategoryName
// (2) No available data - ignore
// (3) CH2000012071,WCHD23BL-CPN00-LX,0,2020-08-11 04:05:27.090,0,4,CHAMPION MF - valid
// (4) MG2000313690,N/A,1,2021-05-14T23:47:30.6430000+08:00,0,10,GOLD - valid
// (5) Empty line - ignore
// (6) empty sku - log
// check if empty line
if ($row == array(null))
{
// no need to log, but send back error
$error = 'Empty line';
$data = [
'serial' => '',
'status' => 'error',
'has_error' => true,
'error_message' => $error,
];
return $data;
}
// check the number of fields
if (count($row) != self::FIELD_COUNT)
{
$error = 'Invalid number of fields.';
$data = [
'serial' => '',
'status' => 'error',
'has_error' => true,
'error_message' => $error,
];
return $data;
}
// check if the line is a header
if ($row[0] == 'SerialNumber')
{
// no need to log, but send back error
$error = 'Invalid information.';
$data = [
'serial' => '',
'status' => 'error',
'has_error' => true,
'error_message' => $error,
];
return $data;
}
// check if empty serial
if (empty($row[0]))
{
// this one, we log
$error = 'Empty serial';
$this->logLoadInfo($user_id, false, '', $error);
$data = [
'serial' => '',
'status' => 'error',
'has_error' => true,
'error_message' => $error,
];
return $data;
}
// check length of serial
$serial = trim($row[0]);
if (strlen($serial) > SELF::SERIAL_LENGTH)
{
// log
$error = 'Serial length too long';
$this->logLoadInfo($user_id, false, $serial, $error);
$data = [
'serial' => $serial,
'status' => 'error',
'has_error' => true,
'error_message' => $error,
];
return $data;
}
// validate the date created
$str_date_create = trim($row[3]);
$date_create = $this->convertDateCreate($str_date_create);
if ($date_create == null)
{
// log
$error = 'Invalid date create.';
$this->logLoadInfo($user_id, false, $serial, $error);
$data = [
'serial' => $serial,
'status' => 'error',
'has_error' => true,
'error_message' => $error,
];
return $data;
}
// check if serial is a dupe
$existing_serial = $this->em->getRepository(WarrantySerial::class)->find($serial);
if ($existing_serial != null)
{
// log
$error = 'Serial already exists.';
$this->logLoadInfo($user_id, false, $serial, $error);
$data = [
'serial' => $serial,
'status' => 'error',
'has_error' => true,
'error_message' => $error,
];
return $data;
}
// valid entry, return empty
return $data;
}
protected function convertDateCreate($str_date_create)
{
// since some people cannot follow simple instructions...
// check the date format on the string
// try 2021-05-15T08:35:46+08:00 format on str_date_create
$date_create = DateTime::createFromFormat('Y-m-d\TH:i:sP', $str_date_create);
if ($date_create == false)
{
// try this format: 2021-05-15T08:47:20.3330000+08:00
// get the date, time and timezone from str_date_create
$str_date_time = substr($str_date_create, 0, 19);
$str_timezone = substr($str_date_create, 27);
$str_datetime_tz = $str_date_time . $str_timezone;
// create DateTime object
// sample: 2021-05-15T12:16:06+08:00
$date_create = DateTime::createFromFormat('Y-m-d\TH:i:sP', $str_datetime_tz);
// check if datetime object was created
// if not, someone f*cked up and we have no date create
if ($date_create == false)
{
return null;
}
}
// if you reach this part, then date string is valid. Since we'll be using
// sql to insert the entries, we return the string
$created_date = $date_create->format('Y-m-d H:i:s');
// $created_date = DateTime::createFromFormat('Y-m-d H:i:s', $str_created_date);
return $created_date;
}
protected function logLoadInfo($user_id, $is_loaded, $serial, $error)
{
$date_create = new DateTime();
$str_date_create = $date_create->format('Y-m-d H:i:s');
$this->log_data[] = [
$str_date_create,
$user_id,
$serial,
$is_loaded,
$error,
];
}
protected function updateWarrantySerialQueue($id)
{
// prepared statement
$db = $this->em->getConnection();
// lock the warranty serial queue table
$db->exec('LOCK TABLES warranty_serial_queue WRITE;');
$delete_stmt = $db->prepare('DELETE FROM warranty_serial_queue
WHERE id = :id');
$res = $delete_stmt->execute([
':id' => $id,
]);
$db->exec('UNLOCK TABLES;');
}
protected function deleteDirectoryAndFile($filedir)
{
$csv_filedir = $this->project_dir . '/public/warranty_serial_uploads/' . $filedir;
$this->filesystem->remove($csv_filedir);
}
protected function setOutputInfo($filename, $file_id, $has_error, $error_message, $entries, $orig_filename)
{
$info = [
'id' => $file_id,
'filename' => $orig_filename,
'has_error' => $has_error,
'error_message' => $error_message,
'data' => $entries,
];
return $info;
}
protected function sendResults($output_info)
{
$body = json_encode($output_info);
// error_log(print_r($body, true));
// error_log('Sending json output to ' . $this->callback_url);
$curl = curl_init();
$options = [
CURLOPT_URL => $this->callback_url,
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
],
];
curl_setopt_array($curl, $options);
$res = curl_exec($curl);
curl_close($curl);
// check result
error_log('Result ' . $res);
}
}

View file

@ -0,0 +1,136 @@
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputOption;
use Doctrine\ORM\EntityManagerInterface;
use App\Ramcar\TransactionStatus;
use App\Entity\GatewayTransaction;
use App\Service\PayMongoConnector;
use DateTime;
class ProcessLatePaymongoTransactionsCommand extends Command
{
protected $em;
protected $paymongo;
protected $webhook_id;
public function __construct(EntityManagerInterface $em, PayMongoConnector $paymongo, $webhook_id)
{
$this->em = $em;
$this->paymongo = $paymongo;
$this->webhook_id = $webhook_id;
parent::__construct();
}
protected function configure()
{
$this->setName('paymongo:checkpending')
->setDescription('Check for any late PayMongo transactions and process if needed.')
->setHelp('Check for any late PayMongo transactions and process if needed.')
->addOption('force', 'f', InputOption::VALUE_NONE, 'Ignore webhook status and process anyway.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$force = $input->getOption('force');
// if we aren't forcing, check webhook status first
if (!$force) {
$output->writeln('Checking webhook status...');
// check if webhook is disabled
$webhook = $this->paymongo->getWebhook($this->webhook_id);
if ($webhook['success'] && $webhook['response']['data']['attributes']['status'] === 'enabled') {
$output->writeln('<info>Webhook is enabled, no need to do anything.</info>');
return 0;
} else {
$output->writeln('<comment>Webhook is disabled! Logging event and attempting to re-enable...</comment>');
// attempt re-enabling of webhook
$result = $this->paymongo->enableWebhook($this->webhook_id);
if ($result['success'] && $result['response']['data']['attributes']['status'] ?? null === 'enabled') {
$output->writeln('<info>Webhook ' . $this->webhook_id . ' re-enabled!</info>');
// log event
$this->paymongo->log('WEBHOOK RE-ENABLED', "[]", json_encode($result['response'], JSON_PRETTY_PRINT), 'webhook');
} else {
$output->writeln('<comment>Webhook ' . $this->webhook_id . ' could not be re-enabled.</comment>');
// log event
$this->paymongo->log('WEBHOOK FAILURE', "[]", json_encode($result['response'], JSON_PRETTY_PRINT), 'webhook');
}
}
}
$output->writeln('Fetching all late pending transactions...');
// set date threshold to 24 hours ago
$date_threshold = (new DateTime())->modify('-24 hours');
$transactions = $this->em->getRepository(GatewayTransaction::class)
->createQueryBuilder('t')
->select('t')
->where('t.status = :status')
->andWhere('t.date_create <= :date_threshold')
->setParameter('status', TransactionStatus::PENDING)
->setParameter('date_threshold', $date_threshold)
->getQuery()
->getResult();
$output->writeln('Found '. count($transactions) . ' rows matching criteria.');
$x = 0;
foreach ($transactions as $trans) {
// check paymongo status
$checkout = $this->paymongo->getCheckout($trans->getExtTransactionId());
if ($checkout['success']) {
// check if we have any payments made
$payments = $checkout['response']['data']['attributes']['payments'] ?? [];
if (!empty($payments)) {
$amount_paid = 0;
// for good measure, we get all successful payments and add them up
foreach ($payments as $payment) {
if ($payment['attributes']['status'] === TransactionStatus::PAID) {
$amount_paid = bcadd($amount_paid, $payment['attributes']['amount']);
}
}
// this transaction is fully paid, so we mark it as paid
if (bccomp($trans->getAmount(), $amount_paid) <= 0) {
$trans->setStatus(TransactionStatus::PAID);
$trans->setDatePay(new DateTime());
$this->em->flush();
$output->writeln('Marked transaction '. $trans->getID() . ' as paid.');
$x++;
} else {
$output->writeln('<comment>Insufficient payment amount (' . $amount_paid . '/' . $trans->getAmount() . ') for this transaction: ' . $trans->getID() . '</comment>');
}
} else {
$output->writeln('<comment>No payments found for transaction: ' . $trans->getID() . '</comment>');
}
} else {
$output->writeln('<comment>Checkout not found: ' . $checkout['error']['message'] . '</comment>');
}
}
$output->writeln('<info>Done! Processed ' . $x . ' rows.</info>');
return 0;
}
}

View file

@ -0,0 +1,80 @@
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use App\Service\JobOrderManager;
class SetJobOrderCustNewCommand extends Command
{
protected $em;
protected $jo_manager;
public function __construct(EntityManagerInterface $em, JobOrderManager $jo_manager)
{
$this->em = $em;
$this->jo_manager = $jo_manager;
parent::__construct();
}
protected function configure()
{
$this->setName('joborder:setcustomernew')
->setDescription('Set job order\'s customer new flag for existing job orders.')
->setHelp('Set job order\'s customer new flag for existing job orders');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->em;
// pdo connection
$db = $em->getConnection();
// get all the ids for all job orders
$all_query_sql = 'SELECT id AS jo_id, customer_id AS cust_id FROM job_order ORDER BY id';
$all_query_stmt = $db->prepare($all_query_sql);
$all_query_stmt->execute();
$all_jo_results = $all_query_stmt->fetchAll();
$output->writeln('Processing job orders...');
foreach ($all_jo_results as $jo_row)
{
// for each jo id, get the customer id
$jo_id = $jo_row['jo_id'];
$cust_id = $jo_row['cust_id'];
// check how many JOs have that customer id
$jo_count = $this->jo_manager->getCustomerJobOrderCount($cust_id);
// if one or less, set flag_cust_new to true
if ($jo_count <= 1)
$this->updateCustNew($db, $jo_id);
}
$output->writeln('All done!');
return 0;
}
protected function updateCustNew($db, $jo_id)
{
$update_jo_sql = 'UPDATE job_order SET flag_cust_new = :flag_cust_new WHERE id = :jo_id';
$update_jo_stmt = $db->prepare($update_jo_sql);
$update_jo_stmt->execute([
'flag_cust_new' => true,
'jo_id' => $jo_id
]);
}
}

View file

@ -0,0 +1,54 @@
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use CrEOF\Spatial\PHP\Types\Geometry\Point;
use App\Service\MapTools;
class TestClosestOpenHubsCommand extends Command
{
protected $maptools;
protected function configure()
{
$this->setName('test:closestopenhubs')
->setDescription('Test the get closest open hubs service.')
->setHelp('Test the get closese open hubs service.')
->addArgument('long', InputArgument::REQUIRED, 'Longitude')
->addArgument('lat', InputArgument::REQUIRED, 'Latitude');
}
public function __construct(MapTools $maptools)
{
$this->maptools = $maptools;
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$long = $input->getArgument('long');
$lat = $input->getArgument('lat');
$point = new Point($long, $lat);
$hubs_with_distance = $this->maptools->getClosestOpenHubs($point, 10);
foreach($hubs_with_distance as $hub_dist)
{
$hub = $hub_dist['hub'];
$distance = $hub_dist['distance'];
error_log('Hub ID ' . $hub->getID() . ' - ' . $hub->getName() . ' = ' . $distance . ' kms away.');
}
return 0;
}
}

View file

@ -0,0 +1,44 @@
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use App\Service\HashGenerator;
class TestHashGeneratorCommand extends Command
{
protected $hash;
protected function configure()
{
$this->setName('test:hash')
->setDescription('Test hash generator.')
->setHelp('Test hash generator service.');
}
public function __construct(HashGenerator $hash)
{
$this->hash = $hash;
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$orig_id = 39095;
error_log('original id - ' . $orig_id);
$hash_id = $this->hash->getHash($orig_id);
error_log('hash id - ' . $hash_id);
$id = $this->hash->getID($hash_id);
error_log('id - ' . $id);
return 0;
}
}

File diff suppressed because it is too large Load diff

View file

@ -7,11 +7,14 @@ use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use App\Service\RisingTideGateway;
class TestSMSCommand extends Command
{
protected $gateway;
protected $translator;
protected function configure()
{
@ -21,9 +24,10 @@ class TestSMSCommand extends Command
->addArgument('destination', InputArgument::REQUIRED, 'Destination number to send to');
}
public function __construct(RisingTideGateway $gateway)
public function __construct(RisingTideGateway $gateway, TranslatorInterface $translator)
{
$this->gateway = $gateway;
$this->translator = $translator;
parent::__construct();
}
@ -34,7 +38,7 @@ class TestSMSCommand extends Command
error_log('sending sms to ' . $number);
$msg = 'This is a test.';
$this->gateway->sendSMS($number, 'MOTOLITE', $msg);
$this->gateway->sendSMS($number, $this->translator->trans('message.battery_brand_allcaps'), $msg);
return 0;
}

View file

@ -0,0 +1,464 @@
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use App\Ramcar\WarrantySource;
use App\Ramcar\WarrantyStatus;
use App\Ramcar\WarrantyClass;
use DateTime;
use DateInterval;
use PDO;
class TestWarrantyUploadCommand extends Command
{
const F_ENCODER = 0;
const F_DATE_ENCODED = 1;
const F_FNAME = 2;
const F_LNAME = 3;
const F_EMAIL = 4;
const F_ADDRESS = 5;
const F_MOBILE = 6;
const F_TELEPHONE = 7;
const F_VMAKE = 8;
const F_VMODEL = 9;
const F_MYEAR = 10;
const F_PLATE_NUMBER = 11;
const F_SERIAL = 12;
const F_INVOICE_NUM = 13;
const F_DATE_PURCHASE = 14;
const F_DIST_NAME = 15;
const F_DIST_ADDRESS = 16;
const F_APP_TYPE_ID = 17;
const F_BATT_ID = 18; // sap code in system
const F_OWNER_TYPE = 19;
protected $em;
protected $batt_hash;
protected $sap_batt_hash;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
parent::__construct();
}
protected function configure()
{
$this->setName('testwarranty:upload')
->setDescription('Test bulk warranty upload.')
->setHelp('Test bulk warranty upload.')
->addArgument('input_file', InputArgument::REQUIRED, 'Path to the CSV file.')
->addArgument('output_file', InputArgument::REQUIRED, 'Path to output file.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// hash the battery table using sap_code as index
$this->populateBatteryIndex();
$csv_file = $input->getArgument('input_file');
$output_file = $input->getArgument('output_file');
// attempt to open file
try
{
$fh = fopen($csv_file, "r");
}
catch (Exception $e)
{
throw new Exception('The file "' . $csv_file . '" could be read.');
}
$output_info = [];
// loop through rows
// ignore first row since that's header data
$row_num = 0;
$sql_values = '';
while (($fields = fgetcsv($fh)) !== false)
{
// ignore first row since that's the header
if ($row_num == 0)
{
$row_num++;
continue;
}
// process row
$output_info[] = $this->processRow($fields, $sql_values);
$row_num++;
}
// check if we have values to insert
if (strlen($sql_values) > 0)
{
$sql_statement = 'INSERT INTO `warranty` (bty_model_id,bty_size_id,sap_bty_id,serial,warranty_class,plate_number,status,date_create,date_purchase,date_expire,first_name,last_name,mobile_number,flag_activated,vehicle_id,customer_id, create_source) VALUES ' . $sql_values . ';' . "\n";
// error_log($sql_statement);
$conn = $this->em->getConnection();
$stmt = $conn->prepare($sql_statement);
$stmt->execute();
}
// write to output file
$this->outputWarrantyInfo($output_file, $output_info);
fclose($fh);
return 0;
}
protected function processRow($fields, &$sql_values)
{
error_log('Processing warranty with serial ' . trim($fields[self::F_SERIAL]));
$output_info = [];
// get necessary fields
$fname = trim($fields[self::F_FNAME]);
$lname = trim($fields[self::F_LNAME]);
$mobile = trim($fields[self::F_MOBILE]);
$serial = trim($fields[self::F_SERIAL]);
$date_purchase = trim($fields[self::F_DATE_PURCHASE]);
$sap_code = trim($fields[self::F_BATT_ID]);
$plate_number = $this->cleanPlateNumber($fields[self::F_PLATE_NUMBER]);
// validate the necessary fields
$output_info = $this->validateFields($fields);
if (!empty($output_info))
return $output_info;
// see if we can get customer id and vehicle id, given the plate number.
// this is not required so if we can't find customer and/or vehicle,
// we still create the warranty
$conn = $this->em->getConnection();
// NOTE: what happens if there's more than one result?
// for now, get the first one
$sql = 'SELECT c.id AS c_id, v.id AS v_id FROM customer_vehicle cv, customer c, vehicle v
WHERE cv.customer_id = c.id AND cv.vehicle_id = v.id AND cv.plate_number = :plate_number LIMIT 1';
$stmt = $conn->prepare($sql);
$stmt->execute(['plate_number' => $plate_number]);
$cv_results = $stmt->fetch();
$cust_id = 'NULL';
$vehicle_id = 'NULL';
if (!empty($cv_results))
{
$cust_id = $cv_results['c_id'];
$vehicle_id = $cv_results['v_id'];
}
// get battery info from hash (battery model id, battery size id, warranty periods (needed for expiration date)
$batt_info = $this->batt_hash[$sap_code];
$b_id = $batt_info['id'];
$model_id = $batt_info['model_id'];
$size_id = $batt_info['size_id'];
$warr_private = $batt_info['warr_private'];
$warr_commercial = $batt_info['warr_commercial'];
$warr_tnv = $batt_info['warr_tnv'];
// format purchase date to DateTime and then change the format to Y-m-d
$purchase_date = DateTime::createFromFormat('m/d/y', $date_purchase);
// need to manually create the created date
$date_create = date('Y-m-d H:i:s');
// compute expiration date
// TODO: might need checking for what kind of warranty for the warranty period
// by default, we use private
$warranty_class = WarrantyClass::WTY_PRIVATE;
$date_expire = $this->computeDateExpire($purchase_date, $warr_private);
// convert all dates to string for the values string for the insert statement
//$str_date_create = $date_create->format('Y-m-d H:i:s');
$str_date_purchase = $purchase_date->format('Y-m-d H:i:s');
$str_date_expire = $date_expire->format('Y-m-d H:i:s');
$first_name = addslashes($fname);
$last_name = addslashes($lname);
$mobile_number = addslashes($mobile);
// populate the values string for the values to be inserted into warranty
$value_string = '(' . $model_id . ',' . $size_id . ',\'' . $sap_code . '\',\'' . $serial . '\',\'' . $warranty_class . '\',\''
. $plate_number . '\',\'' . WarrantyStatus::ACTIVE . '\',\'' . $date_create . '\',\'' . $str_date_purchase
. '\',\'' . $str_date_expire . '\',\'' . $first_name . '\',\'' . $last_name . '\',\'' . $mobile_number . '\',' . 1 . ',' . $vehicle_id . ',' . $cust_id . ',\'' . WarrantySource::BULK_UPLOAD . '\')';
if (strlen($sql_values) == 0)
{
// first entry to insert, should have no comma before
$sql_values = $value_string;
}
else
{
// need to insert a comma after the existing string
$sql_values = $sql_values . ',' . $value_string;
}
// error_log($sql_values);
return $output_info;
}
protected function validateFields($fields)
{
$errors = [];
$serial = trim($fields[self::F_SERIAL]);
$date_purchase = trim($fields[self::F_DATE_PURCHASE]);
$sap_code = trim($fields[self::F_BATT_ID]);
$plate_number = trim($fields[self::F_PLATE_NUMBER]);
// clean the plate number
$clean_plate = $this->cleanPlateNumber($plate_number);
// validate the plate number
// (1) plate number should not be empty
if (empty($clean_plate))
{
$message = 'No plate number.';
$errors = $this->setOutputInfo($fields, 'NOT ADDED', $message);
return $errors;
}
// validate date purchase
// (1) date purchase should not be empty
// (2) date purchase should be of format: d-M-y
if (empty($date_purchase))
{
$message = 'No date purchase.';
$errors = $this->setOutputInfo($fields, 'NOT ADDED', $message);
return $errors;
}
$purchase_date = DateTime::createFromFormat('m/d/y', $date_purchase);
if ($purchase_date === false)
{
$message = 'Invalid date format. Date format should be: m/d/y (example: 06/13/16)';
$errors = $this->setOutputInfo($fields, 'NOT ADDED', $message);
return $errors;
}
// validate serial
// (1) should not be empty
if (empty($serial))
{
$message = 'No battery serial number.';
$errors = $this->setOutputInfo($fields, 'NOT ADDED', $message);
return $errors;
}
// validate battery
// (1) should not be empty
// (2) should find battery using sap_code.
if (empty($sap_code))
{
$message = 'No battery ID.';
$errors = $this->setOutputInfo($fields, 'NOT ADDED', $message);
return $errors;
}
if (!(isset($this->batt_hash[$sap_code])))
{
$message = 'Battery not found.';
$errors = $this->setOutputInfo($fields, 'NOT ADDED', $message);
return $errors;
}
// (1) check if warranty exists using serial + plate number
// (2) check if serial already exists even if for another plate number
$conn = $this->em->getConnection();
// find warranties using serial + plate number
$sql = 'SELECT w.id FROM warranty w WHERE w.serial = :serial AND w.plate_number = :plate_number';
$stmt = $conn->prepare($sql);
$stmt->execute([
'serial' => $serial,
'plate_number' => $plate_number,
]);
$warr_results = $stmt->fetchAll();
if (!empty($warr_results))
{
$message = 'Warranty already exists for serial and plate number.';
$errors = $this->setOutputInfo($fields, 'NOT ADDED', $message);
return $errors;
}
// find warranties using serial number alone
$w_sql = 'SELECT w.id FROM warranty w WHERE w.serial = :serial';
$w_stmt = $conn->prepare($w_sql);
$w_stmt->execute([
'serial' => $serial,
]);
$w_results = $w_stmt->fetchAll();
if (!empty($w_results))
{
$message = 'Warranty already exists for serial.';
$errors = $this->setOutputInfo($fields, 'NOT ADDED', $message);
return $errors;
}
return $errors;
}
protected function computeDateExpire($date_create, $warranty_period)
{
$expire_date = clone $date_create;
$expire_date->add(new DateInterval('P'.$warranty_period.'M'));
return $expire_date;
}
protected function setOutputInfo($fields, $status, $message)
{
$encoder = trim($fields[self::F_ENCODER]);
$date_encoded = trim($fields[self::F_DATE_ENCODED]);
$fname = trim($fields[self::F_FNAME]);
$lname = trim($fields[self::F_LNAME]);
$email = trim($fields[self::F_EMAIL]);
$address = trim($fields[self::F_ADDRESS]);
$mobile = trim($fields[self::F_MOBILE]);
$telephone = trim($fields[self::F_TELEPHONE]);
$vmake = trim($fields[self::F_VMAKE]);
$vmodel = trim($fields[self::F_VMODEL]);
$year = trim($fields[self::F_MYEAR]);
$serial = trim($fields[self::F_SERIAL]);
$invoice_number = trim($fields[self::F_INVOICE_NUM]);
$date_purchase = trim($fields[self::F_DATE_PURCHASE]);
$dist_name = trim($fields[self::F_DIST_NAME]);
$dist_address = trim($fields[self::F_DIST_ADDRESS]);
$app_type_id = trim($fields[self::F_APP_TYPE_ID]);
$sap_code = trim($fields[self::F_BATT_ID]);
$plate_number = trim($fields[self::F_PLATE_NUMBER]);
$owner_type = trim($fields[self::F_OWNER_TYPE]);
return [
$encoder,
$date_encoded,
$fname,
$lname,
$email,
$address,
$mobile,
$telephone,
$vmake,
$vmodel,
$year,
$plate_number,
$serial,
$invoice_number,
$date_purchase,
$dist_name,
$dist_address,
$app_type_id,
$sap_code,
$owner_type,
$status,
$message,
];
}
protected function outputWarrantyInfo($output_file, $entries)
{
try
{
$fh = fopen($output_file, "w");
}
catch (Exception $e)
{
throw new Exception('The file "' . $report_file . '" could be opened.');
}
// write the headers
fputcsv($fh, [
'Encoded By',
'Date of Encoded',
'Owner First Name',
'Owner Last Name',
'Owner Email',
'Owner Address',
'Owner Mobile',
'Owner Telephone',
'Vehicle Make',
'Vehicle Model',
'Vehicle Year',
'Vehicle Plate No.',
'Battery Serial No.',
'Battery Sales Invoice No.',
'Battery Date of Purchase',
'Distributor Name',
'Distributor Address',
'Application Type ID',
'Battery ID',
'Ownership Type',
'Status',
'Reason',
]);
foreach($entries as $row)
{
if ($row != null)
fputcsv($fh, $row);
}
fclose($fh);
}
protected function populateBatteryIndex()
{
$conn = $this->em->getConnection();
// get all the batteries
$sql = 'SELECT b.id, b.model_id, b.size_id, b.sap_code, b.warr_private, b.warr_commercial, b.warr_tnv
FROM battery b';
$stmt = $conn->prepare($sql);
$stmt->execute();
$results = $stmt->fetchAll();
// go through the rows
foreach ($results as $row)
{
// breaking this down for clarity
$battery_id = $row['id'];
$model_id = $row['model_id'];
$size_id = $row['size_id'];
$sap_code = trim($row['sap_code']);
$warr_private = $row['warr_private'];
$warr_commercial = $row['warr_commercial'];
$warr_tnv = $row['warr_tnv'];
if(!empty($sap_code))
{
$this->batt_hash[$sap_code] = [
'id' => $battery_id,
'model_id' => $model_id,
'size_id' => $size_id,
'warr_private' => $warr_private,
'warr_commercial' => $warr_commercial,
'warr_tnv' => $warr_tnv,
];
}
}
}
protected function cleanPlateNumber($plate)
{
return strtoupper(str_replace(' ', '', $plate));
}
}

View file

@ -0,0 +1,153 @@
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Entity\JobOrder;
use App\Entity\Rider;
use PDO;
class UpdateUnacceptedJobOrdersCommand extends Command
{
protected $em;
protected $mclient;
// NOTE: for resq2 app
protected $mclientv2;
protected $fcmclient;
public function __construct(EntityManagerInterface $em, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient)
{
$this->em = $em;
$this->mclient = $mclient;
// NOTE: for resq2 app
$this->mclientv2 = $mclientv2;
$this->fcmclient = $fcmclient;
parent::__construct();
}
protected function configure()
{
$this->setName('joborder:reassignunaccepted')
->setDescription('Requeue for rider assignment assigned but unaccepted job orders that have been assigned for more than 3 mins.')
->setHelp('Requeue for rider assignment assigned but unaccepted job orders that have been assigned for more than 3 mins.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->em;
$mclient = $this->mclient;
// NOTE: for resq2 app
$mclientv2 = $this->mclientv2;
$fcmclient = $this->fcmclient;
// TODO: get the timeout limit from .env
$timeout = 3;
$current_status = 'assigned';
$new_status = 'rider_assign';
// pdo connection
$db = $em->getConnection();
// since we need the actual job orders for mqtt events, we need to get the ids of the job orders
// that will be updated
// need rider id to set rider to available since rider becomes unavailable
// the minute JO is assigned to rider
$query_sql = 'SELECT id FROM job_order WHERE status = :current_status and TIMESTAMPDIFF(MINUTE, date_assign, NOW()) >= :timeout';
$query_stmt = $db->prepare($query_sql);
$query_stmt->execute([
'current_status' => $current_status,
'timeout' => $timeout,
]);
// go through rows
$requeued_jos = [];
while ($row = $query_stmt->fetch(PDO::FETCH_NUM))
{
// $row[0] is the jo id
// store the jos for now for the event sending after update of JOs
// and the updating of rider's availability
$jo_id = $row[0];
$requeued_jo = $em->getRepository(JobOrder::class)->find($jo_id);
$requeued_jos[] = [
'jo' => $requeued_jo,
];
$update_sql = 'UPDATE job_order SET status = :new_status, rider_id = null WHERE id = :jo_id';
$update_stmt = $db->prepare($update_sql);
$update_stmt->execute([
'new_status' => $new_status,
'jo_id' => $jo_id,
]);
}
foreach ($requeued_jos as $jo_info)
{
$jo = $jo_info['jo'];
if ($jo != null)
{
// $output->writeln('Requeuing for rider assignment ' . $jo->getID());
$id = $jo->getID();
// send notifications to rider app, telling rider that jo has been requeued
$rider_payload = [
'event' => 'cancelled',
'reason' => 'Reassigned',
'jo_id' => $id,
];
$mclient->sendRiderEvent($jo, $rider_payload);
// send outlet assign since order should go back to hub and await reassignment to another rider
$payload = [
'event' => 'outlet_assign',
'jo_id' => $id,
];
$mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($jo, $payload);
$fcmclient->sendJoEvent($jo, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
}
$rider = $jo->getRider();
if ($rider != null)
{
// check rider's current job order before changing rider's availability
// since rider's current job order is set when JO is assigned to rider
if ($rider->getCurrentJobOrder() != null)
{
if ($rider->getCurrentJobOrder()->getID() == $jo->getID())
{
// reset rider's availability to true
$rider->setAvailable(true);
// set rider's current job order to null
$rider->setCurrentJobOrder();
}
}
}
}
$em->flush();
return 0;
}
}

View file

@ -0,0 +1,184 @@
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Warranty;
class UpdateWarrantyDealerInfoCommand extends Command
{
// field index in csv file
const F_ID = 0;
const F_BTY_MODEL_ID = 1;
const F_BTY_SIZE_ID = 2;
const F_SERIAL = 3;
const F_WARRANTY_CLASS = 4;
const F_PLATE_NUMBER = 5;
const F_STATUS = 6;
const F_DATE_CREATED = 7;
const F_DATE_PURCHASE = 8;
const F_DATE_EXPIRE = 9;
const F_DATE_CLAIM = 10;
const F_SAP_BTY_ID = 11;
const F_CLAIM_ID = 12;
const F_FIRST_NAME = 13;
const F_LAST_NAME = 14;
const F_MOBILE_NUMBER = 15;
const F_ACTIVATED = 16;
const F_WARR_PRIV_POLICY = 17;
const F_EMAIL = 18;
const F_VEHICLE_ID = 19;
const F_CUSTOMER_ID = 20;
const F_FILE_INVOICE = 21;
const F_FILE_WARR_CARD = 22;
const F_V_MODEL_YEAR = 23;
const F_ODOMETER = 24;
const F_DEALER_NAME = 25;
const F_DEALER_ADDRESS = 26;
const F_CONTACT_NUM = 27;
const F_CUST_ADDRESS = 28;
const F_DATE_PURCHASE_CUST = 29;
const F_VALIDATED = 30;
const F_PROVINCE_ID = 31;
const F_MUNICIPALITY_ID = 32;
const F_CREATE_SOURCE = 33;
const F_DEALER_BRANCH_CODE = 34;
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
parent::__construct();
}
protected function configure()
{
$this->setName('warranty:updatedealerinfo')
->setDescription('Update warranty dealer information.')
->setHelp('Update warranty dealer information.')
->addArgument('input_file', InputArgument::REQUIRED, 'Path to the CSV file with the warranty info.')
->addArgument('output_file', InputArgument::REQUIRED, 'Output filename');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// for now, hardcode new dealer info (G-SIX SUMULONG)
$new_dealer = [
'name' => 'G-SIX SUMULONG',
'address' => '175 SUMULONG HIGHWAY MAYAMOT RIZAL_X000D_',
'branch_code' => 'ZN03587644',
];
$csv_file = $input->getArgument('input_file');
$output_file = $input->getArgument('output_file');
// attempt to open file
try
{
$fh = fopen($csv_file, "r");
}
catch (Exception $e)
{
throw new Exception('The file "' . $csv_file . '" could be opened.');
}
// start at 1 since 0 has the headers
$row_num = 1;
$output_info = [];
while (($fields = fgetcsv($fh)) !== false)
{
// ignore first row
if ($row_num == 1)
{
$row_num++;
continue;
}
// process row
$output_info[] = $this->processRow($fields, $new_dealer);
$row_num++;
}
// write to output file
$this->outputWarrantyInfo($output_file, $output_info);
fclose($fh);
return 0;
}
protected function processRow($fields, $new_dealer)
{
// get the warranty id
$warranty_id = trim($fields[SELF::F_ID]);
// find the warranty
$warranty = $this->em->getRepository(Warranty::class)->find($warranty_id);
if ($warranty == null)
{
// log warranty not found
return $this->setOutputInfo($fields, 'NOT UPDATED', 'Warranty not found');
}
// update warranty dealer information
$dealer_name = $new_dealer['name'];
$dealer_address = $new_dealer['address'];
$dealer_branch_code = $new_dealer['branch_code'];
$warranty->setDealerName($dealer_name)
->setDealerAddress($dealer_address)
->setDealerBranchCode($dealer_branch_code);
$this->em->flush();
// log successful update
return $this->setOutputInfo($fields, 'UPDATED', '');
}
protected function setOutputInfo($fields, $status, $reason)
{
$warranty_id = trim($fields[SELF::F_ID]);
return [
$warranty_id,
$status,
$reason,
];
}
protected function outputWarrantyInfo($output_file, $entries)
{
try
{
$fh = fopen($output_file, "w");
}
catch (Exception $e)
{
throw new Exception('The file "' . $report_file . '" could be opened.');
}
// write the headers
fputcsv($fh, [
'Warranty ID',
'Status',
'Reason',
]);
foreach ($entries as $row)
{
fputcsv($fh, $row);
}
fclose($fh);
}
}

View file

@ -7,6 +7,8 @@ use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Doctrine\ORM\EntityManagerInterface;
use App\Service\RisingTideGateway;
@ -18,19 +20,21 @@ class WarrantySMSCommand extends Command
{
protected $gateway;
protected $em;
protected $translator;
protected function configure()
{
$this->setName('warranty:sms')
->setDescription('Sends an SMS message to users whose warranty expired one month ago.')
->setDescription('Sends an SMS message to users whose warranty expired 45 days ago.')
->setHelp('Sends warranty SMS.')
->addArgument('date', InputArgument::OPTIONAL, 'Date to use as basis of expiration. Defaults to current date.');
}
public function __construct(EntityManagerInterface $em, RisingTideGateway $gateway)
public function __construct(EntityManagerInterface $em, RisingTideGateway $gateway, TranslatorInterface $translator)
{
$this->em = $em;
$this->gateway = $gateway;
$this->translator = $translator;
parent::__construct();
}
@ -46,7 +50,7 @@ class WarrantySMSCommand extends Command
$date = new DateTime();
// -1 month
$date->modify('-1 month');
$date->modify('-45 day');
$warrs = $this->em->getRepository(Warranty::class)->findBy(['date_expire' => $date]);
@ -97,10 +101,10 @@ class WarrantySMSCommand extends Command
error_log(print_r($valid_numbers, true));
foreach ($valid_numbers as $wdata)
{
$msg = 'Hi ' . $wdata['name'] . ', the warranty for the ' . $wdata['batt'] . ' installed in your car(' . $wdata['plate'] . ') has expired already. Please call MOTOLITE EXPRESS HATID at 8370-6686 to have the status of your battery checked to avoid any inconvenience. Thank you for choosing Motolite.';
$msg = 'Hi ' . $wdata['name'] . ', the warranty for the ' . $wdata['batt'] . ' installed in your car(' . $wdata['plate'] . $this->translator->trans('message.partial_warrantysms');
error_log($wdata['number'] . ' - sending ' . $msg);
$this->gateway->sendSMS($wdata['number'], 'MOTOLITE', $msg);
$this->gateway->sendSMS($wdata['number'], $this->translator->trans('message.battery_brand_allcaps'), $msg);
}

File diff suppressed because it is too large Load diff

View file

@ -2,8 +2,8 @@
namespace App\Controller;
use Catalyst\APIBundle\Entity\Role as APIRole;
use Catalyst\APIBundle\Access\Generator as APIACLGenerator;
use Catalyst\ApiBundle\Entity\Role as APIRole;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@ -19,7 +19,7 @@ class APIRoleController extends Controller
{
protected $api_acl_gen;
public function __construct(APIACLGenerator $api_acl_gen)
public function __construct(ACLGenerator $api_acl_gen)
{
$this->api_acl_gen = $api_acl_gen;
}
@ -326,7 +326,7 @@ class APIRoleController extends Controller
protected function padAPIACLHierarchy(&$params)
{
// get acl keys hierarchy
$api_acl_data = $this->api_acl_gen->getACL();
$api_acl_data = $this->api_acl_gen->getACL('api');
$params['api_acl_hierarchy'] = $api_acl_data['hierarchy'];
}

View file

@ -2,8 +2,8 @@
namespace App\Controller;
use Catalyst\APIBundle\Entity\User as APIUser;
use Catalyst\APIBundle\Entity\Role as APIRole;
use App\Entity\ApiUser as APIUser;
use Catalyst\ApiBundle\Entity\Role as APIRole;
use Doctrine\ORM\Query;
use Symfony\Component\HttpFoundation\Request;
@ -155,18 +155,20 @@ class APIUserController extends Controller
// metadata
$rider_id = $req->request->get('rider_id');
$rider = $em->getRepository(Rider::class)->find($rider_id);
// TODO: check for null rider
if ($rider != null)
{
$meta = ['rider_id' => $rider_id];
$meta = ['rider_id' => $rider_id];
// set api user in rider
$rider->setAPIUser($obj);
// set api user in rider
$rider->setAPIUser($obj);
$obj->setRider($rider)
->setMetadata($meta);
}
// set and save values
$obj->setName($req->request->get('name'))
->setEnabled($req->request->get('enabled') ? true : false)
->setMetadata($meta)
->setRider($rider)
->clearRoles();
// set roles

View file

@ -271,20 +271,20 @@ class AnalyticsController extends Controller
// add shift
$args[] = $shift;
//error_log(print_r($args, true));
// error_log(print_r($args, true));
error_log('running...' . $sched_script);
// error_log('running...' . $sched_script);
$proc = new Process($args);
$proc->run();
//error_log('getErrorOutput() ' . $proc->getErrorOutput());
error_log('getErrorOutput() ' . $proc->getErrorOutput());
if (!$proc->isSuccessful())
error_log('SCHEDULER DID NOT RUN PROPERLY');
$res = $proc->getOutput();
error_log($res);
// error_log($res);
// returns lines with format: <day shift>-<hour shift>-<number of riders>
@ -502,7 +502,7 @@ class AnalyticsController extends Controller
}
}
error_log('BEST - ' . $best_batt_id . ' - ' . $best_batt_count);
// error_log('BEST - ' . $best_batt_id . ' - ' . $best_batt_count);
return $best_batt_id;
}
@ -798,6 +798,45 @@ class AnalyticsController extends Controller
];
}
if ($shift == '6AM_7PM') {
$hour_shift = [
['06:00 - 15:00', 6, 7, 8, 9, 10, 11, 12, 13, 14],
['07:00 - 16:00', 7, 8, 9, 10, 11, 12, 13, 14, 15],
['08:00 - 17:00', 8, 9, 10, 11, 12, 13, 14, 15, 16],
['09:00 - 18:00', 9, 10, 11, 12, 13, 14, 15, 16, 17],
['10:00 - 19:00', 10, 11, 12, 13, 14, 15, 16, 17, 18]
];
}
if ($shift == '6AM_10PM') {
$hour_shift = [
['06:00 - 15:00', 6, 7, 8, 9, 10, 11, 12, 13, 14],
['07:00 - 16:00', 7, 8, 9, 10, 11, 12, 13, 14, 15],
['08:00 - 17:00', 8, 9, 10, 11, 12, 13, 14, 15, 16],
['09:00 - 18:00', 9, 10, 11, 12, 13, 14, 15, 16, 17],
['10:00 - 19:00', 10, 11, 12, 13, 14, 15, 16, 17, 18],
['11:00 - 20:00', 11, 12, 13, 14, 15, 16, 17, 18, 19],
['12:00 - 21:00', 12, 13, 14, 15, 16, 17, 18, 19, 20],
['13:00 - 22:00', 13, 14, 15, 16, 17, 18, 19, 20, 21]
];
}
if ($shift == '6AM-12AM') {
$hour_shift = [
['06:00 - 15:00', 6, 7, 8, 9, 10, 11, 12, 13, 14],
['07:00 - 16:00', 7, 8, 9, 10, 11, 12, 13, 14, 15],
['08:00 - 17:00', 8, 9, 10, 11, 12, 13, 14, 15, 16],
['09:00 - 18:00', 9, 10, 11, 12, 13, 14, 15, 16, 17],
['10:00 - 19:00', 10, 11, 12, 13, 14, 15, 16, 17, 18],
['11:00 - 20:00', 11, 12, 13, 14, 15, 16, 17, 18, 19],
['12:00 - 21:00', 12, 13, 14, 15, 16, 17, 18, 19, 20],
['13:00 - 22:00', 13, 14, 15, 16, 17, 18, 19, 20, 21],
['14:00 - 23:00', 14, 15, 16, 17, 18, 19, 20, 21, 22],
['15:00 - 00:00', 15, 16, 17, 18, 19, 20, 21, 22, 23],
['16:00 - 01:00', 16, 17, 18, 19, 20, 21, 22, 23, 0]
];
}
return $hour_shift;
}
}

View file

@ -117,6 +117,7 @@ class BatteryController extends Controller
$row['height'] = $orow[0]->getHeight();
$row['total_height'] = $orow[0]->getTotalHeight();
$row['image_file'] = $orow[0]->getImageFile();
$row['flag_active'] = $orow[0]->isActive();
// add row metadata
$row['meta'] = [
@ -182,7 +183,8 @@ class BatteryController extends Controller
->setHeight($req->request->get('height'))
->setTotalHeight($req->request->get('total_height'))
->setSellingPrice($req->request->get('sell_price'))
->setImageFile($req->request->get('image_file'));
->setImageFile($req->request->get('image_file'))
->setActive($req->request->get('flag_active', false));
// initialize error list
$error_array = [];
@ -308,6 +310,7 @@ class BatteryController extends Controller
->setTotalHeight($req->request->get('total_height'))
->setSellingPrice($req->request->get('sell_price'))
->setImageFile($req->request->get('image_file'))
->setActive($req->request->get('flag_active', false))
->clearVehicles();
// initialize error list
@ -424,7 +427,7 @@ class BatteryController extends Controller
$bmodel_id = $req->query->get('model_id');
$bsize_id = $req->query->get('size_id');
// find the battery using model and size
// find the battery using model and size and battery must be active
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery('SELECT b FROM App\Entity\Battery b
JOIN b.model bm
@ -432,7 +435,8 @@ class BatteryController extends Controller
JOIN b.manufacturer bmfg
WHERE bm.id = :bm_id
AND bs.id = :bs_id
AND bmfg.id = :bmfg_id')
AND bmfg.id = :bmfg_id
AND b.flag_active = true')
->setParameter('bmfg_id', $bmfg_id)
->setParameter('bm_id', $bmodel_id)
->setParameter('bs_id', $bsize_id);

View file

@ -270,7 +270,7 @@ class BatteryManufacturerController extends Controller
// get row data
$em = $this->getDoctrine()->getManager();
$all_batts = $em->getRepository(Battery::class)->findAll();
$all_batts = $em->getRepository(Battery::class)->findBy(['flag_active' => true]);
foreach ($all_batts as $battery)
{

View file

@ -6,14 +6,14 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\SAPBattery;
use App\Entity\SAPBatterySize;
use App\Entity\SAPBatteryBrand;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class BatteryController extends APIController
{
@ -113,7 +113,7 @@ class BatteryController extends APIController
];
$msg = $this->checkRequiredParameters($req, $params);
error_log('msg - ' . $msg);
// error_log('msg - ' . $msg);
if ($msg)
return new APIResponse(false, $msg);

View file

@ -8,16 +8,18 @@ use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\Customer;
use App\Entity\CustomerVehicle;
use App\Entity\Vehicle;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use App\Service\HashGenerator;
class CustomerController extends APIController
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class CustomerController extends ApiController
{
protected $acl_gen;
@ -44,7 +46,7 @@ class CustomerController extends APIController
];
$msg = $this->checkRequiredParameters($req, $params);
error_log('msg - ' . $msg);
// error_log('msg - ' . $msg);
if ($msg)
return new APIResponse(false, $msg);
@ -70,7 +72,7 @@ class CustomerController extends APIController
{
// remove first '0'
$mobile_number = substr($mobile_number, 1);
error_log("CONVERTED TO $mobile_number");
// error_log("CONVERTED TO $mobile_number");
}
// does it fit our 9XXXXXXXXX pattern?
@ -202,6 +204,45 @@ class CustomerController extends APIController
return new APIResponse(true, $message, $data);
}
public function verifyCustomer($customer_hash, EntityManagerInterface $em, HashGenerator $hash)
{
$this->denyAccessUnlessGranted('customer.verify', null, 'No access.');
// get customer id from customer_hash
$cust_id = $hash->getID($customer_hash);
if ($cust_id == null)
return new APIResponse(false, 'Invalid customer hash.');
// find customer using id
$customer = $em->getRepository(Customer::class)->find($cust_id);
$data = [];
$message = '';
if ($customer == null)
{
$message = 'Customer not found.';
$data[] = [
'is_customer' => false,
'first_name' => '',
'last_name' => '',
'mobile_number' => '',
];
}
else
{
$message = 'Customer found.';
$data[] = [
'is_customer' => true,
'first_name' => $customer->getFirstName(),
'last_name' => $customer->getLastName(),
'mobile_number' => $customer->getPhoneMobile(),
];
}
return new APIResponse(true, $message, $data);
}
protected function cleanPlateNumber($plate)
{
// remove spaces and make upper case

View file

@ -10,8 +10,8 @@ use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Service\RisingTideGateway;
use App\Service\WarrantyAPILogger;
@ -37,10 +37,10 @@ use App\Ramcar\WarrantySource;
use DateTime;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
// third party API
class CustomerWarrantyController extends APIController
class CustomerWarrantyController extends ApiController
{
protected $acl_gen;
@ -89,18 +89,30 @@ class CustomerWarrantyController extends APIController
return true;
}
protected function cleanSerial($serial)
{
return trim(strtoupper($serial));
}
protected function cleanPlateNumber($plate_num)
{
return preg_replace('/\s+/', '', strtoupper($plate_num));
}
// TODO: put this in a service
protected function cleanSerial($serial)
{
// trim and make everything upper case
$clean_serial = trim(strtoupper($serial));
// remove QR prefix if it exists
//$prefix = substr($clean_serial, 0, 2);
//if ($prefix == 'QR')
// $clean_serial = substr($clean_serial, 2);
return $clean_serial;
}
public function check($serial, EntityManagerInterface $em, Request $req, WarrantyAPILogger $logger)
{
$serial = $this->cleanSerial($serial);
$user_id = $_SERVER['HTTP_X_CATA_API_KEY'];
$log_data = [
'serial' => $serial,
@ -115,7 +127,7 @@ class CustomerWarrantyController extends APIController
if (!$res)
return $res;
error_log('check warranty serial');
// error_log('check warranty serial');
// TODO: add logging for the other scenarios
// check if warranty serial is there
@ -134,7 +146,7 @@ class CustomerWarrantyController extends APIController
// if we have a warranty entry for the serial already
if ($warr != null)
{
error_log('already have warranty.');
// error_log('already have warranty.');
$warr_plate = $warr->getPlateNumber();
$is_registered = true;
@ -303,7 +315,8 @@ class CustomerWarrantyController extends APIController
public function register($serial, EntityManagerInterface $em, Request $req, KernelInterface $kernel, RisingTideGateway $rt, TranslatorInterface $trans,
WarrantyAPILogger $logger)
{
error_log('HERE - register');
$serial = $this->cleanSerial($serial);
// error_log('HERE - register');
// set up information for logging
// get user from header
@ -325,7 +338,7 @@ class CustomerWarrantyController extends APIController
$username = $this->getUser()->getName();
$source = 'CAPI_USER_' . $username;
error_log('SOURCE: ' . $source);
// error_log('SOURCE: ' . $source);
// TODO: maybe add vmake_id? since warranty cannot be created with no vmake
// TODO: maybe also add mobile and email since customer creation won't let mobile and email be null
@ -345,7 +358,7 @@ class CustomerWarrantyController extends APIController
$invoice = $req->files->get('invoice');
$warr_card = $req->files->get('warr_card');
error_log('handling file uploads');
// error_log('handling file uploads');
// process picture uploads
$upload_dir = $kernel->getProjectDir() . '/public/warranty_uploads';
$inv_filename = $this->handlePictureUpload($invoice, $upload_dir, $serial, 'invoice');
@ -366,11 +379,13 @@ class CustomerWarrantyController extends APIController
// TODO: move this to a service, since it's shared by all warranty updaters
protected function handlePictureUpload($file, $target_dir, $serial, $name)
{
error_log("handling $name upload");
$serial = $this->cleanSerial($serial);
// error_log("handling $name upload");
// no file sent
if ($file == null)
{
error_log('no file');
error_log("handling $name upload but no file");
return null;
}
@ -388,8 +403,8 @@ class CustomerWarrantyController extends APIController
$filename = $name . '.' . $file->getClientOriginalExtension();
$file->move($target_dir . '/' . $serial, $filename);
error_log("filename - $filename");
error_log($target_dir . '/' . $serial . '/' . $filename);
// error_log("filename - $filename");
// error_log($target_dir . '/' . $serial . '/' . $filename);
return $serial . '/' . $filename;
}
@ -399,7 +414,7 @@ class CustomerWarrantyController extends APIController
{
$plate_num = $this->cleanPlateNumber($req->request->get('plate_num'));
error_log('warranty serial check');
// error_log('warranty serial check');
// get serial
$warr_serial = $em->getRepository(WarrantySerial::class)->find($serial);
if ($warr_serial == null)
@ -438,7 +453,7 @@ class CustomerWarrantyController extends APIController
$warr->setCreateSource($source);
}
error_log('sap battery check');
// error_log('sap battery check');
// get sap battery
$sku = $warr_serial->getSKU();
$sap_bty = null;
@ -467,7 +482,7 @@ class CustomerWarrantyController extends APIController
}
}
error_log('date check');
// error_log('date check');
// default date purchase to today
// NOTE: might need to change this later
$date_pur = new DateTime();
@ -513,7 +528,7 @@ class CustomerWarrantyController extends APIController
}
error_log('update entity / database');
// error_log('update entity / database');
// create or update warranty entry
$warr->setSerial($serial)
->setFirstName($req->request->get('first_name'))
@ -563,12 +578,12 @@ class CustomerWarrantyController extends APIController
// send sms confirmation
$this->sendSMSConfirmation($rt, $req->request->get('contact_num'), $sms_message);
$this->sendSMSConfirmation($rt, $req->request->get('contact_num'), $sms_message, $trans);
return new APIResponse(true, 'Warranty registered.', $data);
}
protected function sendSMSConfirmation($rt, $num, $message)
protected function sendSMSConfirmation($rt, $num, $message, $trans)
{
$clean_num = trim($num);
@ -585,8 +600,8 @@ class CustomerWarrantyController extends APIController
if ($clean_num[0] != '0' && $clean_num[0] != '6')
return false;
error_log('sending sms to - ' . $clean_num);
// error_log('sending sms to - ' . $clean_num);
$rt->sendSMS($clean_num, 'MOTOLITE', $message);
$rt->sendSMS($clean_num, $trans->trans('message.battery_brand_allcaps'), $message);
}
}

View file

@ -6,14 +6,14 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\Dealer;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class DealerController extends APIController
class DealerController extends ApiController
{
protected $acl_gen;

View file

@ -0,0 +1,53 @@
<?php
namespace App\Controller\CAPI;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\Hub;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class HubController extends ApiController
{
protected $acl_gen;
public function __construct(ACLGenerator $acl_gen)
{
$this->acl_gen = $acl_gen;
}
public function getAll(EntityManagerInterface $em)
{
// get all hub data order by name
$this->denyAccessUnlessGranted('hub.list', null, 'No access.');
$results = $em->getRepository(Hub::class)->findBy([], ['name' => 'ASC']);
$hubs = [];
foreach($results as $res)
{
$hub_id = $res->getId();
$hub_name = $res->getName();
$hub_address = $res->getAddress();
$hub_branch_code = $res->getBranchCode();
$hubs[$hub_id] = [
'id' => $hub_id,
'name' => $hub_name,
'address' => $hub_address,
'branch_code' => $hub_branch_code,
];
}
$data = [
'hubs' => $hubs,
];
return new APIResponse(true, 'Hubs loaded.', $data);
}
}

View file

@ -0,0 +1,139 @@
<?php
namespace App\Controller\CAPI;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\JobOrder;
use App\Entity\Warranty;
use App\Ramcar\JOStatus;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class JobOrderController extends ApiController
{
protected $acl_gen;
public function __construct(ACLGenerator $acl_gen)
{
$this->acl_gen = $acl_gen;
}
public function getJobOrder($id, EntityManagerInterface $em)
{
$this->denyAccessUnlessGranted('joborder.find', null, 'No access.');
$jo = $em->getRepository(JobOrder::class)->find($id);
if ($jo == null)
return new APIResponse(false, 'No job order found with that number.', null, 404);
$data = $this->generateJobOrderData($jo, $em);
return new APIResponse(true, 'Job order found.', $data);
}
protected function generateJobOrderData($jo, EntityManagerInterface $em)
{
// customer vehicle
$cv = $jo->getCustomerVehicle();
// customer information
$customer = $jo->getCustomer();
// hub
$hub_name = '';
$hub = $jo->getHub();
if ($hub != null)
$hub_name = $hub->getName();
// check if JO is fulfilled, if not, we leave date_purchase blank
$date_purchase = '';
$serial = '';
$status = $jo->getStatus();
if ($status == JOStatus::FULFILLED)
{
if ($jo->getDateFulfill() != null)
$date_purchase = $jo->getDateFulfill()->format('M d, Y H:i');
// find warranty to get the serial using plate number
$serial = $this->getSerialFromWarranty($cv->getPlateNumber(), $em);
}
$jo_data = [
'id' => $jo->getID(),
'first_name' => $customer->getFirstName(),
'last_name' => $customer->getLastName(),
'mobile_number' => $customer->getPhoneMobile(),
'email' => $customer->getEmail(),
'plate_number' => $cv->getPlateNumber(),
'date_purchase' => $date_purchase,
'address' => $jo->getDeliveryAddress(),
'hub' => $hub_name,
'serial' => $serial,
];
// invoice items
$items = [];
$jo_items = $jo->getInvoice()->getItems();
$non_battery_item_titles = ['Promo discount', 'Trade-in', 'Service'];
foreach ($jo_items as $item)
{
$item_title = $item->getTitle();
// check if title has Promo discount, Trade-in, or Service
$flag_battery = $this->checkIfBatteryInvoiceItem($item_title, $non_battery_item_titles);
if ($flag_battery == true)
{
$items[] = [
'title' => $item->getTitle(),
];
}
}
$jo_data['items'] = $items;
return $jo_data;
}
protected function checkIfBatteryInvoiceItem($item_title, $non_battery_item_titles)
{
foreach ($non_battery_item_titles as $nb_item_title)
{
$pos_result = stripos($item_title, $nb_item_title);
// if found, invoice item is not a battery item
if ($pos_result !== false)
return false;
}
return true;
}
protected function getSerialFromWarranty($plate_number, EntityManagerInterface $em)
{
// NOTE: Modify the search for the latest warranty. This seems hacky.
// get latest warranty using plate number
$warranty_results = $em->getRepository(Warranty::class)->findBy(
['plate_number' => $plate_number],
['date_create' => 'desc']
);
$serial = '';
if (!empty($warranty_results))
{
// get first entry
$warranty = current($warranty_results);
$serial = $warranty->getSerial();
}
return $serial;
}
}

View file

@ -6,14 +6,14 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\Municipality;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class MunicipalityController extends APIController
class MunicipalityController extends ApiController
{
protected $acl_gen;

View file

@ -7,15 +7,15 @@ use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\PrivacyPolicy;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
// third party API
class PrivacyPolicyController extends APIController
class PrivacyPolicyController extends ApiController
{
protected $acl_gen;

View file

@ -6,11 +6,13 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\Rider;
use App\Entity\JOEvent;
@ -20,16 +22,21 @@ use App\Entity\BatteryModel;
use App\Entity\BatterySize;
use App\Entity\RiderAPISession;
use App\Entity\User;
use Catalyst\APIBundle\Entity\User as APIUser;
use App\Entity\ApiUser as APIUser;
use App\Entity\JobOrder;
use App\Entity\SAPBattery;
use App\Entity\WarrantySerial;
use App\Service\RedisClientProvider;
use App\Service\RiderCache;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Service\WarrantyHandler;
use App\Service\JobOrderHandlerInterface;
use App\Service\InvoiceGeneratorInterface;
use App\Service\RisingTideGateway;
use App\Service\RiderTracker;
use App\Service\PriceTierManager;
use App\Ramcar\ServiceType;
use App\Ramcar\TradeInType;
@ -44,7 +51,7 @@ use App\Ramcar\DeliveryStatus;
use DateTime;
// third party API for rider
class RiderAppController extends APIController
class RiderAppController extends ApiController
{
/*
public function register(Request $req, EntityManagerInterface $em, RedisClientProvider $redis)
@ -282,8 +289,9 @@ class RiderAppController extends APIController
// do we have a job order?
// $jo = $rider->getActiveJobOrder();
// NOTE: we do not include job orders that have been cancelled
$jo = $rider->getCurrentJobOrder();
if ($jo == null)
if ($jo == null || $jo->getStatus() == JOStatus::CANCELLED)
{
$data = [
'job_order' => null
@ -378,6 +386,7 @@ class RiderAppController extends APIController
'flag_coolant' => $jo->hasCoolant(),
'has_motolite' => $cv->hasMotoliteBattery(),
'delivery_status' => $jo->getDeliveryStatus(),
'flag_sealant' => $jo->hasSealant(),
]
];
}
@ -404,6 +413,11 @@ class RiderAppController extends APIController
if (!empty($msg))
return new APIResponse(false, $msg);
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// TODO: refactor this into a jo handler class, so we don't have to repeat for control center
// set jo status to in transit
@ -435,7 +449,7 @@ class RiderAppController extends APIController
}
public function cancelJobOrder(Request $req, EntityManagerInterface $em, MQTTClient $mclient)
public function cancelJobOrder(Request $req, EntityManagerInterface $em, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient)
{
$required_params = ['jo_id'];
@ -451,7 +465,13 @@ class RiderAppController extends APIController
$msg = $this->checkJO($req, $required_params, $jo, $rider);
if (!empty($msg))
return new APIResponse(false, $msg);
// TODO: this is a workaround for requeue, because rider app gets stuck in accept / decline screen
return new APIResponse(true, $msg);
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// requeue it, instead of cancelling it
$jo->requeue();
@ -480,6 +500,10 @@ class RiderAppController extends APIController
];
$mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($jo, $payload);
$fcmclient->sendJoEvent($jo, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
$data = [];
return new APIResponse(true, 'Job order requeued.', $data);
}
@ -507,6 +531,11 @@ class RiderAppController extends APIController
// get rider's current job order
$jo = $rider->getCurrentJobOrder();
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// set delivery status
$jo->setDeliveryStatus(DeliveryStatus::RIDER_DEPART_HUB);
@ -547,6 +576,11 @@ class RiderAppController extends APIController
// get rider's current job order
$jo = $rider->getCurrentJobOrder();
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// set delivery status
$jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE_HUB_PRE_JO);
@ -587,6 +621,11 @@ class RiderAppController extends APIController
// get rider's current job order
$jo = $rider->getCurrentJobOrder();
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// set delivery status
$jo->setDeliveryStatus(DeliveryStatus::RIDER_DEPART_HUB_PRE_JO);
@ -627,6 +666,11 @@ class RiderAppController extends APIController
// get rider's current job order
$jo = $rider->getCurrentJobOrder();
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// set delivery status
$jo->setDeliveryStatus(DeliveryStatus::RIDER_START);
@ -645,7 +689,7 @@ class RiderAppController extends APIController
}
public function arrive(Request $req, EntityManagerInterface $em, MQTTClient $mclient)
public function arrive(Request $req, EntityManagerInterface $em, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient)
{
$required_params = ['jo_id'];
@ -668,6 +712,11 @@ class RiderAppController extends APIController
// set jo status to in progress
$jo->setStatus(JOStatus::IN_PROGRESS);
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// set delivery status
$jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE);
@ -695,6 +744,10 @@ class RiderAppController extends APIController
];
$mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($jo, $payload);
$fcmclient->sendJoEvent($jo, "jo_fcm_title_driver_arrived", "jo_fcm_body_driver_arrived");
$data = [];
return new APIResponse(true, 'Rider arrived at customer location.', $data);
}
@ -722,6 +775,11 @@ class RiderAppController extends APIController
// get rider's current job order
$jo = $rider->getCurrentJobOrder();
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// set delivery status
$jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE_HUB);
@ -745,8 +803,56 @@ class RiderAppController extends APIController
return new APIResponse(true, 'Rider arrive at hub.', $data);
}
public function getBatterySizes(Request $req, EntityManagerInterface $em)
{
// get capi user
$capi_user = $this->getUser();
if ($capi_user == null)
return new APIResponse(false, 'User not found.');
// get rider id from capi user metadata
$rider = $this->getRiderFromCAPI($capi_user, $em);
if ($rider == null)
return new APIResponse(false, 'No rider found.');
// get sizes
$qb = $em->getRepository(BatterySize::class)
->createQueryBuilder('bs');
$sizes = $qb->select('bs.id, bs.name')
->orderBy('bs.name', 'asc')
->getQuery()
->getResult();
// response
return new APIResponse(true, '', [
'sizes' => $sizes,
]);
}
public function getTradeInTypes(Request $req, EntityManagerInterface $em)
{
// get capi user
$capi_user = $this->getUser();
if ($capi_user == null)
return new APIResponse(false, 'User not found.');
// get rider id from capi user metadata
$rider = $this->getRiderFromCAPI($capi_user, $em);
if ($rider == null)
return new APIResponse(false, 'No rider found.');
// get trade-in types
$types = TradeInType::getCollection();
// response
return new APIResponse(true, '', [
'types' => $types,
]);
}
public function payment(Request $req, EntityManagerInterface $em, JobOrderHandlerInterface $jo_handler,
RisingTideGateway $rt, WarrantyHandler $wh, MQTTClient $mclient)
RisingTideGateway $rt, WarrantyHandler $wh, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient, TranslatorInterface $translator)
{
$required_params = ['jo_id'];
@ -764,6 +870,22 @@ class RiderAppController extends APIController
if (!empty($msg))
return new APIResponse(false, $msg);
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// need to check if service type is battery sales
// if so, serial is a required parameter
$serial = $req->request->get('serial', '');
if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW)
{
/*
if (empty($serial))
return new APIResponse(false, 'Missing parameter(s): serial');
*/
}
// set invoice to paid
$jo->getInvoice()->setStatus(InvoiceStatus::PAID);
@ -806,9 +928,8 @@ class RiderAppController extends APIController
$phone_number = $jo->getCustomer()->getPhoneMobile();
if (!empty($phone_number))
{
// TODO: put this in config file or somewhere
$message = "Your Resq job order has been completed.";
$rt->sendSMS($phone_number, 'MOTOLITE', $message);
$message = $translator->trans('message.joborder_completed');
$rt->sendSMS($phone_number, $translator->trans('message.battery_brand_allcaps'), $message);
}
$em->flush();
@ -816,7 +937,6 @@ class RiderAppController extends APIController
// create warranty
if($jo_handler->checkIfNewBattery($jo))
{
$serial = null;
$warranty_class = $jo->getWarrantyClass();
$first_name = $jo->getCustomer()->getFirstName();
$last_name = $jo->getCustomer()->getLastName();
@ -869,6 +989,10 @@ class RiderAppController extends APIController
];
$mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($jo, $payload);
$fcmclient->sendJoEvent($jo, "jo_fcm_title_fulfilled", "jo_fcm_body_fulfilled");
$data = [];
return new APIResponse(true, 'Job order paid and fulfilled.', $data);
}
@ -896,6 +1020,11 @@ class RiderAppController extends APIController
// get rider's current job order
$jo = $rider->getCurrentJobOrder();
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// set delivery status
$jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE_HUB_POST_JO);
@ -937,6 +1066,11 @@ class RiderAppController extends APIController
// get rider's current job order
$jo = $rider->getCurrentJobOrder();
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// set delivery status
$jo->setDeliveryStatus(DeliveryStatus::RIDER_DEPART_HUB_POST_JO);
@ -1041,7 +1175,7 @@ class RiderAppController extends APIController
if ($rider == null)
return new APIResponse(false, 'No rider found.');
$batts = $em->getRepository(Battery::class)->findAll();
$batts = $em->getRepository(Battery::class)->findBy(['flag_active' => true]);
$models = $em->getRepository(BatteryModel::class)->findAll();
$sizes = $em->getRepository(BatterySize::class)->findAll();
@ -1083,9 +1217,180 @@ class RiderAppController extends APIController
return new APIResponse(true, 'Batteries found.', $data);
}
public function changeService(Request $req, EntityManagerInterface $em, InvoiceGeneratorInterface $ic)
public function getBatteryInfo(Request $req, $serial, EntityManagerInterface $em)
{
$this->debugRequest($req);
if (empty($serial))
{
return new APIResponse(false, 'Missing parameter(s): serial');
}
// get capi user
$capi_user = $this->getUser();
if ($capi_user == null)
return new APIResponse(false, 'User not found.');
// get rider id from capi user metadata
$rider = $this->getRiderFromCAPI($capi_user, $em);
if ($rider == null)
return new APIResponse(false, 'No rider found.');
// find battery given serial/sap_code and flag_active is true
$serial = $em->getRepository(WarrantySerial::class)->find($serial);
if (empty($serial)) {
return new APIResponse(false, 'Warranty serial number not found.');
}
$sap_battery = $em->getRepository(SAPBattery::class)->find($serial->getSKU());
if (empty($sap_battery)) {
return new APIResponse(false, 'No battery info found.');
}
$battery = [
'id' => $sap_battery->getID(),
'brand' => $sap_battery->getBrand()->getName(),
'size' => $sap_battery->getSize()->getName(),
'size_id' => $sap_battery->getSize()->getID(),
'trade_in_type' => TradeInType::MOTOLITE,
'container_size' => $sap_battery->getContainerSize()->getName(),
];
return new APIResponse(true, 'Battery info found.', [
'battery' => $battery,
]);
}
public function updateJobOrder(Request $req, EntityManagerInterface $em, InvoiceGeneratorInterface $ic, PriceTierManager $pt_manager)
{
$items = json_decode(file_get_contents('php://input'), true);
// get job order id
if (!isset($items['jo_id']))
return new APIResponse(false, 'Missing parameter(s): jo_id');
// validate jo_id
$jo_id = $items['jo_id'];
if (empty($jo_id) || $jo_id == null)
return new APIResponse(false, 'Missing parameter(s): jo_id');
// get capi user
$capi_user = $this->getUser();
if ($capi_user == null)
return new APIResponse(false, 'User not found.');
// get rider id from capi user metadata
$rider = $this->getRiderFromCAPI($capi_user, $em);
if ($rider == null)
return new APIResponse(false, 'No rider found.');
// get the job order
$jo = $em->getRepository(JobOrder::class)->find($jo_id);
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// check if we have trade in items
$ti_items = [];
if (isset($items['trade_in_items']))
{
// validate the trade in items first
$ti_items = $items['trade_in_items'];
$msg = $this->validateTradeInItems($em, $ti_items);
if (!empty($msg))
return new APIResponse(false, $msg);
}
// get the service type
if (!isset($items['stype_id']))
return new APIResponse(false, 'Missing parameter(s): stype_id');
// validate service type
$stype_id = $items['stype_id'];
if (!ServiceType::validate($stype_id))
return new APIResponse(false, 'Invalid service type - ' . $stype_id);
// save service type
$jo->setServiceType($stype_id);
// validate promo if any. Promo not required
$promo = null;
if (isset($items['promo_id']))
{
$promo_id = $items['promo_id'];
$promo = $em->getRepository(Promo::class)->find($promo_id);
if ($promo == null)
return new APIResponse(false, 'Invalid promo id - ' . $promo_id);
}
// get other parameters, if any: has motolite battery, has warranty doc, with coolant, payment method, with sealant
if (isset($items['flag_motolite_battery']))
{
// get customer vehicle from jo
$cv = $jo->getCustomerVehicle();
$has_motolite = $items['flag_motolite_battery'];
if ($has_motolite == 'true')
$cv->setHasMotoliteBattery(true);
else
$cv->setHasMotoliteBattery(false);
$em->persist($cv);
}
if (isset($items['flag_warranty_doc']))
{
// TODO: what do we do?
}
if (isset($items['flag_coolant']))
{
$has_coolant = $items['flag_coolant'];
if ($has_coolant == 'true')
$jo->setHasCoolant(true);
else
$jo->setHasCoolant(false);
}
if (isset($items['mode_of_payment']))
{
$payment_method = $items['payment_method'];
if (!ModeOfPayment::validate($payment_method))
$payment_method = ModeOfPayment::CASH;
$jo->setModeOfPayment($payment_method);
}
if (isset($items['flag_sealant']))
{
$has_sealant = $items['flag_sealant'];
if ($has_sealant == 'true')
$jo->setHasSealant(true);
else
$jo->setHasSealant(false);
}
// get capi user
$capi_user = $this->getUser();
if ($capi_user == null)
return new APIResponse(false, 'User not found.');
// get rider id from capi user metadata
$rider = $this->getRiderFromCAPI($capi_user, $em);
if ($rider == null)
return new APIResponse(false, 'No rider found.');
// need to get the existing invoice items using jo id and invoice id
$existing_ii = $this->getInvoiceItems($em, $jo);
$this->generateUpdatedInvoice($em, $ic, $jo, $existing_ii, $ti_items, $promo, $pt_manager);
$data = [];
return new APIResponse(true, 'Job order updated.', $data);
}
public function changeService(Request $req, EntityManagerInterface $em, InvoiceGeneratorInterface $ic, PriceTierManager $pt_manager)
{
// $this->debugRequest($req);
// allow rider to change service, promo, battery and trade-in options
$required_params = ['jo_id', 'stype_id', 'promo_id'];
@ -1104,6 +1409,11 @@ class RiderAppController extends APIController
if (!empty($msg))
return new APIResponse(false, $msg);
// check if JO can be modified first
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
return new APIResponse(false, 'Job order can no longer be modified.');
}
// check service type
$stype_id = $req->request->get('stype_id');
if (!ServiceType::validate($stype_id))
@ -1143,6 +1453,13 @@ class RiderAppController extends APIController
else
$jo->setHasCoolant(false);
// sealant
$flag_sealant = $req->request->get('flag_sealant', 'false');
if ($flag_sealant == 'true')
$jo->setHasSealant(true);
else
$jo->setHasSealant(false);
// has motolite battery
$cv = $jo->getCustomerVehicle();
$has_motolite = $req->request->get('has_motolite', 'false');
@ -1185,6 +1502,11 @@ class RiderAppController extends APIController
$crit->setServiceType($stype_id);
$crit->setCustomerVehicle($cv);
$crit->setHasCoolant($jo->hasCoolant());
$crit->setIsTaxable();
// set price tier
$pt_id = $pt_manager->getPriceTier($jo->getCoordinates());
$crit->setPriceTier($pt_id);
if ($promo != null)
$crit->addPromo($promo);
@ -1192,7 +1514,7 @@ class RiderAppController extends APIController
if ($battery != null)
{
$crit->addEntry($battery, $trade_in, 1);
error_log('adding entry for battery - ' . $battery->getID());
// error_log('adding entry for battery - ' . $battery->getID());
}
$invoice = $ic->generateInvoice($crit);
@ -1224,6 +1546,168 @@ class RiderAppController extends APIController
return new APIResponse(true, 'Job order service changed.', $data);
}
protected function generateUpdatedInvoice(EntityManagerInterface $em, InvoiceGeneratorInterface $ic, JobOrder $jo, $existing_ii, $trade_in_items, $promo, PriceTierManager $pt_manager)
{
// get the service type
$stype = $jo->getServiceType();
// get the source
$source = $jo->getSource();
// get the customer vehicle
$cv = $jo->getCustomerVehicle();
// get coolant if any
$flag_coolant = $jo->hasCoolant();
// get sealant if any
$flag_sealant = $jo->hasSealant();
// check if new promo is null
if ($promo == null)
{
// promo not updated from app so check existing invoice
// get the promo id from existing invoice item
$promo_id = $existing_ii['promo_id'];
if ($promo_id == null)
$promo = null;
else
$promo = $em->getRepository(Promo::class)->find($promo_id);
}
// populate Invoice Criteria
$icrit = new InvoiceCriteria();
$icrit->setServiceType($stype)
->setCustomerVehicle($cv)
->setSource($source)
->setHasCoolant($flag_coolant)
->setHasSealant($flag_sealant)
->setIsTaxable();
// set price tier
$pt_id = $pt_manager->getPriceTier($jo->getCoordinates());
$icrit->setPriceTier($pt_id);
// at this point, all information should be valid
// assuming JO information is already valid since this
// is in the system already
// add promo if any to criteria
if ($promo != null)
$icrit->addPromo($promo);
// get the battery purchased from existing invoice items
// add the batteries ordered to criteria
$ii_items = $existing_ii['invoice_items'];
foreach ($ii_items as $ii_item)
{
$batt_id = $ii_item['batt_id'];
$qty = $ii_item['qty'];
$battery = $em->getRepository(Battery::class)->find($batt_id);
$icrit->addEntry($battery, null, $qty);
}
// add the trade in items to the criteria
foreach ($trade_in_items as $ti_item)
{
$batt_size_id = $ti_item['battery_size_id'];
$qty = $ti_item['qty'];
$trade_in_type = $ti_item['trade_in_type'];
$batt_size = $em->getRepository(BatterySize::class)->find($batt_size_id);
$icrit->addTradeInEntry($batt_size, $trade_in_type, $qty);
}
// call generateInvoice
$invoice = $ic->generateInvoice($icrit);
// remove previous invoice
$old_invoice = $jo->getInvoice();
$em->remove($old_invoice);
$em->flush();
// save new invoice
$jo->setInvoice($invoice);
$em->persist($invoice);
// log event?
$event = new JOEvent();
$event->setDateHappen(new DateTime())
->setTypeID(JOEventType::RIDER_EDIT)
->setJobOrder($jo)
->setRider($jo->getRider());
$em->persist($event);
$em->flush();
}
protected function getInvoiceItems(EntityManagerInterface $em, JobOrder $jo)
{
$jo_id = $jo->getID();
$conn = $em->getConnection();
// need to get the ordered battery id and quantity from invoice item
// and the promo from invoice
$query_sql = 'SELECT ii.battery_id AS battery_id, ii.qty AS qty, i.promo_id AS promo_id
FROM invoice_item ii, invoice i
WHERE ii.invoice_id = i.id
AND i.job_order_id = :jo_id
AND ii.battery_id IS NOT NULL';
$query_stmt = $conn->prepare($query_sql);
$query_stmt->bindValue('jo_id', $jo_id);
$results = $query_stmt->executeQuery();
$promo_id = null;
$invoice_items = [];
while ($row = $results->fetchAssociative())
{
$promo_id = $row['promo_id'];
$invoice_items[] = [
'batt_id' => $row['battery_id'],
'qty' => $row['qty'],
'trade_in' => ''
];
}
$data = [
'promo_id' => $promo_id,
'invoice_items' => $invoice_items
];
return $data;
}
protected function validateTradeInItems(EntityManagerInterface $em, $ti_items)
{
$msg = '';
foreach ($ti_items as $ti_item)
{
$bs_id = $ti_item['battery_size_id'];
$ti_type = $ti_item['trade_in_type'];
// validate the battery size id
$batt_size = $em->getRepository(BatterySize::class)->find($bs_id);
if ($batt_size == null)
{
$msg = 'Invalid battery size for trade in: ' . $bs_id;
return $msg;
}
// validate the trade in type
if (!TradeInType::validate($ti_type))
{
$msg = 'Invalid trade in type: ' . $ti_type;
return $msg;
}
}
return $msg;
}
protected function getCAPIUser($id, EntityManagerInterface $em)
{
$capi_user = $em->getRepository(APIUser::class)->find($id);
@ -1303,6 +1787,42 @@ class RiderAppController extends APIController
return $msg;
}
protected function checkJOProgressionAllowed(EntityManagerInterface $em, JobOrder $jo, &$rider)
{
$allowed = true;
error_log("JO delivery status is " . $jo->getDeliveryStatus() . " (not allowed: " . DeliveryStatus::CANCELLED . ")");
error_log("JO status is " . $jo->getStatus() . " (not allowed: " . JOStatus::CANCELLED . ")");
// TODO: add more statuses to block if needed, hence. this is a failsafe in case MQTT is not working.
// check delivery status
switch ($jo->getDeliveryStatus())
{
case DeliveryStatus::CANCELLED:
$allowed = false;
break;
}
// check JO status as well
switch ($jo->getStatus())
{
case JOStatus::CANCELLED:
$allowed = false;
break;
}
// if this is the rider's current JO, set to null
if (!$allowed) {
if ($rider->getCurrentJobOrder() === $jo) {
$rider->setCurrentJobOrder();
$em->persist($rider);
$em->flush();
}
}
return $allowed;
}
protected function debugRequest(Request $req)
{
$all = $req->request->all();

View file

@ -5,10 +5,10 @@ namespace App\Controller\CAPI;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
class TestController extends APIController
class TestController extends ApiController
{
public function test()
{
@ -17,4 +17,19 @@ class TestController extends APIController
];
return new APIResponse(true, 'Test successful.', $data);
}
public function warrantySerial(Request $req)
{
error_log('Got request');
$res = json_decode($req->getContent(), true);
// return $res;
$data = [
'result' => $res,
];
return new APIResponse(true, 'Test successful.', $data);
}
}

View file

@ -6,14 +6,14 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\Vehicle;
use App\Entity\VehicleManufacturer;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class VehicleController extends APIController
class VehicleController extends ApiController
{
protected $acl_gen;
@ -48,7 +48,7 @@ class VehicleController extends APIController
{
$this->denyAccessUnlessGranted('vehicle.list', null, 'No access.');
$mfg = $this->em->getRepository(VehicleManufacturer::class)->find($mfg_id);
$mfg = $em->getRepository(VehicleManufacturer::class)->find($mfg_id);
// manufacturer not found
if ($mfg == null)
@ -69,6 +69,9 @@ class VehicleController extends APIController
}
// TODO: need to add manufacturer details
$data = [
'vehicles' => $make_data,
];
return new APIResponse(true, 'Vehicles loaded.', $data);
}
@ -77,31 +80,48 @@ class VehicleController extends APIController
{
$this->denyAccessUnlessGranted('vehicle.list', null, 'No access.');
$conn = $em->getConnection();
// get manufacturers
$mfgs = $em->getRepository(VehicleManufacturer::class)->findBy([], ['name' => 'ASC']);
$mfg_sql = 'SELECT vmfg.id, vmfg.name FROM vehicle_manufacturer vmfg ORDER BY vmfg.name ASC';
// get manufacturer results
$mfg_stmt = $conn->prepare($mfg_sql);
$mfg_stmt->execute();
$mfg_results = $mfg_stmt->fetchAll();
// get vehicles
$vehicles = $em->getRepository(Vehicle::class)->findBy([], ['manufacturer' => 'ASC', 'make' => 'ASC']);
$vehicle_sql = 'SELECT v.id, v.manufacturer_id, v.make, v.model_year_from, v.model_year_to
FROM vehicle v ORDER BY v.manufacturer_id ASC, v.make ASC';
// get vehicle results
$vehicle_stmt = $conn->prepare($vehicle_sql);
$vehicle_stmt->execute();
$vehicle_results = $vehicle_stmt->fetchAll();
// process manufacturer results
$mfg_data = [];
foreach($mfgs as $mfg)
foreach($mfg_results as $mfg_row)
{
$mfg_data[] = [
'id' => $mfg->getID(),
'name' => $mfg->getName(),
'id' => $mfg_row['id'],
'name' => $mfg_row['name'],
];
}
// process vehicle results
$make_data = [];
foreach($vehicles as $vehicle)
foreach($vehicle_results as $vrow)
{
// format the model year from and model year to
$model_year = $vrow['model_year_from' ] . ' - ' . $vrow['model_year_to'];
$make_data[] = [
'id' => $vehicle->getID(),
'mfg_id' => $vehicle->getManufacturer()->getID(),
'make' => $vehicle->getMake(),
'model' => $vehicle->getModelYearFormatted(),
'id' => $vrow['id'],
'mfg_id' => $vrow['manufacturer_id'],
'make' => $vrow['make'],
'model' => $model_year,
];
}

View file

@ -7,8 +7,8 @@ use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\Warranty;
use App\Entity\BatteryModel;
@ -33,10 +33,10 @@ use App\Ramcar\WarrantySource;
use DateTime;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
// third party API
class WarrantyController extends APIController
class WarrantyController extends ApiController
{
protected $acl_gen;
@ -199,7 +199,7 @@ class WarrantyController extends APIController
$source = 'CAPI_USER_' . $username;
$msg = $this->checkRequiredParameters($req, $params);
error_log('msg - ' . $msg);
// error_log('msg - ' . $msg);
if ($msg)
{
$logger->logWarrantyInfo($log_data, $msg, $user_id, $action, $source);
@ -330,7 +330,7 @@ class WarrantyController extends APIController
// get the api_user that made the call so that it gets added to the source
// source becomes CAPI_USER_<insert name of api user here>
$username = $this->getAPIUsername($em, $user_id);
$username = $this->getUser()->getName();
$source = 'CAPI_USER_' . $username;
@ -434,7 +434,7 @@ class WarrantyController extends APIController
];
$msg = $this->checkRequiredParameters($req, $params);
error_log('msg - ' . $msg);
// error_log('msg - ' . $msg);
if ($msg)
return new APIResponse(false, $msg);
@ -567,7 +567,7 @@ class WarrantyController extends APIController
];
$msg = $this->checkRequiredParameters($req, $params);
error_log('msg - ' . $msg);
// error_log('msg - ' . $msg);
if ($msg)
return new APIResponse(false, $msg);
@ -600,14 +600,14 @@ class WarrantyController extends APIController
{
$this->denyAccessUnlessGranted('warranty.list.serial', null, 'No access.');
error_log('getWarrantiesBySerialList');
// error_log('getWarrantiesBySerialList');
// required parameters
$params = [
'serial_list',
];
$msg = $this->checkRequiredParameters($req, $params);
error_log('msg - ' . $msg);
// error_log('msg - ' . $msg);
if ($msg)
return new APIResponse(false, $msg);
@ -658,7 +658,7 @@ class WarrantyController extends APIController
{
// remove first '0'
$w_mobile_num = substr($w_mobile_num, 1);
error_log("CONVERTED TO $w_mobile_num");
// error_log("CONVERTED TO $w_mobile_num");
}
// does it fit our 9XXXXXXXXX pattern?
@ -678,7 +678,7 @@ class WarrantyController extends APIController
if (!empty($customers))
{
error_log('found customer for ' . $w_mobile_num);
// error_log('found customer for ' . $w_mobile_num);
foreach ($customers as $customer)
{
// get customer vehicles for customer
@ -707,13 +707,13 @@ class WarrantyController extends APIController
if ($cv_found)
{
// vehicle found, do nothing.
error_log('vehicle found - ' . $w_plate_number);
// error_log('vehicle found - ' . $w_plate_number);
}
else
{
// customer exists but not customer vehicle
// add customer vehicle to existing customer with unknown manufacturer and make
error_log('new vehicle - ' . $w_plate_number);
// error_log('new vehicle - ' . $w_plate_number);
$this->createCustomerVehicle($em, $customer, $this->getDefaultVehicle($em), $w_plate_number);
}
}
@ -721,7 +721,7 @@ class WarrantyController extends APIController
// customer not found
else
{
error_log('NEW customer and vehicle - ' . $w_plate_number);
// error_log('NEW customer and vehicle - ' . $w_plate_number);
// customer not found, add customer and customer vehicle
// get warranty first name, last name
$w_first_name = $warranty->getFirstName();

View file

@ -0,0 +1,182 @@
<?php
namespace App\Controller\CAPI;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\WarrantySerialQueue;
use App\Service\WarrantySerialUploadLogger;
use DateTime;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
// third party API
class WarrantySerialController extends ApiController
{
protected $acl_gen;
protected $upload_logger;
public function __construct(ACLGenerator $acl_gen, WarrantySerialUploadLogger $upload_logger)
{
$this->acl_gen = $acl_gen;
$this->upload_logger = $upload_logger;
}
public function uploadWarrantySerialFile(Request $req, EntityManagerInterface $em, KernelInterface $kernel)
{
$this->denyAccessUnlessGranted('warrantyserial.upload', null, 'No access.');
$required_params = [
'serial_file',
];
$user_id = $_SERVER['HTTP_X_CATA_API_KEY'];
$res = $this->checkRequiredParamsForFiles($req, $required_params, $user_id);
if ($res !== true)
return $res;
// get the csv file
$csv_file = $req->files->get('serial_file');
// process file upload
$upload_dir = $kernel->getProjectDir() . '/public/warranty_serial_uploads';
$serial_filename = $this->handleSerialFileUpload($csv_file, $upload_dir);
// insert to warranty serial queue
$res = $this->registerWarrantySerialFile($em, $csv_file, $serial_filename, $user_id);
// flush to db
$em->flush();
return $res;
}
protected function registerWarrantySerialFile($em, $file, $serial_filename, $user_id)
{
// parse the serial filename to get the file id
$parts = explode('/', $serial_filename);
$file_id = $parts[0];
$orig_filename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME) . '.' . $file->getClientOriginalExtension();
$ws_file = new WarrantySerialQueue();
$ws_file->setFileSerial($serial_filename)
->setStatus('pending')
->setOrigFileSerial($orig_filename)
->setFileID($file_id)
->setApiUser($user_id);
$em->persist($ws_file);
// log upload
$log_data = [
'user_id' => $user_id,
'is_uploaded' => true,
'orig_file_serial' => $orig_filename,
'uploaded_file_serial' => $serial_filename,
];
$this->upload_logger->logWarrantySerialUploadInfo($log_data);
$data = [
'id' => $file_id,
];
return new APIResponse(true, 'Warranty serial file uploaded.', $data);
}
protected function handleSerialFileUpload($file, $target_dir)
{
// create target dir if it doesn't exist
if (!file_exists($target_dir))
{
if (!mkdir($target_dir, 0744, true))
{
$log_data = [
'user_id' => $user_id,
'is_uploaded' => false,
'error' => 'Failed to create folder for warranty serial files.'
];
$this->upload_logger->logWarrantySerialUploadInfo($log_data);
return null;
}
}
// get current date
$curr_date = new DateTime();
$str_curr_date = $curr_date->format('Ymd');
$file_id = $str_curr_date . uniqid();
// move file
$filename = 'warranty_serial' . '.' . $file->getClientOriginalExtension();
$file->move($target_dir . '/' . $file_id, $filename);
return $file_id . '/' . $filename;
}
protected function checkRequiredParamsForFiles(Request $req, $params, $user_id)
{
// check required parameters
$missing = $this->checkMissingParametersForFiles($req, $params);
if (count($missing) > 0)
{
// log the error
$miss_string = implode(', ', $missing);
$log_data = [
'user_id' => $user_id,
'is_uploaded' => false,
'error' => 'Missing parameter(s): ' . $miss_string
];
$this->upload_logger->logWarrantySerialUploadInfo($log_data);
return new APIResponse(false, 'Missing parameter(s): ' . $miss_string);
}
return true;
}
protected function checkMissingParametersForFiles(Request $req, $params = [])
{
$missing = [];
// check if parameters are there
foreach ($params as $param)
{
if ($req->getMethod() == 'GET')
{
$check = $req->query->get($param);
if (empty($check))
$missing[] = $param;
}
else if ($req->getMethod() == 'POST')
{
// get files from request.
$check = $req->files->get($param);
if (empty($check))
{
$missing[] = $param;
}
}
else
return $params;
}
return $missing;
}
}

View file

@ -0,0 +1,207 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Contracts\Translation\TranslatorInterface;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Entity\CustomerDeleteRequest;
use App\Entity\Customer;
use App\Service\RisingTideGateway;
use DateTime;
class AccountController extends ApiController
{
public function deleteAccount(RisingTideGateway $rt, Request $req, TranslatorInterface $translator)
{
// validate params
$missing = $this->hasMissingParams($req, [
'phone_number',
]);
if ($missing) {
return new ApiResponse(false, $missing);
}
// user input
$phone_number = $req->request->get('phone_number');
$reason = $req->request->get('reason');
// use the test code if we're using a test number or are on test mode
$code = $this->getConfirmCode($phone_number);
$success_msg = 'We have sent a confirmation code to the submitted phone number if it is valid.';
// initialize model
$obj = new CustomerDeleteRequest();
// check if a customer record exists for this phone number
$cust_obj = $this->findCustomerByNumber($phone_number);
if (empty($cust_obj)) {
// return a random id anyway if we don't find this customer
return new ApiResponse(true, $success_msg, [
'request_id' => $obj->getID(),
]);
}
// phone number is valid, we continue building the model
$obj->setPhoneNumber($phone_number);
$obj->setReason($reason);
$obj->setConfirmCode($code);
// send sms to number if not in test mode
if ($this->getOtpMode() != 'test') {
$this->sendConfirmationCode($rt, $phone_number, $code, $translator);
}
// save the model
$obj->setDateCodeSent(new DateTime());
$this->em->persist($obj);
$this->em->flush();
// response
return new ApiResponse(true, $success_msg, [
'request_id' => $obj->getID(),
]);
}
public function validateDeleteCode(Request $req)
{
// validate params
$missing = $this->hasMissingParams($req, [
'request_id',
'code',
]);
if ($missing) {
return new ApiResponse(false, $missing);
}
// user input
$code = $req->request->get('code');
$request_id = $req->request->get('request_id');
// get the request
$obj = $this->em->getRepository(CustomerDeleteRequest::class)->findOneBy([
'id' => $request_id,
'confirm_code' => $code,
'flag_confirmed' => false,
'flag_completed' => false,
]);
if (empty($obj)) {
return new ApiResponse(false, 'Your confirmation code is invalid.');
}
// check if a customer record exists for this phone number
$cust_obj = $this->findCustomerByNumber($obj->getPhoneNumber());
if (empty($cust_obj)) {
return new ApiResponse(false, 'No account exists for this phone number.');
}
// confirm the request
$obj->setConfirmed(true);
$obj->setDateConfirmed(new DateTime());
$obj->setCustomer($cust_obj);
$this->em->flush();
// response
return new ApiResponse(true, 'Your request has been submitted for processing.');
}
public function resendCode(Request $req, RisingTideGateway $rt, TranslatorInterface $translator)
{
// validate params
$missing = $this->hasMissingParams($req, [
'request_id',
]);
if ($missing) {
return new ApiResponse(false, $missing);
}
// user input
$request_id = $req->request->get('request_id');
$now = time();
// get the request
$obj = $this->em->getRepository(CustomerDeleteRequest::class)->findOneBy([
'id' => $request_id,
'flag_confirmed' => false,
'flag_completed' => false,
]);
if (empty($obj)) {
return new ApiResponse(false, 'Invalid request details provided.');
}
// prevent resend spamming
if ($now - $obj->getDateCodeSent()->getTimestamp() < 300) {
return new ApiResponse(false, 'You can only request a confirm code every 5 mins.');
}
$success_msg = 'We have re-sent a confirmation code to the submitted phone number if it is valid.';
// check if a customer record exists for this phone number
$cust_obj = $this->findCustomerByNumber($obj->getPhoneNumber());
if (empty($cust_obj)) {
// return successful without resending code if we don't find this customer
return new ApiResponse(true, $success_msg);
}
// use the test code if we're using a test number or are on test mode
$phone_number = $obj->getPhoneNumber();
$code = $this->getConfirmCode($phone_number);
// send sms to number if not in test mode
if ($this->getOtpMode()!= 'test') {
$this->sendConfirmationCode($rt, $phone_number, $code, $translator);
}
// update last sent timestamp
$obj->setDateCodeSent(new DateTime());
$this->em->flush();
// response
return new ApiResponse(true, $success_msg);
}
protected function getConfirmCode($phone_number)
{
// check for hardcoded phone number for app store testing
$test_numbers = explode(",", $_ENV['TEST_PHONE_NUMBERS']);
if (in_array($phone_number, $test_numbers) || $this->getOtpMode() == 'test') {
$code = "123456";
} else {
// generate code
$code = $this->generateConfirmCode();
}
return $code;
}
protected function generateConfirmCode()
{
return sprintf("%06d", mt_rand(100000, 999999));
}
protected function sendConfirmationCode(RisingTideGateway $rt, $phone_number, $code, TranslatorInterface $translator)
{
// send sms to number
$message = $translator->trans('message.confirmation_code') . ' ' . $code;
$rt->sendSMS($phone_number, $translator->trans('message.battery_brand_allcaps'), $message);
}
protected function findCustomerByNumber($number)
{
$cust_obj = $this->em->getRepository(Customer::class)->findOneBy([
'phone_mobile' => $number,
]);
return $cust_obj;
}
protected function getOtpMode()
{
return $_ENV['OTP_MODE'];
}
}

View file

@ -0,0 +1,167 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpKernel\KernelInterface;
use Catalyst\ApiBundle\Controller\ApiController as BaseApiController;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Ramcar\JOStatus;
use App\Entity\Warranty;
use App\Entity\JobOrder;
use App\Entity\CustomerSession;
class ApiController extends BaseApiController
{
protected $em;
protected $session;
public function __construct(EntityManagerInterface $em, KernelInterface $kernel)
{
$this->session = new CustomerSession; // NOTE: original was null
$this->em = $em;
// load env file
$dotenv = new Dotenv();
$dotenv->loadEnv($kernel->getProjectDir() . '/.env');
}
protected function debugRequest(Request $req)
{
$all = $req->request->all();
error_log(print_r($all, true));
}
protected function hasMissingParams(Request $req, $params = [])
{
return $this->checkRequiredParameters($req, $params);
}
protected function validateSession($session_key)
{
// check if the session exists
$session = $this->em->getRepository(CustomerSession::class)->find($session_key);
if ($session === null) {
return false;
}
$this->session = $session;
return true;
}
protected function validateRequest(Request $req, $params = [])
{
$error = $this->hasMissingParams($req, $params);
$session_key = $req->query->get('session_key');
if (!$error) {
if (empty($session_key) || !$this->validateSession($session_key)) {
$error = 'Invalid session key.';
}
}
return [
'is_valid' => !$error,
'error' => $error,
];
}
protected function findWarranty($plate_number)
{
// NOTE: Modify the search for the latest warranty. This seems hacky.
// get latest warranty using plate number
$warranty_results = $this->em->getRepository(Warranty::class)->findBy(
['plate_number' => $plate_number],
['date_create' => 'desc']
);
$warr = [];
// check if warranty_results is empty
if (empty($warranty_results)) {
/*
$res->setError(true)
->setErrorMessage('No warranty found for plate number');
return $res->getReturnResponse();
*/
return $warr;
}
// get first entry
$warranty = current($warranty_results);
// check for null values for battery and date claim and date expire
$batt_model = '';
$batt_size = '';
$sap_batt = '';
$claim_date = '';
$expiry_date = '';
if (!(is_null($warranty->getBatteryModel()))) {
$batt_model = $warranty->getBatteryModel()->getName();
}
if (!(is_null($warranty->getBatterySize()))) {
$batt_size = $warranty->getBatterySize()->getName();
}
if (!(is_null($warranty->getSAPBattery()))) {
$sap_batt = $warranty->getSAPBattery()->getID();
}
if (!(is_null($warranty->getDateClaim()))) {
$claim_date = $warranty->getDateClaim()->format("d M Y");
}
if (!(is_null($warranty->getDateExpire()))) {
$expiry_date = $warranty->getDateExpire()->format("d M Y");
}
$warr[] = [
'id' => $warranty->getID(),
'serial' => $warranty->getSerial(),
'warranty_class' => $warranty->getWarrantyClass(),
'plate_number' => $warranty->getPlateNumber(),
'first_name' => $warranty->getFirstName(),
'last_name' => $warranty->getLastName(),
'mobile_number' => $warranty->getMobileNumber(),
'battery_model' => $batt_model,
'battery_size' => $batt_size,
'sap_battery' => $sap_batt,
'status' => $warranty->getStatus(),
'date_create' => $warranty->getDateCreate()->format("d M Y g:i A"),
'date_purchase' => $warranty->getDatePurchase()->format("d M Y"),
'date_expire' => $expiry_date,
'date_claim' => $claim_date,
'claim_from' => $warranty->getClaimedFrom(),
'is_activated' => $warranty->isActivated() ? 1 : 0,
];
return $warr;
}
protected function getBatteryImageURL($req, $batt)
{
// TODO: workaround for now, we get static image of battery based on model name
$filename = trim(strtolower($batt->getModel()->getName())) . '_mobile.jpg';
$filename = str_replace(" ", "_", $filename);
$file_path = $req->getSchemeAndHttpHost() . $this->generateUrl('static_battery_image') . '/' . $filename;
return $file_path;
}
protected function getOngoingJobOrders($cust)
{
$ongoing_jos = $this->em->getRepository(JobOrder::class)->findBy([
'customer' => $cust,
'status' => [JOStatus::PENDING, JOStatus::RIDER_ASSIGN, JOStatus::IN_TRANSIT, JOStatus::ASSIGNED, JOStatus::IN_PROGRESS],
], ['date_schedule' => 'desc']);
return $ongoing_jos;
}
protected function getGeoErrorMessage()
{
return 'Our services are currently limited to some areas in Metro Manila, Baguio, Batangas, Laguna, Cavite, Pampanga, and Palawan. We will update you as soon as we are available in your area. Thank you for understanding. Keep safe!';
}
}

View file

@ -0,0 +1,53 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
class AppController extends ApiController
{
public function versionCheck(Request $req)
{
// validate params
$missing = $this->hasMissingParams($req, [
'version',
'os',
]);
if ($missing) {
return new ApiResponse(false, $missing);
}
$need_update = false;
$msg = 'Version is up to date.';
$os = $req->query->get('os');
// putting this in for the future, in case we have diverging versions
//$platform = $req->query->get('platform');
// get only the major version numbers
$app_version = $req->query->get('version');
$app_major = substr($app_version, 0, strripos($app_version, "."));
$latest_version = $this->getParameter($os . '_app_version');
$latest_major = substr($latest_version, 0, strripos($latest_version, "."));
if ($latest_major < $app_major) {
return new ApiResponse(false, 'Invalid application version: ' . $app_version);
}
if ($latest_major > $app_major) {
$need_update = true;
$msg = 'Your version is outdated and needs an update to use the latest features RES-Q has to offer.';
}
// response
return new ApiResponse(true, '', [
'need_update' => $need_update,
'latest_version' => $latest_version,
'message' => $msg,
]);
}
}

View file

@ -0,0 +1,292 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Doctrine\DBAL\DBALException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Contracts\Translation\TranslatorInterface;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Entity\Customer;
use App\Entity\CustomerUser;
use App\Entity\CustomerSession;
use App\Service\RisingTideGateway;
use DateTime;
class AuthController extends ApiController
{
public function register(Request $req)
{
// validate params
$missing = $this->hasMissingParams($req, [
'phone_model',
'os_type',
'os_version',
'phone_id',
]);
if ($missing) {
return new ApiResponse(false, $missing);
}
// retry until we get a unique id
while (true) {
try {
// instantiate session
$sess = new CustomerSession();
$sess->setPhoneModel($req->request->get('phone_model'))
->setOSType($req->request->get('os_type'))
->setOSVersion($req->request->get('os_version'))
->setPhoneID($req->request->get('phone_id'));
// reopen in case we get an exception
if (!$this->em->isOpen()) {
$this->em = $this->em->create(
$this->em->getConnection(),
$this->em->getConfiguration()
);
}
// save
$this->em->persist($sess);
$this->em->flush();
} catch (DBALException $e) {
error_log($e->getMessage());
// delay one second and try again
sleep(1);
continue;
}
break;
}
// return data
return new ApiResponse(true, '', [
'session_key' => $sess->getID(),
]);
}
public function confirmNumber(RisingTideGateway $rt, Request $req, TranslatorInterface $translator)
{
// validate request
$validity = $this->validateRequest($req, [
'phone_number'
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// phone number
$phone_number = $req->request->get('phone_number');
// get otp_mode from .env
$otp_mode = $_ENV['OTP_MODE'];
// check for hardcoded phone number for app store testing
$test_numbers = explode(",", $_ENV['TEST_PHONE_NUMBERS']);
if (in_array($phone_number, $test_numbers)) {
$code = '123456';
$this->session->setConfirmCode($code)
->setPhoneNumber($phone_number);
$this->em->flush();
return new ApiResponse();
}
// check if otp_mode is test
if ($otp_mode == 'test') {
$code = '123456';
$this->session->setConfirmCode($code)
->setPhoneNumber($phone_number);
$this->em->flush();
return new ApiResponse();
}
// TODO: spam protection
// TODO: validate phone number
// generate code and save
$code = $this->generateConfirmCode();
$this->session->setConfirmCode($code)
->setPhoneNumber($phone_number);
$this->em->flush();
if ($otp_mode != 'test') {
// send sms to number
$this->sendConfirmationCode($rt, $phone_number, $code, $translator);
}
// response
return new ApiResponse();
}
public function validateCode(Request $req)
{
// validate request
$validity = $this->validateRequest($req, [
'code',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// already confirmed
if ($this->session->isConfirmed()) {
return new ApiResponse(false, 'User is already confirmed.');
}
// code is wrong
$code = $req->request->get('code');
if ($this->session->getConfirmCode() != $code) {
return new ApiResponse(false, 'Wrong confirm code.');
}
// set confirm date
$date = new DateTime();
$this->session->setDateConfirmed($date)
->setConfirmed();
// figure out if we have customer and customer user already
$customer_user = false;
// TODO: check if we have the number registered before and merge
$dupe_sess = $this->findNumberSession($this->session->getPhoneNumber());
if ($dupe_sess != null) {
error_log("Found existing customer session for " . $this->session->getPhoneNumber());
$dupe_cust = $dupe_sess->getCustomer();
$this->session->setCustomer($dupe_cust);
// set customer user if it exists
$customer_user = $dupe_sess->getCustomerUser() ?? $dupe_cust->getCustomerUser();
}
// TODO: check if mobile matches mobile of customer
$customer = $this->findCustomerByNumber($this->session->getPhoneNumber());
if ($customer != null) {
// TODO: if there is a dupe_sess, do we need to check if
// dupe_cust is the same as the customer we found?
$this->session->setCustomer($customer);
}
if (!$customer_user) {
error_log("We don't have a customer user for session " . $this->session->getID());
$customer_user = $this->findCustomerUserByNumber($this->session->getPhoneNumber());
if ($customer_user === null) {
error_log("Creating a new customer user for " . $this->session->getPhoneNumber());
$customer_user = new CustomerUser();
$customer_user->setCustomer($this->session->getCustomer())
->setPhoneNumber($this->session->getPhoneNumber());
// save
$this->em->persist($customer_user);
$this->em->flush();
} else {
error_log("Found existing customer user for " . $this->session->getPhoneNumber());
}
}
error_log("Customer user ID is " . $customer_user->getID());
// set session customer user
$this->session->setCustomerUser($customer_user);
$this->em->flush();
// response
return new ApiResponse(true, '', [
'api_key' => $customer_user->getApiKey(),
'secret_key'=> $customer_user->getSecretKey(),
]);
}
public function resendCode(Request $req, RisingTideGateway $rt, TranslatorInterface $translator)
{
// validate request
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// already confirmed
if ($this->session->isConfirmed()) {
return new ApiResponse(false, 'User is already confirmed.');
}
// have sent code before
if ($this->session->getDateCodeSent() != null) {
return new ApiResponse(false, 'Can only send confirm code every 5 mins.');
}
// TODO: send via sms
$phone_number = $this->session->getPhoneNumber();
$code = $this->session->getConfirmCode();
$this->sendConfirmationCode($rt, $phone_number, $code, $translator);
// response
return new ApiResponse();
}
protected function generateConfirmCode()
{
return sprintf("%06d", mt_rand(100000, 999999));
}
protected function sendConfirmationCode(RisingTideGateway $rt, $phone_number, $code, TranslatorInterface $translator)
{
// send sms to number
$message = $translator->trans('message.confirmation_code') . ' ' . $code;
$rt->sendSMS($phone_number, $translator->trans('message.battery_brand_allcaps'), $message);
}
// TODO: find session customer by phone number
protected function findNumberSession($number)
{
$query = $this->em->getRepository(CustomerSession::class)->createQueryBuilder('s')
->where('s.phone_number = :number')
->andWhere('s.customer is not null')
->andWhere('s.customer_user is not null')
->andWhere('s.confirm_flag = 1')
->setParameter('number', $number)
->setMaxResults(1)
->getQuery();
// we just need one
$res = $query->getOneOrNullResult();
return $res;
}
protected function findCustomerByNumber($number)
{
$customers = $this->em->getRepository(Customer::class)->findBy(['phone_mobile' => $number]);
// find the customer with the most number of cars
$car_count = 0;
$cust = null;
foreach ($customers as $customer) {
$vehicles = $customer->getVehicles();
if (count($vehicles) > $car_count) {
$car_count = count($vehicles);
// "save" customer object
$cust = $customer;
}
}
return $cust;
}
protected function findCustomerUserByNumber($number)
{
return $this->em->getRepository(CustomerUser::class)->findOneBy(['phone_number' => $number]);
}
}

View file

@ -0,0 +1,145 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Ramcar\CustomerSource;
use App\Entity\Customer;
use App\Entity\PrivacyPolicy;
use App\Service\HashGenerator;
class CustomerController extends ApiController
{
public function getInfo(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// if no customer found
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(true, '', [
'first_name' => '',
'last_name' => '',
'priv_third_party' => (bool) false,
'priv_promo' => (bool) false,
]);
}
// send back customer details
return new ApiResponse(true, '', [
'first_name' => $cust->getFirstName(),
'last_name' => $cust->getLastName(),
'priv_third_party' => (bool) $cust->getPrivacyThirdParty(),
'priv_promo' => (bool) $cust->getPrivacyPromo(),
]);
}
public function updateInfo(Request $req)
{
// validate params
$validity = $this->validateRequest($req, [
'first_name',
'last_name',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
$cust = $this->updateCustomerInfo($req);
$policy_mobile_id = $_ENV['POLICY_MOBILE'];
$mobile_policy = $this->em->getRepository(PrivacyPolicy::class)->find($policy_mobile_id);
// set policy id
if ($mobile_policy != null) {
$cust->setPrivacyPolicyMobile($mobile_policy);
}
$this->em->flush();
// response
return new ApiResponse();
}
public function getStatus(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// set data
$data = [];
if ($this->session->isConfirmed()) {
$data['status'] = 'confirmed';
} else {
$data['status'] = 'unconfirmed';
}
return new ApiResponse(true, '', $data);
}
public function getCustomerHash(Request $req, HashGenerator $hash)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// hash customer id
$hashed_id = $hash->getHash($cust->getID());
// response
return new ApiResponse(true, '', [
'cust_hash' => $hashed_id,
]);
}
protected function updateCustomerInfo(Request $req)
{
// create new customer if it's not there
$cust = $this->session->getCustomer();
if ($cust == null) {
$cust = new Customer();
// set customer source
$cust->setCreateSource(CustomerSource::MOBILE);
$this->em->persist($cust);
$this->session->setCustomer($cust);
}
$cust->setFirstName($req->request->get('first_name'))
->setLastName($req->request->get('last_name'))
->setEmail($req->request->get('email', ''))
->setConfirmed($this->session->isConfirmed());
// if customer user isn't set, set it now
if ($cust->getCustomerUser() == null) {
$cust->setCustomerUser($this->session->getCustomerUser());
}
// update mobile phone of customer
$cust->setPhoneMobile($this->session->getPhoneNumber());
return $cust;
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
class DeviceController extends ApiController
{
public function updateDeviceID(Request $req)
{
// validate params
$validity = $this->validateRequest($req, [
'device_id',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
$device_id = $req->request->get('device_id');
$this->session->setDevicePushID($device_id);
$this->em->flush();
// response
return new ApiResponse();
}
}

View file

@ -0,0 +1,364 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Service\InsuranceConnector;
use App\Service\PayMongoConnector;
use App\Entity\InsuranceApplication;
use App\Entity\GatewayTransaction;
use App\Entity\CustomerVehicle;
use App\Ramcar\InsuranceApplicationStatus;
use App\Ramcar\InsuranceMVType;
use App\Ramcar\InsuranceClientType;
use App\Ramcar\TransactionStatus;
use App\Ramcar\InsuranceBodyType;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use DateTime;
class InsuranceController extends ApiController
{
protected $client;
public function __construct(EntityManagerInterface $em, KernelInterface $kernel, InsuranceConnector $client)
{
parent::__construct($em, $kernel);
$this->client = $client;
}
public function createApplication(Request $req, PayMongoConnector $paymongo, UrlGeneratorInterface $router)
{
// validate params
$validity = $this->validateRequest($req, [
// internal
'customer_vehicle_id',
// client info
'client_type',
'first_name',
//'middle_name', // not required
'surname',
'corporate_name',
// client contact info
'address_number',
//'address_street', // not required
//'address_building', // not required
'address_barangay',
'address_city',
'address_province',
'zipcode',
'mobile_number',
'email_address',
// car info
'make',
'model',
'series',
'color',
//'plate_number', // NOTE: we get this from the internal cv record instead
'mv_file_number',
'motor_number',
'serial_chasis', // NOTE: this is how it's spelled on their API
'year_model',
'mv_type_id',
'body_type',
//'is_public', // not required, boolean, only show field if mv_type_id in [4, 13]
//'orcr_file', // this is a file
// mv_type_id specific fields
//'vehicle_use_type', // not required, only show field if mv_type_id is not in [4, 13]. accepted values are: 'commercial', 'private'
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// conditionally require is_public or vehicle_use_type
switch ($req->request->get('mv_type_id')) {
case 4:
case 13:
if (empty($req->request->get('is_public'))) {
return new ApiResponse(false, 'Missing required parameter(s): is_public is required when mv_type_id is in [4, 13]');
}
break;
default:
if (empty($req->request->get('vehicle_use_type'))) {
return new ApiResponse(false, 'Missing required parameter(s): vehicle_use_type is required when mv_type_id is not in [4, 13]');
}
break;
}
// require the orcr file
if ($req->files->get('orcr_file') === null) {
return new ApiResponse(false, 'Missing required file: orcr_file');
}
// get our listener url
$notif_url = $router->generate('insurance_listener', [], UrlGeneratorInterface::ABSOLUTE_URL);
// get customer and cv info
$cust = $this->session->getCustomer();
$cv = $this->em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle_id'));
if ($cv == null) {
return new ApiResponse(false, 'Invalid customer vehicle id.');
}
// confirm that customer vehicle belongs to customer
if ($cv->getCustomer()->getID() != $cust->getID()) {
return new ApiResponse(false, 'Vehicle does not belong to customer.');
}
// process all our inputs first
$input = $req->request->all();
if (!isset($input['is_public'])) {
$input['is_public'] = false;
}
$input['line'] = $this->getLineType($input['mv_type_id'], $input['vehicle_use_type'], $input['is_public']);
// submit insurance application
$result = $this->client->createApplication(
$cv,
$notif_url,
$input,
$req->files->get('orcr_file')
);
if (!$result['success']) {
return new ApiResponse(false, $result['error']['message']);
}
$premium_amount_int = (int)bcmul($result['response']['premium'], 100);
// build checkout item and metadata
$items = [
[
'name' => "Insurance Premium",
'description' => "Premium fee for vehicle insurance",
'quantity' => 1,
'amount' => $premium_amount_int,
'currency' => 'PHP',
],
];
$now = new DateTime();
// create gateway transaction
$gt = new GatewayTransaction();
$gt->setCustomer($cust);
$gt->setDateCreate($now);
$gt->setAmount($premium_amount_int);
$gt->setStatus(TransactionStatus::PENDING);
$gt->setGateway('paymongo'); // TODO: define values elsewhere
$gt->setType('insurance_premium'); // TODO: define values elsewhere
$this->em->persist($gt);
$this->em->flush();
// create paymongo checkout resource
$checkout = $paymongo->createCheckout(
$cust,
$items,
$gt->getID(),
"Motolite RES-Q Vehicle Insurance",
$router->generate('paymongo_payment_success', [], UrlGeneratorInterface::ABSOLUTE_URL),
$router->generate('paymongo_payment_cancelled', [], UrlGeneratorInterface::ABSOLUTE_URL),
['transaction_id' => $gt->getID()], // NOTE: passing this here too for payment resource metadata
);
if (!$checkout['success']) {
return new ApiResponse(false, $checkout['error']['message']);
}
$checkout_url = $checkout['response']['data']['attributes']['checkout_url'];
// add checkout url and id to transaction metadata
$gt->setExtTransactionId($checkout['response']['data']['id']);
$gt->setMetadata([
'checkout_url' => $checkout_url,
]);
// store application in db
$app = new InsuranceApplication();
$app->setDateSubmit($now);
$app->setCustomer($cust);
$app->setCustomerVehicle($cv);
$app->setGatewayTransaction($gt);
$app->setStatus(InsuranceApplicationStatus::CREATED);
$app->setExtTransactionId($result['response']['id']);
$app->setMetadata($input);
$this->em->persist($app);
// save everything
$this->em->flush();
// return
return new ApiResponse(true, '', [
'app_id' => $app->getID(),
'checkout_url' => $checkout_url,
'premium_amount' => (string)$result['response']['premium'],
]);
}
public function getVehicleMakers(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get maker list
$result = $this->client->getVehicleMakers();
if (!$result['success']) {
return new ApiResponse(false, $result['error']['message']);
}
return new ApiResponse(true, '', [
'makers' => $result['response']['data']['vehicleMakers'],
]);
}
public function getVehicleModels($maker_id, Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get maker list
$result = $this->client->getVehicleModels($maker_id);
if (!$result['success']) {
return new ApiResponse(false, $result['error']['message']);
}
return new ApiResponse(true, '', [
'models' => $result['response']['data']['vehicleModels'],
]);
}
public function getVehicleTrims($model_id, Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get maker list
$result = $this->client->getVehicleTrims($model_id);
if (!$result['success']) {
return new ApiResponse(false, $result['error']['message']);
}
return new ApiResponse(true, '', [
'trims' => $result['response']['data']['vehicleTrims'],
]);
}
public function getMVTypes(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
return new ApiResponse(true, '', [
'mv_types' => InsuranceMVType::getCollection(),
]);
}
public function getClientTypes(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
return new ApiResponse(true, '', [
'mv_types' => InsuranceClientType::getCollection(),
]);
}
public function getPremiumsBanner(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
return new ApiResponse(true, '', [
'url' => $this->getParameter('insurance_premiums_banner_url'),
]);
}
public function getBodyTypes(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
$bt_collection = InsuranceBodyType::getCollection();
$body_types = [];
// NOTE: formatting it this way to match how insurance third party API returns their own stuff, so it's all handled one way on the app
foreach ($bt_collection as $bt_key => $bt_name) {
$body_types[] = [
'id' => $bt_key,
'name' => $bt_name,
];
}
return new ApiResponse(true, '', [
'body_types' => $body_types,
]);
}
protected function getLineType($mv_type_id, $vehicle_use_type, $is_public = false)
{
$line = '';
// NOTE: this is a bit of a hack since we're hardcoding values, but this is fine for now
switch ($mv_type_id) {
case '3':
$line = 'mcoc';
break;
case '4':
case '13':
if ($is_public) {
$line = 'lcoc';
} else {
$line = 'mcoc';
}
break;
default:
if ($vehicle_use_type === 'commercial') {
$line = 'ccoc';
} else {
$line = 'pcoc';
}
break;
}
return $line;
}
}

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