From df950006c13ed259945e162b4281b65c4db2e146 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 5 Aug 2020 10:17:40 +0000 Subject: [PATCH 1/2] Revert "Merge branch '457-cmb-add-telephone-number-to-search' into 'master'" This reverts merge request !536 --- .env.dist | 3 - composer.lock | 14 +- config/acl.yaml | 2 - config/cmb.menu.yaml | 4 - config/cmb.services.yaml | 19 +- config/menu.yaml | 39 +- config/packages/security.yaml | 4 - config/packages/twig.yaml | 1 - config/resq.services.yaml | 1 - config/routes/cmb_rider_api.yaml | 156 -- config/routes/job_order.yaml | 11 - config/routes/rider.yaml | 10 - config/services.yaml | 24 +- public/assets/css/style.css | 25 +- public/assets/js/dashboard_map.js | 67 +- public/assets/js/map_mqtt.js | 129 +- resq_settings/cmb/menu.yaml | 179 -- resq_settings/cmb/messages.en.yaml | 27 - resq_settings/cmb/services.yaml | 246 --- resq_settings/resq/menu.yaml | 186 -- resq_settings/resq/messages.en.yaml | 27 - resq_settings/resq/services.yaml | 244 --- src/Command/ConfigureResqCommand.php | 55 - src/Command/CreateJOTestDataCommand.php | 173 -- src/Controller/CMBRAPIController.php | 317 --- src/Controller/HomeController.php | 4 - src/Controller/JobOrderController.php | 33 +- src/Controller/RiderController.php | 33 - src/Entity/JOExtra.php | 140 -- src/Entity/JobOrder.php | 50 - src/Entity/Rider.php | 5 - src/Ramcar/CMBCancelReason.php | 22 - src/Ramcar/CMBJOEventType.php | 42 - src/Ramcar/CMBModeOfPayment.php | 10 +- src/Ramcar/CMBTransactionOrigin.php | 25 - src/Ramcar/JOStatus.php | 18 +- src/Ramcar/NewAPIResult.php | 92 - .../CustomerHandler/CMBCustomerHandler.php | 24 +- .../InvoiceGenerator/CMBInvoiceGenerator.php | 7 +- .../JobOrderHandler/CMBJobOrderHandler.php | 343 +-- src/Service/JobOrderHandlerInterface.php | 2 +- .../RiderAPIHandler/CMBRiderAPIHandler.php | 1879 ++--------------- templates/customer/cmb.form.html.twig | 15 +- templates/home.html.twig | 14 +- .../job-order/cmb.form.onestep.html.twig | 253 +-- templates/job-order/cmb.form.walkin.html.twig | 153 +- templates/job-order/cmb.list.all.html.twig | 16 +- .../cmb.list.behindschedule.html.twig | 199 -- templates/job-order/cmb.list.open.html.twig | 12 +- translations/messages.en.yaml | 34 +- 50 files changed, 477 insertions(+), 4911 deletions(-) delete mode 100644 config/routes/cmb_rider_api.yaml delete mode 100644 resq_settings/cmb/menu.yaml delete mode 100644 resq_settings/cmb/messages.en.yaml delete mode 100644 resq_settings/cmb/services.yaml delete mode 100644 resq_settings/resq/menu.yaml delete mode 100644 resq_settings/resq/messages.en.yaml delete mode 100644 resq_settings/resq/services.yaml delete mode 100644 src/Command/ConfigureResqCommand.php delete mode 100644 src/Command/CreateJOTestDataCommand.php delete mode 100644 src/Controller/CMBRAPIController.php delete mode 100644 src/Entity/JOExtra.php delete mode 100644 src/Ramcar/CMBCancelReason.php delete mode 100644 src/Ramcar/CMBJOEventType.php delete mode 100644 src/Ramcar/CMBTransactionOrigin.php delete mode 100644 src/Ramcar/NewAPIResult.php delete mode 100644 templates/job-order/cmb.list.behindschedule.html.twig diff --git a/.env.dist b/.env.dist index 11794311..bd82f980 100644 --- a/.env.dist +++ b/.env.dist @@ -74,6 +74,3 @@ MAPTILER_API_KEY=map_tiler_api_key # API version API_VERSION=insert_api_version_here - -# SSL -SSL_ENABLE=true_or_false diff --git a/composer.lock b/composer.lock index 3d02c0bb..1e76e914 100644 --- a/composer.lock +++ b/composer.lock @@ -1,7 +1,7 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], "content-hash": "f03b92d48946e8b2ee19466f931c826f", @@ -3214,20 +3214,20 @@ }, { "name": "symfony/filesystem", - "version": "v4.4.10", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "b27f491309db5757816db672b256ea2e03677d30" + "reference": "266c9540b475f26122b61ef8b23dd9198f5d1cfd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/b27f491309db5757816db672b256ea2e03677d30", - "reference": "b27f491309db5757816db672b256ea2e03677d30", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/266c9540b475f26122b61ef8b23dd9198f5d1cfd", + "reference": "266c9540b475f26122b61ef8b23dd9198f5d1cfd", "shasum": "" }, "require": { - "php": ">=7.1.3", + "php": "^7.1.3", "symfony/polyfill-ctype": "~1.8" }, "type": "library", @@ -3260,7 +3260,7 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2020-05-30T18:50:54+00:00" + "time": "2020-01-21T08:20:44+00:00" }, { "name": "symfony/finder", diff --git a/config/acl.yaml b/config/acl.yaml index 1d1a0c74..abd73118 100644 --- a/config/acl.yaml +++ b/config/acl.yaml @@ -270,8 +270,6 @@ access_keys: label: Autoassign Test - id: jo_hub.list label: Hub View - - id: jo_behind_schedule.list - label: View Behind Schedule - id: support label: Customer Support Access diff --git a/config/cmb.menu.yaml b/config/cmb.menu.yaml index ca756046..9f28b315 100644 --- a/config/cmb.menu.yaml +++ b/config/cmb.menu.yaml @@ -118,10 +118,6 @@ main_menu: acl: jo_all.list label: View All parent: joborder - - id: jo_behind_schedule - acl: jo_behind_schedule.list - label: View Behind Schedule - parent: joborder - id: support acl: support.menu diff --git a/config/cmb.services.yaml b/config/cmb.services.yaml index 3d9fd7a3..5f24e525 100644 --- a/config/cmb.services.yaml +++ b/config/cmb.services.yaml @@ -5,7 +5,6 @@ parameters: latitude: 14.6091 longitude: 121.0223 image_upload_directory: '%kernel.project_dir%/public/uploads' - jo_extra_upload_directory: '%kernel.project_dir%/public/uploads/jo_extra' job_order_refresh_interval: 300000 api_acl_file: 'api_acl.yaml' api_access_key: 'api_access_keys' @@ -13,7 +12,6 @@ parameters: app_access_key: 'access_keys' cvu_brand_id: "%env(CVU_BRAND_ID)%" country_code: "%env(COUNTRY_CODE)%" - api_version: "%env(API_VERSION)%" services: # default configuration for services in *this* file @@ -75,7 +73,6 @@ services: $pass: "%env(RT_PASS)%" $usage_type: "%env(RT_USAGE_TYPE)%" $shortcode: "%env(RT_SHORTCODE)%" - $dr_url: "https://resqaws.jankstudio.com/sms/delivery_receipt" App\Service\MQTTClient: arguments: @@ -170,7 +167,7 @@ services: # job order generator App\Service\JobOrderHandler\CMBJobOrderHandler: arguments: - $country_code: "%env(COUNTRY_CODE)%" + $country_code: "%env(COUNTRY_CODE)%" #job order generator interface App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\CMBJobOrderHandler" @@ -190,13 +187,13 @@ services: App\Service\RiderAssignmentHandlerInterface: "@App\\Service\\RiderAssignmentHandler\\CMBRiderAssignmentHandler" # rider API service - App\Service\RiderAPIHandler\CMBRiderAPIHandler: + App\Service\RiderAPIHandler\CMBRiderAPIHandler: arguments: $country_code: "%env(COUNTRY_CODE)%" - $upload_dir: "%jo_extra_upload_directory%" + # rider API interface App\Service\RiderAPIHandlerInterface: "@App\\Service\\RiderAPIHandler\\CMBRiderAPIHandler" - + # map manager #App\Service\GISManager\Bing: ~ App\Service\GISManager\OpenStreet: ~ @@ -232,14 +229,6 @@ services: $loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%" $status_key: "%env(STATUS_RIDER_KEY)%" - # inventory manager - App\Service\InventoryManager: - arguments: - $api_url: "%env(INVENTORY_API_URL)%" - $api_ocp_key: "%env(INVENTORY_API_OCP)%" - $api_auth_prefix: "%env(INVENTORY_API_AUTH_TOKEN_PREFIX)%" - $api_auth_token: "%env(INVENTORY_API_AUTH_TOKEN)%" - # API logging App\EventSubscriber\LogSubscriber: arguments: diff --git a/config/menu.yaml b/config/menu.yaml index ca756046..246eda01 100644 --- a/config/menu.yaml +++ b/config/menu.yaml @@ -37,10 +37,6 @@ main_menu: acl: rider.list label: Riders parent: logistics - - id: service_charge_list - acl: service_charge.list - label: Service Charges - parent: logistics - id: battery acl: battery.menu @@ -102,13 +98,21 @@ main_menu: acl: joborder.menu label: Job Order icon: flaticon-calendar-3 - - id: jo_onestep_form - acl: jo_onestep.form - label: One-step Process + - id: jo_in + acl: jo_in.list + label: Incoming parent: joborder - - id: jo_walkin_form - acl: jo_walkin.form - label: Walk-in + - id: jo_proc + acl: jo_proc.list + label: Dispatch + parent: joborder + - id: jo_assign + acl: jo_assign.list + label: Rider Assignment + parent: joborder + - id: jo_fulfill + acl: jo_fulfill.list + label: Fulfillment parent: joborder - id: jo_open acl: jo_open.list @@ -118,9 +122,9 @@ main_menu: acl: jo_all.list label: View All parent: joborder - - id: jo_behind_schedule - acl: jo_behind_schedule.list - label: View Behind Schedule + - id: jo_hub_view + acl: jo_hub.list + label: Hub View parent: joborder - id: support @@ -181,3 +185,12 @@ main_menu: acl: review.list label: Reviews parent: partner + + - id: analytics + acl: analytics.menu + label: Analytics + icon: flaticon-graphic + - id: analytics_forecast_form + acl: analytics.forecast + label: Forecasting + parent: analytics diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 86a9b1d7..4339eba4 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -46,10 +46,6 @@ security: provider: api_key_user_provider user_checker: Catalyst\AuthBundle\Service\UserChecker - cmb_rider_api: - pattern: ^\/cmbrapi\/ - security: false - main: provider: user_provider form_login: diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index ade96bcc..1c848030 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -8,4 +8,3 @@ twig: mqtt_host: "%env(MQTT_WS_HOST)%" mqtt_port: "%env(MQTT_WS_PORT)%" dashboard_enable: "%env(DASHBOARD_ENABLE)%" - ssl_enable: "%env(SSL_ENABLE)%" diff --git a/config/resq.services.yaml b/config/resq.services.yaml index 05fd3b1a..82eb4cc5 100644 --- a/config/resq.services.yaml +++ b/config/resq.services.yaml @@ -74,7 +74,6 @@ services: $pass: "%env(RT_PASS)%" $usage_type: "%env(RT_USAGE_TYPE)%" $shortcode: "%env(RT_SHORTCODE)%" - $dr_url: "https://resqaws.jankstudio.com/sms/delivery_receipt" App\Service\MQTTClient: arguments: diff --git a/config/routes/cmb_rider_api.yaml b/config/routes/cmb_rider_api.yaml deleted file mode 100644 index 805d898d..00000000 --- a/config/routes/cmb_rider_api.yaml +++ /dev/null @@ -1,156 +0,0 @@ -# rider app api - -cmb_rapi_register: - path: /cmbrapi/register - controller: App\Controller\CMBRAPIController::register - methods: [POST] - -cmb_rapi_login: - path: /cmbrapi/login - controller: App\Controller\CMBRAPIController::login - methods: [POST] - -cmb_rapi_logout: - path: /cmbrapi/logout - controller: App\Controller\CMBRAPIController::logout - methods: [POST] - -cmb_rapi_jo_get: - path: /cmbrapi/joborder - controller: App\Controller\CMBRAPIController::getJobOrder - methods: [GET] - -cmb_rapi_jo_accept: - path: /cmbrapi/joaccept - controller: App\Controller\CMBRAPIController::acceptJobOrder - methods: [POST] - -cmb_rapi_jo_cancel: - path: /cmbrapi/jocancel - controller: App\Controller\CMBRAPIController::cancelJobOrder - methods: [POST] - -cmb_rapi_arrive: - path: /cmbrapi/arrive - controller: App\Controller\CMBRAPIController::arrive - methods: [POST] - -cmb_rapi_performed: - path: /cmbrapi/joperform - controller: App\Controller\CMBRAPIController::performJobOrder - methods: [POST] - -cmb_rapi_payment: - path: /cmbrapi/jopayment - controller: App\Controller\CMBRAPIController::payment - methods: [POST] - -cmb_rapi_hub_arrive: - path: /cmbrapi/hub_arrive - controller: App\Controller\CMBRAPIController::hubArrive - methods: [POST] - -cmb_rapi_promos: - path: /cmbrapi/promos - controller: App\Controller\CMBRAPIController::getPromos - methods: [GET] - -cmb_rapi_batteries: - path: /cmbrapi/batteries - controller: App\Controller\CMBRAPIController::getBatteries - methods: [GET] - -cmb_rapi_change_service: - path: /cmbrapi/service - controller: App\Controller\CMBRAPIController::changeService - methods: [POST] - -cmb_rapi_available: - path: /cmbrapi/available - controller: App\Controller\CMBRAPIController::available - methods: [POST] - -cmb_rapi_jo_history: - path: /cmbrapi/johistory/{period} - controller: App\Controller\CMBRAPIController::getJobOrderHistory - methods: [GET] - -cmb_rapi_assigned_jo_get: - path: /cmbrapi/assignedjos - controller: App\Controller\CMBRAPIController::getAssignedJobOrders - methods: [GET] - -cmb_rapi_jo_in_transit: - path: /cmbrapi/jotransit - controller: App\Controller\CMBRAPIController::setJobOrderInTransit - methods: [POST] - -cmb_rapi_invoice_generate: - path: /cmbrapi/generateinvoice - controller: App\Controller\CMBRAPIController::generateInvoice - methods: [GET] - -cmb_rapi_online: - path: /cmbrapi/online - controller: App\Controller\CMBRAPIController::goOnline - methods: [POST] - -cmb_rapi_offline: - path: /cmbrapi/offline - controller: App\Controller\CMBRAPIController::goOffline - methods: [POST] - -cmb_rapi_jo_start: - path: /cmbrapi/jostart - controller: App\Controller\CMBRAPIController::startJobOrder - methods: [POST] - -cmb_rapi_jo_complete: - path: /cmbrapi/jocomplete - controller: App\Controller\CMBRAPIController::completeJobOrder - methods: [POST] - -cmb_rapi_jo_set_active: - path: /cmbrapi/joactive - controller: App\Controller\CMBRAPIController::setActiveJobOrder - methods: [POST] - -cmb_rapi_jo_reject: - path: /cmbrapi/joreject - controller: App\Controller\CMBRAPIController::rejectJobOrder - methods: [POST] - -cmb_rapi_jo_odometer: - path: /cmbrapi/odometer - controller: App\Controller\CMBRAPIController::setOdometer - methods: [POST] - -cmb_rapi_jo_finish_photos_upload: - path: /cmbrapi/uploadfinishphotos - controller: App\Controller\CMBRAPIController::uploadFinishPhotos - methods: [POST] - -cmb_rapi_status: - path: /cmbrapi/status - controller: App\Controller\CMBRAPIController::getStatus - methods: [GET] - -cmb_rapi_jo_ongoing: - path: /cmbrapi/joongoing - controller: App\Controller\CMBRAPIController::getOngoingJobOrder - methods: [GET] - -cmb_rapi_payment_methods: - path: /cmbrapi/paymentmethods - controller: App\Controller\CMBRAPIController::getPaymentMethods - methods: [GET] - -cmb_rapi_cancel_reasons: - path: /cmbrapi/cancelreasons - controller: App\Controller\CMBRAPIController::getCancelReasons - methods: [GET] - -cmb_rapi_jo_verify: - path: /cmbrapi/joverify - controller: App\Controller\CMBRAPIController::verifyJobOrder - methods: [GET] diff --git a/config/routes/job_order.yaml b/config/routes/job_order.yaml index 4ec4279e..586ed81f 100644 --- a/config/routes/job_order.yaml +++ b/config/routes/job_order.yaml @@ -253,14 +253,3 @@ jo_hub_view_form: controller: App\Controller\JobOrderController::hubViewForm methods: [GET] -jo_behind_schedule: - path: /job-order/behind-schedule - controller: App\Controller\JobOrderController::listBehindSchedule - methods: [GET] - -jo_behind_schedule_rows: - path: /job-order/behind-schedule-rows - controller: App\Controller\JobOrderController::getRows - methods: [POST] - defaults: - tier: "behind_schedule" diff --git a/config/routes/rider.yaml b/config/routes/rider.yaml index 5e31dfb4..1934a1b1 100644 --- a/config/routes/rider.yaml +++ b/config/routes/rider.yaml @@ -56,13 +56,3 @@ rider_priority_down_jo: path: /riders/{id}/priority_down/{jo_id} controller: App\Controller\RiderController::priorityDownJO methods: [GET] - -rider_ajax_avialable: - path: /riders/{id}/available - controller: App\Controller\RiderController::ajaxAvailable - methods: [GET] - -rider_ajax_rider_name: - path: /riders/rider_name - controller: App\Controller\RiderController::ajaxRiderName - methods: [GET] diff --git a/config/services.yaml b/config/services.yaml index 3d9fd7a3..05fd3b1a 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -5,7 +5,6 @@ parameters: latitude: 14.6091 longitude: 121.0223 image_upload_directory: '%kernel.project_dir%/public/uploads' - jo_extra_upload_directory: '%kernel.project_dir%/public/uploads/jo_extra' job_order_refresh_interval: 300000 api_acl_file: 'api_acl.yaml' api_access_key: 'api_access_keys' @@ -162,40 +161,39 @@ services: - { name: kernel.event_listener, event: kernel.controller, method: onKernelController } # invoice generator - App\Service\InvoiceGenerator\CMBInvoiceGenerator: ~ + App\Service\InvoiceGenerator\ResqInvoiceGenerator: ~ # invoice generator interface - App\Service\InvoiceGeneratorInterface: "@App\\Service\\InvoiceGenerator\\CMBInvoiceGenerator" + App\Service\InvoiceGeneratorInterface: "@App\\Service\\InvoiceGenerator\\ResqInvoiceGenerator" # job order generator - App\Service\JobOrderHandler\CMBJobOrderHandler: + App\Service\JobOrderHandler\ResqJobOrderHandler: arguments: $country_code: "%env(COUNTRY_CODE)%" #job order generator interface - App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\CMBJobOrderHandler" + App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\ResqJobOrderHandler" # customer generator - App\Service\CustomerHandler\CMBCustomerHandler: + App\Service\CustomerHandler\ResqCustomerHandler: arguments: $country_code: "%env(COUNTRY_CODE)%" # customer generator interface - App\Service\CustomerHandlerInterface: "@App\\Service\\CustomerHandler\\CMBCustomerHandler" + App\Service\CustomerHandlerInterface: "@App\\Service\\CustomerHandler\\ResqCustomerHandler" # rider assignment - App\Service\RiderAssignmentHandler\CMBRiderAssignmentHandler: ~ + App\Service\RiderAssignmentHandler\ResqRiderAssignmentHandler: ~ # rider assignment interface - App\Service\RiderAssignmentHandlerInterface: "@App\\Service\\RiderAssignmentHandler\\CMBRiderAssignmentHandler" + App\Service\RiderAssignmentHandlerInterface: "@App\\Service\\RiderAssignmentHandler\\ResqRiderAssignmentHandler" # rider API service - App\Service\RiderAPIHandler\CMBRiderAPIHandler: + App\Service\RiderAPIHandler\ResqRiderAPIHandler: arguments: - $country_code: "%env(COUNTRY_CODE)%" - $upload_dir: "%jo_extra_upload_directory%" + $country_code: "%env(COUNTRY_CODE)%" - App\Service\RiderAPIHandlerInterface: "@App\\Service\\RiderAPIHandler\\CMBRiderAPIHandler" + App\Service\RiderAPIHandlerInterface: "@App\\Service\\RiderAPIHandler\\ResqRiderAPIHandler" # map manager #App\Service\GISManager\Bing: ~ diff --git a/public/assets/css/style.css b/public/assets/css/style.css index 4b69c445..140966da 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -155,29 +155,6 @@ span.has-danger, color: #fff !important; } -.m-table__row--is_in_progress td { - background-color: #FFA500 !important; - color: #fff !important; -} - -.m-table__row--is_in_progress td > span, -.m-table__row--is_in_progress td > span a, -.m-table__row--is_in_progress td > span a i { - color: #fff !important; -} - -.m-table__row--is_assigned td { - background-color: #0000ff !important; - color: #fff !important; -} - -.m-table__row--is_assigned td > span, -.m-table__row--is_assigned td > span a, -.m-table__row--is_assigned td > span a i { - color: #fff !important; -} - - .m-datatable.m-datatable--default > .m-datatable__table { min-height: 0 !important; } @@ -381,4 +358,4 @@ span.has-danger, .map-info .m-badge { border-radius: 0; -} +} \ No newline at end of file diff --git a/public/assets/js/dashboard_map.js b/public/assets/js/dashboard_map.js index a00612a6..3f02d1f4 100644 --- a/public/assets/js/dashboard_map.js +++ b/public/assets/js/dashboard_map.js @@ -3,7 +3,6 @@ class DashboardMap { this.options = options; this.rider_markers = rider_markers; this.cust_markers = cust_markers; - this.rider_availability = {}; // layer groups this.layer_groups = { @@ -147,49 +146,6 @@ class DashboardMap { } } - putMarkerWithLabel(id, lat, lng, markers, icon, layer_group, popup_url, name) { - var my = this; - // existing marker - if (markers.hasOwnProperty(id)) { - markers[id].setLatLng(L.latLng(lat, lng)); - return; - } - - // new marker - // add label - markers[id] = L.marker( - [lat, lng], - { icon: icon } - ); - - var marker_label = id + ' - ' + name; - - markers[id].bindTooltip(marker_label, - { - permanent: true, - direction: 'right' - } - ); - - markers[id].addTo(layer_group); - - if (my.options.enable_popup) { - markers[id].bindPopup('Loading...'); - - // bind ajax for popup - markers[id].on('click', function(e) { - var popup = e.target.getPopup(); - var url = popup_url.replace('[id]', id); - console.log(url); - $.get(url).done(function(data) { - popup.setContent(data); - popup.update(); - }); - }); - } - } - - putCustomerMarker(id, lat, lng) { this.putMarker( id, @@ -214,8 +170,6 @@ class DashboardMap { this.layer_groups.customer.removeLayer(markers[id]); this.layer_groups.mobile_customer.removeLayer(markers[id]); - - delete markers[id]; } putMobileCustomerMarker(id, lat, lng) { @@ -230,29 +184,27 @@ class DashboardMap { ); } - putRiderAvailableMarker(id, lat, lng, name) { - this.putMarkerWithLabel( + putRiderAvailableMarker(id, lat, lng) { + this.putMarker( id, lat, lng, this.rider_markers, this.options.icons.rider_available, this.layer_groups.rider_available, - this.options.rider_popup_url, - name + this.options.rider_popup_url ); } - putRiderActiveJOMarker(id, lat, lng, name) { - this.putMarkerWithLabel( + putRiderActiveJOMarker(id, lat, lng) { + this.putMarker( id, lat, lng, this.rider_markers, this.options.icons.rider_active_jo, this.layer_groups.rider_active_jo, - this.options.rider_popup_url, - name + this.options.rider_popup_url ); } @@ -267,8 +219,6 @@ class DashboardMap { this.layer_groups.rider_active_jo.removeLayer(markers[id]); this.layer_groups.rider_available.removeLayer(markers[id]); - - delete markers[id]; } loadLocations(location_url) { @@ -302,12 +252,11 @@ class DashboardMap { $.each(riders, function(id, data) { var lat = data.latitude; var lng = data.longitude; - var name = data.name; if (data.has_jo) - my.putRiderActiveJOMarker(id, lat, lng, name); + my.putRiderActiveJOMarker(id, lat, lng); else - my.putRiderAvailableMarker(id, lat, lng, name); + my.putRiderAvailableMarker(id, lat, lng); }); // console.log(rider_markers); diff --git a/public/assets/js/map_mqtt.js b/public/assets/js/map_mqtt.js index 825bf065..0e6bdb31 100644 --- a/public/assets/js/map_mqtt.js +++ b/public/assets/js/map_mqtt.js @@ -1,8 +1,7 @@ class MapEventHandler { - constructor(options, dashmap, ssl) { + constructor(options, dashmap) { this.options = options; this.dashmap = dashmap; - this.ssl = ssl; } connect(user_id, host, port) { @@ -12,7 +11,7 @@ class MapEventHandler { this.mqtt = new Paho.MQTT.Client(host, port, client_id); var options = { - useSSL: this.ssl, + // useSSL: true, timeout: 3, invocationContext: this, onSuccess: this.onConnect.bind(this), @@ -36,10 +35,6 @@ class MapEventHandler { // subscribe to rider status console.log('subscribing to ' + my.options.channels.rider_status); my.mqtt.subscribe(my.options.channels.rider_status); - - // subscribe to rider availability - console.log('subscribing to ' + my.options.channels.rider_availability); - my.mqtt.subscribe(my.options.channels.rider_availability); } if (my.options.track_jo) { @@ -60,7 +55,7 @@ class MapEventHandler { onMessage(msg) { // console.log(msg); - // console.log('received message'); + console.log('received message'); var channel = msg.destinationName; var chan_split = channel.split('/'); @@ -78,99 +73,39 @@ class MapEventHandler { } handleRider(chan_split, payload) { - // console.log("rider message"); - // get rider name using chan_split[1] which is rider id - var rider_id = chan_split[1]; - $.ajax({ - method: "GET", - url: "{{ url('rider_ajax_rider_name') }}", - data: {id: rider_id} - }).done(function(response) { - var name = response.rider_name; - console.log('rider_name ' + name); - switch (chan_split[2]) { - case "availability": - console.log("got availability for rider " + chan_split[1] + " - " + payload); - var obj = JSON.parse(payload); + console.log("rider message"); + switch (chan_split[2]) { + case "location": + console.log("got location for rider " + chan_split[1] + " - " + payload); + var pl_split = payload.split(':'); + console.log(pl_split); - var status = obj.status; - console.log("status " + status); - switch (status) { - case 'rider_offline': - this.dashmap.rider_availability[chan_split[1]] = false; - this.dashmap.removeRiderMarker(chan_split[1]); - break; - case 'rider_online': - this.dashmap.rider_availability[chan_split[1]] = true; - var lat = parseFloat(obj.latitude); - var lng = parseFloat(obj.longitude); - - // cheeck if rider is available / unavailable - // TODO: make url not hardcoded - var dashmap = this.dashmap; - $.get('https://cmbdev.wildcard.cc/riders/' + chan_split[1] + '/available').done(function(data) { - console.log('rider availability - ' + data); - switch (data) { - case 'available': - console.log('putting available marker ' + chan_split[1] + ' ' + lat + ':' + lng); - dashmap.switchRiderStatus(chan_split[1], 'available'); - dashmap.putRiderAvailableMarker(chan_split[1], lat, lng, name); - break; - case 'unavailable': - console.log('putting active jo marker ' + chan_split[1] + ' ' + lat + ':' + lng); - dashmap.switchRiderStatus(chan_split[1], 'jo'); - dashmap.putRiderActiveJOMarker(chan_split[1], lat, lng, name); - break; - } - }); - break; - } + // check for correct format + if (pl_split.length != 2) break; - case "location": - // console.log("got location for rider " + chan_split[1] + " - " + payload); - var pl_split = payload.split(':'); - // console.log(pl_split); - // check for correct format - if (pl_split.length != 2) + var lat = parseFloat(pl_split[0]); + var lng = parseFloat(pl_split[1]); + + // TODO: check if available or not + this.dashmap.putRiderAvailableMarker(chan_split[1], lat, lng); + break; + case "status": + console.log("got status for rider " + chan_split[1] + " - " + payload); + switch (payload) { + case 'available': + this.dashmap.switchRiderStatus(chan_split[1], 'available'); break; - - var lat = parseFloat(pl_split[0]); - var lng = parseFloat(pl_split[1]); - - var display_marker = true; - if (this.dashmap.rider_availability.hasOwnProperty(chan_split[1])) { - if (!this.dashmap.rider_availability[chan_split[1]]) { - console.log('NOT displaying marker for inactive rider'); - display_marker = false; - } - } else { - console.log('rider not in availability check'); - } - - // TODO: cache rider availability (available vs active jo) status and check before displaying icon - // NOTE: we really should fix our terms since available can mean many things - if (display_marker) { - this.dashmap.putRiderAvailableMarker(chan_split[1], lat, lng, name); - } - break; - case "status": - console.log("got status for rider " + chan_split[1] + " - " + payload); - switch (payload) { - case 'available': - this.dashmap.switchRiderStatus(chan_split[1], 'available'); - break; - case 'jo': - console.log('jo status'); - this.dashmap.switchRiderStatus(chan_split[1], 'jo'); - break; - case 'logout': - this.dashmap.removeRiderMarker(chan_split[1]); - break; - } - break; - } - }); + case 'jo': + console.log('jo status'); + this.dashmap.switchRiderStatus(chan_split[1], 'jo'); + break; + case 'logout': + this.dashmap.removeRiderMarker(chan_split[1]); + break; + } + break; + } } handleJobOrder(chan_split, payload) { diff --git a/resq_settings/cmb/menu.yaml b/resq_settings/cmb/menu.yaml deleted file mode 100644 index 9f28b315..00000000 --- a/resq_settings/cmb/menu.yaml +++ /dev/null @@ -1,179 +0,0 @@ -main_menu: - - id: home - acl: dashboard.menu - label: Dashboard - icon: flaticon-line-graph - - id: user - acl: user.menu - label: User - icon: flaticon-users - - id: user_list - acl: user.list - label: Users - parent: user - - id: role_list - acl: role.list - label: Roles - parent: user - - - id: apiuser - acl: apiuser.menu - label: API User - icon: flaticon-users - - id: api_user_list - acl: apiuser.list - label: API Users - parent: apiuser - - id: api_role_list - acl: apirole.list - label: API Roles - parent: apiuser - - - id: logistics - acl: logistics.menu - label: Logistics - icon: fa fa-truck - - id: rider_list - acl: rider.list - label: Riders - parent: logistics - - id: service_charge_list - acl: service_charge.list - label: Service Charges - parent: logistics - - - id: battery - acl: battery.menu - label: Battery - icon: fa fa-battery-3 - - id: battery_list - acl: battery.list - label: Batteries - parent: battery - - id: bmfg_list - acl: bmfg.list - label: Manufacturers - parent: battery - - id: bmodel_list - acl: bmodel.list - label: Models - parent: battery - - id: bsize_list - acl: bsize.list - label: Sizes - parent: battery - - id: promo_list - acl: promo.list - label: Promos - parent: battery - - - id: vehicle - acl: vehicle.menu - label: Vehicle - icon: fa fa-car - - id: vehicle_list - acl: vehicle.list - label: Vehicles - parent: vehicle - - id: vmfg_list - acl: vmfg.list - label: Manufacturers - parent: vehicle - - - id: location - acl: location.menu - label: Location - icon: fa fa-home - - id: outlet_list - acl: outlet.menu - label: Outlet - parent: location - - id: hub_list - acl: hub.menu - label: Hub - parent: location - - id: geofence_list - acl: geofence.menu - label: Geofence - parent: location - - - - id: joborder - acl: joborder.menu - label: Job Order - icon: flaticon-calendar-3 - - id: jo_onestep_form - acl: jo_onestep.form - label: One-step Process - parent: joborder - - id: jo_walkin_form - acl: jo_walkin.form - label: Walk-in - parent: joborder - - id: jo_open - acl: jo_open.list - label: Open - parent: joborder - - id: jo_all - acl: jo_all.list - label: View All - parent: joborder - - - id: support - acl: support.menu - label: Customer Support - icon: flaticon-support - - id: customer_list - acl: customer.list - label: Customers - parent: support - - id: ticket_list - acl: ticket.list - label: Tickets - parent: support - - id: general_search - acl: general.search - label: Search - parent: support - - id: warranty_search - acl: warranty.search - label: Customer Battery Search - parent: support - - id: privacy_policy_list - acl: privacy_policy.list - label: Privacy Policy - parent: support - - id: warranty_list - acl: warranty.list - label: Warranty - parent: support - - id: warranty_upload - acl: warranty.upload - label: Warranty Upload - parent: support - - id: static_content_list - acl: static_content.list - label: Static Content - parent: support - - - id: service - acl: service.menu - label: Other Services - icon: flaticon-squares - - id: service_list - acl: service.list - label: Services - parent: service - - - id: partner - acl: partner.menu - label: Partners - icon: flaticon-network - - id: partner_list - acl: partner.list - label: Partners - parent: partner - - id: review_list - acl: review.list - label: Reviews - parent: partner diff --git a/resq_settings/cmb/messages.en.yaml b/resq_settings/cmb/messages.en.yaml deleted file mode 100644 index 3e12543b..00000000 --- a/resq_settings/cmb/messages.en.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# text -title_login: Res-Q for CMB | Login -block_title: Res-Q for CMB -control_panel_sign_in: Sign-in to Control Panel -alt_image_logo_login: Res-Q for CMB -alt_image_dashboard: Res-Q for CMB -copyright: Res-Q for CMB -battery_size_tradein_brand: Trade-in Motolite -battery_size_tradein_premium: Trade-in Premium -battery_size_tradein_other: Trade-in Other -add_cust_vehicle_battery_info: This vehicle is using a Motolite battery -jo_title_pdf: Res-Q for CMB Job Order -country_code_prefix: '+60' -delivery_instructions_label: 'CarFix Details' - -# images -image_logo_login: /assets/images/black-text-logo-01.png -icon_login: /assets/images/battery-assist-bm-logo-32x32.png -icon_base_32x32: /assets/images/black-text-logo-01-32x32.png -icon_base_16x16: /assets/images/black-text-logo-01-16x16.png -image_dashboard: /assets/images/century_logo.png -image_jo_pdf: /public/assets/images/black-text-logo-01-115x115.png - -# default point for maps -default_lat: 3.084216 -default_long: 101.6129996 -default_region: my diff --git a/resq_settings/cmb/services.yaml b/resq_settings/cmb/services.yaml deleted file mode 100644 index 3d9fd7a3..00000000 --- a/resq_settings/cmb/services.yaml +++ /dev/null @@ -1,246 +0,0 @@ -# Put parameters here that don't need to change on each machine where the app is deployed -# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration -parameters: - map_default: - latitude: 14.6091 - longitude: 121.0223 - image_upload_directory: '%kernel.project_dir%/public/uploads' - jo_extra_upload_directory: '%kernel.project_dir%/public/uploads/jo_extra' - job_order_refresh_interval: 300000 - api_acl_file: 'api_acl.yaml' - api_access_key: 'api_access_keys' - app_acl_file: 'acl.yaml' - app_access_key: 'access_keys' - cvu_brand_id: "%env(CVU_BRAND_ID)%" - country_code: "%env(COUNTRY_CODE)%" - api_version: "%env(API_VERSION)%" - -services: - # default configuration for services in *this* file - _defaults: - autowire: true # Automatically injects dependencies in your services. - autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. - public: false # Allows optimizing the container by removing unused services; this also means - # fetching services directly from the container via $container->get() won't work. - # The best practice is to be explicit about your dependencies anyway. - - # makes classes in src/ available to be used as services - # this creates a service per class whose id is the fully-qualified class name - App\: - resource: '../src/*' - exclude: '../src/{Entity,Migrations,Tests,Menu,Access}' - - # controllers are imported separately to make sure services can be injected - # as action arguments even if you don't extend any base controller class - App\Controller\: - resource: '../src/Controller' - tags: ['controller.service_arguments'] - - # add more service definitions when explicit configuration is needed - # please note that last definitions always *replace* previous ones - App\Menu\Generator: - arguments: - $router: "@router.default" - $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%' - - App\Service\MapTools: - arguments: - $em: "@doctrine.orm.entity_manager" - $gmaps_api_key: "%env(GMAPS_API_KEY)%" - $cust_dist_limit: "%env(CUST_DISTANCE_LIMIT)%" - - App\Service\RisingTideGateway: - arguments: - $em: "@doctrine.orm.entity_manager" - $user: "%env(RT_USER)%" - $pass: "%env(RT_PASS)%" - $usage_type: "%env(RT_USAGE_TYPE)%" - $shortcode: "%env(RT_SHORTCODE)%" - $dr_url: "https://resqaws.jankstudio.com/sms/delivery_receipt" - - App\Service\MQTTClient: - arguments: - $redis_client: "@App\\Service\\RedisClientProvider" - $key: "mqtt_events" - - App\Service\APNSClient: - arguments: - $redis_client: "@App\\Service\\RedisClientProvider" - - App\Service\RedisClientProvider: - arguments: - $scheme: "%env(REDIS_CLIENT_SCHEME)%" - $host: "%env(REDIS_CLIENT_HOST)%" - $port: "%env(REDIS_CLIENT_PORT)%" - $password: "%env(REDIS_CLIENT_PASSWORD)%" - - App\Service\GeofenceTracker: - arguments: - $geofence_flag: "%env(GEOFENCE_ENABLE)%" - - App\Service\WarrantyHandler: - arguments: - $em: "@doctrine.orm.entity_manager" - - App\Command\SetCustomerPrivacyPolicyCommand: - arguments: - $policy_promo: "%env(POLICY_PROMO)%" - $policy_third_party: "%env(POLICY_THIRD_PARTY)%" - $policy_mobile: "%env(POLICY_MOBILE)%" - - App\Command\CreateCustomerFromWarrantyCommand: - arguments: - $cvu_mfg_id: "%env(CVU_MFG_ID)%" - $cvu_brand_id: "%env(CVU_BRAND_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\CMBInvoiceGenerator: ~ - - # invoice generator interface - App\Service\InvoiceGeneratorInterface: "@App\\Service\\InvoiceGenerator\\CMBInvoiceGenerator" - - # job order generator - App\Service\JobOrderHandler\CMBJobOrderHandler: - arguments: - $country_code: "%env(COUNTRY_CODE)%" - - #job order generator interface - App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\CMBJobOrderHandler" - - # customer generator - App\Service\CustomerHandler\CMBCustomerHandler: - arguments: - $country_code: "%env(COUNTRY_CODE)%" - - # customer generator interface - App\Service\CustomerHandlerInterface: "@App\\Service\\CustomerHandler\\CMBCustomerHandler" - - # rider assignment - App\Service\RiderAssignmentHandler\CMBRiderAssignmentHandler: ~ - - # rider assignment interface - App\Service\RiderAssignmentHandlerInterface: "@App\\Service\\RiderAssignmentHandler\\CMBRiderAssignmentHandler" - - # rider API service - App\Service\RiderAPIHandler\CMBRiderAPIHandler: - arguments: - $country_code: "%env(COUNTRY_CODE)%" - $upload_dir: "%jo_extra_upload_directory%" - - App\Service\RiderAPIHandlerInterface: "@App\\Service\\RiderAPIHandler\\CMBRiderAPIHandler" - - # map manager - #App\Service\GISManager\Bing: ~ - App\Service\GISManager\OpenStreet: ~ - #App\Service\GISManager\Google: ~ - - #App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Bing" - App\Service\GISManagerInterface: "@App\\Service\\GISManager\\OpenStreet" - #App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Google" - - App\EventListener\JobOrderActiveCacheListener: - arguments: - $jo_cache: "@App\\Service\\JobOrderCache" - $mqtt: "@App\\Service\\MQTTClient" - tags: - - name: 'doctrine.orm.entity_listener' - event: 'postUpdate' - entity: 'App\Entity\JobOrder' - - name: 'doctrine.orm.entity_listener' - event: 'postRemove' - entity: 'App\Entity\JobOrder' - - name: 'doctrine.orm.entity_listener' - event: 'postPersist' - entity: 'App\Entity\JobOrder' - - App\Service\JobOrderCache: - arguments: - $redis_prov: "@App\\Service\\RedisClientProvider" - $active_jo_key: "%env(LOCATION_JO_ACTIVE_KEY)%" - - App\Service\RiderCache: - arguments: - $redis_prov: "@App\\Service\\RedisClientProvider" - $loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%" - $status_key: "%env(STATUS_RIDER_KEY)%" - - # inventory manager - App\Service\InventoryManager: - arguments: - $api_url: "%env(INVENTORY_API_URL)%" - $api_ocp_key: "%env(INVENTORY_API_OCP)%" - $api_auth_prefix: "%env(INVENTORY_API_AUTH_TOKEN_PREFIX)%" - $api_auth_token: "%env(INVENTORY_API_AUTH_TOKEN)%" - - # API logging - App\EventSubscriber\LogSubscriber: - arguments: - $api_log_flag: "%env(API_LOGGING)%" diff --git a/resq_settings/resq/menu.yaml b/resq_settings/resq/menu.yaml deleted file mode 100644 index 69f0b806..00000000 --- a/resq_settings/resq/menu.yaml +++ /dev/null @@ -1,186 +0,0 @@ -main_menu: - - id: home - acl: dashboard.menu - label: Dashboard - icon: flaticon-line-graph - - id: user - acl: user.menu - label: User - icon: flaticon-users - - id: user_list - acl: user.list - label: Users - parent: user - - id: role_list - acl: role.list - label: Roles - parent: user - - - id: apiuser - acl: apiuser.menu - label: API User - icon: flaticon-users - - id: api_user_list - acl: apiuser.list - label: API Users - parent: apiuser - - id: api_role_list - acl: apirole.list - label: API Roles - parent: apiuser - - - id: logistics - acl: logistics.menu - label: Logistics - icon: fa fa-truck - - id: rider_list - acl: rider.list - label: Riders - parent: logistics - - - id: battery - acl: battery.menu - label: Battery - icon: fa fa-battery-3 - - id: battery_list - acl: battery.list - label: Batteries - parent: battery - - id: bmfg_list - acl: bmfg.list - label: Manufacturers - parent: battery - - id: bmodel_list - acl: bmodel.list - label: Models - parent: battery - - id: bsize_list - acl: bsize.list - label: Sizes - parent: battery - - id: promo_list - acl: promo.list - label: Promos - parent: battery - - - id: vehicle - acl: vehicle.menu - label: Vehicle - icon: fa fa-car - - id: vehicle_list - acl: vehicle.list - label: Vehicles - parent: vehicle - - id: vmfg_list - acl: vmfg.list - label: Manufacturers - parent: vehicle - - - id: location - acl: location.menu - label: Location - icon: fa fa-home - - id: outlet_list - acl: outlet.menu - label: Outlet - parent: location - - id: hub_list - acl: hub.menu - label: Hub - parent: location - - id: geofence_list - acl: geofence.menu - label: Geofence - parent: location - - - - id: joborder - acl: joborder.menu - label: Job Order - icon: flaticon-calendar-3 - - id: jo_in - acl: jo_in.list - label: Incoming - parent: joborder - - id: jo_proc - acl: jo_proc.list - label: Dispatch - parent: joborder - - id: jo_assign - acl: jo_assign.list - label: Rider Assignment - parent: joborder - - id: jo_fulfill - acl: jo_fulfill.list - label: Fulfillment - parent: joborder - - id: jo_open - acl: jo_open.list - label: Open - parent: joborder - - id: jo_all - acl: jo_all.list - label: View All - parent: joborder - - id: jo_hub.view - label: Hub View - parent: joborder - - - id: support - acl: support.menu - label: Customer Support - icon: flaticon-support - - id: customer_list - acl: customer.list - label: Customers - parent: support - - id: ticket_list - acl: ticket.list - label: Tickets - parent: support - - id: general_search - acl: general.search - label: Search - parent: support - - id: warranty_search - acl: warranty.search - label: Customer Battery Search - parent: support - - id: privacy_policy_list - acl: privacy_policy.list - label: Privacy Policy - parent: support - - id: warranty_list - acl: warranty.list - label: Warranty - parent: support - - id: warranty_upload - acl: warranty.upload - label: Warranty Upload - parent: support - - id: static_content_list - acl: static_content.list - label: Static Content - parent: support - - - id: service - acl: service.menu - label: Other Services - icon: flaticon-squares - - id: service_list - acl: service.list - label: Services - parent: service - - - id: partner - acl: partner.menu - label: Partners - icon: flaticon-network - - id: partner_list - acl: partner.list - label: Partners - parent: partner - - id: review_list - acl: review.list - label: Reviews - parent: partner diff --git a/resq_settings/resq/messages.en.yaml b/resq_settings/resq/messages.en.yaml deleted file mode 100644 index c0fb8ca1..00000000 --- a/resq_settings/resq/messages.en.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# text -title_login: Motolite Res-Q | Login -block_title: Motolite Res-Q -control_panel_sign_in: Sign-in to Control Panel -alt_image_logo_login: Res-Q -alt_image_dashboard: Motolite -copyright: Motolite Res-Q -battery_size_tradein_brand: Trade-in Motolite -battery_size_tradein_premium: Trade-in Premium -battery_size_tradein_other: Trade-in Other -add_cust_vehicle_battery_info: This vehicle is using a Motolite battery -jo_title_pdf: Motolite Res-Q Job Order -country_code_prefix: '+63' -delivery_instructions_label: Delivery Instructions - -# images -image_logo_login: /assets/images/logo-resq.png -icon_login: /assets/demo/default/media/img/logo/favicon.ico -icon_base_32x32: /assets/images/favicon/favicon-32x32.png -icon_base_16x16: /assets/images/favicon/favicon-16x16.png -image_dashboard: /assets/images/logo-motolite.png -image_jo_pdf: /public/assets/images/logo-resq.png - -# default point for maps -default_lat: 14.6091 -default_long: 121.0223 -default_region: ph diff --git a/resq_settings/resq/services.yaml b/resq_settings/resq/services.yaml deleted file mode 100644 index 7f568033..00000000 --- a/resq_settings/resq/services.yaml +++ /dev/null @@ -1,244 +0,0 @@ -# Put parameters here that don't need to change on each machine where the app is deployed -# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration -parameters: - map_default: - latitude: 14.6091 - longitude: 121.0223 - image_upload_directory: '%kernel.project_dir%/public/uploads' - job_order_refresh_interval: 300000 - api_acl_file: 'api_acl.yaml' - api_access_key: 'api_access_keys' - app_acl_file: 'acl.yaml' - app_access_key: 'access_keys' - cvu_brand_id: "%env(CVU_BRAND_ID)%" - country_code: "%env(COUNTRY_CODE)%" - api_version: "%env(API_VERSION)%" - -services: - # default configuration for services in *this* file - _defaults: - autowire: true # Automatically injects dependencies in your services. - autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. - public: false # Allows optimizing the container by removing unused services; this also means - # fetching services directly from the container via $container->get() won't work. - # The best practice is to be explicit about your dependencies anyway. - - # makes classes in src/ available to be used as services - # this creates a service per class whose id is the fully-qualified class name - App\: - resource: '../src/*' - exclude: '../src/{Entity,Migrations,Tests,Menu,Access}' - - # controllers are imported separately to make sure services can be injected - # as action arguments even if you don't extend any base controller class - App\Controller\: - resource: '../src/Controller' - tags: ['controller.service_arguments'] - - # add more service definitions when explicit configuration is needed - # please note that last definitions always *replace* previous ones - App\Menu\Generator: - arguments: - $router: "@router.default" - $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%' - - App\Service\MapTools: - arguments: - $em: "@doctrine.orm.entity_manager" - $gmaps_api_key: "%env(GMAPS_API_KEY)%" - $cust_dist_limit: "%env(CUST_DISTANCE_LIMIT)%" - - App\Service\RisingTideGateway: - arguments: - $em: "@doctrine.orm.entity_manager" - $user: "%env(RT_USER)%" - $pass: "%env(RT_PASS)%" - $usage_type: "%env(RT_USAGE_TYPE)%" - $shortcode: "%env(RT_SHORTCODE)%" - $dr_url: "https://resqaws.jankstudio.com/sms/delivery_receipt" - - App\Service\MQTTClient: - arguments: - $redis_client: "@App\\Service\\RedisClientProvider" - $key: "mqtt_events" - - App\Service\APNSClient: - arguments: - $redis_client: "@App\\Service\\RedisClientProvider" - - App\Service\RedisClientProvider: - arguments: - $scheme: "%env(REDIS_CLIENT_SCHEME)%" - $host: "%env(REDIS_CLIENT_HOST)%" - $port: "%env(REDIS_CLIENT_PORT)%" - $password: "%env(REDIS_CLIENT_PASSWORD)%" - - App\Service\GeofenceTracker: - arguments: - $geofence_flag: "%env(GEOFENCE_ENABLE)%" - - App\Service\WarrantyHandler: - arguments: - $em: "@doctrine.orm.entity_manager" - - App\Command\SetCustomerPrivacyPolicyCommand: - arguments: - $policy_promo: "%env(POLICY_PROMO)%" - $policy_third_party: "%env(POLICY_THIRD_PARTY)%" - $policy_mobile: "%env(POLICY_MOBILE)%" - - App\Command\CreateCustomerFromWarrantyCommand: - arguments: - $cvu_mfg_id: "%env(CVU_MFG_ID)%" - $cvu_brand_id: "%env(CVU_BRAND_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" - - # job order generator - App\Service\JobOrderHandler\ResqJobOrderHandler: - arguments: - $country_code: "%env(COUNTRY_CODE)%" - - #job order generator interface - App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\ResqJobOrderHandler" - - # customer generator - App\Service\CustomerHandler\ResqCustomerHandler: - arguments: - $country_code: "%env(COUNTRY_CODE)%" - - # customer generator interface - App\Service\CustomerHandlerInterface: "@App\\Service\\CustomerHandler\\ResqCustomerHandler" - - # rider assignment - App\Service\RiderAssignmentHandler\ResqRiderAssignmentHandler: ~ - - # rider assignment interface - App\Service\RiderAssignmentHandlerInterface: "@App\\Service\\RiderAssignmentHandler\\ResqRiderAssignmentHandler" - - # rider API service - App\Service\RiderAPIHandler\ResqRiderAPIHandler: - arguments: - $country_code: "%env(COUNTRY_CODE)%" - - App\Service\RiderAPIHandlerInterface: "@App\\Service\\RiderAPIHandler\\ResqRiderAPIHandler" - - # map manager - #App\Service\GISManager\Bing: ~ - App\Service\GISManager\OpenStreet: ~ - #App\Service\GISManager\Google: ~ - - #App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Bing" - App\Service\GISManagerInterface: "@App\\Service\\GISManager\\OpenStreet" - #App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Google" - - App\EventListener\JobOrderActiveCacheListener: - arguments: - $jo_cache: "@App\\Service\\JobOrderCache" - $mqtt: "@App\\Service\\MQTTClient" - tags: - - name: 'doctrine.orm.entity_listener' - event: 'postUpdate' - entity: 'App\Entity\JobOrder' - - name: 'doctrine.orm.entity_listener' - event: 'postRemove' - entity: 'App\Entity\JobOrder' - - name: 'doctrine.orm.entity_listener' - event: 'postPersist' - entity: 'App\Entity\JobOrder' - - App\Service\JobOrderCache: - arguments: - $redis_prov: "@App\\Service\\RedisClientProvider" - $active_jo_key: "%env(LOCATION_JO_ACTIVE_KEY)%" - - App\Service\RiderCache: - arguments: - $redis_prov: "@App\\Service\\RedisClientProvider" - $loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%" - $status_key: "%env(STATUS_RIDER_KEY)%" - - # inventory manager - App\Service\InventoryManager: - arguments: - $api_url: "%env(INVENTORY_API_URL)%" - $api_ocp_key: "%env(INVENTORY_API_OCP)%" - $api_auth_prefix: "%env(INVENTORY_API_AUTH_TOKEN_PREFIX)%" - $api_auth_token: "%env(INVENTORY_API_AUTH_TOKEN)%" - - # API logging - App\EventSubscriber\LogSubscriber: - arguments: - $api_log_flag: "%env(API_LOGGING)%" diff --git a/src/Command/ConfigureResqCommand.php b/src/Command/ConfigureResqCommand.php deleted file mode 100644 index f4316056..00000000 --- a/src/Command/ConfigureResqCommand.php +++ /dev/null @@ -1,55 +0,0 @@ -setName('resq:configure') - ->setDescription('Copies the configuration files, depending on environment.') - ->setHelp('Copies the configuration files, depending on environment.') - ->addArgument('dir_name', InputArgument::REQUIRED, 'Name of source subdirectory.'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $dir_name = $input->getArgument('dir_name'); - - $filesystem = new Filesystem(); - $current_dir = getcwd(); - - $source_dir = $current_dir . '/resq_settings/' . $dir_name . '/'; - $config_dir = $current_dir . '/config/'; - $translations_dir = $current_dir . '/translations/'; - - // copy services.yaml file - error_log('Copying services.yaml file...'); - $filesystem->copy($source_dir . 'services.yaml', $config_dir . 'services.yaml', true); - - // copy menu.yaml file - error_log('Copying menu.yaml file...'); - $filesystem->copy($source_dir . 'menu.yaml', $config_dir . 'menu.yaml', true); - - // copy messages.en.yaml file - error_log('Copying messages.en.yaml file...'); - $filesystem->copy($source_dir . 'messages.en.yaml', $translations_dir . 'messages.en.yaml', true); - - error_log('Done copying files.'); - - return 0; - } -} diff --git a/src/Command/CreateJOTestDataCommand.php b/src/Command/CreateJOTestDataCommand.php deleted file mode 100644 index 7aafe444..00000000 --- a/src/Command/CreateJOTestDataCommand.php +++ /dev/null @@ -1,173 +0,0 @@ -em = $em; - - parent::__construct(); - } - - protected function configure() - { - $this->setName('joborder:create_testdata') - ->setDescription('Create JO test data, given a rider id.') - ->setHelp('Create JO test data, given a rider id.') - ->addArgument('rider_id', InputArgument::REQUIRED, 'Rider id.'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $rider_id = $input->getArgument('rider_id'); - - $rider = $this->em->getRepository(Rider::class)->find($rider_id); - - // get customer vehicles where plate number is not null - $cv_query = $this->em->createQuery('SELECT cv FROM App\Entity\CustomerVehicle cv WHERE cv.plate_number is not null'); - $cv_results = $cv_query->getResult(); - - // get the first customer vehicle - $cv = current($cv_results); - - // get batteries - $battery_results = $this->em->getRepository(Battery::class)->findAll(); - - // get the first battery - $battery = current($battery_results); - - error_log($cv->getPlateNumber()); - error_log($battery->getID()); - - if (empty($rider)) - { - error_log('Rider not found.'); - } - else - { - // get current date - $current_date = new DateTime(); - - // for this month JO - $current_year = $current_date->format('Y'); - $current_month = $current_date->format('M'); - - // for last month JO - $date_interval = new DateInterval('P1M'); - $last_month_date = $current_date->sub($date_interval); - - $last_month_year = $last_month_date->format('Y'); - $last_month_month = $last_month_date->format('M'); - - $time_schedule = $current_date->format('h:i A'); - - $this->createJobOrders($rider, $cv, $battery, $last_month_year, $last_month_month, $time_schedule); - $this->createJobOrders($rider, $cv, $battery, $current_year, $current_month, $time_schedule); - } - - return 0; - } - - protected function createJobOrders(Rider $rider, CustomerVehicle $cv, Battery $battery, $year, $month, $time) - { - // insert 15 JOs for last month - for ($i = 1; $i <= 15; $i++) - { - $jo = new JobOrder(); - - // set customer data - $jo->setCustomerVehicle($cv); - $jo->setCustomer($cv->getCustomer()); - - // set hub and rider data - $jo->setRider($rider); - $jo->setHub($rider->getHub()); - - // set JO details - $point = new Point(121.0223, 14.6091); - $s_type = CMBServiceType::BATTERY_REPLACEMENT_NEW; - $source = TransactionOrigin::CALL; - $advance_order = true; - $warranty_class = WarrantyClass::WTY_PRIVATE; - $status = JOStatus::FULFILLED; - $delivery_address = '#1234 Moogle Lane'; - $mode_of_payment = ModeOfPayment::CASH; - - // set invoice details - $invoice = new Invoice(); - $invoice_item = new InvoiceItem(); - - // set invoice item details - $invoice_item->setBattery($battery) - ->setTitle($battery->getModel()->getName() . ' ' . $battery->getSize()->getName()) - ->setQuantity(1) - ->setPrice($battery->getSellingPrice()) - ->setInvoice($invoice); - - $invoice->addItem($invoice_item); - - $this->em->persist($invoice_item); - - // set invoice details - $invoice->setTotalPrice($battery->getSellingPrice()) - ->setStatus(InvoiceStatus::DRAFT) - ->setVATExclusivePrice($battery->getSellingPrice()) - ->setDiscount(0.0) - ->setTradeIn(0.0) - ->setVAT(0.00); - - $this->em->persist($invoice); - - $jo->setInvoice($invoice); - - // for last month - $date_schedule_date = $i . ' ' . $month . ' ' . $year . ' ' . $time; - error_log('Adding JO with date schedule ' . $date_schedule_date); - $date_schedule = DateTime::createFromFormat("d M Y h:i A", $date_schedule_date); - - $jo->setDateSchedule($date_schedule) - ->setCoordinates($point) - ->setAdvanceOrder($advance_order) - ->setServiceType($s_type) - ->setWarrantyClass($warranty_class) - ->setSource($source) - ->setStatus($status) - ->setDeliveryAddress($delivery_address); - - $this->em->persist($jo); - } - - $this->em->flush(); - - } -} diff --git a/src/Controller/CMBRAPIController.php b/src/Controller/CMBRAPIController.php deleted file mode 100644 index 6ddf842e..00000000 --- a/src/Controller/CMBRAPIController.php +++ /dev/null @@ -1,317 +0,0 @@ -register($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function login(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->login($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function logout(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->logout($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function getJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->getJobOrder($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function acceptJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->acceptJobOrder($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function cancelJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->cancelJobOrder($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function arrive(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->arrive($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function performJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->performJobOrder($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function hubArrive(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->hubArrive($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function payment(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->payment($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function available(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->available($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function getPromos(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->getPromos($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function getBatteries(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->getBatteries($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function changeService(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->changeService($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function getJobOrderHistory(Request $req, $period, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->getJobOrderHistory($req, $period); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function getAssignedJobOrders(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->getAssignedJobOrders($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function setJobOrderInTransit(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->setJobOrderInTransit($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function generateInvoice(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->generateInvoice($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function goOnline(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->goOnline($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function goOffline(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->goOffline($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function startJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->startJobOrder($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function completeJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->completeJobOrder($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function setActiveJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->setActiveJobOrder($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function rejectJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->rejectJobOrder($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function setOdometer(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->setOdometer($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function uploadFinishPhotos(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->uploadFinishPhotos($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function getStatus(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->getStatus($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function getOngoingJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->getOngoingJobOrder($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function getPaymentMethods(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->getPaymentMethods($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function getCancelReasons(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->getCancelReasons($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - public function verifyJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) - { - $data = $rapi_handler->verifyJobOrder($req); - - $res = $this->generateResultFromHandler($data); - - return $res->getReturnResponse(); - } - - protected function generateResultFromHandler($data) - { - $res = new NewAPIResult(); - - if (isset($data['error'])) - { - $message = $data['error']; - $title = $data['title']; - - $res->setError(true) - ->setErrorTitle($title) - ->setErrorMessage($message); - } - else - { - $res->setData($data); - } - - return $res; - } - -} diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php index 46f50c19..1a157b78 100644 --- a/src/Controller/HomeController.php +++ b/src/Controller/HomeController.php @@ -58,10 +58,6 @@ class HomeController extends Controller continue; } - // get full name of rider - $name = $rider->getFullName(); - $riders[$rider_id]['name'] = $name; - $jo = $rider->getActiveJobOrder(); if ($jo == null) $riders[$rider_id]['has_jo'] = false; diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index 1b7a451f..f23fc73c 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -286,11 +286,6 @@ class JobOrderController extends Controller $rows[$key]['meta']['edit_url'] = $this->generateUrl($jo_handler->getEditRoute($jo_id, $tier_params['edit_route']), ['id' => $jo_id]); $rows[$key]['meta']['onestep_edit_url'] = $this->generateUrl('jo_onestep_edit_form', ['id' => $jo_id]); } - else if ($tier == 'behind_schedule') - { - $rows[$key]['meta']['edit_url'] = $this->generateUrl($jo_handler->getEditRoute($jo_id, $tier_params['edit_route']), ['id' => $jo_id]); - $rows[$key]['meta']['onestep_edit_url'] = $this->generateUrl('jo_onestep_edit_form', ['id' => $jo_id]); - } else { // $rows[$key]['meta']['update_url'] = $this->generateUrl($tier_params['edit_route'], ['id' => $jo_id]); @@ -769,10 +764,7 @@ class JobOrderController extends Controller // use invoice object values in a json friendly array $invoice = [ - // TODO: CMB needs to have no decimal places for discount. - // Resq requires the two decimal places since discount is computed. - //'discount' => number_format($iobj->getDiscount(), 2), - 'discount' => number_format($iobj->getDiscount(), 0), + 'discount' => number_format($iobj->getDiscount(), 2), 'trade_in' => number_format($iobj->getTradeIn(), 2), // TODO: computations not done yet for this on invoice creator 'price' => number_format($iobj->getVATExclusivePrice(), 2), 'vat' => number_format($iobj->getVAT(), 2), @@ -875,14 +867,14 @@ class JobOrderController extends Controller return $this->render($template, $params); } - public function oneStepSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient) + public function oneStepSubmit(Request $req, JobOrderHandlerInterface $jo_handler) { $this->denyAccessUnlessGranted('jo_onestep.form', null, 'No access.'); // initialize error list $error_array = []; $id = -1; - $error_array = $jo_handler->processOneStepJobOrder($req, $id, $mclient); + $error_array = $jo_handler->processOneStepJobOrder($req, $id); // check if any errors were found if (!empty($error_array)) { @@ -921,12 +913,12 @@ class JobOrderController extends Controller return $this->render($template, $params); } - public function oneStepEditSubmit(Request $req, JobOrderHandlerInterface $jo_handler, $id, MQTTClient $mclient) + public function oneStepEditSubmit(Request $req, JobOrderHandlerInterface $jo_handler, $id) { $this->denyAccessUnlessGranted('jo_onestep.edit', null, 'No access.'); $error_array = []; - $error_array = $jo_handler->processOneStepJobOrder($req, $id, $mclient); + $error_array = $jo_handler->processOneStepJobOrder($req, $id); // check if any errors were found if (!empty($error_array)) { @@ -1217,21 +1209,6 @@ class JobOrderController extends Controller } - /** - * @Menu(selected="jo_behind_schedule") - */ - public function listBehindSchedule(JobOrderHandlerInterface $jo_handler) - { - $this->denyAccessUnlessGranted('jo_behind_schedule.list', null, 'No access.'); - - $template = $jo_handler->getTwigTemplate('jo_behind_schedule'); - - $params = $jo_handler->getOtherParameters(); - $params['table_refresh_rate'] = $this->container->getParameter('job_order_refresh_interval'); - - return $this->render($template, $params); - } - protected function autoAssignHubAndRider($jo, EntityManagerInterface $em, MapTools $map_tools, InventoryManager $im) { diff --git a/src/Controller/RiderController.php b/src/Controller/RiderController.php index bdfd3b85..43f5d6d6 100644 --- a/src/Controller/RiderController.php +++ b/src/Controller/RiderController.php @@ -596,37 +596,4 @@ class RiderController extends Controller return $this->redirecttoRoute('rider_update', ['id' => $rider->getID()]); } - - /** - * @ParamConverter("rider", class="App\Entity\Rider") - */ - public function ajaxAvailable(EntityManagerInterface $em, Rider $rider) - { - $jo = $rider->getRiderActiveJobOrder(); - if ($jo == null || $jo->isClosed()) - $avail = 'available'; - else - $avail = 'unavailable'; - - $response = new Response( - $avail, - Response::HTTP_OK, - ['content-type' => 'text/plain'] - ); - return $response; - } - - public function ajaxRiderName(EntityManagerInterface $em, Request $req) - { - $rider_id = $req->query->get('id'); - - $rider = $em->getRepository(Rider::class)->find($rider_id); - $rider_name = ''; - if ($rider != null) - $rider_name = $rider->getFullName(); - - return $this->json([ - 'rider_name' => $rider_name, - ]); - } } diff --git a/src/Entity/JOExtra.php b/src/Entity/JOExtra.php deleted file mode 100644 index 7770c150..00000000 --- a/src/Entity/JOExtra.php +++ /dev/null @@ -1,140 +0,0 @@ -other_images = new ArrayCollection(); - } - - public function getID() - { - return $this->id; - } - - public function setImage1Filename($image_filename) - { - $this->image_1_filename = $image_filename; - return $this; - } - - public function getImage1Filename() - { - return $this->image_1_filename; - } - - public function setImage2Filename($image_filename) - { - $this->image_2_filename = $image_filename; - return $this; - } - - public function getImage2Filename() - { - return $this->image_2_filename; - } - - public function setImage3Filename($image_filename) - { - $this->image_3_filename = $image_filename; - return $this; - } - - public function getImage3Filename() - { - return $this->image_3_filename; - } - - public function setImage4Filename($image_filename) - { - $this->image_4_filename = $image_filename; - return $this; - } - - public function getImage4Filename() - { - return $this->image_4_filename; - } - - public function getOtherImages() - { - return $this->other_images; - } - - public function setOtherImages(array $images) - { - $this->other_images = new ArrayCollection(); - - foreach ($images as $image_filename) - { - $this->other_images->add($image_filename); - } - - return $this; - } - - public function clearOtherImages() - { - $this->other_images = new ArrayCollection(); - return $this; - } - - public function setCustomerSignature($sig_file) - { - $this->cust_signature = $sig_file; - return $this; - } - - public function getCustomerSignature() - { - return $this->cust_signature; - } -} diff --git a/src/Entity/JobOrder.php b/src/Entity/JobOrder.php index 7335c512..8bcdbb77 100644 --- a/src/Entity/JobOrder.php +++ b/src/Entity/JobOrder.php @@ -334,24 +334,6 @@ class JobOrder */ protected $phone_mobile; - // link to JOExtra - /** - * @ORM\OneToOne(targetEntity="JOExtra") - */ - protected $jo_extra; - - // date that the status last changed - /** - * @ORM\Column(type="datetime", nullable=true) - */ - protected $date_status_change; - - // insurer/responsible party handling the onsite job - /** - * @ORM\Column(type="string", length=80, nullable=true) - */ - protected $responsible_party; - public function __construct() { $this->date_create = new DateTime(); @@ -601,7 +583,6 @@ class JobOrder { // TODO: validate status $this->status = $status; - $this->date_status_change = new DateTime(); return $this; } @@ -615,11 +596,6 @@ class JobOrder return JOStatus::getName($this->status); } - public function getDateStatusChange() - { - return $this->date_status_change; - } - public function setDeliveryInstructions($delivery_instructions) { $this->delivery_instructions = $delivery_instructions; @@ -820,11 +796,6 @@ class JobOrder $this->makeRiderAvailable(); } - public function perform() - { - $this->setStatus(JOStatus::PERFORMED); - } - public function fulfill() { $this->setStatus(JOStatus::FULFILLED) @@ -991,26 +962,5 @@ class JobOrder return $this->phone_mobile; } - public function setJOExtra(JOExtra $jo_extra) - { - $this->jo_extra = $jo_extra; - return $this; - } - - public function getJOExtra() - { - return $this->jo_extra; - } - - public function setResponsibleParty($responsible_party) - { - $this->responsible_party = $responsible_party; - return $this; - } - - public function getResponsibleParty() - { - return $this->responsible_party; - } } diff --git a/src/Entity/Rider.php b/src/Entity/Rider.php index 6416a443..502d93bc 100644 --- a/src/Entity/Rider.php +++ b/src/Entity/Rider.php @@ -347,11 +347,6 @@ class Rider return $this->job_orders->matching($criteria)[0]; } - public function getRiderActiveJobOrder() - { - return $this->active_job_order; - } - public function getOpenJobOrders() { $active_status = [ diff --git a/src/Ramcar/CMBCancelReason.php b/src/Ramcar/CMBCancelReason.php deleted file mode 100644 index b681a40a..00000000 --- a/src/Ramcar/CMBCancelReason.php +++ /dev/null @@ -1,22 +0,0 @@ - 'Accident', - 'breakdown' => 'Breakdown', - 'fuel_runout' => 'Fuel Runout', - 'wrong_battery_size' => 'Wrong Battery Size', - 'customer_cancel' => 'Cancelled by Customer', - 'others' => 'Others' - ]; -} diff --git a/src/Ramcar/CMBJOEventType.php b/src/Ramcar/CMBJOEventType.php deleted file mode 100644 index 631b434b..00000000 --- a/src/Ramcar/CMBJOEventType.php +++ /dev/null @@ -1,42 +0,0 @@ - 'Created', - 'hub_assign' => 'Assigned to Hub', - 'rider_assign' => 'Assigned Rider', - 'cancel' => 'Cancelled', - 'fulfill' => 'Fulfilled', - 'open_edit' => 'Open Edit', - 'requeue' => 'Requeue', - 'accept' => 'Rider Accept', - 'rider_in_transit' => 'Rider in Transit', - 'arrive' => 'Rider Arrive', - 'rider_start' => 'Rider Start', - 'rider_edit' => 'Rider Edit', - 'paid' => 'Paid', - 'perform' => 'Perform', - 'finish' => 'Finish', - 'rider_upload_photo' => 'Rider Upload Photo', - ]; -} diff --git a/src/Ramcar/CMBModeOfPayment.php b/src/Ramcar/CMBModeOfPayment.php index 63bb9a2d..c7ae9908 100644 --- a/src/Ramcar/CMBModeOfPayment.php +++ b/src/Ramcar/CMBModeOfPayment.php @@ -5,18 +5,12 @@ namespace App\Ramcar; class CMBModeOfPayment extends NameValue { const CASH = 'cash'; - const SHOPEE = 'shopee'; - const LAZADA = 'lazada'; const CREDIT_CARD = 'credit_card'; - const ONLINE_TRANSFER = 'online_transfer'; - const E_WALLET = 'e_wallet'; + const BANK_TRANSFER = 'bank_transfer'; const COLLECTION = [ 'cash' => 'Cash', - 'shopee' => 'Shopee', - 'lazada' => 'Lazada', 'credit_card' => 'Credit Card', - 'online_transfer' => 'Online Transfer', - 'e_wallet' => 'E-Wallet', + 'bank_transfer' => 'Bank Transfer', ]; } diff --git a/src/Ramcar/CMBTransactionOrigin.php b/src/Ramcar/CMBTransactionOrigin.php deleted file mode 100644 index 7ea6a02a..00000000 --- a/src/Ramcar/CMBTransactionOrigin.php +++ /dev/null @@ -1,25 +0,0 @@ - 'Hotline', - 'online' => 'Online', - 'facebook' => 'Facebook', - 'vip' => 'VIP', - 'mobile_app' => 'Mobile App', - 'walk_in' => 'Walk-in', - 'whatsapp' => 'Whatsapp', - ]; -} diff --git a/src/Ramcar/JOStatus.php b/src/Ramcar/JOStatus.php index 08177198..5ba8f5d1 100644 --- a/src/Ramcar/JOStatus.php +++ b/src/Ramcar/JOStatus.php @@ -4,15 +4,13 @@ namespace App\Ramcar; class JOStatus extends NameValue { - const PENDING = 'pending'; // JO has no hub assigned - const RIDER_ASSIGN = 'rider_assign'; // JO has hub assigned but no rider assigned - const ASSIGNED = 'assigned'; // JO has hub and rider assigned - const IN_TRANSIT = 'in_transit'; // Rider is on his way - const IN_PROGRESS = 'in_progress'; // Rider has arrived at customer's location and fulfillment is in progress - const PERFORMED = 'performed'; // Rider has finished performing JO task / service - const PAID = 'paid'; // Rider has finished collecting payment for JO - const CANCELLED = 'cancelled'; // JO is cancelled - const FULFILLED = 'fulfilled'; // JO is fulfilled + const PENDING = 'pending'; // NOTE: JO has no hub assigned + const RIDER_ASSIGN = 'rider_assign'; // NOTE: JO has hub assigned but no rider assigned + const ASSIGNED = 'assigned'; // NOTE: JO has hub and rider assigned + const IN_TRANSIT = 'in_transit'; // NOTE: JO's rider is on his way + const IN_PROGRESS = 'in_progress'; // NOTE: JO fulfillment in progress + const CANCELLED = 'cancelled'; // NOTE: JO is cancelled + const FULFILLED = 'fulfilled'; // NOTE: JO is fulfilled const COLLECTION = [ 'pending' => 'For Dispatch', @@ -20,8 +18,6 @@ class JOStatus extends NameValue 'assigned' => 'Assigned', 'in_transit' => 'In Transit', 'in_progress' => 'In Progress', - 'performed' => 'Service Performed', - 'paid' => 'Customer Paid', 'cancelled' => 'Cancelled', 'fulfilled' => 'Completed', ]; diff --git a/src/Ramcar/NewAPIResult.php b/src/Ramcar/NewAPIResult.php deleted file mode 100644 index 5c46bc21..00000000 --- a/src/Ramcar/NewAPIResult.php +++ /dev/null @@ -1,92 +0,0 @@ -err_title = ''; - $this->err_flag = false; - $this->err_message = ''; - $this->data = []; - } - - public function setError($flag = true) - { - $this->err_flag = $flag; - return $this; - } - - public function isError() - { - return $this->err_flag; - } - - public function setErrorMessage($message) - { - $this->err_message = $message; - return $this; - } - - public function getErrorMessage() - { - return $this->err_message; - } - - public function setData($data) - { - $this->data = $data; - return $this; - } - - public function getData() - { - return $this->data; - } - - public function setErrorTitle($title) - { - $this->err_title = $title; - return $this; - } - - public function getErrorTitle() - { - return $this->err_title; - } - - - public function getReturnResponse() - { - if ($this->isError()) - $status = 'error'; - else - $status = 'success'; - - if (count($this->data) == 0) - $this->data = new \stdClass(); - - $return_data = [ - 'error' => [ - 'title' => $this->err_title, - 'status' => $status, - 'message' => $this->err_message - ], - 'data' => $this->data - ]; - - // $json_data = json_encode($return_data, JSON_NUMERIC_CHECK); - $json_data = json_encode($return_data); - $json = new Response($json_data); - - return $json; - } -} diff --git a/src/Service/CustomerHandler/CMBCustomerHandler.php b/src/Service/CustomerHandler/CMBCustomerHandler.php index 28612897..371f674b 100644 --- a/src/Service/CustomerHandler/CMBCustomerHandler.php +++ b/src/Service/CustomerHandler/CMBCustomerHandler.php @@ -189,7 +189,7 @@ class CMBCustomerHandler implements CustomerHandlerInterface $cust_vehicle = new CustomerVehicle(); $cust_vehicle->setName($vehicle->name) ->setVehicle($vobj) - ->setPlateNumber(trim($vehicle->plate_number)) + ->setPlateNumber($vehicle->plate_number) ->setModelYear($vehicle->model_year) ->setColor('') ->setStatusCondition('') @@ -416,14 +416,8 @@ class CMBCustomerHandler implements CustomerHandlerInterface // add filters to count query if (!empty($term)) { - //$tquery->where('q.plate_number like :search') - // ->setParameter('search', $term . '%'); - // TODO: this is really slow. Need to optimize - $tquery->innerJoin('q.customer', 'c') - ->where('q.plate_number like :search') - ->orWhere('c.phone_mobile = :number') - ->setParameter('search', $term . '%') - ->setParameter('number', $term); + $tquery->where('q.plate_number like :search') + ->setParameter('search', $term . '%'); /* $tquery->where('match_against (q.plate_number, :search \'in boolean mode\') > 0.1') ->setParameter('search', $term . '*'); @@ -454,14 +448,8 @@ class CMBCustomerHandler implements CustomerHandlerInterface // add filters if needed if (!empty($term)) { - // TODO: this is really slow. Need to optimize - $query->innerJoin('q.customer', 'cust') - ->where('q.plate_number like :search') - ->orWhere('cust.phone_mobile = :number') - ->setParameter('search', $term . '%') - ->setParameter('number', $term); - //$query->where('q.plate_number like :search') - // ->setParameter('search', $term . '%'); + $query->where('q.plate_number like :search') + ->setParameter('search', $term . '%'); /* $query->where('match_against (q.plate_number, :search \'in boolean mode\') > 0.1') ->setParameter('search', $term . '*'); @@ -606,7 +594,7 @@ class CMBCustomerHandler implements CustomerHandlerInterface protected function generateYearOptions() { $start_year = 1950; - return range($start_year, date("Y")); + return range($start_year, date("Y") + 1); } diff --git a/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php b/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php index 69b4e55a..534600fb 100644 --- a/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php +++ b/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php @@ -270,7 +270,7 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface } // check if discount is greater than 50 or negative number - if (($discount > 60) || ($discount < 0)) + if (($discount > 50) || ($discount < 0)) return 'Invalid discount specified'; $criteria->setDiscount($discount); @@ -363,10 +363,9 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface if (!isset($con_batts[$batt_id])) $con_batts[$batt->getID()] = [ 'batt' => $batt, - 'qty' => $qty + 'qty' => 0 ]; - else - $con_batts[$batt_id]['qty'] += $qty; + $con_batts[$batt_id]['qty']++; // no trade-in diff --git a/src/Service/JobOrderHandler/CMBJobOrderHandler.php b/src/Service/JobOrderHandler/CMBJobOrderHandler.php index 9ffb102a..862d431b 100644 --- a/src/Service/JobOrderHandler/CMBJobOrderHandler.php +++ b/src/Service/JobOrderHandler/CMBJobOrderHandler.php @@ -31,12 +31,12 @@ use App\Entity\ServiceCharge; use App\Ramcar\InvoiceCriteria; use App\Ramcar\CMBServiceType; use App\Ramcar\CMBTradeInType; -use App\Ramcar\CMBJOEventType; +use App\Ramcar\JOEventType; use App\Ramcar\JOStatus; use App\Ramcar\CMBWarrantyClass; use App\Ramcar\DiscountApply; use App\Ramcar\CMBModeOfPayment; -use App\Ramcar\CMBTransactionOrigin; +use App\Ramcar\TransactionOrigin; use App\Ramcar\FacilitatedType; use App\Ramcar\JORejectionReason; @@ -177,35 +177,13 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // get rider information $rider_name = ''; $rider_plate_number = ''; - $rider_id = ''; $rider = $orow->getRider(); if (!empty($rider)) { - $rider_id = $rider->getID(); $rider_name = $rider->getFullName(); $rider_plate_number = $rider->getPlateNumber(); } - // get time when JO was started by rider - $start_event_type = CMBJOEventType::RIDER_START; - $date_start = ''; - $start_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $start_event_type, 'rider' => $rider_id, 'job_order' => $orow->getID()], ['date_happen' => 'DESC']); - if ($start_results != null) - { - $jo_event = current($start_results); - $date_start = $jo_event->getDateHappen()->format('d M Y g:i A'); - } - - // get time when JO was finished by rider - $finish_event_type = CMBJOEventType::RIDER_FINISH; - $date_finish = ''; - $finish_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $finish_event_type, 'rider' => $rider_id, 'job_order' => $orow->getID()], ['date_happen' => 'DESC']); - if ($finish_results != null) - { - $jo_event = current($finish_results); - $date_finish = $jo_event->getDateHappen()->format('d M Y g:i A'); - } - // add row data $row['id'] = $orow->getID(); $row['customer_name'] = $orow->getCustomer()->getFirstName() . ' ' . $orow->getCustomer()->getLastName(); @@ -216,12 +194,10 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $row['status'] = $statuses[$orow->getStatus()]; $row['flag_advance'] = $orow->isAdvanceOrder(); $row['plate_number'] = $orow->getCustomerVehicle()->getPlateNumber(); - $row['is_mobile'] = $orow->getSource() == CMBTransactionOrigin::MOBILE_APP; + $row['is_mobile'] = $orow->getSource() == TransactionOrigin::MOBILE_APP; $row['car_model'] = $car_model; $row['rider_name'] = $rider_name; $row['rider_plate_number'] = $rider_plate_number; - $row['date_start'] = $date_start; - $row['date_finish'] = $date_finish; $processor = $orow->getProcessedBy(); if ($processor == null) @@ -374,7 +350,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface ->setTier2Notes($req->request->get('tier2_notes')) ->setDeliveryAddress($req->request->get('delivery_address')) ->setORName($req->request->get('or_name')) - ->setPromoDetail($req->request->get('promo_detail', '')) + ->setPromoDetail($req->request->get('promo_detail')) ->setModeOfPayment($req->request->get('mode_of_payment')) ->setLandmark($req->request->get('landmark')); @@ -424,7 +400,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::CREATE) + ->setTypeID(JOEventType::CREATE) ->setJobOrder($jo); if ($user != null) @@ -440,7 +416,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface return $error_array; } - public function processOneStepJobOrder(Request $req, $id, MQTTClient $mclient) + public function processOneStepJobOrder(Request $req, $id) { // initialize error list $error_array = []; @@ -448,17 +424,11 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $em = $this->em; $jo = $em->getRepository(JobOrder::class)->find($id); - $old_jo_status = null; if (empty($jo)) { // new job order $jo = new JobOrder(); } - else - { - //$old_rider = $jo->getRider(); - $old_jo_status = $jo->getStatus(); - } // check if lat and lng are provided if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) { @@ -468,14 +438,19 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // check if new customer if ($req->request->get('new_customer', false)) { + if (empty($req->request->get('customer_customer_notes'))) + { + $error_array['customer_customer_notes'] = 'Customer notes cannot be null.'; + } + // validate mobile phone - $valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('phone_mobile')); + $valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('customer_phone_mobile')); if (!($valid_mobile)) - $error_array['phone_mobile'] = 'Invalid mobile phone number.'; + $error_array['customer_phone_mobile'] = 'Invalid mobile phone number.'; // check if plate number is in request - if (empty(trim($req->request->get('plate_number')))) - $error_array['plate_number'] = 'Plate number is required.'; + if (empty($req->request->get('cv_plate'))) + $error_array['cv_plate'] = 'Plate number is required.'; // find the vehicle using vid $new_vehicle = $em->getRepository(Vehicle::class)->find($req->request->get('vid')); @@ -489,17 +464,17 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $new_cust = new Customer(); $new_cv = new CustomerVehicle(); - $new_cust->setLastName($req->request->get('last_name')) - ->setFirstName($req->request->get('first_name')) - ->setPhoneMobile($req->request->get('phone_mobile')) - ->setPhoneLandline($req->request->get('phone_landline')) - ->setPhoneOffice($req->request->get('phone_office')) - ->setPhoneFax($req->request->get('phone_fax')) - ->setCustomerNotes($req->request->get('customer_notes')); + $new_cust->setLastName($req->request->get('customer_last_name')) + ->setFirstName($req->request->get('customer_first_name')) + ->setPhoneMobile($req->request->get('customer_phone_mobile')) + ->setPhoneLandline($req->request->get('customer_phone_landline')) + ->setPhoneOffice($req->request->get('customer_phone_office')) + ->setPhoneFax($req->request->get('customer_phone_fax')) + ->setCustomerNotes($req->request->get('customer_customer_notes')); $new_cv->setCustomer($new_cust) ->setVehicle($new_vehicle) - ->setPlateNumber(trim($req->request->get('plate_number'))) + ->setPlateNumber($req->request->get('cv_plate')) ->setModelYear($req->request->get('cv_year')) ->setColor('') ->setStatusCondition('') @@ -569,41 +544,36 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface if (empty($rider)) { $error_array['rider'] = 'Invalid rider specified.'; - } else { - // check if rider is still available - if (!($rider->isAvailable())) - $error_array['rider'] = 'Selected rider is unavailable.'; } } } } - // get discount and set to meta - $discount = $req->request->get('invoice_discount'); + // set priority based on rider's existing open job orders + $rider_jos = $rider->getOpenJobOrders(); - if (($discount > 60) || ($discount < 0)) + // get maximum priority then add 1 + // NOTE: this can be a bit buggy due to concurrency issues + // ideally have to lock jo table, but that isn't feasible right now + $priority = 0; + foreach ($rider_jos as $rider_jo) { - $error_array['invoice_discount'] = 'Invalid discount specified'; + if ($priority < $rider_jo->getPriority()) + $priority = $rider_jo->getPriority() + 1; } + // get discount and set to meta + $discount = $req->request->get('invoice_discount', []); + + // check if discount is greater than 50 or negative number + if (($discount > 50) || ($discount < 0)) + $error_array['invoice_discount'] = 'Invalid discount specified'; + // get list of service charges $service_charges = $req->request->get('service_charges', []); if (empty($error_array)) { - // set priority based on rider's existing open job orders - $rider_jos = $rider->getOpenJobOrders(); - - // get maximum priority then add 1 - // NOTE: this can be a bit buggy due to concurrency issues - // ideally have to lock jo table, but that isn't feasible right now - $priority = 0; - foreach ($rider_jos as $rider_jo) - { - if ($priority < $rider_jo->getPriority()) - $priority = $rider_jo->getPriority() + 1; - } - // get current user $user = $this->security->getUser(); @@ -619,31 +589,22 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface ->setServiceType($stype) ->setWarrantyClass($req->request->get('warranty_class')) ->setSource($req->request->get('source')) + ->setStatus(JOStatus::ASSIGNED) ->setDeliveryInstructions($req->request->get('delivery_instructions')) ->setTier1Notes($req->request->get('tier1_notes')) ->setTier2Notes($req->request->get('tier2_notes')) ->setDeliveryAddress($req->request->get('delivery_address')) ->setORName($req->request->get('or_name')) - ->setPromoDetail($req->request->get('promo_detail', '')) + ->setPromoDetail($req->request->get('promo_detail')) ->setModeOfPayment($req->request->get('mode_of_payment')) ->setLandmark($req->request->get('landmark')) ->setHub($hub) ->setRider($rider) - ->setPriority($priority) - ->setResponsibleParty($req->request->get('responsible_party', '')); + ->setPriority($priority); $jo->addMeta('discount', $discount); $jo->addMeta('service_charges', $service_charges); - // TODO: what happens if hub and rider are changed - // and JO is already in_transit or in_progress? - - // retain old jo status if it's an update JO - if ($old_jo_status != null) - $jo->setStatus($old_jo_status); - else - $jo->setStatus(JOStatus::ASSIGNED); - // check if user is null, meaning call to create came from API if ($user != null) { @@ -690,7 +651,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::CREATE) + ->setTypeID(JOEventType::CREATE) ->setJobOrder($jo); if ($user != null) @@ -700,21 +661,6 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $em->persist($event); $em->flush(); - - // check if JO has been reassigned - //if ($old_rider != $rider) - if ($old_jo_status != $jo->getStatus()) - { - error_log('JO has been reassigned'); - // TODO: refactor later - $channel = 'rider/' . $rider->getID() . '/events'; - $payload = [ - 'event' => 'new_jo', - 'jo_id' => $jo->getID(), - ]; - - $mclient->publish($channel, json_encode($payload)); - } } } @@ -829,7 +775,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::HUB_ASSIGN) + ->setTypeID(JOEventType::HUB_ASSIGN) ->setJobOrder($obj); if ($user != null) @@ -928,7 +874,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::RIDER_ASSIGN) + ->setTypeID(JOEventType::RIDER_ASSIGN) ->setJobOrder($obj); if ($user != null) @@ -999,7 +945,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::FULFILL) + ->setTypeID(JOEventType::FULFILL) ->setJobOrder($obj); // get current user @@ -1097,7 +1043,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::CANCEL) + ->setTypeID(JOEventType::CANCEL) ->setJobOrder($obj); // get current user @@ -1207,7 +1153,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // add event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::HUB_ASSIGN) + ->setTypeID(JOEventType::HUB_ASSIGN) ->setJobOrder($obj); if ($user != null) @@ -1407,7 +1353,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // add event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::RIDER_ASSIGN) + ->setTypeID(JOEventType::RIDER_ASSIGN) ->setJobOrder($obj); if ($user != null) @@ -1479,19 +1425,9 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface public function initializeOneStepForm() { - $new_jo = new JobOrder(); - - // set time schedule - $date_schedule = new DateTime(); - - // add 45 minutes to time - $date_schedule->add(new DateInterval('PT45M')); - $new_jo->setDateSchedule($date_schedule); - - $params['obj'] = $new_jo; + $params['obj'] = new JobOrder(); $params['mode'] = 'onestep'; $params['jo_service_charges'] = []; - $params['current_date'] = new DateTime(); $this->fillDropdownParameters($params); $this->fillFormTags($params); @@ -1512,7 +1448,6 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $params['mode'] = 'onestep-edit'; $params['cvid'] = $obj->getCustomerVehicle()->getID(); $params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID(); - $params['current_date'] = new DateTime(); // get service charges $sc_array = []; @@ -1530,53 +1465,6 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $params['jo_service_charges'] = $sc_array; - // get odometer - $odometer = $obj->getMeta('odometer'); - - $params['odometer'] = $odometer; - - // get customer email used in JO - $email = $obj->getMeta('customer_email'); - - $params['email'] = $email; - - // get images if any - $jo_extra = $obj->getJOExtra(); - $pic_array = []; - $params['signature'] = null; - if ($jo_extra != null) - { - $img_1 = $jo_extra->getImage1Filename(); - $img_2 = $jo_extra->getImage2Filename(); - $img_3 = $jo_extra->getImage3Filename(); - $img_4 = $jo_extra->getImage4Filename(); - - $other_images = $jo_extra->getOtherImages(); - - $cust_signature = $jo_extra->getCustomerSignature(); - - if ($img_1 != null) - $pic_array['image_1'] = $img_1; - if ($img_2 != null) - $pic_array['image_2'] = $img_2; - if ($img_3 != null) - $pic_array['image_3'] = $img_3; - if ($img_4 != null) - $pic_array['image_4'] = $img_4; - - if ($other_images != null) - { - foreach ($other_images as $img) - { - $pic_array['other_images'][] = $img; - } - } - - $params['signature'] = $cust_signature; - } - - $params['jo_pictures'] = $pic_array; - $this->fillDropdownParameters($params); $this->fillFormTags($params); @@ -1699,7 +1587,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // get template to display // check transaction origin if walkin - if ($obj->getSource() == CMBTransactionOrigin::WALK_IN) + if ($obj->getSource() == TransactionOrigin::WALK_IN) $params['template'] = $this->getTwigTemplate('jo_walkin_form'); else $params['template'] = $this->getTwigTemplate('jo_onestep_form'); @@ -2539,19 +2427,8 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface public function initializeWalkinForm() { - $new_jo = new JobOrder(); - - // set time schedule - $date_schedule = new DateTime(); - - // add 45 minutes to time - $date_schedule->add(new DateInterval('PT45M')); - $new_jo->setDateSchedule($date_schedule); - - $params['obj'] = $new_jo; + $params['obj'] = new JobOrder(); $params['mode'] = 'walk-in'; - $params['discounts'] = $this->generateDiscountOptions(); - $params['current_date'] = new DateTime(); $this->fillDropdownParameters($params); $this->fillFormTags($params); @@ -2580,14 +2457,19 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // check if new customer if ($req->request->get('new_customer', false)) { + if (empty($req->request->get('customer_customer_notes'))) + { + $error_array['customer_customer_notes'] = 'Customer notes cannot be null.'; + } + // validate mobile phone - $valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('phone_mobile')); + $valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('customer_phone_mobile')); if (!($valid_mobile)) - $error_array['phone_mobile'] = 'Invalid mobile phone number.'; + $error_array['customer_phone_mobile'] = 'Invalid mobile phone number.'; // check if plate number is in request - if (empty(trim($req->request->get('plate_number')))) - $error_array['plate_number'] = 'Plate number is required.'; + if (empty($req->request->get('cv_plate'))) + $error_array['cv_plate'] = 'Plate number is required.'; // find the vehicle using vid $new_vehicle = $em->getRepository(Vehicle::class)->find($req->request->get('vid')); @@ -2602,17 +2484,17 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $new_cust = new Customer(); $new_cv = new CustomerVehicle(); - $new_cust->setLastName($req->request->get('last_name')) - ->setFirstName($req->request->get('first_name')) - ->setPhoneMobile($req->request->get('phone_mobile')) - ->setPhoneLandline($req->request->get('phone_landline')) - ->setPhoneOffice($req->request->get('phone_office')) - ->setPhoneFax($req->request->get('phone_fax')) - ->setCustomerNotes($req->request->get('customer_notes')); + $new_cust->setLastName($req->request->get('customer_last_name')) + ->setFirstName($req->request->get('customer_first_name')) + ->setPhoneMobile($req->request->get('customer_phone_mobile')) + ->setPhoneLandline($req->request->get('customer_phone_landline')) + ->setPhoneOffice($req->request->get('customer_phone_office')) + ->setPhoneFax($req->request->get('customer_phone_fax')) + ->setCustomerNotes($req->request->get('customer_customer_notes')); $new_cv->setCustomer($new_cust) ->setVehicle($new_vehicle) - ->setPlateNumber(trim($req->request->get('plate_number'))) + ->setPlateNumber($req->request->get('cv_plate')) ->setModelYear($req->request->get('cv_year')) ->setColor('') ->setStatusCondition('') @@ -2681,8 +2563,8 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // get discount and set to meta $discount = $req->request->get('invoice_discount'); - // check if discount is greater than 60 or negative number - if (($discount > 60) || ($discount < 0)) + // check if discount is greater than 50 or negative number + if (($discount > 50) || ($discount < 0)) $error_array['invoice_discount'] = 'Invalid discount specified'; if (empty($error_array)) @@ -2702,14 +2584,13 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface ->setTier1Notes($req->request->get('tier1_notes')) ->setTier2Notes($req->request->get('tier2_notes')) ->setORName($req->request->get('or_name')) - ->setPromoDetail($req->request->get('promo_detail', '')) + ->setPromoDetail($req->request->get('promo_detail')) ->setModeOfPayment($req->request->get('mode_of_payment')) ->setLandmark($req->request->get('landmark')) ->setDeliveryAddress('Walk-in') ->setLandmark('Walk-in') ->setCoordinates($hub_coordinates) - ->setHub($hub) - ->setResponsibleParty($req->request->get('responsible_party', '')); + ->setHub($hub); $jo->addMeta('discount', $discount); @@ -2759,7 +2640,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::CREATE) + ->setTypeID(JOEventType::CREATE) ->setJobOrder($jo); if ($user != null) @@ -2838,7 +2719,6 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $params['mode'] = 'walk-in-edit'; $params['cvid'] = $obj->getCustomerVehicle()->getID(); $params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID(); - $params['current_date'] = new DateTime(); $this->fillDropdownParameters($params); $this->fillFormTags($params); @@ -2876,10 +2756,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $params['trade_in_types'] = CMBTradeInType::getCollection(); $params['facilitated_types'] = FacilitatedType::getCollection(); $params['facilitated_hubs'] = $fac_hubs; - $params['sources'] = CMBTransactionOrigin::getCollection(); - - $params['model_years'] = $this->generateYearOptions(); - $params['discounts'] = $this->generateDiscountOptions(); + $params['sources'] = TransactionOrigin::getCollection(); } protected function initFormTags(&$params) @@ -2966,7 +2843,6 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $this->template_hash['jo_walkin_form'] = 'job-order/cmb.form.walkin.html.twig'; $this->template_hash['jo_walkin_edit_form'] = 'job-order/cmb.form.walkin.html.twig'; $this->template_hash['jo_popup'] = 'job-order/cmb.popup.html.twig'; - $this->template_hash['jo_behind_schedule'] = 'job-order/cmb.list.behindschedule.html.twig'; } protected function checkTier($tier) @@ -3022,14 +2898,6 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $unlock_route = ''; $jo_status = ''; break; - case 'behind_schedule': - $tier_key = 'jo_behind_schedule'; - $tier_name = 'Behind Schedule'; - $rows_route = 'jo_behind_schedule_rows'; - $edit_route = ''; - $unlock_route = ''; - $jo_status = JOStatus::ASSIGNED; - break; default: throw new AccessDeniedHttpException('No access.'); } @@ -3160,53 +3028,6 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface ->setParameter('date_start', $date_start) ->setParameter('date_end', $date_end); } - break; - case 'behind_schedule': - if (isset($datatable['query']['data-rows-search'])) - { - $query->innerJoin('q.cus_vehicle', 'cv') - ->innerJoin('q.customer', 'c') - ->where('cv.plate_number like :filter') - ->orWhere('c.phone_mobile like :filter') - ->orWhere('c.first_name like :filter or c.last_name like :filter') - ->setParameter('filter', $datatable['query']['data-rows-search'] . '%'); - } - if (isset($datatable['query']['rider'])) - { - $query->innerJoin('q.rider', 'r') - ->andWhere('r.id = :rider_id') - ->setParameter('rider_id', $datatable['query']['rider']); - } - if (isset($datatable['query']['schedule_date'])) - { - $start = $datatable['query']['schedule_date'][0] . ' ' . '00:00:00'; - $end = $datatable['query']['schedule_date'][1] . ' ' . '23:59:00'; - - $date_start = DateTime::createFromFormat('m/d/Y H:i:s', $start); - $date_end = DateTime::createFromFormat('m/d/Y H:i:s', $end); - - $query->andWhere('q.date_schedule >= :date_start') - ->andWhere('q.date_schedule <= :date_end') - ->setParameter('date_start', $date_start) - ->setParameter('date_end', $date_end); - } - // status should be assigned - $query->andWhere('q.status = :status') - ->setParameter('status', $status); - - $current_datetime = new DateTime(); - $other_date = new DateTime(); - - $interval = new DateInterval('PT15M'); - $other_date->add($interval); - - //error_log('current datetime ' . $current_datetime->format('Y-m-d H:i:s')); - //error_log('other_date ' . $other_date->format('Y-m-d H:i:s')); - - $query->andWhere('q.date_schedule < :current_datetime OR q.date_schedule <= :other_date') - ->setParameter('current_datetime', $current_datetime) - ->setParameter('other_date', $other_date); - break; default: $query->where('q.status = :status') @@ -3221,21 +3042,9 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface throw new NotFoundHttpException('The item does not exist'); // check transaction origin - if ($jo->getSource() == CMBTransactionOrigin::WALK_IN) + if ($jo->getSource() == TransactionOrigin::WALK_IN) return 'jo_walkin_edit_form'; else return 'jo_onestep_edit_form'; } - - protected function generateDiscountOptions() - { - $discount_start = 0; - return range($discount_start, 60); - } - - protected function generateYearOptions() - { - $start_year = 1950; - return range($start_year, date("Y")); - } } diff --git a/src/Service/JobOrderHandlerInterface.php b/src/Service/JobOrderHandlerInterface.php index 22320c18..590a0926 100644 --- a/src/Service/JobOrderHandlerInterface.php +++ b/src/Service/JobOrderHandlerInterface.php @@ -25,7 +25,7 @@ interface JobOrderHandlerInterface public function generateJobOrder(Request $req, int $id); // process one step job order - //public function processOneStepJobOrder(Request $req, int $id, MQTTClient $mclient); + public function processOneStepJobOrder(Request $req, int $id); // dispatch job order public function dispatchJobOrder(Request $req, int $id, MQTTClient $mclient); diff --git a/src/Service/RiderAPIHandler/CMBRiderAPIHandler.php b/src/Service/RiderAPIHandler/CMBRiderAPIHandler.php index 282f6bb6..3c0236e1 100644 --- a/src/Service/RiderAPIHandler/CMBRiderAPIHandler.php +++ b/src/Service/RiderAPIHandler/CMBRiderAPIHandler.php @@ -7,13 +7,12 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; use App\Ramcar\CMBServiceType; -use App\Ramcar\TradeInType; +use App\Ramcar\CMBTradeInType; use App\Ramcar\JOStatus; -use App\Ramcar\CMBJOEventType; +use App\Ramcar\JOEventType; use App\Ramcar\InvoiceStatus; -use App\Ramcar\CMBModeOfPayment; +use App\Ramcar\ModeOfPayment; use App\Ramcar\InvoiceCriteria; -use App\Ramcar\CMBCancelReason; use App\Service\RiderAPIHandlerInterface; use App\Service\RedisClientProvider; @@ -22,7 +21,6 @@ use App\Service\MQTTClient; use App\Service\WarrantyHandler; use App\Service\JobOrderHandlerInterface; use App\Service\InvoiceGeneratorInterface; -use App\Service\RiderTracker; use App\Entity\RiderSession; use App\Entity\Rider; @@ -32,16 +30,12 @@ use App\Entity\Promo; use App\Entity\Battery; use App\Entity\BatteryModel; use App\Entity\BatterySize; -use App\Entity\JobOrder; -use App\Entity\JOExtra; +use App\Entity\Warranty; use DateTime; -use DateInterval; class CMBRiderAPIHandler implements RiderAPIHandlerInterface { - // NOTE: Rider's constructor sets flag_available and flag_active to true, by default. - protected $em; protected $redis; protected $ef; @@ -52,14 +46,12 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface protected $jo_handler; protected $ic; protected $session; - protected $upload_dir; public function __construct(EntityManagerInterface $em, RedisClientProvider $redis, EncoderFactoryInterface $ef, RiderCache $rcache, string $country_code, MQTTClient $mclient, WarrantyHandler $wh, JobOrderHandlerInterface $jo_handler, - InvoiceGeneratorInterface $ic, string $upload_dir, - RiderTracker $rider_tracker) + InvoiceGeneratorInterface $ic) { $this->em = $em; $this->redis = $redis; @@ -70,8 +62,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $this->wh = $wh; $this->jo_handler = $jo_handler; $this->ic = $ic; - $this->upload_dir = $upload_dir; - $this->rider_tracker = $rider_tracker; // one device = one session, since we have control over the devices // when a rider logs in, we just change the rider assigned to the device @@ -92,16 +82,11 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface { $params = implode(', ', $missing); $data = [ - 'title' => 'Failed Registration', 'error' => 'Missing parameter(s): ' . $params ]; return $data; } - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - // retry until we get a unique id while (true) { @@ -158,16 +143,12 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface ]; $data = $this->checkParamsAndKey($req, $required_params); if (isset($data['error'])) - { - $data['title'] = 'Failed Login'; return $data; - } // check if session has a rider already if ($this->session->hasRider()) { $data = [ - 'title' => 'Failed Login', 'error' => 'Another rider is already logged in. Please logout first.' ]; return $data; @@ -178,7 +159,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface if ($rider == null) { $data = [ - 'title' => 'Failed Login', 'error' => 'Invalid username or password.' ]; return $data; @@ -189,21 +169,15 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface if (!$encoder->isPasswordValid($rider->getPassword(), $req->request->get('pass'), '')) { $data = [ - 'title' => 'Failed Login', 'error' => 'Invalid username or password.' ]; return $data; } - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - // assign rider to session $this->session->setRider($rider); - //$rider->setAvailable(true); - $rider->setActive(true); + $rider->setAvailable(true); $rider_id = $rider->getID(); // cache rider location (default to hub) @@ -251,31 +225,11 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $required_params = []; $data = $this->checkParamsAndKey($req, $required_params); if (isset($data['error'])) - { - $data['title'] = 'Failed Logout'; return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); // make rider unavailable $rider = $this->session->getRider(); - - // check if rider has assigned JOs - $assigned_jos = $this->em->getRepository(JobOrder::class)->findBy(['rider' => $rider->getID(), 'status' => JOStatus::ASSIGNED]); - if ($assigned_jos != null) - { - $data = [ - 'title' => 'Failed Logout', - 'error' => 'Rider has assigned job orders.' - ]; - return $data; - } - $rider->setAvailable(false); - $rider->setActive(false); // remove from cache $this->rcache->removeActiveRider($rider->getID()); @@ -290,473 +244,45 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface return $data; } - public function goOnline(Request $req) + public function getJobOrder(Request $req) { + // get the job order of the rider assigned to this session $required_params = []; $data = $this->checkParamsAndKey($req, $required_params); if (isset($data['error'])) - { - $data['title'] = 'Failed Go Online'; return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - // set rider to available to take on JOs - $rider = $this->session->getRider(); - - $rider->setAvailable(true); - - $this->em->flush(); - - // send mqtt event to put rider on map - // get rider coordinates from redis - $coord = $this->rider_tracker->getRiderLocation($rider->getID()); - - $lng = $coord->getLongitude(); - $lat = $coord->getLatitude();; - $channel = 'rider/' . $rider->getID() . '/availability'; - $payload = [ - 'status' => 'rider_online', - 'longitude' => $lng, - 'latitude' => $lat, - ]; - $this->mclient->publish($channel, json_encode($payload)); - - return $data; - } - - public function goOffline(Request $req) - { - $required_params = []; - $data = $this->checkParamsAndKey($req, $required_params); - if (isset($data['error'])) - { - $data['title'] = 'Failed Go Offline'; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - // set rider to unavailable to take on JOs - $rider = $this->session->getRider(); - - // check if rider has assigned JOs - $assigned_jos = $this->em->getRepository(JobOrder::class)->findBy(['rider' => $rider->getID(), 'status' => JOStatus::ASSIGNED]); - if ($assigned_jos != null) - { - $data = [ - 'title' => 'Failed Go Offline', - 'error' => 'Rider has assigned job orders.' - ]; - return $data; - } - - $rider->setAvailable(false); - - $this->em->flush(); - - // send mqtt event to remove rider from map - $channel = 'rider/' . $rider->getID() . '/availability'; - $payload = [ - 'status' => 'rider_offline' - ]; - $this->mclient->publish($channel, json_encode($payload)); - - return $data; - - } - - public function getJobOrderHistory(Request $req, $period) - { - $required_params = []; - $data = $this->checkParamsAndKey($req, $required_params); - if (isset($data['error'])) - { - $data['title'] = 'Failed Get Job Order History'; - return $data; - } // are we logged in? if (!$this->session->hasRider()) { $data = [ - 'title' => 'Failed Get Job Order History', 'error' => 'No logged in rider.' ]; return $data; } - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - $rider = $this->session->getRider(); - // get JOs assigned to rider for the month given - // setup start date and end dates - // get current year - $current_date = new DateTime(); - - if ($period == 'lastmonth') + // do we have a job order? + $jo = $rider->getActiveJobOrder(); + if ($jo == null) { - $date_interval = new DateInterval('P1M'); - $period_date = $current_date->sub($date_interval); + $data = [ + 'job_order' => null + ]; } else - $period_date = $current_date; - - $period_year = $period_date->format('Y'); - $period_month = $period_date->format('m'); - - // get number of days in month requested - $last_day = cal_days_in_month(CAL_GREGORIAN, $period_month, $period_year); - - $s_date = $period_year . '-' . $period_month . '-01 00:00:00'; - $e_date = $period_year . '-' . $period_month . '-' . $last_day . ' 23:59:59'; - - $qb = $this->em->getRepository(JobOrder::class)->createQueryBuilder('j'); - - $query = $qb->innerJoin('j.rider', 'r') - ->where('j.date_schedule >= :start') - ->andWhere('j.date_schedule <= :end') - ->andWhere('r.id = :rider_id') - ->setParameter('start', $s_date) - ->setParameter('end', $e_date) - ->setParameter('rider_id', $rider->getID()) - ->getQuery(); - - $jo_results = $query->getResult(); - - $jo_data = []; - - if (!(empty($jo_results))) { - foreach ($jo_results as $jo) - { - // TODO: refactor this to call formatJobOrderData - $coord = $jo->getCoordinates(); - $cust = $jo->getCustomer(); - $cv = $jo->getCustomerVehicle(); - $v = $cv->getVehicle(); - $inv = $jo->getInvoice(); - $promo = $inv->getPromo(); + $coord = $jo->getCoordinates(); + $cust = $jo->getCustomer(); + $cv = $jo->getCustomerVehicle(); + $v = $cv->getVehicle(); + $inv = $jo->getInvoice(); + $promo = $inv->getPromo(); - // invoice items - $inv_items = []; - foreach ($inv->getItems() as $item) - { - // if more than 1, split it into one of each of the same item - $item_qty = $item->getQuantity(); - for ($i = 0; $i < $item_qty; $i++) - { - $item_batt = $item->getBattery(); - if ($item_batt == null) - $batt_id = null; - else - $batt_id = $item_batt->getID(); - - $inv_items[] = [ - 'id' => $item->getID(), - 'title' => $item->getTitle(), - 'qty' => 1, - 'price' => $item->getPrice(), - 'batt_id' => $batt_id, - ]; - } - } - - // promo - if ($promo != null) - { - $promo_data = [ - 'id' => $promo->getID(), - 'name' => $promo->getName(), - 'code' => $promo->getCode(), - 'discount_rate' => $promo->getDiscountRate(), - 'discount_apply' => $promo->getDiscountApply(), - ]; - } - else - { - $promo_data = null; - } - - $trade_in_type = $jo->getTradeInType(); - if (empty($trade_in_type)) - $trade_in_type = 'none'; - - // get time when JO was accepted by rider - $accept_event_type = CMBJOEventType::RIDER_ACCEPT; - $rider_id = $this->session->getRider()->getID(); - $jo_id = $jo->getID(); - $date_accept = ''; - - $accept_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $accept_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); - if ($accept_results != null) - { - $jo_event = current($accept_results); - $date_accept = $jo_event->getDateHappen()->format('Ymd H:i:s'); - } - - // get time when JO was started by rider - $start_event_type = CMBJOEventType::RIDER_START; - $date_start = ''; - $start_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $start_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); - if ($start_results != null) - { - $jo_event = current($start_results); - $date_start = $jo_event->getDateHappen()->format('Ymd H:i:s'); - } - - // get time when JO was completed by rider - $complete_event_type = CMBJOEventType::RIDER_FINISH; - $date_complete = ''; - $complete_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $complete_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); - if ($complete_results != null) - { - $jo_event = current($complete_results); - $date_complete = $jo_event->getDateHappen()->format('Ymd H:i:s'); - } - else - { - // find the time when photos were uploaded - $upload_event_type = CMBJOEventType::RIDER_UPLOAD_PHOTO; - $upload_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $upload_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); - if ($upload_results != null) - { - $jo_event = current($upload_results); - $date_complete = $jo_event->getDateHappen()->format('Ymd H:i:s'); - } - } - - $jo_data[] = [ - 'job_order' => [ - 'id' => $jo->getID(), - 'service_type' => $jo->getServiceType(), - 'date_schedule' => $jo->getDateSchedule()->format('Ymd H:i:s'), - 'longitude' => $coord->getLongitude(), - 'latitude' => $coord->getLatitude(), - 'status' => $jo->getStatus(), - 'customer' => [ - 'title' => $cust->getTitle(), - 'first_name' => $cust->getFirstName(), - 'last_name' => $cust->getLastName(), - 'phone_mobile' => $this->country_code . $cust->getPhoneMobile(), - 'phone_landline' => $this->country_code . $cust->getPhoneLandline(), - ], - 'vehicle' => [ - 'manufacturer' => $v->getManufacturer()->getName(), - 'make' => $v->getMake(), - 'model' => $cv->getModelYear(), - 'plate_number' => $cv->getPlateNumber(), - 'color' => $cv->getColor(), - ], - 'or_num' => $jo->getORNum(), - 'or_name' => $jo->getORName(), - 'delivery_instructions' => $jo->getDeliveryInstructions(), - 'delivery_address' => $jo->getDeliveryAddress(), - 'landmark' => $jo->getLandmark(), - 'invoice' => [ - 'discount' => $inv->getDiscount(), - 'trade_in' => $inv->getTradeIn(), - 'total_price' => $inv->getTotalPrice(), - 'vat' => $inv->getVat(), - 'items' => $inv_items, - ], - 'mode_of_payment' => $jo->getModeOfPayment(), - 'mode_of_payment_display' => CMBModeOfPayment::getName($jo->getModeOfPayment()), - 'trade_in_type' => $trade_in_type, - 'promo' => $promo_data, - // TODO: load the actual - 'has_warranty_doc' => false, - 'flag_coolant' => $jo->hasCoolant(), - 'has_motolite' => $cv->hasMotoliteBattery(), - // date and time accepted and started - 'date_accept' => $date_accept, - 'date_start' => $date_start, - 'date_complete' => $date_complete, - ] - ]; - } - } - - $data = [ - 'jo_history' => $jo_data, - ]; - - return $data; - } - - public function getAssignedJobOrders(Request $req) - { - $required_params = []; - $data = $this->checkParamsAndKey($req, $required_params); - if (isset($data['error'])) - { - $data['title'] = 'Failed Get Assigned Job Orders'; - return $data; - } - - // are we logged in? - if (!$this->session->hasRider()) - { - $data = [ - 'title' => 'Failed Get Assigned Job Orders', - 'error' => 'No logged in rider.' - ]; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - $rider = $this->session->getRider(); - - $qb = $this->em->getRepository(JobOrder::class)->createQueryBuilder('j'); - - $query = $qb->innerJoin('j.rider', 'r') - ->andWhere('r.id = :rider_id') - ->andWhere('j.status = :status') - ->setParameter('rider_id', $rider->getID()) - ->setParameter('status', JOStatus::ASSIGNED) - ->getQuery(); - - $jo_results = $query->getResult(); - - $jo_data = []; - - if (!(empty($jo_results))) - { - foreach ($jo_results as $jo) - { - // TODO: refactor this to call formatJobOrderData - $coord = $jo->getCoordinates(); - $cust = $jo->getCustomer(); - $cv = $jo->getCustomerVehicle(); - $v = $cv->getVehicle(); - $inv = $jo->getInvoice(); - $promo = $inv->getPromo(); - - // invoice items - $inv_items = []; - foreach ($inv->getItems() as $item) - { - // if more than 1, split it into one of each of the same item - $item_qty = $item->getQuantity(); - for ($i = 0; $i < $item_qty; $i++) - { - $item_batt = $item->getBattery(); - if ($item_batt == null) - $batt_id = null; - else - $batt_id = $item_batt->getID(); - - $inv_items[] = [ - 'id' => $item->getID(), - 'title' => $item->getTitle(), - 'qty' => 1, - 'price' => $item->getPrice(), - 'batt_id' => $batt_id, - ]; - } - } - - // promo - if ($promo != null) - { - $promo_data = [ - 'id' => $promo->getID(), - 'name' => $promo->getName(), - 'code' => $promo->getCode(), - 'discount_rate' => $promo->getDiscountRate(), - 'discount_apply' => $promo->getDiscountApply(), - ]; - } - else - { - $promo_data = null; - } - - $trade_in_type = $jo->getTradeInType(); - if (empty($trade_in_type)) - $trade_in_type = 'none'; - - $jo_data[] = [ - 'job_order' => [ - 'id' => $jo->getID(), - 'service_type' => $jo->getServiceType(), - 'date_schedule' => $jo->getDateSchedule()->format('Ymd H:i:s'), - 'longitude' => $coord->getLongitude(), - 'latitude' => $coord->getLatitude(), - 'status' => $jo->getStatus(), - 'customer' => [ - 'title' => $cust->getTitle(), - 'first_name' => $cust->getFirstName(), - 'last_name' => $cust->getLastName(), - 'phone_mobile' => $this->country_code . $cust->getPhoneMobile(), - 'phone_landline' => $this->country_code . $cust->getPhoneLandline(), - ], - 'vehicle' => [ - 'manufacturer' => $v->getManufacturer()->getName(), - 'make' => $v->getMake(), - 'model' => $cv->getModelYear(), - 'plate_number' => $cv->getPlateNumber(), - 'color' => $cv->getColor(), - ], - 'or_num' => $jo->getORNum(), - 'or_name' => $jo->getORName(), - 'delivery_instructions' => $jo->getDeliveryInstructions(), - 'delivery_address' => $jo->getDeliveryAddress(), - 'landmark' => $jo->getLandmark(), - 'invoice' => [ - 'discount' => $inv->getDiscount(), - 'trade_in' => $inv->getTradeIn(), - 'total_price' => $inv->getTotalPrice(), - 'vat' => $inv->getVat(), - 'items' => $inv_items, - ], - 'mode_of_payment' => $jo->getModeOfPayment(), - 'mode_of_payment_display' => CMBModeOfPayment::getName($jo->getModeOfPayment()), - 'trade_in_type' => $trade_in_type, - 'promo' => $promo_data, - // TODO: load the actual - 'has_warranty_doc' => false, - 'flag_coolant' => $jo->hasCoolant(), - 'has_motolite' => $cv->hasMotoliteBattery(), - ] - ]; - } - } - - $data = [ - 'assigned_jos' => $jo_data, - ]; - - return $data; - } - - protected function formatJobOrderData($req, $jo) - { - $coord = $jo->getCoordinates(); - $cust = $jo->getCustomer(); - $cv = $jo->getCustomerVehicle(); - $v = $cv->getVehicle(); - $inv = $jo->getInvoice(); - $promo = $inv->getPromo(); - - // invoice items - $inv_items = []; - foreach ($inv->getItems() as $item) - { - // if more than 1, split it into one of each of the same item - $item_qty = $item->getQuantity(); - for ($i = 0; $i < $item_qty; $i++) + // invoice items + $inv_items = []; + foreach ($inv->getItems() as $item) { $item_batt = $item->getBattery(); if ($item_batt == null) @@ -764,258 +290,90 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface else $batt_id = $item_batt->getID(); - $inv_items[] = [ + $inv_items[] = [ 'id' => $item->getID(), 'title' => $item->getTitle(), - 'qty' => 1, + 'qty' => $item->getQuantity(), 'price' => $item->getPrice(), 'batt_id' => $batt_id, ]; } - } - // promo - if ($promo != null) - { - $promo_data = [ - 'id' => $promo->getID(), - 'name' => $promo->getName(), - 'code' => $promo->getCode(), - 'discount_rate' => $promo->getDiscountRate(), - 'discount_apply' => $promo->getDiscountApply(), + // promo + if ($promo != null) + { + $promo_data = [ + 'id' => $promo->getID(), + 'name' => $promo->getName(), + 'code' => $promo->getCode(), + 'discount_rate' => $promo->getDiscountRate(), + 'discount_apply' => $promo->getDiscountApply(), + ]; + } + else + { + $promo_data = null; + } + + $trade_in_type = $jo->getTradeInType(); + if (empty($trade_in_type)) + $trade_in_type = 'none'; + + $data = [ + 'job_order' => [ + 'id' => $jo->getID(), + 'service_type' => $jo->getServiceType(), + 'date_schedule' => $jo->getDateSchedule()->format('Ymd H:i:s'), + 'longitude' => $coord->getLongitude(), + 'latitude' => $coord->getLatitude(), + 'status' => $jo->getStatus(), + 'customer' => [ + 'title' => $cust->getTitle(), + 'first_name' => $cust->getFirstName(), + 'last_name' => $cust->getLastName(), + 'phone_mobile' => $this->country_code . $cust->getPhoneMobile(), + ], + 'vehicle' => [ + 'manufacturer' => $v->getManufacturer()->getName(), + 'make' => $v->getMake(), + 'model' => $cv->getModelYear(), + 'plate_number' => $cv->getPlateNumber(), + 'color' => $cv->getColor(), + ], + 'or_num' => $jo->getORNum(), + 'or_name' => $jo->getORName(), + 'delivery_instructions' => $jo->getDeliveryInstructions(), + 'delivery_address' => $jo->getDeliveryAddress(), + 'landmark' => $jo->getLandmark(), + 'invoice' => [ + 'discount' => $inv->getDiscount(), + 'trade_in' => $inv->getTradeIn(), + 'total_price' => $inv->getTotalPrice(), + 'vat' => $inv->getVat(), + 'items' => $inv_items, + ], + 'mode_of_payment' => $jo->getModeOfPayment(), + 'trade_in_type' => $trade_in_type, + 'promo' => $promo_data, + // TODO: load the actual + 'has_warranty_doc' => false, + 'flag_coolant' => $jo->hasCoolant(), + 'has_motolite' => $cv->hasMotoliteBattery(), + ] ]; } - else - { - $promo_data = null; - } - - $trade_in_type = $jo->getTradeInType(); - if (empty($trade_in_type)) - $trade_in_type = 'none'; - - // get date of status last change - if ($jo->getDateStatusChange() == null) - $date_status_change = null; - else - $date_status_change = $jo->getDateStatusChange()->format('Ymd H:i:s'); - - // get odometer reading - $odo = $jo->getMeta('odometer'); - if ($odo <= 0) - $odo = 0; - - $images = [ - 'image_1' => null, - 'image_2' => null, - 'image_3' => null, - 'image_4' => null, - 'others' => [], - ]; - $jo_extra = $jo->getJOExtra(); - if ($jo_extra != null) - { - $images['image_1'] = $this->getURLExtraImage($req, $jo_extra->getImage1Filename()); - $images['image_2'] = $this->getURLExtraImage($req, $jo_extra->getImage2Filename()); - $images['image_3'] = $this->getURLExtraImage($req, $jo_extra->getImage3Filename()); - $images['image_4'] = $this->getURLExtraImage($req, $jo_extra->getImage4Filename()); - - // other images - $other_images = []; - foreach ($jo_extra->getOtherImages() as $others) - { - $other_images[] = $this->getURLExtraImage($req, $others); - } - $images['others'] = $other_images; - } - - // customer email - if ($jo->getMeta('customer_email') == null) - $cust_email = ''; - else - $cust_email = $jo->getMeta('customer_email'); - - // get time when JO was accepted by rider - $accept_event_type = CMBJOEventType::RIDER_ACCEPT; - $rider_id = $this->session->getRider()->getID(); - $jo_id = $jo->getID(); - $date_accept = ''; - - $accept_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $accept_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); - if ($accept_results != null) - { - $jo_event = current($accept_results); - $date_accept = $jo_event->getDateHappen()->format('Ymd H:i:s'); - } - - // get time when JO was started by rider - $start_event_type = CMBJOEventType::RIDER_START; - $date_start = ''; - $start_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $start_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); - if ($start_results != null) - { - $jo_event = current($start_results); - $date_start = $jo_event->getDateHappen()->format('Ymd H:i:s'); - } - - // get time when JO was completed by rider - $complete_event_type = CMBJOEventType::RIDER_FINISH; - $date_complete = ''; - $complete_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $complete_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); - if ($complete_results != null) - { - $jo_event = current($complete_results); - $date_complete = $jo_event->getDateHappen()->format('Ymd H:i:s'); - } - else - { - // find the time when photos were uploaded - $upload_event_type = CMBJOEventType::RIDER_UPLOAD_PHOTO; - $upload_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $upload_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); - if ($upload_results != null) - { - $jo_event = current($upload_results); - $date_complete = $jo_event->getDateHappen()->format('Ymd H:i:s'); - } - } - - $data = [ - 'id' => $jo->getID(), - 'service_type' => $jo->getServiceType(), - 'date_schedule' => $jo->getDateSchedule()->format('Ymd H:i:s'), - 'longitude' => $coord->getLongitude(), - 'latitude' => $coord->getLatitude(), - 'status' => $jo->getStatus(), - 'date_status_change' => $date_status_change, - 'customer' => [ - 'title' => $cust->getTitle(), - 'first_name' => $cust->getFirstName(), - 'last_name' => $cust->getLastName(), - 'phone_mobile' => $this->country_code . $cust->getPhoneMobile(), - 'phone_landline' => $this->country_code . $cust->getPhoneLandline(), - ], - 'vehicle' => [ - 'manufacturer' => $v->getManufacturer()->getName(), - 'make' => $v->getMake(), - 'model' => $cv->getModelYear(), - 'plate_number' => $cv->getPlateNumber(), - 'color' => $cv->getColor(), - ], - 'or_num' => $jo->getORNum(), - 'or_name' => $jo->getORName(), - 'delivery_instructions' => $jo->getDeliveryInstructions(), - 'delivery_address' => $jo->getDeliveryAddress(), - 'landmark' => $jo->getLandmark(), - 'invoice' => [ - 'discount' => $inv->getDiscount(), - 'trade_in' => $inv->getTradeIn(), - 'total_price' => $inv->getTotalPrice(), - 'vat' => $inv->getVat(), - 'items' => $inv_items, - ], - 'mode_of_payment' => $jo->getModeOfPayment(), - 'mode_of_payment_display' => CMBModeOfPayment::getName($jo->getModeOfPayment()), - 'trade_in_type' => $trade_in_type, - 'promo' => $promo_data, - // TODO: load the actual - 'has_warranty_doc' => false, - 'flag_coolant' => $jo->hasCoolant(), - 'has_motolite' => $cv->hasMotoliteBattery(), - - // BEGIN: cmb specific details - - // odometer - 'odometer' => $odo, - - // images - 'finish_photos' => $images, - - // customer email - 'customer_email' => $cust_email, - - // date and time accepted and started - 'date_accept' => $date_accept, - 'date_start' => $date_start, - 'date_complete' => $date_complete, - - // END: cmb specific details - ]; - - return $data; - } - - public function getJobOrder(Request $req) - { - $required_params = [ - 'jo_id' - ]; - $data = $this->checkJO($req, $required_params, $jo); - if (isset($data['error'])) - { - $data['title'] = 'Failed Get Job Order'; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - $jo_data = $this->formatJobOrderData($req, $jo); - - $data = [ - 'job_order' => $jo_data - ]; return $data; } public function acceptJobOrder(Request $req) { - $required_params = [ - 'jo_id' - ]; + $required_params = ['jo_id']; $data = $this->checkJO($req, $required_params, $jo); if (isset($data['error'])) - { - $data['title'] = 'Failed Accept Job Order'; return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - // TODO: put JO in job queue // TODO: refactor this into a jo handler class, so we don't have to repeat for control center - // TODO: send mqtt event (?) - // add event log - $rider = $this->session->getRider(); - $event = new JOEvent(); - $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::RIDER_ACCEPT) - ->setJobOrder($jo) - ->setRider($rider); - $this->em->persist($event); - - $this->em->flush(); - - return $data; - } - - public function setJobOrderInTransit(Request $req) - { - $required_params = ['jo_id']; - $data = $this->checkActiveJO($req, $required_params, $jo); - if (isset($data['error'])) - { - $data['title'] = 'Failed Set Job Order in Transit'; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); // set jo status to in transit $jo->setStatus(JOStatus::IN_TRANSIT); @@ -1026,7 +384,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $rider = $this->session->getRider(); $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::RIDER_IN_TRANSIT) + ->setTypeID(JOEventType::RIDER_ACCEPT) ->setJobOrder($jo) ->setRider($rider); $this->em->persist($event); @@ -1034,110 +392,28 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $this->em->flush(); return $data; - } public function cancelJobOrder(Request $req) { - $required_params = [ - 'jo_id', - 'cancel_reason' - ]; + $required_params = ['jo_id']; $data = $this->checkJO($req, $required_params, $jo); if (isset($data['error'])) - { - $data['title'] = 'Failed Job Order Cancellation'; return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - $cancel_reason = $req->request->get('cancel_reason'); - - $jo->cancel($cancel_reason); - - // add event log - $rider = $this->session->getRider(); - $event = new JOEvent(); - $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::REQUEUE) - ->setJobOrder($jo) - ->setRider($rider); - $this->em->persist($event); - - $this->em->flush(); - - return $data; - } - - public function performJobOrder(Request $req) - { - $required_params = [ - 'jo_id', - ]; - - $data = $this->checkJO($req, $required_params, $jo); - if (isset($data['error'])) - { - $data['title'] = 'Failed Job Order Perform'; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - $jo->perform(); - - // add event log - $rider = $this->session->getRider(); - $event = new JOEvent(); - $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::PERFORM) - ->setJobOrder($jo) - ->setRider($rider); - $this->em->persist($event); - - $this->em->flush(); - - return $data; - } - - public function rejectJobOrder(Request $req) - { - $required_params = [ - 'jo_id' - ]; - $data = $this->checkJO($req, $required_params, $jo); - if (isset($data['error'])) - { - $data['title'] = 'Failed Job Order Rejection'; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); + // $jo->cancel("rider cancelled"); + // requeue it, instead of cancelling it $jo->requeue(); - // set rider to null - $jo->clearRider(); - // add event log $rider = $this->session->getRider(); $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::REQUEUE) + ->setTypeID(JOEventType::REQUEUE) ->setJobOrder($jo) ->setRider($rider); $this->em->persist($event); - // set rider's active JO to null - $rider->setActiveJobOrder(); - $this->em->flush(); // send mqtt event @@ -1148,28 +424,15 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface ]; $this->mclient->sendEvent($jo, $payload); - // send available event to change rider icon status - $channel = 'rider/' . $rider->getID() . '/status'; - $rider_status = 'available'; - - $this->mclient->publish($channel, $rider_status); - return $data; } public function arrive(Request $req) { $required_params = ['jo_id']; - $data = $this->checkActiveJO($req, $required_params, $jo); + $data = $this->checkJO($req, $required_params, $jo); if (isset($data['error'])) - { - $data['title'] = 'Failed Arrive'; return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); // TODO: refactor this into a jo handler class, so we don't have to repeat for control center @@ -1180,7 +443,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $rider = $this->session->getRider(); $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::RIDER_ARRIVE) + ->setTypeID(JOEventType::RIDER_ARRIVE) ->setJobOrder($jo) ->setRider($rider); $this->em->persist($event); @@ -1221,9 +484,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface return $data; } - // tag rider as available - $rider = $this->session->getRider(); - $rider->setAvailable(true); + // TODO: tag rider as available $this->em->flush(); @@ -1232,43 +493,91 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface public function payment(Request $req) { - $required_params = [ - 'jo_id', - 'mode_of_payment', - ]; - $data = $this->checkActiveJO($req, $required_params, $jo); + $required_params = ['jo_id']; + $data = $this->checkJO($req, $required_params, $jo); if (isset($data['error'])) - { - $data['title'] = 'Failed Payment'; return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - // add mode of payment - $mode = $req->request->get('mode_of_payment'); - $jo->setModeOfPayment($mode); - - // set status to paid - $jo->setStatus(JOStatus::PAID); - // set invoice to paid $jo->getInvoice()->setStatus(InvoiceStatus::PAID); + /* + // set jo status to fulfilled + $jo->setStatus(JOStatus::FULFILLED); + */ + $jo->fulfill(); + // add event log $rider = $this->session->getRider(); $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::PAID) + ->setTypeID(JOEventType::FULFILL) ->setJobOrder($jo) ->setRider($rider); $this->em->persist($event); + // TODO: tag rider as unavailable + + // save to customer vehicle battery record + $this->jo_handler->updateVehicleBattery($jo); + $this->em->flush(); + // create warranty + if($this->jo_handler->checkIfNewBattery($jo)) + { + $serial = $jo->getCustomerVehicle()->getWarrantyCode(); + $warranty_class = $jo->getWarrantyClass(); + $first_name = $jo->getCustomer()->getFirstName(); + $last_name = $jo->getCustomer()->getLastName(); + $mobile_number = $jo->getCustomer()->getPhoneMobile(); + + // check if date fulfilled is null + if ($jo->getDateFulfill() == null) + $date_purchase = $jo->getDateCreate(); + else + $date_purchase = $jo->getDateFulfill(); + + // validate plate number + // $plate_number = $this->wh->cleanPlateNumber($jo->getCustomerVehicle()->getPlateNumber()); + $plate_number = Warranty::cleanPlateNumber($jo->getCustomerVehicle()->getPlateNumber()); + if ($plate_number != false) + { + $batt_list = array(); + $invoice = $jo->getInvoice(); + if (!empty($invoice)) + { + // get battery + $invoice_items = $invoice->getItems(); + foreach ($invoice_items as $item) + { + $battery = $item->getBattery(); + if ($battery != null) + { + $batt_list[] = $item->getBattery(); + } + } + } + + $this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class); + } + } + + // send mqtt event (fulfilled) + $rider = $this->session->getRider(); + $image_url = $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/assets/images/user.gif'; + if ($rider->getImageFile() != null) + $image_url = $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/uploads/' . $rider->getImageFile(); + + $payload = [ + 'event' => 'fulfilled', + 'jo_id' => $jo->getID(), + 'driver_image' => $image_url, + 'driver_name' => $rider->getFullName(), + 'driver_id' => $rider->getID(), + ]; + $this->mclient->sendEvent($jo, $payload); + return $data; } @@ -1277,10 +586,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $required_params = []; $data = $this->checkParamsAndKey($req, $required_params); if (isset($data['error'])) - { - $data['title'] = 'Failed Available Rider'; return $data; - } // make rider available $this->session->getRider()->setAvailable(true); @@ -1296,10 +602,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $required_params = []; $data = $this->checkParamsAndKey($req, $required_params); if (isset($data['error'])) - { - $data['title'] = 'Failed Get Promos'; return $data; - } $promos = $this->em->getRepository(Promo::class)->findAll(); @@ -1326,10 +629,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $required_params = []; $data = $this->checkParamsAndKey($req, $required_params); if (isset($data['error'])) - { - $data['title'] = 'Failed Get Batteries'; return $data; - } $batts = $this->em->getRepository(Battery::class)->findAll(); $models = $this->em->getRepository(BatteryModel::class)->findAll(); @@ -1378,21 +678,17 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $this->debugRequest($req); // allow rider to change service, promo, battery and trade-in options - $required_params = ['jo_id', 'service_type', 'promo_id']; + $required_params = ['jo_id', 'stype_id', 'promo_id']; $data = $this->checkJO($req, $required_params, $jo); if (isset($data['error'])) - { - $data['title'] = 'Failed Service Change'; return $data; - } // check service type - $service_type = $req->request->get('service_type'); - if (!CMBServiceType::validate($service_type)) + $stype_id = $req->request->get('stype_id'); + if (!CMBServiceType::validate($stype_id)) { $data = [ - 'title' => 'Failed Service Change', - 'error' => 'Invalid service type - ' . $service_type + 'error' => 'Invalid service type - ' . $stype_id ]; return $data; } @@ -1408,7 +704,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface if ($promo == null) { $data = [ - 'title' => 'Failed Service Change', 'error' => 'Invalid promo id - ' . $promo_id ]; return $data; @@ -1447,7 +742,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface if ($battery == null) { $data = [ - 'title' => 'Failed Service Change', 'error' => 'Invalid battery id - ' . $batt_id ]; return $data; @@ -1456,19 +750,18 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface // check trade in $trade_in = $req->request->get('trade_in'); - if (!TradeInType::validate($trade_in)) + if (!CMBTradeInType::validate($trade_in)) $trade_in = null; // check mode of payment - // TODO: defaulting to credit_card for now if mode of payment is invalid $mode = $req->request->get('mode_of_payment'); - if (!CMBModeOfPayment::validate($mode)) - $mode = CMBModeOfPayment::CASH; + if (!ModeOfPayment::validate($mode)) + $mode = ModeOfPayment::CASH; $jo->setModeOfPayment($mode); // generate new invoice $crit = new InvoiceCriteria(); - $crit->setServiceType($service_type); + $crit->setServiceType($stype_id); $crit->setCustomerVehicle($cv); $crit->setHasCoolant($jo->hasCoolant()); @@ -1489,7 +782,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $this->em->flush(); // save job order - $jo->setServiceType($service_type); + $jo->setServiceType($stype_id); // save invoice $jo->setInvoice($invoice); @@ -1499,7 +792,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $rider = $this->session->getRider(); $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::RIDER_EDIT) + ->setTypeID(JOEventType::RIDER_EDIT) ->setJobOrder($jo) ->setRider($rider); $this->em->persist($event); @@ -1510,680 +803,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface return $data; } - public function generateInvoice(Request $req) - { - $required_params = ['jo_id']; - $data = $this->checkActiveJO($req, $required_params, $jo); - if (isset($data['error'])) - { - $data['title'] = 'Failed Invoice Generation'; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - $inv = $jo->getInvoice(); - $promo = $inv->getPromo(); - - // invoice items - $inv_items = []; - foreach ($inv->getItems() as $item) - { - // if more than 1, split it into one of each of the same item - $item_qty = $item->getQuantity(); - for ($i = 0; $i < $item_qty; $i++) - { - $item_batt = $item->getBattery(); - if ($item_batt == null) - $batt_id = null; - else - $batt_id = $item_batt->getID(); - - $inv_items[] = [ - 'id' => $item->getID(), - 'title' => $item->getTitle(), - 'qty' => 1, - 'price' => $item->getPrice(), - 'batt_id' => $batt_id, - ]; - } - } - - // promo - if ($promo != null) - { - $promo_data = [ - 'id' => $promo->getID(), - 'name' => $promo->getName(), - 'code' => $promo->getCode(), - 'discount_rate' => $promo->getDiscountRate(), - 'discount_apply' => $promo->getDiscountApply(), - ]; - } - else - { - $promo_data = null; - } - - $trade_in_type = $jo->getTradeInType(); - if (empty($trade_in_type)) - $trade_in_type = 'none'; - - $data = [ - 'invoice' => [ - 'id' => $inv->getID(), - 'discount' => $inv->getDiscount(), - 'trade_in' => $inv->getTradeIn(), - 'total_price' => $inv->getTotalPrice(), - 'vat' => $inv->getVat(), - 'items' => $inv_items, - 'trade_in_type' => $trade_in_type, - 'promo' => $promo_data, - ] - ]; - - return $data; - } - - public function startJobOrder(Request $req) - { - $required_params = ['jo_id']; - $data = $this->checkActiveJO($req, $required_params, $jo); - if (isset($data['error'])) - { - $data['title'] = 'Failed Job Order Start'; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - // set jo status to in progress - $jo->setStatus(JOStatus::IN_PROGRESS); - - // add event log - $rider = $this->session->getRider(); - $event = new JOEvent(); - $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::RIDER_START) - ->setJobOrder($jo) - ->setRider($rider); - $this->em->persist($event); - - $this->em->flush(); - - return $data; - } - - public function completeJobOrder(Request $req) - { - $required_params = ['jo_id']; - $data = $this->checkActiveJO($req, $required_params, $jo); - if (isset($data['error'])) - { - $data['title'] = 'Failed Job Order Completion'; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - // set customer signature - $jo_extra = $jo->getJOExtra(); - $sig_file = $this->handleFileUpload($req, 'signature'); - if ($sig_file) - $jo_extra->setCustomerSignature($sig_file); - - // set email - $cust_email = $req->request->get('customer_email', ''); - $jo->addMeta('customer_email', $cust_email); - - - /* - // set jo status to fulfilled - $jo->setStatus(JOStatus::FULFILLED); - */ - //$jo->fulfill(); - $jo->setStatus(JOStatus::FULFILLED) - ->setDateFulfill(new DateTime()); - - // add event log - $rider = $this->session->getRider(); - $event = new JOEvent(); - $event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::FULFILL) - ->setJobOrder($jo) - ->setRider($rider); - $this->em->persist($event); - - $rider_event = new JOEvent(); - $rider_event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::RIDER_FINISH) - ->setJobOrder($jo) - ->setRider($rider); - $this->em->persist($rider_event); - - // save to customer vehicle battery record - $this->jo_handler->updateVehicleBattery($jo); - - $this->em->flush(); - - // create warranty - if($this->jo_handler->checkIfNewBattery($jo)) - { - $serial = null; - $warranty_class = $jo->getWarrantyClass(); - $first_name = $jo->getCustomer()->getFirstName(); - $last_name = $jo->getCustomer()->getLastName(); - $mobile_number = $jo->getCustomer()->getPhoneMobile(); - - // check if date fulfilled is null - //if ($jo->getDateFulfill() == null) - // $date_purchase = $jo->getDateCreate(); - //else - // $date_purchase = $jo->getDateFulfill(); - - // use date_schedule for warranty expiration computation - $date_purchase = $jo->getDateSchedule(); - - $plate_number = $this->wh->cleanPlateNumber($jo->getCustomerVehicle()->getPlateNumber()); - - $batt_list = array(); - $invoice = $jo->getInvoice(); - if (!empty($invoice)) - { - // get battery - $invoice_items = $invoice->getItems(); - foreach ($invoice_items as $item) - { - $battery = $item->getBattery(); - if ($battery != null) - { - $batt_list[] = $item->getBattery(); - } - } - } - - $this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class); - } - - // TODO: Need to verify if needed. - // send mqtt event (fulfilled) - $image_url = $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/assets/images/user.gif'; - if ($rider->getImageFile() != null) - $image_url = $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/uploads/' . $rider->getImageFile(); - - $payload = [ - 'event' => 'fulfilled', - 'jo_id' => $jo->getID(), - 'driver_image' => $image_url, - 'driver_name' => $rider->getFullName(), - 'driver_id' => $rider->getID(), - ]; - $this->mclient->sendEvent($jo, $payload); - - return $data; - } - - public function setActiveJobOrder(Request $req) - { - $required_params = [ - 'jo_id' - ]; - $data = $this->checkJO($req, $required_params, $jo); - if (isset($data['error'])) - { - $data['title'] = 'Failed Set Active Job Order'; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - $rider = $this->session->getRider(); - $rider->setActiveJobOrder($jo); - - $this->em->persist($rider); - $this->em->flush(); - - return $data; - } - - public function setOdometer(Request $req) - { - $required_params = [ - 'jo_id', - 'odometer' - ]; - $data = $this->checkActiveJO($req, $required_params, $jo); - if (isset($data['error'])) - { - $data['title'] = 'Failed Set Odometer'; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - $odometer_reading = $req->request->get('odometer'); - - if ($odometer_reading > 999999) - { - $data = [ - 'title' => 'Failed Set Odometer', - 'error' => 'Odometer cannot be more than 6 figures.', - ]; - return $data; - } - - $jo->addMeta('odometer', $odometer_reading); - - $this->em->flush(); - - return $data; - } - - protected function handleFileUpload($req, $name) - { - $file = $req->files->get($name); - if (empty($file)) - return false; - - $orig_filename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME); - - // generate prefix to assure uniqueness - $prefix = uniqid() . '_'; - $new_filename = $prefix . $orig_filename . '.' . $file->guessClientExtension(); - - // move to our upload dir - $dest = $this->upload_dir; - try - { - $file->move($dest, $new_filename); - } - catch (FileException $e) - { - return false; - } - - return $new_filename; - } - - public function uploadFinishPhotos(Request $req) - { - $required_params = [ - 'jo_id', - ]; - $data = $this->checkActiveJO($req, $required_params, $jo); - if (isset($data['error'])) - { - $data['title'] = 'Failed Upload Finish Photos'; - return $data; - } - - $rider = $this->session->getRider(); - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - $dest = $this->upload_dir; - - $img_1_file = $req->files->get('img_1'); - $img_2_file = $req->files->get('img_2'); - $img_3_file = $req->files->get('img_3'); - $img_4_file = $req->files->get('img_4'); - $other_img_files[]= $req->files->get('other_images'); - - if ((empty($img_1_file)) && - (empty($img_2_file)) && - (empty($img_3_file)) && - (empty($img_4_file))) - { - $data = [ - 'title' => 'Failed Upload Arrive Photos', - 'error' => 'No image files received.' - ]; - return $data; - } - else - { - $new_img1_filename = ''; - $new_img2_filename = ''; - $new_img3_filename = ''; - $new_img4_filename = ''; - $other_filenames = []; - - if (!empty($img_1_file)) - { - $orig_img1_filename = pathinfo($img_1_file->getClientOriginalName(), PATHINFO_FILENAME); - $new_img1_filename = uniqid() . '-'. $orig_img1_filename . '.' . $img_1_file->guessClientExtension(); - - try - { - $img_1_file->move($dest, $new_img1_filename); - } - catch (FileException $e) - { - $data = [ - 'error' => 'Error saving image files.' - ]; - return $data; - } - } - if (!empty($img_2_file)) - { - $orig_img2_filename = pathinfo($img_2_file->getClientOriginalName(), PATHINFO_FILENAME); - $new_img2_filename = uniqid() . '-' . $orig_img2_filename . '.' . $img_2_file->guessClientExtension(); - - try - { - $img_2_file->move($dest, $new_img2_filename); - } - catch (FileException $e) - { - $data = [ - 'error' => 'Error saving image files.' - ]; - return $data; - } - } - if (!empty($img_3_file)) - { - $orig_img3_filename = pathinfo($img_3_file->getClientOriginalName(), PATHINFO_FILENAME); - $new_img3_filename = uniqid() . '-' . $orig_img3_filename . '.' . $img_3_file->guessClientExtension(); - - try - { - $img_3_file->move($dest, $new_img3_filename); - } - catch (FileException $e) - { - $data = [ - 'error' => 'Error saving image files.' - ]; - return $data; - } - } - - if (!empty($img_4_file)) - { - $orig_img4_filename = pathinfo($img_4_file->getClientOriginalName(), PATHINFO_FILENAME); - $new_img4_filename = uniqid() . '-' . $orig_img4_filename . '.' . $img_4_file->guessClientExtension(); - - try - { - $img_4_file->move($dest, $new_img4_filename); - } - catch (FileException $e) - { - $data = [ - 'error' => 'Error saving image files.' - ]; - return $data; - } - } - - foreach ($other_img_files as $other_img_file) - { - if (!(empty($other_img_file))) - { - foreach($other_img_file as $other_img) - { - $orig_other_filename = pathinfo($other_img->getClientOriginalName(), PATHINFO_FILENAME); - $new_other_filename = uniqid() . '-'. $orig_other_filename . '.' . $other_img->guessClientExtension(); - - $other_filenames[] = $new_other_filename; - - try - { - $other_img->move($dest, $new_other_filename); - } - catch (FileException $e) - { - $data = [ - 'error' => 'Error saving image files.' - ]; - return $data; - } - } - } - } - - $jo_extra = $jo->getJOExtra(); - if ($jo_extra == null) - { - // create JOExtra entity - $jo_extra = new JOExtra(); - - $jo_extra->setImage1Filename($new_img1_filename); - $jo_extra->setImage2Filename($new_img2_filename); - $jo_extra->setImage3Filename($new_img3_filename); - $jo_extra->setImage4Filename($new_img4_filename); - - if (empty($other_filenames)) - { - $jo_extra->clearOtherImages(); - } - else - { - $jo_extra->setOtherImages($other_filenames); - } - - $jo->setJOExtra($jo_extra); - - $this->em->persist($jo_extra); - } - else - { - $jo_extra->setImage1Filename($new_img1_filename); - $jo_extra->setImage2Filename($new_img2_filename); - $jo_extra->setImage3Filename($new_img3_filename); - $jo_extra->setImage4Filename($new_img4_filename); - - if (empty($other_filenames)) - { - $jo_extra->clearOtherImages(); - } - else - { - $jo_extra->setOtherImages($other_filenames); - } - } - - // create event for upload photo - $rider_event = new JOEvent(); - $rider_event->setDateHappen(new DateTime()) - ->setTypeID(CMBJOEventType::RIDER_UPLOAD_PHOTO) - ->setJobOrder($jo) - ->setRider($rider); - $this->em->persist($rider_event); - - $this->em->flush(); - } - - return $data; - } - - public function getStatus(Request $req) - { - $required_params = []; - $data = $this->checkParamsAndKey($req, $required_params); - if (isset($data['error'])) - { - $data['title'] = 'Failed Get Status'; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - $rider = $this->session->getRider(); - - $rider_status = $rider->isAvailable(); - - $status = 'Offline'; - if ($rider_status) - $status = 'Online'; - - $data = [ - 'status' => $status, - ]; - - return $data; - } - - public function getOngoingJobOrder(Request $req) - { - $required_params = []; - $data = $this->checkParamsAndKey($req, $required_params); - if (isset($data['error'])) - { - $data['title'] = 'Failed Get Ongoing Job Order'; - $data['job_order'] = []; - return $data; - } - - // are we logged in? - if (!$this->session->hasRider()) - { - $data = [ - 'title' => 'Failed Get Ongoing Job Order', - 'error' => 'No logged in rider.', - 'job_order' => null, - ]; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - $rider = $this->session->getRider(); - - // check if we have an active JO - $jo = $rider->getRiderActiveJobOrder(); - if ($jo == null) - { - $data = [ - //'title' => 'Failed Get Ongoing Job Order', - //'error' => 'No active job order.', - 'job_order' => [], - ]; - return $data; - } - - $jo_data = []; - // check if JO status is in_progress, in_transit, performed, paid - switch($jo->getStatus()) - { - case JOStatus::IN_TRANSIT: - case JOStatus::IN_PROGRESS: - case JOStatus::PERFORMED: - case JOStatus::PAID: - $jo_data = $this->formatJobOrderData($req, $jo); - break; - } - - $data = [ - 'job_order' => $jo_data - ]; - - return $data; - } - - public function getPaymentMethods(Request $req) - { - $required_params = []; - $data = $this->checkParamsAndKey($req, $required_params); - if (isset($data['error'])) - { - $data['title'] = 'Failed Get Payment Methods'; - return $data; - } - - $data = [ - 'payment_methods' => CMBModeOfPayment::getCollection(), - ]; - - return $data; - - } - - public function getCancelReasons(Request $req) - { - $required_params = []; - $data = $this->checkParamsAndKey($req, $required_params); - if (isset($data['error'])) - { - $data['title'] = 'Failed Get Cancel Reasons'; - return $data; - } - - $data = [ - 'cancel_reasons' => CMBCancelReason::getCollection(), - ]; - - return $data; - - } - - public function verifyJobOrder(Request $req) - { - $required_params = [ - 'jo_id' - ]; - $data = $this->checkJOForVerify($req, $required_params, $jo); - if (isset($data['error'])) - { - $data['title'] = 'Failed Verify Job Order'; - return $data; - } - - // get longitude and latitude - // TODO: right now, we're just checking if we get the coordinates - $this->getHeaderCoordinates($req); - - $rider = $this->session->getRider(); - // check if rider is assigned to JO - if ($jo->getRider() != null) - { - if ($rider->getID() != $jo->getRider()->getID()) - { - $data = [ - 'assigned' => false, - 'available' => false, - ]; - return $data; - } - } - - // check if JO status is not fulfilled and not cancelled - if (($jo->getStatus() == JOStatus::FULFILLED) || - ($jo->getStatus() == JOStatus::CANCELLED)) - { - $data = [ - 'assigned' => true, - 'available' => false - ]; - return $data; - } - - $data = [ - 'assigned' => true, - 'available' => true, - ]; - - return $data; - } - protected function checkMissingParameters(Request $req, $params = []) { $missing = []; @@ -2261,51 +880,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface return $session; } - protected function checkActiveJO(Request $req, $required_params, &$jo = null) - { - // set jo status to in transit - $data = $this->checkParamsAndKey($req, $required_params); - if (isset($data['error'])) - return $data; - - // are we logged in? - if (!$this->session->hasRider()) - { - $data = [ - 'error' => 'No logged in rider.' - ]; - return $data; - } - - $rider = $this->session->getRider(); - - // check if we have an active JO - $jo = $rider->getRiderActiveJobOrder(); - if ($jo == null) - { - $data = [ - 'error' => 'No active job order.' - ]; - return $data; - } - $jo_id = ''; - if ($req->getMethod() == 'GET') - $jo_id = $req->query->get('jo_id'); - else - $jo_id = $req->request->get('jo_id'); - - // check if the jo_id sent is the same as our active jo - if ($jo_id != $jo->getID()) - { - $data = [ - 'error' => 'Job order selected is not active job order.' - ]; - return $data; - } - - return $data; - } - protected function checkJO(Request $req, $required_params, &$jo = null) { // set jo status to in transit @@ -2324,97 +898,24 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $rider = $this->session->getRider(); - // get jo - $jo_id = ''; - if ($req->getMethod() == 'GET') - $jo_id = $req->query->get('jo_id'); - else - $jo_id = $req->request->get('jo_id'); - - $jo = $this->em->getRepository(JobOrder::class)->find($jo_id); + // check if we have an active JO + $jo = $rider->getActiveJobOrder(); if ($jo == null) { $data = [ - 'error' => 'No job order found.' - ]; - return $data; - - } - - // check if rider assigned to jo is our rider - if ($jo->getRider() == null) - { - $data = [ - 'error' => 'Job order selected has no rider assigned.' + 'error' => 'No active job order.' ]; return $data; } - // check if rider is assigned to JO - if ($rider->getID() != $jo->getRider()->getID()) + // check if the jo_id sent is the same as our active jo + if ($req->request->get('jo_id') != $jo->getID()) { $data = [ - 'error' => 'Job order selected is not assigned to rider' + 'error' => 'Job order selected is not active job order.' ]; return $data; } - - return $data; - } - - protected function checkJOForVerify(Request $req, $required_params, &$jo = null) - { - // set jo status to in transit - $data = $this->checkParamsAndKey($req, $required_params); - if (isset($data['error'])) - return $data; - - // are we logged in? - if (!$this->session->hasRider()) - { - $data = [ - 'error' => 'No logged in rider.' - ]; - return $data; - } - - $rider = $this->session->getRider(); - - // get jo - $jo_id = ''; - if ($req->getMethod() == 'GET') - $jo_id = $req->query->get('jo_id'); - else - $jo_id = $req->request->get('jo_id'); - - $jo = $this->em->getRepository(JobOrder::class)->find($jo_id); - if ($jo == null) - { - $data = [ - 'error' => 'No job order found.' - ]; - return $data; - - } - - // check if rider assigned to jo is our rider - if ($jo->getRider() == null) - { - $data = [ - 'error' => 'Job order selected has no rider assigned.' - ]; - return $data; - } - - /* - // check if rider is assigned to JO - if ($rider->getID() != $jo->getRider()->getID()) - { - $data = [ - 'error' => 'Job order selected is not assigned to rider' - ]; - return $data; - } */ return $data; } @@ -2424,24 +925,4 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $all = $req->request->all(); error_log(print_r($all, true)); } - - protected function getURLExtraImage(Request $req, $filename) - { - // return null if blank filename - if (strlen(trim($filename)) <= 0) - return null; - - return $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/uploads/jo_extra/' . $filename; - } - - protected function getHeaderCoordinates(Request $req) - { - $x_lng = $req->headers->get('x-longitude'); - $x_lat = $req->headers->get('x-latitude'); - - // TODO: this is still unfinished - - //error_log('rider_longitude ' . $x_lng); - //error_log('rider_latitude ' . $x_lat); - } } diff --git a/templates/customer/cmb.form.html.twig b/templates/customer/cmb.form.html.twig index c979b7d7..e417f3bb 100644 --- a/templates/customer/cmb.form.html.twig +++ b/templates/customer/cmb.form.html.twig @@ -663,18 +663,9 @@ // display create vehicle form $("#add-vehicle").click(function() { - // check if there are already 2 vehicles in list - if (vehicleRows.length == 2) - { - swal({ - text: 'Customer is limited to only 2 vehicles..', - type: 'info', - }); - } else { - $("#vehicle-form").data('mode', 'create'); - $("#vehicle-form-title").html("Add Vehicle"); - $("#vehicle-form-modal").modal('show'); - } + $("#vehicle-form").data('mode', 'create'); + $("#vehicle-form-title").html("Add Vehicle"); + $("#vehicle-form-modal").modal('show'); }); // find vehicle row by index diff --git a/templates/home.html.twig b/templates/home.html.twig index 8e5b1760..69cb59c0 100644 --- a/templates/home.html.twig +++ b/templates/home.html.twig @@ -45,7 +45,7 @@ function initMap(r_markers, c_markers, icons) { return dashmap; } -function initEventHandler(dashmap, icons, ssl) { +function initEventHandler(dashmap) { var options = { 'track_jo': true, 'track_rider': true, @@ -54,12 +54,11 @@ function initEventHandler(dashmap, icons, ssl) { 'rider_status': 'rider/+/status', 'jo_location': 'jo/+/location', 'jo_status': 'jo/+/status', - 'jo_origin': 'jo/+/origin', - 'rider_availability': 'rider/+/availability' + 'jo_origin': 'jo/+/origin' }, }; - var event_handler = new MapEventHandler(options, dashmap, ssl); + var event_handler = new MapEventHandler(options, dashmap); event_handler.connect('{{ app.user.getID }}', '{{ mqtt_host }}', {{ mqtt_port }}); } @@ -95,13 +94,8 @@ var icons = { var r_markers = {}; var c_markers = {}; - var ssl = false; - {% if ssl_enable == 'true' %} - ssl = true; - {% endif %} - var dashmap = initMap(r_markers, c_markers, icons); - initEventHandler(dashmap, icons, ssl); + initEventHandler(dashmap, icons); {% endif %} diff --git a/templates/job-order/cmb.form.onestep.html.twig b/templates/job-order/cmb.form.onestep.html.twig index d6d5ba20..7d2344f2 100644 --- a/templates/job-order/cmb.form.onestep.html.twig +++ b/templates/job-order/cmb.form.onestep.html.twig @@ -92,57 +92,57 @@
- - - + + +
- - - + + +
- +
{% trans %}country_code_prefix{% endtrans %} - - + +
- +
{% trans %}country_code_prefix{% endtrans %} - - + +
- +
{% trans %}country_code_prefix{% endtrans %} - - + +
- +
{% trans %}country_code_prefix{% endtrans %} - - + +
- - - + + +
@@ -178,26 +178,17 @@
- +
-
@@ -474,13 +462,14 @@ Last Name Contact No. Plate Number + Action {% if mode in ['onestep-edit', 'view-all', 'update-fulfillment'] %} {% set avail_riders = obj.getHub.getAvailableRiders|default([]) %} - + No riders available. @@ -506,73 +495,6 @@
- {% if mode in ['onestep-edit'] %} -
-
-
-

- Other Information -

-
-
-
- - -
-
- - -
-
- -
-
-
-
-
- -
- {% for key, picture in jo_pictures %} - {% if key == 'image_1' %} -
-
-
- {% endif %} - {% if key == 'image_2' %} -
-
-
- {% endif %} - {% if key == 'image_3' %} -
-
-
- {% endif %} - {% if key == 'image_4' %} -
-
-
- {% endif %} - - {% endfor %} -
- -
- {% endif %} -
@@ -622,7 +544,7 @@
-
- +
-
-
-
-
-

- Job Orders (Behind Schedule) -

-
-
-
- -
- -
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
- -
-
-
-
-
-
- -
- -
- -
-
-
-
-
-
-
- -
- -
-
-
-
-
-{% endblock %} - -{% block scripts %} - -{% endblock %} diff --git a/templates/job-order/cmb.list.open.html.twig b/templates/job-order/cmb.list.open.html.twig index 4fa85c70..a575e645 100644 --- a/templates/job-order/cmb.list.open.html.twig +++ b/templates/job-order/cmb.list.open.html.twig @@ -93,12 +93,12 @@ }, rows: { beforeTemplate: function (row, data, index) { - if (data.status == 'In Progress') { - $(row).addClass('m-table__row--is_in_progress'); + if (data.flag_advance) { + $(row).addClass('m-table__row--danger'); } - if (data.status == 'Assigned') { - $(row).addClass('m-table__row--is_assigned'); + if (data.is_mobile) { + $(row).addClass('m-table__row--is_mobile'); } } }, @@ -131,10 +131,6 @@ field: 'type', title: 'Schedule' }, - { - field: 'date_start', - title: 'Start Date' - }, { field: 'date_schedule', title: 'Scheduled Date' diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 3e12543b..c0fb8ca1 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -1,27 +1,27 @@ # text -title_login: Res-Q for CMB | Login -block_title: Res-Q for CMB +title_login: Motolite Res-Q | Login +block_title: Motolite Res-Q control_panel_sign_in: Sign-in to Control Panel -alt_image_logo_login: Res-Q for CMB -alt_image_dashboard: Res-Q for CMB -copyright: Res-Q for CMB +alt_image_logo_login: Res-Q +alt_image_dashboard: Motolite +copyright: Motolite Res-Q battery_size_tradein_brand: Trade-in Motolite battery_size_tradein_premium: Trade-in Premium battery_size_tradein_other: Trade-in Other add_cust_vehicle_battery_info: This vehicle is using a Motolite battery -jo_title_pdf: Res-Q for CMB Job Order -country_code_prefix: '+60' -delivery_instructions_label: 'CarFix Details' +jo_title_pdf: Motolite Res-Q Job Order +country_code_prefix: '+63' +delivery_instructions_label: Delivery Instructions # images -image_logo_login: /assets/images/black-text-logo-01.png -icon_login: /assets/images/battery-assist-bm-logo-32x32.png -icon_base_32x32: /assets/images/black-text-logo-01-32x32.png -icon_base_16x16: /assets/images/black-text-logo-01-16x16.png -image_dashboard: /assets/images/century_logo.png -image_jo_pdf: /public/assets/images/black-text-logo-01-115x115.png +image_logo_login: /assets/images/logo-resq.png +icon_login: /assets/demo/default/media/img/logo/favicon.ico +icon_base_32x32: /assets/images/favicon/favicon-32x32.png +icon_base_16x16: /assets/images/favicon/favicon-16x16.png +image_dashboard: /assets/images/logo-motolite.png +image_jo_pdf: /public/assets/images/logo-resq.png # default point for maps -default_lat: 3.084216 -default_long: 101.6129996 -default_region: my +default_lat: 14.6091 +default_long: 121.0223 +default_region: ph From 526296c8a3def22e7b3224c19b9c266bc1cd183b Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 14 Aug 2020 11:21:53 +0000 Subject: [PATCH 2/2] Revert "Merge branch '467-cmb-release-2' into '457-cmb-add-telephone-number-to-search'" This reverts commit 4874791fed7507085b109bd59b6661723730f04c --- .env.dist | 3 + composer.lock | 14 +- config/acl.yaml | 2 + config/cmb.menu.yaml | 4 + config/cmb.services.yaml | 19 +- config/menu.yaml | 39 +- config/packages/security.yaml | 4 + config/packages/twig.yaml | 1 + config/resq.services.yaml | 1 + config/routes/cmb_rider_api.yaml | 156 ++ config/routes/job_order.yaml | 11 + config/services.yaml | 24 +- public/assets/css/style.css | 25 +- public/assets/js/dashboard_map.js | 61 +- public/assets/js/map_mqtt.js | 11 +- resq_settings/cmb/menu.yaml | 179 ++ resq_settings/cmb/messages.en.yaml | 27 + resq_settings/cmb/services.yaml | 246 +++ resq_settings/resq/menu.yaml | 186 ++ resq_settings/resq/messages.en.yaml | 27 + resq_settings/resq/services.yaml | 244 +++ src/Command/ConfigureResqCommand.php | 55 + src/Command/CreateJOTestDataCommand.php | 173 ++ src/Controller/CMBRAPIController.php | 317 +++ src/Controller/JobOrderController.php | 33 +- src/Entity/JOExtra.php | 140 ++ src/Entity/JobOrder.php | 50 + src/Entity/Rider.php | 5 + src/Ramcar/CMBCancelReason.php | 22 + src/Ramcar/CMBJOEventType.php | 42 + src/Ramcar/CMBModeOfPayment.php | 10 +- src/Ramcar/CMBTransactionOrigin.php | 25 + src/Ramcar/JOStatus.php | 18 +- src/Ramcar/NewAPIResult.php | 92 + .../CustomerHandler/CMBCustomerHandler.php | 24 +- .../InvoiceGenerator/CMBInvoiceGenerator.php | 7 +- .../JobOrderHandler/CMBJobOrderHandler.php | 345 ++- src/Service/JobOrderHandlerInterface.php | 2 +- .../RiderAPIHandler/CMBRiderAPIHandler.php | 1879 +++++++++++++++-- templates/customer/cmb.form.html.twig | 15 +- .../job-order/cmb.form.onestep.html.twig | 253 ++- templates/job-order/cmb.form.walkin.html.twig | 153 +- templates/job-order/cmb.list.all.html.twig | 16 +- .../cmb.list.behindschedule.html.twig | 199 ++ templates/job-order/cmb.list.open.html.twig | 12 +- translations/messages.en.yaml | 34 +- 46 files changed, 4762 insertions(+), 443 deletions(-) create mode 100644 config/routes/cmb_rider_api.yaml create mode 100644 resq_settings/cmb/menu.yaml create mode 100644 resq_settings/cmb/messages.en.yaml create mode 100644 resq_settings/cmb/services.yaml create mode 100644 resq_settings/resq/menu.yaml create mode 100644 resq_settings/resq/messages.en.yaml create mode 100644 resq_settings/resq/services.yaml create mode 100644 src/Command/ConfigureResqCommand.php create mode 100644 src/Command/CreateJOTestDataCommand.php create mode 100644 src/Controller/CMBRAPIController.php create mode 100644 src/Entity/JOExtra.php create mode 100644 src/Ramcar/CMBCancelReason.php create mode 100644 src/Ramcar/CMBJOEventType.php create mode 100644 src/Ramcar/CMBTransactionOrigin.php create mode 100644 src/Ramcar/NewAPIResult.php create mode 100644 templates/job-order/cmb.list.behindschedule.html.twig diff --git a/.env.dist b/.env.dist index bd82f980..11794311 100644 --- a/.env.dist +++ b/.env.dist @@ -74,3 +74,6 @@ MAPTILER_API_KEY=map_tiler_api_key # API version API_VERSION=insert_api_version_here + +# SSL +SSL_ENABLE=true_or_false diff --git a/composer.lock b/composer.lock index 1e76e914..3d02c0bb 100644 --- a/composer.lock +++ b/composer.lock @@ -1,7 +1,7 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], "content-hash": "f03b92d48946e8b2ee19466f931c826f", @@ -3214,20 +3214,20 @@ }, { "name": "symfony/filesystem", - "version": "v4.4.4", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "266c9540b475f26122b61ef8b23dd9198f5d1cfd" + "reference": "b27f491309db5757816db672b256ea2e03677d30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/266c9540b475f26122b61ef8b23dd9198f5d1cfd", - "reference": "266c9540b475f26122b61ef8b23dd9198f5d1cfd", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b27f491309db5757816db672b256ea2e03677d30", + "reference": "b27f491309db5757816db672b256ea2e03677d30", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.1.3", "symfony/polyfill-ctype": "~1.8" }, "type": "library", @@ -3260,7 +3260,7 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2020-01-21T08:20:44+00:00" + "time": "2020-05-30T18:50:54+00:00" }, { "name": "symfony/finder", diff --git a/config/acl.yaml b/config/acl.yaml index abd73118..1d1a0c74 100644 --- a/config/acl.yaml +++ b/config/acl.yaml @@ -270,6 +270,8 @@ access_keys: label: Autoassign Test - id: jo_hub.list label: Hub View + - id: jo_behind_schedule.list + label: View Behind Schedule - id: support label: Customer Support Access diff --git a/config/cmb.menu.yaml b/config/cmb.menu.yaml index 9f28b315..ca756046 100644 --- a/config/cmb.menu.yaml +++ b/config/cmb.menu.yaml @@ -118,6 +118,10 @@ main_menu: acl: jo_all.list label: View All parent: joborder + - id: jo_behind_schedule + acl: jo_behind_schedule.list + label: View Behind Schedule + parent: joborder - id: support acl: support.menu diff --git a/config/cmb.services.yaml b/config/cmb.services.yaml index 5f24e525..3d9fd7a3 100644 --- a/config/cmb.services.yaml +++ b/config/cmb.services.yaml @@ -5,6 +5,7 @@ parameters: latitude: 14.6091 longitude: 121.0223 image_upload_directory: '%kernel.project_dir%/public/uploads' + jo_extra_upload_directory: '%kernel.project_dir%/public/uploads/jo_extra' job_order_refresh_interval: 300000 api_acl_file: 'api_acl.yaml' api_access_key: 'api_access_keys' @@ -12,6 +13,7 @@ parameters: app_access_key: 'access_keys' cvu_brand_id: "%env(CVU_BRAND_ID)%" country_code: "%env(COUNTRY_CODE)%" + api_version: "%env(API_VERSION)%" services: # default configuration for services in *this* file @@ -73,6 +75,7 @@ services: $pass: "%env(RT_PASS)%" $usage_type: "%env(RT_USAGE_TYPE)%" $shortcode: "%env(RT_SHORTCODE)%" + $dr_url: "https://resqaws.jankstudio.com/sms/delivery_receipt" App\Service\MQTTClient: arguments: @@ -167,7 +170,7 @@ services: # job order generator App\Service\JobOrderHandler\CMBJobOrderHandler: arguments: - $country_code: "%env(COUNTRY_CODE)%" + $country_code: "%env(COUNTRY_CODE)%" #job order generator interface App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\CMBJobOrderHandler" @@ -187,13 +190,13 @@ services: App\Service\RiderAssignmentHandlerInterface: "@App\\Service\\RiderAssignmentHandler\\CMBRiderAssignmentHandler" # rider API service - App\Service\RiderAPIHandler\CMBRiderAPIHandler: + App\Service\RiderAPIHandler\CMBRiderAPIHandler: arguments: $country_code: "%env(COUNTRY_CODE)%" + $upload_dir: "%jo_extra_upload_directory%" - # rider API interface App\Service\RiderAPIHandlerInterface: "@App\\Service\\RiderAPIHandler\\CMBRiderAPIHandler" - + # map manager #App\Service\GISManager\Bing: ~ App\Service\GISManager\OpenStreet: ~ @@ -229,6 +232,14 @@ services: $loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%" $status_key: "%env(STATUS_RIDER_KEY)%" + # inventory manager + App\Service\InventoryManager: + arguments: + $api_url: "%env(INVENTORY_API_URL)%" + $api_ocp_key: "%env(INVENTORY_API_OCP)%" + $api_auth_prefix: "%env(INVENTORY_API_AUTH_TOKEN_PREFIX)%" + $api_auth_token: "%env(INVENTORY_API_AUTH_TOKEN)%" + # API logging App\EventSubscriber\LogSubscriber: arguments: diff --git a/config/menu.yaml b/config/menu.yaml index 246eda01..ca756046 100644 --- a/config/menu.yaml +++ b/config/menu.yaml @@ -37,6 +37,10 @@ main_menu: acl: rider.list label: Riders parent: logistics + - id: service_charge_list + acl: service_charge.list + label: Service Charges + parent: logistics - id: battery acl: battery.menu @@ -98,21 +102,13 @@ main_menu: acl: joborder.menu label: Job Order icon: flaticon-calendar-3 - - id: jo_in - acl: jo_in.list - label: Incoming + - id: jo_onestep_form + acl: jo_onestep.form + label: One-step Process parent: joborder - - id: jo_proc - acl: jo_proc.list - label: Dispatch - parent: joborder - - id: jo_assign - acl: jo_assign.list - label: Rider Assignment - parent: joborder - - id: jo_fulfill - acl: jo_fulfill.list - label: Fulfillment + - id: jo_walkin_form + acl: jo_walkin.form + label: Walk-in parent: joborder - id: jo_open acl: jo_open.list @@ -122,9 +118,9 @@ main_menu: acl: jo_all.list label: View All parent: joborder - - id: jo_hub_view - acl: jo_hub.list - label: Hub View + - id: jo_behind_schedule + acl: jo_behind_schedule.list + label: View Behind Schedule parent: joborder - id: support @@ -185,12 +181,3 @@ main_menu: acl: review.list label: Reviews parent: partner - - - id: analytics - acl: analytics.menu - label: Analytics - icon: flaticon-graphic - - id: analytics_forecast_form - acl: analytics.forecast - label: Forecasting - parent: analytics diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 4339eba4..86a9b1d7 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -46,6 +46,10 @@ security: provider: api_key_user_provider user_checker: Catalyst\AuthBundle\Service\UserChecker + cmb_rider_api: + pattern: ^\/cmbrapi\/ + security: false + main: provider: user_provider form_login: diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index 1c848030..ade96bcc 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -8,3 +8,4 @@ twig: mqtt_host: "%env(MQTT_WS_HOST)%" mqtt_port: "%env(MQTT_WS_PORT)%" dashboard_enable: "%env(DASHBOARD_ENABLE)%" + ssl_enable: "%env(SSL_ENABLE)%" diff --git a/config/resq.services.yaml b/config/resq.services.yaml index 82eb4cc5..05fd3b1a 100644 --- a/config/resq.services.yaml +++ b/config/resq.services.yaml @@ -74,6 +74,7 @@ services: $pass: "%env(RT_PASS)%" $usage_type: "%env(RT_USAGE_TYPE)%" $shortcode: "%env(RT_SHORTCODE)%" + $dr_url: "https://resqaws.jankstudio.com/sms/delivery_receipt" App\Service\MQTTClient: arguments: diff --git a/config/routes/cmb_rider_api.yaml b/config/routes/cmb_rider_api.yaml new file mode 100644 index 00000000..805d898d --- /dev/null +++ b/config/routes/cmb_rider_api.yaml @@ -0,0 +1,156 @@ +# rider app api + +cmb_rapi_register: + path: /cmbrapi/register + controller: App\Controller\CMBRAPIController::register + methods: [POST] + +cmb_rapi_login: + path: /cmbrapi/login + controller: App\Controller\CMBRAPIController::login + methods: [POST] + +cmb_rapi_logout: + path: /cmbrapi/logout + controller: App\Controller\CMBRAPIController::logout + methods: [POST] + +cmb_rapi_jo_get: + path: /cmbrapi/joborder + controller: App\Controller\CMBRAPIController::getJobOrder + methods: [GET] + +cmb_rapi_jo_accept: + path: /cmbrapi/joaccept + controller: App\Controller\CMBRAPIController::acceptJobOrder + methods: [POST] + +cmb_rapi_jo_cancel: + path: /cmbrapi/jocancel + controller: App\Controller\CMBRAPIController::cancelJobOrder + methods: [POST] + +cmb_rapi_arrive: + path: /cmbrapi/arrive + controller: App\Controller\CMBRAPIController::arrive + methods: [POST] + +cmb_rapi_performed: + path: /cmbrapi/joperform + controller: App\Controller\CMBRAPIController::performJobOrder + methods: [POST] + +cmb_rapi_payment: + path: /cmbrapi/jopayment + controller: App\Controller\CMBRAPIController::payment + methods: [POST] + +cmb_rapi_hub_arrive: + path: /cmbrapi/hub_arrive + controller: App\Controller\CMBRAPIController::hubArrive + methods: [POST] + +cmb_rapi_promos: + path: /cmbrapi/promos + controller: App\Controller\CMBRAPIController::getPromos + methods: [GET] + +cmb_rapi_batteries: + path: /cmbrapi/batteries + controller: App\Controller\CMBRAPIController::getBatteries + methods: [GET] + +cmb_rapi_change_service: + path: /cmbrapi/service + controller: App\Controller\CMBRAPIController::changeService + methods: [POST] + +cmb_rapi_available: + path: /cmbrapi/available + controller: App\Controller\CMBRAPIController::available + methods: [POST] + +cmb_rapi_jo_history: + path: /cmbrapi/johistory/{period} + controller: App\Controller\CMBRAPIController::getJobOrderHistory + methods: [GET] + +cmb_rapi_assigned_jo_get: + path: /cmbrapi/assignedjos + controller: App\Controller\CMBRAPIController::getAssignedJobOrders + methods: [GET] + +cmb_rapi_jo_in_transit: + path: /cmbrapi/jotransit + controller: App\Controller\CMBRAPIController::setJobOrderInTransit + methods: [POST] + +cmb_rapi_invoice_generate: + path: /cmbrapi/generateinvoice + controller: App\Controller\CMBRAPIController::generateInvoice + methods: [GET] + +cmb_rapi_online: + path: /cmbrapi/online + controller: App\Controller\CMBRAPIController::goOnline + methods: [POST] + +cmb_rapi_offline: + path: /cmbrapi/offline + controller: App\Controller\CMBRAPIController::goOffline + methods: [POST] + +cmb_rapi_jo_start: + path: /cmbrapi/jostart + controller: App\Controller\CMBRAPIController::startJobOrder + methods: [POST] + +cmb_rapi_jo_complete: + path: /cmbrapi/jocomplete + controller: App\Controller\CMBRAPIController::completeJobOrder + methods: [POST] + +cmb_rapi_jo_set_active: + path: /cmbrapi/joactive + controller: App\Controller\CMBRAPIController::setActiveJobOrder + methods: [POST] + +cmb_rapi_jo_reject: + path: /cmbrapi/joreject + controller: App\Controller\CMBRAPIController::rejectJobOrder + methods: [POST] + +cmb_rapi_jo_odometer: + path: /cmbrapi/odometer + controller: App\Controller\CMBRAPIController::setOdometer + methods: [POST] + +cmb_rapi_jo_finish_photos_upload: + path: /cmbrapi/uploadfinishphotos + controller: App\Controller\CMBRAPIController::uploadFinishPhotos + methods: [POST] + +cmb_rapi_status: + path: /cmbrapi/status + controller: App\Controller\CMBRAPIController::getStatus + methods: [GET] + +cmb_rapi_jo_ongoing: + path: /cmbrapi/joongoing + controller: App\Controller\CMBRAPIController::getOngoingJobOrder + methods: [GET] + +cmb_rapi_payment_methods: + path: /cmbrapi/paymentmethods + controller: App\Controller\CMBRAPIController::getPaymentMethods + methods: [GET] + +cmb_rapi_cancel_reasons: + path: /cmbrapi/cancelreasons + controller: App\Controller\CMBRAPIController::getCancelReasons + methods: [GET] + +cmb_rapi_jo_verify: + path: /cmbrapi/joverify + controller: App\Controller\CMBRAPIController::verifyJobOrder + methods: [GET] diff --git a/config/routes/job_order.yaml b/config/routes/job_order.yaml index 586ed81f..4ec4279e 100644 --- a/config/routes/job_order.yaml +++ b/config/routes/job_order.yaml @@ -253,3 +253,14 @@ jo_hub_view_form: controller: App\Controller\JobOrderController::hubViewForm methods: [GET] +jo_behind_schedule: + path: /job-order/behind-schedule + controller: App\Controller\JobOrderController::listBehindSchedule + methods: [GET] + +jo_behind_schedule_rows: + path: /job-order/behind-schedule-rows + controller: App\Controller\JobOrderController::getRows + methods: [POST] + defaults: + tier: "behind_schedule" diff --git a/config/services.yaml b/config/services.yaml index 05fd3b1a..3d9fd7a3 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -5,6 +5,7 @@ parameters: latitude: 14.6091 longitude: 121.0223 image_upload_directory: '%kernel.project_dir%/public/uploads' + jo_extra_upload_directory: '%kernel.project_dir%/public/uploads/jo_extra' job_order_refresh_interval: 300000 api_acl_file: 'api_acl.yaml' api_access_key: 'api_access_keys' @@ -161,39 +162,40 @@ services: - { name: kernel.event_listener, event: kernel.controller, method: onKernelController } # invoice generator - App\Service\InvoiceGenerator\ResqInvoiceGenerator: ~ + App\Service\InvoiceGenerator\CMBInvoiceGenerator: ~ # invoice generator interface - App\Service\InvoiceGeneratorInterface: "@App\\Service\\InvoiceGenerator\\ResqInvoiceGenerator" + App\Service\InvoiceGeneratorInterface: "@App\\Service\\InvoiceGenerator\\CMBInvoiceGenerator" # job order generator - App\Service\JobOrderHandler\ResqJobOrderHandler: + App\Service\JobOrderHandler\CMBJobOrderHandler: arguments: $country_code: "%env(COUNTRY_CODE)%" #job order generator interface - App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\ResqJobOrderHandler" + App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\CMBJobOrderHandler" # customer generator - App\Service\CustomerHandler\ResqCustomerHandler: + App\Service\CustomerHandler\CMBCustomerHandler: arguments: $country_code: "%env(COUNTRY_CODE)%" # customer generator interface - App\Service\CustomerHandlerInterface: "@App\\Service\\CustomerHandler\\ResqCustomerHandler" + App\Service\CustomerHandlerInterface: "@App\\Service\\CustomerHandler\\CMBCustomerHandler" # rider assignment - App\Service\RiderAssignmentHandler\ResqRiderAssignmentHandler: ~ + App\Service\RiderAssignmentHandler\CMBRiderAssignmentHandler: ~ # rider assignment interface - App\Service\RiderAssignmentHandlerInterface: "@App\\Service\\RiderAssignmentHandler\\ResqRiderAssignmentHandler" + App\Service\RiderAssignmentHandlerInterface: "@App\\Service\\RiderAssignmentHandler\\CMBRiderAssignmentHandler" # rider API service - App\Service\RiderAPIHandler\ResqRiderAPIHandler: + App\Service\RiderAPIHandler\CMBRiderAPIHandler: arguments: - $country_code: "%env(COUNTRY_CODE)%" + $country_code: "%env(COUNTRY_CODE)%" + $upload_dir: "%jo_extra_upload_directory%" - App\Service\RiderAPIHandlerInterface: "@App\\Service\\RiderAPIHandler\\ResqRiderAPIHandler" + App\Service\RiderAPIHandlerInterface: "@App\\Service\\RiderAPIHandler\\CMBRiderAPIHandler" # map manager #App\Service\GISManager\Bing: ~ diff --git a/public/assets/css/style.css b/public/assets/css/style.css index 140966da..4b69c445 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -155,6 +155,29 @@ span.has-danger, color: #fff !important; } +.m-table__row--is_in_progress td { + background-color: #FFA500 !important; + color: #fff !important; +} + +.m-table__row--is_in_progress td > span, +.m-table__row--is_in_progress td > span a, +.m-table__row--is_in_progress td > span a i { + color: #fff !important; +} + +.m-table__row--is_assigned td { + background-color: #0000ff !important; + color: #fff !important; +} + +.m-table__row--is_assigned td > span, +.m-table__row--is_assigned td > span a, +.m-table__row--is_assigned td > span a i { + color: #fff !important; +} + + .m-datatable.m-datatable--default > .m-datatable__table { min-height: 0 !important; } @@ -358,4 +381,4 @@ span.has-danger, .map-info .m-badge { border-radius: 0; -} \ No newline at end of file +} diff --git a/public/assets/js/dashboard_map.js b/public/assets/js/dashboard_map.js index 32f775ab..5d753cab 100644 --- a/public/assets/js/dashboard_map.js +++ b/public/assets/js/dashboard_map.js @@ -148,6 +148,49 @@ class DashboardMap { } } + putMarkerWithLabel(id, lat, lng, markers, icon, layer_group, popup_url, name) { + var my = this; + // existing marker + if (markers.hasOwnProperty(id)) { + markers[id].setLatLng(L.latLng(lat, lng)); + return; + } + + // new marker + // add label + markers[id] = L.marker( + [lat, lng], + { icon: icon } + ); + + var marker_label = id + ' - ' + name; + + markers[id].bindTooltip(marker_label, + { + permanent: true, + direction: 'right' + } + ); + + markers[id].addTo(layer_group); + + if (my.options.enable_popup) { + markers[id].bindPopup('Loading...'); + + // bind ajax for popup + markers[id].on('click', function(e) { + var popup = e.target.getPopup(); + var url = popup_url.replace('[id]', id); + console.log(url); + $.get(url).done(function(data) { + popup.setContent(data); + popup.update(); + }); + }); + } + } + + putCustomerMarker(id, lat, lng) { this.putMarker( id, @@ -172,6 +215,8 @@ class DashboardMap { this.layer_groups.customer.removeLayer(markers[id]); this.layer_groups.mobile_customer.removeLayer(markers[id]); + + delete markers[id]; } putMobileCustomerMarker(id, lat, lng) { @@ -186,27 +231,29 @@ class DashboardMap { ); } - putRiderAvailableMarker(id, lat, lng) { - this.putMarker( + putRiderAvailableMarker(id, lat, lng, name) { + this.putMarkerWithLabel( id, lat, lng, this.rider_markers, this.options.icons.rider_available, this.layer_groups.rider_available, - this.options.rider_popup_url + this.options.rider_popup_url, + name ); } - putRiderActiveJOMarker(id, lat, lng) { - this.putMarker( + putRiderActiveJOMarker(id, lat, lng, name) { + this.putMarkerWithLabel( id, lat, lng, this.rider_markers, this.options.icons.rider_active_jo, this.layer_groups.rider_active_jo, - this.options.rider_popup_url + this.options.rider_popup_url, + name ); } @@ -221,6 +268,8 @@ class DashboardMap { this.layer_groups.rider_active_jo.removeLayer(markers[id]); this.layer_groups.rider_available.removeLayer(markers[id]); + + delete markers[id]; } loadLocations(location_url) { diff --git a/public/assets/js/map_mqtt.js b/public/assets/js/map_mqtt.js index 75334c63..c3f4db0e 100644 --- a/public/assets/js/map_mqtt.js +++ b/public/assets/js/map_mqtt.js @@ -1,7 +1,8 @@ class MapEventHandler { - constructor(options, dashmap) { + constructor(options, dashmap, ssl) { this.options = options; this.dashmap = dashmap; + this.ssl = ssl; } connect(user_id, host, port) { @@ -11,7 +12,7 @@ class MapEventHandler { this.mqtt = new Paho.MQTT.Client(host, port, client_id); var options = { - // useSSL: true, + useSSL: this.ssl, timeout: 3, invocationContext: this, onSuccess: this.onConnect.bind(this), @@ -35,6 +36,10 @@ class MapEventHandler { // subscribe to rider status console.log('subscribing to ' + my.options.channels.rider_status); my.mqtt.subscribe(my.options.channels.rider_status); + + // subscribe to rider availability + console.log('subscribing to ' + my.options.channels.rider_availability); + my.mqtt.subscribe(my.options.channels.rider_availability); } if (my.options.track_jo) { @@ -55,7 +60,7 @@ class MapEventHandler { onMessage(msg) { // console.log(msg); - console.log('received message'); + // console.log('received message'); var channel = msg.destinationName; var chan_split = channel.split('/'); diff --git a/resq_settings/cmb/menu.yaml b/resq_settings/cmb/menu.yaml new file mode 100644 index 00000000..9f28b315 --- /dev/null +++ b/resq_settings/cmb/menu.yaml @@ -0,0 +1,179 @@ +main_menu: + - id: home + acl: dashboard.menu + label: Dashboard + icon: flaticon-line-graph + - id: user + acl: user.menu + label: User + icon: flaticon-users + - id: user_list + acl: user.list + label: Users + parent: user + - id: role_list + acl: role.list + label: Roles + parent: user + + - id: apiuser + acl: apiuser.menu + label: API User + icon: flaticon-users + - id: api_user_list + acl: apiuser.list + label: API Users + parent: apiuser + - id: api_role_list + acl: apirole.list + label: API Roles + parent: apiuser + + - id: logistics + acl: logistics.menu + label: Logistics + icon: fa fa-truck + - id: rider_list + acl: rider.list + label: Riders + parent: logistics + - id: service_charge_list + acl: service_charge.list + label: Service Charges + parent: logistics + + - id: battery + acl: battery.menu + label: Battery + icon: fa fa-battery-3 + - id: battery_list + acl: battery.list + label: Batteries + parent: battery + - id: bmfg_list + acl: bmfg.list + label: Manufacturers + parent: battery + - id: bmodel_list + acl: bmodel.list + label: Models + parent: battery + - id: bsize_list + acl: bsize.list + label: Sizes + parent: battery + - id: promo_list + acl: promo.list + label: Promos + parent: battery + + - id: vehicle + acl: vehicle.menu + label: Vehicle + icon: fa fa-car + - id: vehicle_list + acl: vehicle.list + label: Vehicles + parent: vehicle + - id: vmfg_list + acl: vmfg.list + label: Manufacturers + parent: vehicle + + - id: location + acl: location.menu + label: Location + icon: fa fa-home + - id: outlet_list + acl: outlet.menu + label: Outlet + parent: location + - id: hub_list + acl: hub.menu + label: Hub + parent: location + - id: geofence_list + acl: geofence.menu + label: Geofence + parent: location + + + - id: joborder + acl: joborder.menu + label: Job Order + icon: flaticon-calendar-3 + - id: jo_onestep_form + acl: jo_onestep.form + label: One-step Process + parent: joborder + - id: jo_walkin_form + acl: jo_walkin.form + label: Walk-in + parent: joborder + - id: jo_open + acl: jo_open.list + label: Open + parent: joborder + - id: jo_all + acl: jo_all.list + label: View All + parent: joborder + + - id: support + acl: support.menu + label: Customer Support + icon: flaticon-support + - id: customer_list + acl: customer.list + label: Customers + parent: support + - id: ticket_list + acl: ticket.list + label: Tickets + parent: support + - id: general_search + acl: general.search + label: Search + parent: support + - id: warranty_search + acl: warranty.search + label: Customer Battery Search + parent: support + - id: privacy_policy_list + acl: privacy_policy.list + label: Privacy Policy + parent: support + - id: warranty_list + acl: warranty.list + label: Warranty + parent: support + - id: warranty_upload + acl: warranty.upload + label: Warranty Upload + parent: support + - id: static_content_list + acl: static_content.list + label: Static Content + parent: support + + - id: service + acl: service.menu + label: Other Services + icon: flaticon-squares + - id: service_list + acl: service.list + label: Services + parent: service + + - id: partner + acl: partner.menu + label: Partners + icon: flaticon-network + - id: partner_list + acl: partner.list + label: Partners + parent: partner + - id: review_list + acl: review.list + label: Reviews + parent: partner diff --git a/resq_settings/cmb/messages.en.yaml b/resq_settings/cmb/messages.en.yaml new file mode 100644 index 00000000..3e12543b --- /dev/null +++ b/resq_settings/cmb/messages.en.yaml @@ -0,0 +1,27 @@ +# text +title_login: Res-Q for CMB | Login +block_title: Res-Q for CMB +control_panel_sign_in: Sign-in to Control Panel +alt_image_logo_login: Res-Q for CMB +alt_image_dashboard: Res-Q for CMB +copyright: Res-Q for CMB +battery_size_tradein_brand: Trade-in Motolite +battery_size_tradein_premium: Trade-in Premium +battery_size_tradein_other: Trade-in Other +add_cust_vehicle_battery_info: This vehicle is using a Motolite battery +jo_title_pdf: Res-Q for CMB Job Order +country_code_prefix: '+60' +delivery_instructions_label: 'CarFix Details' + +# images +image_logo_login: /assets/images/black-text-logo-01.png +icon_login: /assets/images/battery-assist-bm-logo-32x32.png +icon_base_32x32: /assets/images/black-text-logo-01-32x32.png +icon_base_16x16: /assets/images/black-text-logo-01-16x16.png +image_dashboard: /assets/images/century_logo.png +image_jo_pdf: /public/assets/images/black-text-logo-01-115x115.png + +# default point for maps +default_lat: 3.084216 +default_long: 101.6129996 +default_region: my diff --git a/resq_settings/cmb/services.yaml b/resq_settings/cmb/services.yaml new file mode 100644 index 00000000..3d9fd7a3 --- /dev/null +++ b/resq_settings/cmb/services.yaml @@ -0,0 +1,246 @@ +# Put parameters here that don't need to change on each machine where the app is deployed +# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration +parameters: + map_default: + latitude: 14.6091 + longitude: 121.0223 + image_upload_directory: '%kernel.project_dir%/public/uploads' + jo_extra_upload_directory: '%kernel.project_dir%/public/uploads/jo_extra' + job_order_refresh_interval: 300000 + api_acl_file: 'api_acl.yaml' + api_access_key: 'api_access_keys' + app_acl_file: 'acl.yaml' + app_access_key: 'access_keys' + cvu_brand_id: "%env(CVU_BRAND_ID)%" + country_code: "%env(COUNTRY_CODE)%" + api_version: "%env(API_VERSION)%" + +services: + # default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + public: false # Allows optimizing the container by removing unused services; this also means + # fetching services directly from the container via $container->get() won't work. + # The best practice is to be explicit about your dependencies anyway. + + # makes classes in src/ available to be used as services + # this creates a service per class whose id is the fully-qualified class name + App\: + resource: '../src/*' + exclude: '../src/{Entity,Migrations,Tests,Menu,Access}' + + # controllers are imported separately to make sure services can be injected + # as action arguments even if you don't extend any base controller class + App\Controller\: + resource: '../src/Controller' + tags: ['controller.service_arguments'] + + # add more service definitions when explicit configuration is needed + # please note that last definitions always *replace* previous ones + App\Menu\Generator: + arguments: + $router: "@router.default" + $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%' + + App\Service\MapTools: + arguments: + $em: "@doctrine.orm.entity_manager" + $gmaps_api_key: "%env(GMAPS_API_KEY)%" + $cust_dist_limit: "%env(CUST_DISTANCE_LIMIT)%" + + App\Service\RisingTideGateway: + arguments: + $em: "@doctrine.orm.entity_manager" + $user: "%env(RT_USER)%" + $pass: "%env(RT_PASS)%" + $usage_type: "%env(RT_USAGE_TYPE)%" + $shortcode: "%env(RT_SHORTCODE)%" + $dr_url: "https://resqaws.jankstudio.com/sms/delivery_receipt" + + App\Service\MQTTClient: + arguments: + $redis_client: "@App\\Service\\RedisClientProvider" + $key: "mqtt_events" + + App\Service\APNSClient: + arguments: + $redis_client: "@App\\Service\\RedisClientProvider" + + App\Service\RedisClientProvider: + arguments: + $scheme: "%env(REDIS_CLIENT_SCHEME)%" + $host: "%env(REDIS_CLIENT_HOST)%" + $port: "%env(REDIS_CLIENT_PORT)%" + $password: "%env(REDIS_CLIENT_PASSWORD)%" + + App\Service\GeofenceTracker: + arguments: + $geofence_flag: "%env(GEOFENCE_ENABLE)%" + + App\Service\WarrantyHandler: + arguments: + $em: "@doctrine.orm.entity_manager" + + App\Command\SetCustomerPrivacyPolicyCommand: + arguments: + $policy_promo: "%env(POLICY_PROMO)%" + $policy_third_party: "%env(POLICY_THIRD_PARTY)%" + $policy_mobile: "%env(POLICY_MOBILE)%" + + App\Command\CreateCustomerFromWarrantyCommand: + arguments: + $cvu_mfg_id: "%env(CVU_MFG_ID)%" + $cvu_brand_id: "%env(CVU_BRAND_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\CMBInvoiceGenerator: ~ + + # invoice generator interface + App\Service\InvoiceGeneratorInterface: "@App\\Service\\InvoiceGenerator\\CMBInvoiceGenerator" + + # job order generator + App\Service\JobOrderHandler\CMBJobOrderHandler: + arguments: + $country_code: "%env(COUNTRY_CODE)%" + + #job order generator interface + App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\CMBJobOrderHandler" + + # customer generator + App\Service\CustomerHandler\CMBCustomerHandler: + arguments: + $country_code: "%env(COUNTRY_CODE)%" + + # customer generator interface + App\Service\CustomerHandlerInterface: "@App\\Service\\CustomerHandler\\CMBCustomerHandler" + + # rider assignment + App\Service\RiderAssignmentHandler\CMBRiderAssignmentHandler: ~ + + # rider assignment interface + App\Service\RiderAssignmentHandlerInterface: "@App\\Service\\RiderAssignmentHandler\\CMBRiderAssignmentHandler" + + # rider API service + App\Service\RiderAPIHandler\CMBRiderAPIHandler: + arguments: + $country_code: "%env(COUNTRY_CODE)%" + $upload_dir: "%jo_extra_upload_directory%" + + App\Service\RiderAPIHandlerInterface: "@App\\Service\\RiderAPIHandler\\CMBRiderAPIHandler" + + # map manager + #App\Service\GISManager\Bing: ~ + App\Service\GISManager\OpenStreet: ~ + #App\Service\GISManager\Google: ~ + + #App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Bing" + App\Service\GISManagerInterface: "@App\\Service\\GISManager\\OpenStreet" + #App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Google" + + App\EventListener\JobOrderActiveCacheListener: + arguments: + $jo_cache: "@App\\Service\\JobOrderCache" + $mqtt: "@App\\Service\\MQTTClient" + tags: + - name: 'doctrine.orm.entity_listener' + event: 'postUpdate' + entity: 'App\Entity\JobOrder' + - name: 'doctrine.orm.entity_listener' + event: 'postRemove' + entity: 'App\Entity\JobOrder' + - name: 'doctrine.orm.entity_listener' + event: 'postPersist' + entity: 'App\Entity\JobOrder' + + App\Service\JobOrderCache: + arguments: + $redis_prov: "@App\\Service\\RedisClientProvider" + $active_jo_key: "%env(LOCATION_JO_ACTIVE_KEY)%" + + App\Service\RiderCache: + arguments: + $redis_prov: "@App\\Service\\RedisClientProvider" + $loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%" + $status_key: "%env(STATUS_RIDER_KEY)%" + + # inventory manager + App\Service\InventoryManager: + arguments: + $api_url: "%env(INVENTORY_API_URL)%" + $api_ocp_key: "%env(INVENTORY_API_OCP)%" + $api_auth_prefix: "%env(INVENTORY_API_AUTH_TOKEN_PREFIX)%" + $api_auth_token: "%env(INVENTORY_API_AUTH_TOKEN)%" + + # API logging + App\EventSubscriber\LogSubscriber: + arguments: + $api_log_flag: "%env(API_LOGGING)%" diff --git a/resq_settings/resq/menu.yaml b/resq_settings/resq/menu.yaml new file mode 100644 index 00000000..69f0b806 --- /dev/null +++ b/resq_settings/resq/menu.yaml @@ -0,0 +1,186 @@ +main_menu: + - id: home + acl: dashboard.menu + label: Dashboard + icon: flaticon-line-graph + - id: user + acl: user.menu + label: User + icon: flaticon-users + - id: user_list + acl: user.list + label: Users + parent: user + - id: role_list + acl: role.list + label: Roles + parent: user + + - id: apiuser + acl: apiuser.menu + label: API User + icon: flaticon-users + - id: api_user_list + acl: apiuser.list + label: API Users + parent: apiuser + - id: api_role_list + acl: apirole.list + label: API Roles + parent: apiuser + + - id: logistics + acl: logistics.menu + label: Logistics + icon: fa fa-truck + - id: rider_list + acl: rider.list + label: Riders + parent: logistics + + - id: battery + acl: battery.menu + label: Battery + icon: fa fa-battery-3 + - id: battery_list + acl: battery.list + label: Batteries + parent: battery + - id: bmfg_list + acl: bmfg.list + label: Manufacturers + parent: battery + - id: bmodel_list + acl: bmodel.list + label: Models + parent: battery + - id: bsize_list + acl: bsize.list + label: Sizes + parent: battery + - id: promo_list + acl: promo.list + label: Promos + parent: battery + + - id: vehicle + acl: vehicle.menu + label: Vehicle + icon: fa fa-car + - id: vehicle_list + acl: vehicle.list + label: Vehicles + parent: vehicle + - id: vmfg_list + acl: vmfg.list + label: Manufacturers + parent: vehicle + + - id: location + acl: location.menu + label: Location + icon: fa fa-home + - id: outlet_list + acl: outlet.menu + label: Outlet + parent: location + - id: hub_list + acl: hub.menu + label: Hub + parent: location + - id: geofence_list + acl: geofence.menu + label: Geofence + parent: location + + + - id: joborder + acl: joborder.menu + label: Job Order + icon: flaticon-calendar-3 + - id: jo_in + acl: jo_in.list + label: Incoming + parent: joborder + - id: jo_proc + acl: jo_proc.list + label: Dispatch + parent: joborder + - id: jo_assign + acl: jo_assign.list + label: Rider Assignment + parent: joborder + - id: jo_fulfill + acl: jo_fulfill.list + label: Fulfillment + parent: joborder + - id: jo_open + acl: jo_open.list + label: Open + parent: joborder + - id: jo_all + acl: jo_all.list + label: View All + parent: joborder + - id: jo_hub.view + label: Hub View + parent: joborder + + - id: support + acl: support.menu + label: Customer Support + icon: flaticon-support + - id: customer_list + acl: customer.list + label: Customers + parent: support + - id: ticket_list + acl: ticket.list + label: Tickets + parent: support + - id: general_search + acl: general.search + label: Search + parent: support + - id: warranty_search + acl: warranty.search + label: Customer Battery Search + parent: support + - id: privacy_policy_list + acl: privacy_policy.list + label: Privacy Policy + parent: support + - id: warranty_list + acl: warranty.list + label: Warranty + parent: support + - id: warranty_upload + acl: warranty.upload + label: Warranty Upload + parent: support + - id: static_content_list + acl: static_content.list + label: Static Content + parent: support + + - id: service + acl: service.menu + label: Other Services + icon: flaticon-squares + - id: service_list + acl: service.list + label: Services + parent: service + + - id: partner + acl: partner.menu + label: Partners + icon: flaticon-network + - id: partner_list + acl: partner.list + label: Partners + parent: partner + - id: review_list + acl: review.list + label: Reviews + parent: partner diff --git a/resq_settings/resq/messages.en.yaml b/resq_settings/resq/messages.en.yaml new file mode 100644 index 00000000..c0fb8ca1 --- /dev/null +++ b/resq_settings/resq/messages.en.yaml @@ -0,0 +1,27 @@ +# text +title_login: Motolite Res-Q | Login +block_title: Motolite Res-Q +control_panel_sign_in: Sign-in to Control Panel +alt_image_logo_login: Res-Q +alt_image_dashboard: Motolite +copyright: Motolite Res-Q +battery_size_tradein_brand: Trade-in Motolite +battery_size_tradein_premium: Trade-in Premium +battery_size_tradein_other: Trade-in Other +add_cust_vehicle_battery_info: This vehicle is using a Motolite battery +jo_title_pdf: Motolite Res-Q Job Order +country_code_prefix: '+63' +delivery_instructions_label: Delivery Instructions + +# images +image_logo_login: /assets/images/logo-resq.png +icon_login: /assets/demo/default/media/img/logo/favicon.ico +icon_base_32x32: /assets/images/favicon/favicon-32x32.png +icon_base_16x16: /assets/images/favicon/favicon-16x16.png +image_dashboard: /assets/images/logo-motolite.png +image_jo_pdf: /public/assets/images/logo-resq.png + +# default point for maps +default_lat: 14.6091 +default_long: 121.0223 +default_region: ph diff --git a/resq_settings/resq/services.yaml b/resq_settings/resq/services.yaml new file mode 100644 index 00000000..7f568033 --- /dev/null +++ b/resq_settings/resq/services.yaml @@ -0,0 +1,244 @@ +# Put parameters here that don't need to change on each machine where the app is deployed +# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration +parameters: + map_default: + latitude: 14.6091 + longitude: 121.0223 + image_upload_directory: '%kernel.project_dir%/public/uploads' + job_order_refresh_interval: 300000 + api_acl_file: 'api_acl.yaml' + api_access_key: 'api_access_keys' + app_acl_file: 'acl.yaml' + app_access_key: 'access_keys' + cvu_brand_id: "%env(CVU_BRAND_ID)%" + country_code: "%env(COUNTRY_CODE)%" + api_version: "%env(API_VERSION)%" + +services: + # default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + public: false # Allows optimizing the container by removing unused services; this also means + # fetching services directly from the container via $container->get() won't work. + # The best practice is to be explicit about your dependencies anyway. + + # makes classes in src/ available to be used as services + # this creates a service per class whose id is the fully-qualified class name + App\: + resource: '../src/*' + exclude: '../src/{Entity,Migrations,Tests,Menu,Access}' + + # controllers are imported separately to make sure services can be injected + # as action arguments even if you don't extend any base controller class + App\Controller\: + resource: '../src/Controller' + tags: ['controller.service_arguments'] + + # add more service definitions when explicit configuration is needed + # please note that last definitions always *replace* previous ones + App\Menu\Generator: + arguments: + $router: "@router.default" + $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%' + + App\Service\MapTools: + arguments: + $em: "@doctrine.orm.entity_manager" + $gmaps_api_key: "%env(GMAPS_API_KEY)%" + $cust_dist_limit: "%env(CUST_DISTANCE_LIMIT)%" + + App\Service\RisingTideGateway: + arguments: + $em: "@doctrine.orm.entity_manager" + $user: "%env(RT_USER)%" + $pass: "%env(RT_PASS)%" + $usage_type: "%env(RT_USAGE_TYPE)%" + $shortcode: "%env(RT_SHORTCODE)%" + $dr_url: "https://resqaws.jankstudio.com/sms/delivery_receipt" + + App\Service\MQTTClient: + arguments: + $redis_client: "@App\\Service\\RedisClientProvider" + $key: "mqtt_events" + + App\Service\APNSClient: + arguments: + $redis_client: "@App\\Service\\RedisClientProvider" + + App\Service\RedisClientProvider: + arguments: + $scheme: "%env(REDIS_CLIENT_SCHEME)%" + $host: "%env(REDIS_CLIENT_HOST)%" + $port: "%env(REDIS_CLIENT_PORT)%" + $password: "%env(REDIS_CLIENT_PASSWORD)%" + + App\Service\GeofenceTracker: + arguments: + $geofence_flag: "%env(GEOFENCE_ENABLE)%" + + App\Service\WarrantyHandler: + arguments: + $em: "@doctrine.orm.entity_manager" + + App\Command\SetCustomerPrivacyPolicyCommand: + arguments: + $policy_promo: "%env(POLICY_PROMO)%" + $policy_third_party: "%env(POLICY_THIRD_PARTY)%" + $policy_mobile: "%env(POLICY_MOBILE)%" + + App\Command\CreateCustomerFromWarrantyCommand: + arguments: + $cvu_mfg_id: "%env(CVU_MFG_ID)%" + $cvu_brand_id: "%env(CVU_BRAND_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" + + # job order generator + App\Service\JobOrderHandler\ResqJobOrderHandler: + arguments: + $country_code: "%env(COUNTRY_CODE)%" + + #job order generator interface + App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\ResqJobOrderHandler" + + # customer generator + App\Service\CustomerHandler\ResqCustomerHandler: + arguments: + $country_code: "%env(COUNTRY_CODE)%" + + # customer generator interface + App\Service\CustomerHandlerInterface: "@App\\Service\\CustomerHandler\\ResqCustomerHandler" + + # rider assignment + App\Service\RiderAssignmentHandler\ResqRiderAssignmentHandler: ~ + + # rider assignment interface + App\Service\RiderAssignmentHandlerInterface: "@App\\Service\\RiderAssignmentHandler\\ResqRiderAssignmentHandler" + + # rider API service + App\Service\RiderAPIHandler\ResqRiderAPIHandler: + arguments: + $country_code: "%env(COUNTRY_CODE)%" + + App\Service\RiderAPIHandlerInterface: "@App\\Service\\RiderAPIHandler\\ResqRiderAPIHandler" + + # map manager + #App\Service\GISManager\Bing: ~ + App\Service\GISManager\OpenStreet: ~ + #App\Service\GISManager\Google: ~ + + #App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Bing" + App\Service\GISManagerInterface: "@App\\Service\\GISManager\\OpenStreet" + #App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Google" + + App\EventListener\JobOrderActiveCacheListener: + arguments: + $jo_cache: "@App\\Service\\JobOrderCache" + $mqtt: "@App\\Service\\MQTTClient" + tags: + - name: 'doctrine.orm.entity_listener' + event: 'postUpdate' + entity: 'App\Entity\JobOrder' + - name: 'doctrine.orm.entity_listener' + event: 'postRemove' + entity: 'App\Entity\JobOrder' + - name: 'doctrine.orm.entity_listener' + event: 'postPersist' + entity: 'App\Entity\JobOrder' + + App\Service\JobOrderCache: + arguments: + $redis_prov: "@App\\Service\\RedisClientProvider" + $active_jo_key: "%env(LOCATION_JO_ACTIVE_KEY)%" + + App\Service\RiderCache: + arguments: + $redis_prov: "@App\\Service\\RedisClientProvider" + $loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%" + $status_key: "%env(STATUS_RIDER_KEY)%" + + # inventory manager + App\Service\InventoryManager: + arguments: + $api_url: "%env(INVENTORY_API_URL)%" + $api_ocp_key: "%env(INVENTORY_API_OCP)%" + $api_auth_prefix: "%env(INVENTORY_API_AUTH_TOKEN_PREFIX)%" + $api_auth_token: "%env(INVENTORY_API_AUTH_TOKEN)%" + + # API logging + App\EventSubscriber\LogSubscriber: + arguments: + $api_log_flag: "%env(API_LOGGING)%" diff --git a/src/Command/ConfigureResqCommand.php b/src/Command/ConfigureResqCommand.php new file mode 100644 index 00000000..f4316056 --- /dev/null +++ b/src/Command/ConfigureResqCommand.php @@ -0,0 +1,55 @@ +setName('resq:configure') + ->setDescription('Copies the configuration files, depending on environment.') + ->setHelp('Copies the configuration files, depending on environment.') + ->addArgument('dir_name', InputArgument::REQUIRED, 'Name of source subdirectory.'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $dir_name = $input->getArgument('dir_name'); + + $filesystem = new Filesystem(); + $current_dir = getcwd(); + + $source_dir = $current_dir . '/resq_settings/' . $dir_name . '/'; + $config_dir = $current_dir . '/config/'; + $translations_dir = $current_dir . '/translations/'; + + // copy services.yaml file + error_log('Copying services.yaml file...'); + $filesystem->copy($source_dir . 'services.yaml', $config_dir . 'services.yaml', true); + + // copy menu.yaml file + error_log('Copying menu.yaml file...'); + $filesystem->copy($source_dir . 'menu.yaml', $config_dir . 'menu.yaml', true); + + // copy messages.en.yaml file + error_log('Copying messages.en.yaml file...'); + $filesystem->copy($source_dir . 'messages.en.yaml', $translations_dir . 'messages.en.yaml', true); + + error_log('Done copying files.'); + + return 0; + } +} diff --git a/src/Command/CreateJOTestDataCommand.php b/src/Command/CreateJOTestDataCommand.php new file mode 100644 index 00000000..7aafe444 --- /dev/null +++ b/src/Command/CreateJOTestDataCommand.php @@ -0,0 +1,173 @@ +em = $em; + + parent::__construct(); + } + + protected function configure() + { + $this->setName('joborder:create_testdata') + ->setDescription('Create JO test data, given a rider id.') + ->setHelp('Create JO test data, given a rider id.') + ->addArgument('rider_id', InputArgument::REQUIRED, 'Rider id.'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $rider_id = $input->getArgument('rider_id'); + + $rider = $this->em->getRepository(Rider::class)->find($rider_id); + + // get customer vehicles where plate number is not null + $cv_query = $this->em->createQuery('SELECT cv FROM App\Entity\CustomerVehicle cv WHERE cv.plate_number is not null'); + $cv_results = $cv_query->getResult(); + + // get the first customer vehicle + $cv = current($cv_results); + + // get batteries + $battery_results = $this->em->getRepository(Battery::class)->findAll(); + + // get the first battery + $battery = current($battery_results); + + error_log($cv->getPlateNumber()); + error_log($battery->getID()); + + if (empty($rider)) + { + error_log('Rider not found.'); + } + else + { + // get current date + $current_date = new DateTime(); + + // for this month JO + $current_year = $current_date->format('Y'); + $current_month = $current_date->format('M'); + + // for last month JO + $date_interval = new DateInterval('P1M'); + $last_month_date = $current_date->sub($date_interval); + + $last_month_year = $last_month_date->format('Y'); + $last_month_month = $last_month_date->format('M'); + + $time_schedule = $current_date->format('h:i A'); + + $this->createJobOrders($rider, $cv, $battery, $last_month_year, $last_month_month, $time_schedule); + $this->createJobOrders($rider, $cv, $battery, $current_year, $current_month, $time_schedule); + } + + return 0; + } + + protected function createJobOrders(Rider $rider, CustomerVehicle $cv, Battery $battery, $year, $month, $time) + { + // insert 15 JOs for last month + for ($i = 1; $i <= 15; $i++) + { + $jo = new JobOrder(); + + // set customer data + $jo->setCustomerVehicle($cv); + $jo->setCustomer($cv->getCustomer()); + + // set hub and rider data + $jo->setRider($rider); + $jo->setHub($rider->getHub()); + + // set JO details + $point = new Point(121.0223, 14.6091); + $s_type = CMBServiceType::BATTERY_REPLACEMENT_NEW; + $source = TransactionOrigin::CALL; + $advance_order = true; + $warranty_class = WarrantyClass::WTY_PRIVATE; + $status = JOStatus::FULFILLED; + $delivery_address = '#1234 Moogle Lane'; + $mode_of_payment = ModeOfPayment::CASH; + + // set invoice details + $invoice = new Invoice(); + $invoice_item = new InvoiceItem(); + + // set invoice item details + $invoice_item->setBattery($battery) + ->setTitle($battery->getModel()->getName() . ' ' . $battery->getSize()->getName()) + ->setQuantity(1) + ->setPrice($battery->getSellingPrice()) + ->setInvoice($invoice); + + $invoice->addItem($invoice_item); + + $this->em->persist($invoice_item); + + // set invoice details + $invoice->setTotalPrice($battery->getSellingPrice()) + ->setStatus(InvoiceStatus::DRAFT) + ->setVATExclusivePrice($battery->getSellingPrice()) + ->setDiscount(0.0) + ->setTradeIn(0.0) + ->setVAT(0.00); + + $this->em->persist($invoice); + + $jo->setInvoice($invoice); + + // for last month + $date_schedule_date = $i . ' ' . $month . ' ' . $year . ' ' . $time; + error_log('Adding JO with date schedule ' . $date_schedule_date); + $date_schedule = DateTime::createFromFormat("d M Y h:i A", $date_schedule_date); + + $jo->setDateSchedule($date_schedule) + ->setCoordinates($point) + ->setAdvanceOrder($advance_order) + ->setServiceType($s_type) + ->setWarrantyClass($warranty_class) + ->setSource($source) + ->setStatus($status) + ->setDeliveryAddress($delivery_address); + + $this->em->persist($jo); + } + + $this->em->flush(); + + } +} diff --git a/src/Controller/CMBRAPIController.php b/src/Controller/CMBRAPIController.php new file mode 100644 index 00000000..6ddf842e --- /dev/null +++ b/src/Controller/CMBRAPIController.php @@ -0,0 +1,317 @@ +register($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function login(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->login($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function logout(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->logout($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function getJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->getJobOrder($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function acceptJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->acceptJobOrder($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function cancelJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->cancelJobOrder($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function arrive(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->arrive($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function performJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->performJobOrder($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function hubArrive(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->hubArrive($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function payment(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->payment($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function available(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->available($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function getPromos(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->getPromos($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function getBatteries(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->getBatteries($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function changeService(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->changeService($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function getJobOrderHistory(Request $req, $period, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->getJobOrderHistory($req, $period); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function getAssignedJobOrders(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->getAssignedJobOrders($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function setJobOrderInTransit(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->setJobOrderInTransit($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function generateInvoice(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->generateInvoice($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function goOnline(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->goOnline($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function goOffline(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->goOffline($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function startJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->startJobOrder($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function completeJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->completeJobOrder($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function setActiveJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->setActiveJobOrder($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function rejectJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->rejectJobOrder($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function setOdometer(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->setOdometer($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function uploadFinishPhotos(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->uploadFinishPhotos($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function getStatus(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->getStatus($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function getOngoingJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->getOngoingJobOrder($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function getPaymentMethods(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->getPaymentMethods($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function getCancelReasons(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->getCancelReasons($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + public function verifyJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) + { + $data = $rapi_handler->verifyJobOrder($req); + + $res = $this->generateResultFromHandler($data); + + return $res->getReturnResponse(); + } + + protected function generateResultFromHandler($data) + { + $res = new NewAPIResult(); + + if (isset($data['error'])) + { + $message = $data['error']; + $title = $data['title']; + + $res->setError(true) + ->setErrorTitle($title) + ->setErrorMessage($message); + } + else + { + $res->setData($data); + } + + return $res; + } + +} diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index f23fc73c..1b7a451f 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -286,6 +286,11 @@ class JobOrderController extends Controller $rows[$key]['meta']['edit_url'] = $this->generateUrl($jo_handler->getEditRoute($jo_id, $tier_params['edit_route']), ['id' => $jo_id]); $rows[$key]['meta']['onestep_edit_url'] = $this->generateUrl('jo_onestep_edit_form', ['id' => $jo_id]); } + else if ($tier == 'behind_schedule') + { + $rows[$key]['meta']['edit_url'] = $this->generateUrl($jo_handler->getEditRoute($jo_id, $tier_params['edit_route']), ['id' => $jo_id]); + $rows[$key]['meta']['onestep_edit_url'] = $this->generateUrl('jo_onestep_edit_form', ['id' => $jo_id]); + } else { // $rows[$key]['meta']['update_url'] = $this->generateUrl($tier_params['edit_route'], ['id' => $jo_id]); @@ -764,7 +769,10 @@ class JobOrderController extends Controller // use invoice object values in a json friendly array $invoice = [ - 'discount' => number_format($iobj->getDiscount(), 2), + // TODO: CMB needs to have no decimal places for discount. + // Resq requires the two decimal places since discount is computed. + //'discount' => number_format($iobj->getDiscount(), 2), + 'discount' => number_format($iobj->getDiscount(), 0), 'trade_in' => number_format($iobj->getTradeIn(), 2), // TODO: computations not done yet for this on invoice creator 'price' => number_format($iobj->getVATExclusivePrice(), 2), 'vat' => number_format($iobj->getVAT(), 2), @@ -867,14 +875,14 @@ class JobOrderController extends Controller return $this->render($template, $params); } - public function oneStepSubmit(Request $req, JobOrderHandlerInterface $jo_handler) + public function oneStepSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient) { $this->denyAccessUnlessGranted('jo_onestep.form', null, 'No access.'); // initialize error list $error_array = []; $id = -1; - $error_array = $jo_handler->processOneStepJobOrder($req, $id); + $error_array = $jo_handler->processOneStepJobOrder($req, $id, $mclient); // check if any errors were found if (!empty($error_array)) { @@ -913,12 +921,12 @@ class JobOrderController extends Controller return $this->render($template, $params); } - public function oneStepEditSubmit(Request $req, JobOrderHandlerInterface $jo_handler, $id) + public function oneStepEditSubmit(Request $req, JobOrderHandlerInterface $jo_handler, $id, MQTTClient $mclient) { $this->denyAccessUnlessGranted('jo_onestep.edit', null, 'No access.'); $error_array = []; - $error_array = $jo_handler->processOneStepJobOrder($req, $id); + $error_array = $jo_handler->processOneStepJobOrder($req, $id, $mclient); // check if any errors were found if (!empty($error_array)) { @@ -1209,6 +1217,21 @@ class JobOrderController extends Controller } + /** + * @Menu(selected="jo_behind_schedule") + */ + public function listBehindSchedule(JobOrderHandlerInterface $jo_handler) + { + $this->denyAccessUnlessGranted('jo_behind_schedule.list', null, 'No access.'); + + $template = $jo_handler->getTwigTemplate('jo_behind_schedule'); + + $params = $jo_handler->getOtherParameters(); + $params['table_refresh_rate'] = $this->container->getParameter('job_order_refresh_interval'); + + return $this->render($template, $params); + } + protected function autoAssignHubAndRider($jo, EntityManagerInterface $em, MapTools $map_tools, InventoryManager $im) { diff --git a/src/Entity/JOExtra.php b/src/Entity/JOExtra.php new file mode 100644 index 00000000..7770c150 --- /dev/null +++ b/src/Entity/JOExtra.php @@ -0,0 +1,140 @@ +other_images = new ArrayCollection(); + } + + public function getID() + { + return $this->id; + } + + public function setImage1Filename($image_filename) + { + $this->image_1_filename = $image_filename; + return $this; + } + + public function getImage1Filename() + { + return $this->image_1_filename; + } + + public function setImage2Filename($image_filename) + { + $this->image_2_filename = $image_filename; + return $this; + } + + public function getImage2Filename() + { + return $this->image_2_filename; + } + + public function setImage3Filename($image_filename) + { + $this->image_3_filename = $image_filename; + return $this; + } + + public function getImage3Filename() + { + return $this->image_3_filename; + } + + public function setImage4Filename($image_filename) + { + $this->image_4_filename = $image_filename; + return $this; + } + + public function getImage4Filename() + { + return $this->image_4_filename; + } + + public function getOtherImages() + { + return $this->other_images; + } + + public function setOtherImages(array $images) + { + $this->other_images = new ArrayCollection(); + + foreach ($images as $image_filename) + { + $this->other_images->add($image_filename); + } + + return $this; + } + + public function clearOtherImages() + { + $this->other_images = new ArrayCollection(); + return $this; + } + + public function setCustomerSignature($sig_file) + { + $this->cust_signature = $sig_file; + return $this; + } + + public function getCustomerSignature() + { + return $this->cust_signature; + } +} diff --git a/src/Entity/JobOrder.php b/src/Entity/JobOrder.php index 8bcdbb77..7335c512 100644 --- a/src/Entity/JobOrder.php +++ b/src/Entity/JobOrder.php @@ -334,6 +334,24 @@ class JobOrder */ protected $phone_mobile; + // link to JOExtra + /** + * @ORM\OneToOne(targetEntity="JOExtra") + */ + protected $jo_extra; + + // date that the status last changed + /** + * @ORM\Column(type="datetime", nullable=true) + */ + protected $date_status_change; + + // insurer/responsible party handling the onsite job + /** + * @ORM\Column(type="string", length=80, nullable=true) + */ + protected $responsible_party; + public function __construct() { $this->date_create = new DateTime(); @@ -583,6 +601,7 @@ class JobOrder { // TODO: validate status $this->status = $status; + $this->date_status_change = new DateTime(); return $this; } @@ -596,6 +615,11 @@ class JobOrder return JOStatus::getName($this->status); } + public function getDateStatusChange() + { + return $this->date_status_change; + } + public function setDeliveryInstructions($delivery_instructions) { $this->delivery_instructions = $delivery_instructions; @@ -796,6 +820,11 @@ class JobOrder $this->makeRiderAvailable(); } + public function perform() + { + $this->setStatus(JOStatus::PERFORMED); + } + public function fulfill() { $this->setStatus(JOStatus::FULFILLED) @@ -962,5 +991,26 @@ class JobOrder return $this->phone_mobile; } + public function setJOExtra(JOExtra $jo_extra) + { + $this->jo_extra = $jo_extra; + return $this; + } + + public function getJOExtra() + { + return $this->jo_extra; + } + + public function setResponsibleParty($responsible_party) + { + $this->responsible_party = $responsible_party; + return $this; + } + + public function getResponsibleParty() + { + return $this->responsible_party; + } } diff --git a/src/Entity/Rider.php b/src/Entity/Rider.php index 502d93bc..6416a443 100644 --- a/src/Entity/Rider.php +++ b/src/Entity/Rider.php @@ -347,6 +347,11 @@ class Rider return $this->job_orders->matching($criteria)[0]; } + public function getRiderActiveJobOrder() + { + return $this->active_job_order; + } + public function getOpenJobOrders() { $active_status = [ diff --git a/src/Ramcar/CMBCancelReason.php b/src/Ramcar/CMBCancelReason.php new file mode 100644 index 00000000..b681a40a --- /dev/null +++ b/src/Ramcar/CMBCancelReason.php @@ -0,0 +1,22 @@ + 'Accident', + 'breakdown' => 'Breakdown', + 'fuel_runout' => 'Fuel Runout', + 'wrong_battery_size' => 'Wrong Battery Size', + 'customer_cancel' => 'Cancelled by Customer', + 'others' => 'Others' + ]; +} diff --git a/src/Ramcar/CMBJOEventType.php b/src/Ramcar/CMBJOEventType.php new file mode 100644 index 00000000..631b434b --- /dev/null +++ b/src/Ramcar/CMBJOEventType.php @@ -0,0 +1,42 @@ + 'Created', + 'hub_assign' => 'Assigned to Hub', + 'rider_assign' => 'Assigned Rider', + 'cancel' => 'Cancelled', + 'fulfill' => 'Fulfilled', + 'open_edit' => 'Open Edit', + 'requeue' => 'Requeue', + 'accept' => 'Rider Accept', + 'rider_in_transit' => 'Rider in Transit', + 'arrive' => 'Rider Arrive', + 'rider_start' => 'Rider Start', + 'rider_edit' => 'Rider Edit', + 'paid' => 'Paid', + 'perform' => 'Perform', + 'finish' => 'Finish', + 'rider_upload_photo' => 'Rider Upload Photo', + ]; +} diff --git a/src/Ramcar/CMBModeOfPayment.php b/src/Ramcar/CMBModeOfPayment.php index c7ae9908..63bb9a2d 100644 --- a/src/Ramcar/CMBModeOfPayment.php +++ b/src/Ramcar/CMBModeOfPayment.php @@ -5,12 +5,18 @@ namespace App\Ramcar; class CMBModeOfPayment extends NameValue { const CASH = 'cash'; + const SHOPEE = 'shopee'; + const LAZADA = 'lazada'; const CREDIT_CARD = 'credit_card'; - const BANK_TRANSFER = 'bank_transfer'; + const ONLINE_TRANSFER = 'online_transfer'; + const E_WALLET = 'e_wallet'; const COLLECTION = [ 'cash' => 'Cash', + 'shopee' => 'Shopee', + 'lazada' => 'Lazada', 'credit_card' => 'Credit Card', - 'bank_transfer' => 'Bank Transfer', + 'online_transfer' => 'Online Transfer', + 'e_wallet' => 'E-Wallet', ]; } diff --git a/src/Ramcar/CMBTransactionOrigin.php b/src/Ramcar/CMBTransactionOrigin.php new file mode 100644 index 00000000..7ea6a02a --- /dev/null +++ b/src/Ramcar/CMBTransactionOrigin.php @@ -0,0 +1,25 @@ + 'Hotline', + 'online' => 'Online', + 'facebook' => 'Facebook', + 'vip' => 'VIP', + 'mobile_app' => 'Mobile App', + 'walk_in' => 'Walk-in', + 'whatsapp' => 'Whatsapp', + ]; +} diff --git a/src/Ramcar/JOStatus.php b/src/Ramcar/JOStatus.php index 5ba8f5d1..08177198 100644 --- a/src/Ramcar/JOStatus.php +++ b/src/Ramcar/JOStatus.php @@ -4,13 +4,15 @@ namespace App\Ramcar; class JOStatus extends NameValue { - const PENDING = 'pending'; // NOTE: JO has no hub assigned - const RIDER_ASSIGN = 'rider_assign'; // NOTE: JO has hub assigned but no rider assigned - const ASSIGNED = 'assigned'; // NOTE: JO has hub and rider assigned - const IN_TRANSIT = 'in_transit'; // NOTE: JO's rider is on his way - const IN_PROGRESS = 'in_progress'; // NOTE: JO fulfillment in progress - const CANCELLED = 'cancelled'; // NOTE: JO is cancelled - const FULFILLED = 'fulfilled'; // NOTE: JO is fulfilled + const PENDING = 'pending'; // JO has no hub assigned + const RIDER_ASSIGN = 'rider_assign'; // JO has hub assigned but no rider assigned + const ASSIGNED = 'assigned'; // JO has hub and rider assigned + const IN_TRANSIT = 'in_transit'; // Rider is on his way + const IN_PROGRESS = 'in_progress'; // Rider has arrived at customer's location and fulfillment is in progress + const PERFORMED = 'performed'; // Rider has finished performing JO task / service + const PAID = 'paid'; // Rider has finished collecting payment for JO + const CANCELLED = 'cancelled'; // JO is cancelled + const FULFILLED = 'fulfilled'; // JO is fulfilled const COLLECTION = [ 'pending' => 'For Dispatch', @@ -18,6 +20,8 @@ class JOStatus extends NameValue 'assigned' => 'Assigned', 'in_transit' => 'In Transit', 'in_progress' => 'In Progress', + 'performed' => 'Service Performed', + 'paid' => 'Customer Paid', 'cancelled' => 'Cancelled', 'fulfilled' => 'Completed', ]; diff --git a/src/Ramcar/NewAPIResult.php b/src/Ramcar/NewAPIResult.php new file mode 100644 index 00000000..5c46bc21 --- /dev/null +++ b/src/Ramcar/NewAPIResult.php @@ -0,0 +1,92 @@ +err_title = ''; + $this->err_flag = false; + $this->err_message = ''; + $this->data = []; + } + + public function setError($flag = true) + { + $this->err_flag = $flag; + return $this; + } + + public function isError() + { + return $this->err_flag; + } + + public function setErrorMessage($message) + { + $this->err_message = $message; + return $this; + } + + public function getErrorMessage() + { + return $this->err_message; + } + + public function setData($data) + { + $this->data = $data; + return $this; + } + + public function getData() + { + return $this->data; + } + + public function setErrorTitle($title) + { + $this->err_title = $title; + return $this; + } + + public function getErrorTitle() + { + return $this->err_title; + } + + + public function getReturnResponse() + { + if ($this->isError()) + $status = 'error'; + else + $status = 'success'; + + if (count($this->data) == 0) + $this->data = new \stdClass(); + + $return_data = [ + 'error' => [ + 'title' => $this->err_title, + 'status' => $status, + 'message' => $this->err_message + ], + 'data' => $this->data + ]; + + // $json_data = json_encode($return_data, JSON_NUMERIC_CHECK); + $json_data = json_encode($return_data); + $json = new Response($json_data); + + return $json; + } +} diff --git a/src/Service/CustomerHandler/CMBCustomerHandler.php b/src/Service/CustomerHandler/CMBCustomerHandler.php index 371f674b..28612897 100644 --- a/src/Service/CustomerHandler/CMBCustomerHandler.php +++ b/src/Service/CustomerHandler/CMBCustomerHandler.php @@ -189,7 +189,7 @@ class CMBCustomerHandler implements CustomerHandlerInterface $cust_vehicle = new CustomerVehicle(); $cust_vehicle->setName($vehicle->name) ->setVehicle($vobj) - ->setPlateNumber($vehicle->plate_number) + ->setPlateNumber(trim($vehicle->plate_number)) ->setModelYear($vehicle->model_year) ->setColor('') ->setStatusCondition('') @@ -416,8 +416,14 @@ class CMBCustomerHandler implements CustomerHandlerInterface // add filters to count query if (!empty($term)) { - $tquery->where('q.plate_number like :search') - ->setParameter('search', $term . '%'); + //$tquery->where('q.plate_number like :search') + // ->setParameter('search', $term . '%'); + // TODO: this is really slow. Need to optimize + $tquery->innerJoin('q.customer', 'c') + ->where('q.plate_number like :search') + ->orWhere('c.phone_mobile = :number') + ->setParameter('search', $term . '%') + ->setParameter('number', $term); /* $tquery->where('match_against (q.plate_number, :search \'in boolean mode\') > 0.1') ->setParameter('search', $term . '*'); @@ -448,8 +454,14 @@ class CMBCustomerHandler implements CustomerHandlerInterface // add filters if needed if (!empty($term)) { - $query->where('q.plate_number like :search') - ->setParameter('search', $term . '%'); + // TODO: this is really slow. Need to optimize + $query->innerJoin('q.customer', 'cust') + ->where('q.plate_number like :search') + ->orWhere('cust.phone_mobile = :number') + ->setParameter('search', $term . '%') + ->setParameter('number', $term); + //$query->where('q.plate_number like :search') + // ->setParameter('search', $term . '%'); /* $query->where('match_against (q.plate_number, :search \'in boolean mode\') > 0.1') ->setParameter('search', $term . '*'); @@ -594,7 +606,7 @@ class CMBCustomerHandler implements CustomerHandlerInterface protected function generateYearOptions() { $start_year = 1950; - return range($start_year, date("Y") + 1); + return range($start_year, date("Y")); } diff --git a/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php b/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php index ba94d8ee..f2e75a78 100644 --- a/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php +++ b/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php @@ -274,7 +274,7 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface } // check if discount is greater than 50 or negative number - if (($discount > 50) || ($discount < 0)) + if (($discount > 60) || ($discount < 0)) return 'Invalid discount specified'; $criteria->setDiscount($discount); @@ -367,9 +367,10 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface if (!isset($con_batts[$batt_id])) $con_batts[$batt->getID()] = [ 'batt' => $batt, - 'qty' => 0 + 'qty' => $qty ]; - $con_batts[$batt_id]['qty']++; + else + $con_batts[$batt_id]['qty'] += $qty; // no trade-in diff --git a/src/Service/JobOrderHandler/CMBJobOrderHandler.php b/src/Service/JobOrderHandler/CMBJobOrderHandler.php index 862d431b..9ffb102a 100644 --- a/src/Service/JobOrderHandler/CMBJobOrderHandler.php +++ b/src/Service/JobOrderHandler/CMBJobOrderHandler.php @@ -31,12 +31,12 @@ use App\Entity\ServiceCharge; use App\Ramcar\InvoiceCriteria; use App\Ramcar\CMBServiceType; use App\Ramcar\CMBTradeInType; -use App\Ramcar\JOEventType; +use App\Ramcar\CMBJOEventType; use App\Ramcar\JOStatus; use App\Ramcar\CMBWarrantyClass; use App\Ramcar\DiscountApply; use App\Ramcar\CMBModeOfPayment; -use App\Ramcar\TransactionOrigin; +use App\Ramcar\CMBTransactionOrigin; use App\Ramcar\FacilitatedType; use App\Ramcar\JORejectionReason; @@ -177,13 +177,35 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // get rider information $rider_name = ''; $rider_plate_number = ''; + $rider_id = ''; $rider = $orow->getRider(); if (!empty($rider)) { + $rider_id = $rider->getID(); $rider_name = $rider->getFullName(); $rider_plate_number = $rider->getPlateNumber(); } + // get time when JO was started by rider + $start_event_type = CMBJOEventType::RIDER_START; + $date_start = ''; + $start_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $start_event_type, 'rider' => $rider_id, 'job_order' => $orow->getID()], ['date_happen' => 'DESC']); + if ($start_results != null) + { + $jo_event = current($start_results); + $date_start = $jo_event->getDateHappen()->format('d M Y g:i A'); + } + + // get time when JO was finished by rider + $finish_event_type = CMBJOEventType::RIDER_FINISH; + $date_finish = ''; + $finish_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $finish_event_type, 'rider' => $rider_id, 'job_order' => $orow->getID()], ['date_happen' => 'DESC']); + if ($finish_results != null) + { + $jo_event = current($finish_results); + $date_finish = $jo_event->getDateHappen()->format('d M Y g:i A'); + } + // add row data $row['id'] = $orow->getID(); $row['customer_name'] = $orow->getCustomer()->getFirstName() . ' ' . $orow->getCustomer()->getLastName(); @@ -194,10 +216,12 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $row['status'] = $statuses[$orow->getStatus()]; $row['flag_advance'] = $orow->isAdvanceOrder(); $row['plate_number'] = $orow->getCustomerVehicle()->getPlateNumber(); - $row['is_mobile'] = $orow->getSource() == TransactionOrigin::MOBILE_APP; + $row['is_mobile'] = $orow->getSource() == CMBTransactionOrigin::MOBILE_APP; $row['car_model'] = $car_model; $row['rider_name'] = $rider_name; $row['rider_plate_number'] = $rider_plate_number; + $row['date_start'] = $date_start; + $row['date_finish'] = $date_finish; $processor = $orow->getProcessedBy(); if ($processor == null) @@ -350,7 +374,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface ->setTier2Notes($req->request->get('tier2_notes')) ->setDeliveryAddress($req->request->get('delivery_address')) ->setORName($req->request->get('or_name')) - ->setPromoDetail($req->request->get('promo_detail')) + ->setPromoDetail($req->request->get('promo_detail', '')) ->setModeOfPayment($req->request->get('mode_of_payment')) ->setLandmark($req->request->get('landmark')); @@ -400,7 +424,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::CREATE) + ->setTypeID(CMBJOEventType::CREATE) ->setJobOrder($jo); if ($user != null) @@ -416,7 +440,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface return $error_array; } - public function processOneStepJobOrder(Request $req, $id) + public function processOneStepJobOrder(Request $req, $id, MQTTClient $mclient) { // initialize error list $error_array = []; @@ -424,11 +448,17 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $em = $this->em; $jo = $em->getRepository(JobOrder::class)->find($id); + $old_jo_status = null; if (empty($jo)) { // new job order $jo = new JobOrder(); } + else + { + //$old_rider = $jo->getRider(); + $old_jo_status = $jo->getStatus(); + } // check if lat and lng are provided if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) { @@ -438,19 +468,14 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // check if new customer if ($req->request->get('new_customer', false)) { - if (empty($req->request->get('customer_customer_notes'))) - { - $error_array['customer_customer_notes'] = 'Customer notes cannot be null.'; - } - // validate mobile phone - $valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('customer_phone_mobile')); + $valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('phone_mobile')); if (!($valid_mobile)) - $error_array['customer_phone_mobile'] = 'Invalid mobile phone number.'; + $error_array['phone_mobile'] = 'Invalid mobile phone number.'; // check if plate number is in request - if (empty($req->request->get('cv_plate'))) - $error_array['cv_plate'] = 'Plate number is required.'; + if (empty(trim($req->request->get('plate_number')))) + $error_array['plate_number'] = 'Plate number is required.'; // find the vehicle using vid $new_vehicle = $em->getRepository(Vehicle::class)->find($req->request->get('vid')); @@ -464,17 +489,17 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $new_cust = new Customer(); $new_cv = new CustomerVehicle(); - $new_cust->setLastName($req->request->get('customer_last_name')) - ->setFirstName($req->request->get('customer_first_name')) - ->setPhoneMobile($req->request->get('customer_phone_mobile')) - ->setPhoneLandline($req->request->get('customer_phone_landline')) - ->setPhoneOffice($req->request->get('customer_phone_office')) - ->setPhoneFax($req->request->get('customer_phone_fax')) - ->setCustomerNotes($req->request->get('customer_customer_notes')); + $new_cust->setLastName($req->request->get('last_name')) + ->setFirstName($req->request->get('first_name')) + ->setPhoneMobile($req->request->get('phone_mobile')) + ->setPhoneLandline($req->request->get('phone_landline')) + ->setPhoneOffice($req->request->get('phone_office')) + ->setPhoneFax($req->request->get('phone_fax')) + ->setCustomerNotes($req->request->get('customer_notes')); $new_cv->setCustomer($new_cust) ->setVehicle($new_vehicle) - ->setPlateNumber($req->request->get('cv_plate')) + ->setPlateNumber(trim($req->request->get('plate_number'))) ->setModelYear($req->request->get('cv_year')) ->setColor('') ->setStatusCondition('') @@ -544,36 +569,41 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface if (empty($rider)) { $error_array['rider'] = 'Invalid rider specified.'; + } else { + // check if rider is still available + if (!($rider->isAvailable())) + $error_array['rider'] = 'Selected rider is unavailable.'; } } } } - // set priority based on rider's existing open job orders - $rider_jos = $rider->getOpenJobOrders(); - - // get maximum priority then add 1 - // NOTE: this can be a bit buggy due to concurrency issues - // ideally have to lock jo table, but that isn't feasible right now - $priority = 0; - foreach ($rider_jos as $rider_jo) - { - if ($priority < $rider_jo->getPriority()) - $priority = $rider_jo->getPriority() + 1; - } - // get discount and set to meta - $discount = $req->request->get('invoice_discount', []); - - // check if discount is greater than 50 or negative number - if (($discount > 50) || ($discount < 0)) + $discount = $req->request->get('invoice_discount'); + + if (($discount > 60) || ($discount < 0)) + { $error_array['invoice_discount'] = 'Invalid discount specified'; + } // get list of service charges $service_charges = $req->request->get('service_charges', []); if (empty($error_array)) { + // set priority based on rider's existing open job orders + $rider_jos = $rider->getOpenJobOrders(); + + // get maximum priority then add 1 + // NOTE: this can be a bit buggy due to concurrency issues + // ideally have to lock jo table, but that isn't feasible right now + $priority = 0; + foreach ($rider_jos as $rider_jo) + { + if ($priority < $rider_jo->getPriority()) + $priority = $rider_jo->getPriority() + 1; + } + // get current user $user = $this->security->getUser(); @@ -589,22 +619,31 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface ->setServiceType($stype) ->setWarrantyClass($req->request->get('warranty_class')) ->setSource($req->request->get('source')) - ->setStatus(JOStatus::ASSIGNED) ->setDeliveryInstructions($req->request->get('delivery_instructions')) ->setTier1Notes($req->request->get('tier1_notes')) ->setTier2Notes($req->request->get('tier2_notes')) ->setDeliveryAddress($req->request->get('delivery_address')) ->setORName($req->request->get('or_name')) - ->setPromoDetail($req->request->get('promo_detail')) + ->setPromoDetail($req->request->get('promo_detail', '')) ->setModeOfPayment($req->request->get('mode_of_payment')) ->setLandmark($req->request->get('landmark')) ->setHub($hub) ->setRider($rider) - ->setPriority($priority); + ->setPriority($priority) + ->setResponsibleParty($req->request->get('responsible_party', '')); $jo->addMeta('discount', $discount); $jo->addMeta('service_charges', $service_charges); + // TODO: what happens if hub and rider are changed + // and JO is already in_transit or in_progress? + + // retain old jo status if it's an update JO + if ($old_jo_status != null) + $jo->setStatus($old_jo_status); + else + $jo->setStatus(JOStatus::ASSIGNED); + // check if user is null, meaning call to create came from API if ($user != null) { @@ -651,7 +690,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::CREATE) + ->setTypeID(CMBJOEventType::CREATE) ->setJobOrder($jo); if ($user != null) @@ -661,6 +700,21 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $em->persist($event); $em->flush(); + + // check if JO has been reassigned + //if ($old_rider != $rider) + if ($old_jo_status != $jo->getStatus()) + { + error_log('JO has been reassigned'); + // TODO: refactor later + $channel = 'rider/' . $rider->getID() . '/events'; + $payload = [ + 'event' => 'new_jo', + 'jo_id' => $jo->getID(), + ]; + + $mclient->publish($channel, json_encode($payload)); + } } } @@ -775,7 +829,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::HUB_ASSIGN) + ->setTypeID(CMBJOEventType::HUB_ASSIGN) ->setJobOrder($obj); if ($user != null) @@ -874,7 +928,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::RIDER_ASSIGN) + ->setTypeID(CMBJOEventType::RIDER_ASSIGN) ->setJobOrder($obj); if ($user != null) @@ -945,7 +999,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::FULFILL) + ->setTypeID(CMBJOEventType::FULFILL) ->setJobOrder($obj); // get current user @@ -1043,7 +1097,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::CANCEL) + ->setTypeID(CMBJOEventType::CANCEL) ->setJobOrder($obj); // get current user @@ -1153,7 +1207,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // add event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::HUB_ASSIGN) + ->setTypeID(CMBJOEventType::HUB_ASSIGN) ->setJobOrder($obj); if ($user != null) @@ -1353,7 +1407,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // add event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::RIDER_ASSIGN) + ->setTypeID(CMBJOEventType::RIDER_ASSIGN) ->setJobOrder($obj); if ($user != null) @@ -1425,9 +1479,19 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface public function initializeOneStepForm() { - $params['obj'] = new JobOrder(); + $new_jo = new JobOrder(); + + // set time schedule + $date_schedule = new DateTime(); + + // add 45 minutes to time + $date_schedule->add(new DateInterval('PT45M')); + $new_jo->setDateSchedule($date_schedule); + + $params['obj'] = $new_jo; $params['mode'] = 'onestep'; $params['jo_service_charges'] = []; + $params['current_date'] = new DateTime(); $this->fillDropdownParameters($params); $this->fillFormTags($params); @@ -1448,6 +1512,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $params['mode'] = 'onestep-edit'; $params['cvid'] = $obj->getCustomerVehicle()->getID(); $params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID(); + $params['current_date'] = new DateTime(); // get service charges $sc_array = []; @@ -1465,6 +1530,53 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $params['jo_service_charges'] = $sc_array; + // get odometer + $odometer = $obj->getMeta('odometer'); + + $params['odometer'] = $odometer; + + // get customer email used in JO + $email = $obj->getMeta('customer_email'); + + $params['email'] = $email; + + // get images if any + $jo_extra = $obj->getJOExtra(); + $pic_array = []; + $params['signature'] = null; + if ($jo_extra != null) + { + $img_1 = $jo_extra->getImage1Filename(); + $img_2 = $jo_extra->getImage2Filename(); + $img_3 = $jo_extra->getImage3Filename(); + $img_4 = $jo_extra->getImage4Filename(); + + $other_images = $jo_extra->getOtherImages(); + + $cust_signature = $jo_extra->getCustomerSignature(); + + if ($img_1 != null) + $pic_array['image_1'] = $img_1; + if ($img_2 != null) + $pic_array['image_2'] = $img_2; + if ($img_3 != null) + $pic_array['image_3'] = $img_3; + if ($img_4 != null) + $pic_array['image_4'] = $img_4; + + if ($other_images != null) + { + foreach ($other_images as $img) + { + $pic_array['other_images'][] = $img; + } + } + + $params['signature'] = $cust_signature; + } + + $params['jo_pictures'] = $pic_array; + $this->fillDropdownParameters($params); $this->fillFormTags($params); @@ -1587,7 +1699,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // get template to display // check transaction origin if walkin - if ($obj->getSource() == TransactionOrigin::WALK_IN) + if ($obj->getSource() == CMBTransactionOrigin::WALK_IN) $params['template'] = $this->getTwigTemplate('jo_walkin_form'); else $params['template'] = $this->getTwigTemplate('jo_onestep_form'); @@ -2427,8 +2539,19 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface public function initializeWalkinForm() { - $params['obj'] = new JobOrder(); + $new_jo = new JobOrder(); + + // set time schedule + $date_schedule = new DateTime(); + + // add 45 minutes to time + $date_schedule->add(new DateInterval('PT45M')); + $new_jo->setDateSchedule($date_schedule); + + $params['obj'] = $new_jo; $params['mode'] = 'walk-in'; + $params['discounts'] = $this->generateDiscountOptions(); + $params['current_date'] = new DateTime(); $this->fillDropdownParameters($params); $this->fillFormTags($params); @@ -2457,19 +2580,14 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // check if new customer if ($req->request->get('new_customer', false)) { - if (empty($req->request->get('customer_customer_notes'))) - { - $error_array['customer_customer_notes'] = 'Customer notes cannot be null.'; - } - // validate mobile phone - $valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('customer_phone_mobile')); + $valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('phone_mobile')); if (!($valid_mobile)) - $error_array['customer_phone_mobile'] = 'Invalid mobile phone number.'; + $error_array['phone_mobile'] = 'Invalid mobile phone number.'; // check if plate number is in request - if (empty($req->request->get('cv_plate'))) - $error_array['cv_plate'] = 'Plate number is required.'; + if (empty(trim($req->request->get('plate_number')))) + $error_array['plate_number'] = 'Plate number is required.'; // find the vehicle using vid $new_vehicle = $em->getRepository(Vehicle::class)->find($req->request->get('vid')); @@ -2484,17 +2602,17 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $new_cust = new Customer(); $new_cv = new CustomerVehicle(); - $new_cust->setLastName($req->request->get('customer_last_name')) - ->setFirstName($req->request->get('customer_first_name')) - ->setPhoneMobile($req->request->get('customer_phone_mobile')) - ->setPhoneLandline($req->request->get('customer_phone_landline')) - ->setPhoneOffice($req->request->get('customer_phone_office')) - ->setPhoneFax($req->request->get('customer_phone_fax')) - ->setCustomerNotes($req->request->get('customer_customer_notes')); + $new_cust->setLastName($req->request->get('last_name')) + ->setFirstName($req->request->get('first_name')) + ->setPhoneMobile($req->request->get('phone_mobile')) + ->setPhoneLandline($req->request->get('phone_landline')) + ->setPhoneOffice($req->request->get('phone_office')) + ->setPhoneFax($req->request->get('phone_fax')) + ->setCustomerNotes($req->request->get('customer_notes')); $new_cv->setCustomer($new_cust) ->setVehicle($new_vehicle) - ->setPlateNumber($req->request->get('cv_plate')) + ->setPlateNumber(trim($req->request->get('plate_number'))) ->setModelYear($req->request->get('cv_year')) ->setColor('') ->setStatusCondition('') @@ -2563,8 +2681,8 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // get discount and set to meta $discount = $req->request->get('invoice_discount'); - // check if discount is greater than 50 or negative number - if (($discount > 50) || ($discount < 0)) + // check if discount is greater than 60 or negative number + if (($discount > 60) || ($discount < 0)) $error_array['invoice_discount'] = 'Invalid discount specified'; if (empty($error_array)) @@ -2584,13 +2702,14 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface ->setTier1Notes($req->request->get('tier1_notes')) ->setTier2Notes($req->request->get('tier2_notes')) ->setORName($req->request->get('or_name')) - ->setPromoDetail($req->request->get('promo_detail')) + ->setPromoDetail($req->request->get('promo_detail', '')) ->setModeOfPayment($req->request->get('mode_of_payment')) ->setLandmark($req->request->get('landmark')) ->setDeliveryAddress('Walk-in') ->setLandmark('Walk-in') ->setCoordinates($hub_coordinates) - ->setHub($hub); + ->setHub($hub) + ->setResponsibleParty($req->request->get('responsible_party', '')); $jo->addMeta('discount', $discount); @@ -2640,7 +2759,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // the event $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::CREATE) + ->setTypeID(CMBJOEventType::CREATE) ->setJobOrder($jo); if ($user != null) @@ -2719,6 +2838,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $params['mode'] = 'walk-in-edit'; $params['cvid'] = $obj->getCustomerVehicle()->getID(); $params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID(); + $params['current_date'] = new DateTime(); $this->fillDropdownParameters($params); $this->fillFormTags($params); @@ -2756,7 +2876,10 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $params['trade_in_types'] = CMBTradeInType::getCollection(); $params['facilitated_types'] = FacilitatedType::getCollection(); $params['facilitated_hubs'] = $fac_hubs; - $params['sources'] = TransactionOrigin::getCollection(); + $params['sources'] = CMBTransactionOrigin::getCollection(); + + $params['model_years'] = $this->generateYearOptions(); + $params['discounts'] = $this->generateDiscountOptions(); } protected function initFormTags(&$params) @@ -2843,6 +2966,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $this->template_hash['jo_walkin_form'] = 'job-order/cmb.form.walkin.html.twig'; $this->template_hash['jo_walkin_edit_form'] = 'job-order/cmb.form.walkin.html.twig'; $this->template_hash['jo_popup'] = 'job-order/cmb.popup.html.twig'; + $this->template_hash['jo_behind_schedule'] = 'job-order/cmb.list.behindschedule.html.twig'; } protected function checkTier($tier) @@ -2898,6 +3022,14 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $unlock_route = ''; $jo_status = ''; break; + case 'behind_schedule': + $tier_key = 'jo_behind_schedule'; + $tier_name = 'Behind Schedule'; + $rows_route = 'jo_behind_schedule_rows'; + $edit_route = ''; + $unlock_route = ''; + $jo_status = JOStatus::ASSIGNED; + break; default: throw new AccessDeniedHttpException('No access.'); } @@ -3028,6 +3160,53 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface ->setParameter('date_start', $date_start) ->setParameter('date_end', $date_end); } + break; + case 'behind_schedule': + if (isset($datatable['query']['data-rows-search'])) + { + $query->innerJoin('q.cus_vehicle', 'cv') + ->innerJoin('q.customer', 'c') + ->where('cv.plate_number like :filter') + ->orWhere('c.phone_mobile like :filter') + ->orWhere('c.first_name like :filter or c.last_name like :filter') + ->setParameter('filter', $datatable['query']['data-rows-search'] . '%'); + } + if (isset($datatable['query']['rider'])) + { + $query->innerJoin('q.rider', 'r') + ->andWhere('r.id = :rider_id') + ->setParameter('rider_id', $datatable['query']['rider']); + } + if (isset($datatable['query']['schedule_date'])) + { + $start = $datatable['query']['schedule_date'][0] . ' ' . '00:00:00'; + $end = $datatable['query']['schedule_date'][1] . ' ' . '23:59:00'; + + $date_start = DateTime::createFromFormat('m/d/Y H:i:s', $start); + $date_end = DateTime::createFromFormat('m/d/Y H:i:s', $end); + + $query->andWhere('q.date_schedule >= :date_start') + ->andWhere('q.date_schedule <= :date_end') + ->setParameter('date_start', $date_start) + ->setParameter('date_end', $date_end); + } + // status should be assigned + $query->andWhere('q.status = :status') + ->setParameter('status', $status); + + $current_datetime = new DateTime(); + $other_date = new DateTime(); + + $interval = new DateInterval('PT15M'); + $other_date->add($interval); + + //error_log('current datetime ' . $current_datetime->format('Y-m-d H:i:s')); + //error_log('other_date ' . $other_date->format('Y-m-d H:i:s')); + + $query->andWhere('q.date_schedule < :current_datetime OR q.date_schedule <= :other_date') + ->setParameter('current_datetime', $current_datetime) + ->setParameter('other_date', $other_date); + break; default: $query->where('q.status = :status') @@ -3042,9 +3221,21 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface throw new NotFoundHttpException('The item does not exist'); // check transaction origin - if ($jo->getSource() == TransactionOrigin::WALK_IN) + if ($jo->getSource() == CMBTransactionOrigin::WALK_IN) return 'jo_walkin_edit_form'; else return 'jo_onestep_edit_form'; } + + protected function generateDiscountOptions() + { + $discount_start = 0; + return range($discount_start, 60); + } + + protected function generateYearOptions() + { + $start_year = 1950; + return range($start_year, date("Y")); + } } diff --git a/src/Service/JobOrderHandlerInterface.php b/src/Service/JobOrderHandlerInterface.php index 590a0926..22320c18 100644 --- a/src/Service/JobOrderHandlerInterface.php +++ b/src/Service/JobOrderHandlerInterface.php @@ -25,7 +25,7 @@ interface JobOrderHandlerInterface public function generateJobOrder(Request $req, int $id); // process one step job order - public function processOneStepJobOrder(Request $req, int $id); + //public function processOneStepJobOrder(Request $req, int $id, MQTTClient $mclient); // dispatch job order public function dispatchJobOrder(Request $req, int $id, MQTTClient $mclient); diff --git a/src/Service/RiderAPIHandler/CMBRiderAPIHandler.php b/src/Service/RiderAPIHandler/CMBRiderAPIHandler.php index 3c0236e1..282f6bb6 100644 --- a/src/Service/RiderAPIHandler/CMBRiderAPIHandler.php +++ b/src/Service/RiderAPIHandler/CMBRiderAPIHandler.php @@ -7,12 +7,13 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; use App\Ramcar\CMBServiceType; -use App\Ramcar\CMBTradeInType; +use App\Ramcar\TradeInType; use App\Ramcar\JOStatus; -use App\Ramcar\JOEventType; +use App\Ramcar\CMBJOEventType; use App\Ramcar\InvoiceStatus; -use App\Ramcar\ModeOfPayment; +use App\Ramcar\CMBModeOfPayment; use App\Ramcar\InvoiceCriteria; +use App\Ramcar\CMBCancelReason; use App\Service\RiderAPIHandlerInterface; use App\Service\RedisClientProvider; @@ -21,6 +22,7 @@ use App\Service\MQTTClient; use App\Service\WarrantyHandler; use App\Service\JobOrderHandlerInterface; use App\Service\InvoiceGeneratorInterface; +use App\Service\RiderTracker; use App\Entity\RiderSession; use App\Entity\Rider; @@ -30,12 +32,16 @@ use App\Entity\Promo; use App\Entity\Battery; use App\Entity\BatteryModel; use App\Entity\BatterySize; -use App\Entity\Warranty; +use App\Entity\JobOrder; +use App\Entity\JOExtra; use DateTime; +use DateInterval; class CMBRiderAPIHandler implements RiderAPIHandlerInterface { + // NOTE: Rider's constructor sets flag_available and flag_active to true, by default. + protected $em; protected $redis; protected $ef; @@ -46,12 +52,14 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface protected $jo_handler; protected $ic; protected $session; + protected $upload_dir; public function __construct(EntityManagerInterface $em, RedisClientProvider $redis, EncoderFactoryInterface $ef, RiderCache $rcache, string $country_code, MQTTClient $mclient, WarrantyHandler $wh, JobOrderHandlerInterface $jo_handler, - InvoiceGeneratorInterface $ic) + InvoiceGeneratorInterface $ic, string $upload_dir, + RiderTracker $rider_tracker) { $this->em = $em; $this->redis = $redis; @@ -62,6 +70,8 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $this->wh = $wh; $this->jo_handler = $jo_handler; $this->ic = $ic; + $this->upload_dir = $upload_dir; + $this->rider_tracker = $rider_tracker; // one device = one session, since we have control over the devices // when a rider logs in, we just change the rider assigned to the device @@ -82,11 +92,16 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface { $params = implode(', ', $missing); $data = [ + 'title' => 'Failed Registration', 'error' => 'Missing parameter(s): ' . $params ]; return $data; } + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + // retry until we get a unique id while (true) { @@ -143,12 +158,16 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface ]; $data = $this->checkParamsAndKey($req, $required_params); if (isset($data['error'])) + { + $data['title'] = 'Failed Login'; return $data; + } // check if session has a rider already if ($this->session->hasRider()) { $data = [ + 'title' => 'Failed Login', 'error' => 'Another rider is already logged in. Please logout first.' ]; return $data; @@ -159,6 +178,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface if ($rider == null) { $data = [ + 'title' => 'Failed Login', 'error' => 'Invalid username or password.' ]; return $data; @@ -169,15 +189,21 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface if (!$encoder->isPasswordValid($rider->getPassword(), $req->request->get('pass'), '')) { $data = [ + 'title' => 'Failed Login', 'error' => 'Invalid username or password.' ]; return $data; } + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + // assign rider to session $this->session->setRider($rider); - $rider->setAvailable(true); + //$rider->setAvailable(true); + $rider->setActive(true); $rider_id = $rider->getID(); // cache rider location (default to hub) @@ -225,11 +251,31 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $required_params = []; $data = $this->checkParamsAndKey($req, $required_params); if (isset($data['error'])) + { + $data['title'] = 'Failed Logout'; return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); // make rider unavailable $rider = $this->session->getRider(); + + // check if rider has assigned JOs + $assigned_jos = $this->em->getRepository(JobOrder::class)->findBy(['rider' => $rider->getID(), 'status' => JOStatus::ASSIGNED]); + if ($assigned_jos != null) + { + $data = [ + 'title' => 'Failed Logout', + 'error' => 'Rider has assigned job orders.' + ]; + return $data; + } + $rider->setAvailable(false); + $rider->setActive(false); // remove from cache $this->rcache->removeActiveRider($rider->getID()); @@ -244,45 +290,473 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface return $data; } - public function getJobOrder(Request $req) + public function goOnline(Request $req) { - // get the job order of the rider assigned to this session $required_params = []; $data = $this->checkParamsAndKey($req, $required_params); if (isset($data['error'])) + { + $data['title'] = 'Failed Go Online'; return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + // set rider to available to take on JOs + $rider = $this->session->getRider(); + + $rider->setAvailable(true); + + $this->em->flush(); + + // send mqtt event to put rider on map + // get rider coordinates from redis + $coord = $this->rider_tracker->getRiderLocation($rider->getID()); + + $lng = $coord->getLongitude(); + $lat = $coord->getLatitude();; + $channel = 'rider/' . $rider->getID() . '/availability'; + $payload = [ + 'status' => 'rider_online', + 'longitude' => $lng, + 'latitude' => $lat, + ]; + $this->mclient->publish($channel, json_encode($payload)); + + return $data; + } + + public function goOffline(Request $req) + { + $required_params = []; + $data = $this->checkParamsAndKey($req, $required_params); + if (isset($data['error'])) + { + $data['title'] = 'Failed Go Offline'; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + // set rider to unavailable to take on JOs + $rider = $this->session->getRider(); + + // check if rider has assigned JOs + $assigned_jos = $this->em->getRepository(JobOrder::class)->findBy(['rider' => $rider->getID(), 'status' => JOStatus::ASSIGNED]); + if ($assigned_jos != null) + { + $data = [ + 'title' => 'Failed Go Offline', + 'error' => 'Rider has assigned job orders.' + ]; + return $data; + } + + $rider->setAvailable(false); + + $this->em->flush(); + + // send mqtt event to remove rider from map + $channel = 'rider/' . $rider->getID() . '/availability'; + $payload = [ + 'status' => 'rider_offline' + ]; + $this->mclient->publish($channel, json_encode($payload)); + + return $data; + + } + + public function getJobOrderHistory(Request $req, $period) + { + $required_params = []; + $data = $this->checkParamsAndKey($req, $required_params); + if (isset($data['error'])) + { + $data['title'] = 'Failed Get Job Order History'; + return $data; + } // are we logged in? if (!$this->session->hasRider()) { $data = [ + 'title' => 'Failed Get Job Order History', 'error' => 'No logged in rider.' ]; return $data; } + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + $rider = $this->session->getRider(); - // do we have a job order? - $jo = $rider->getActiveJobOrder(); - if ($jo == null) + // get JOs assigned to rider for the month given + // setup start date and end dates + // get current year + $current_date = new DateTime(); + + if ($period == 'lastmonth') { - $data = [ - 'job_order' => null - ]; + $date_interval = new DateInterval('P1M'); + $period_date = $current_date->sub($date_interval); } else - { - $coord = $jo->getCoordinates(); - $cust = $jo->getCustomer(); - $cv = $jo->getCustomerVehicle(); - $v = $cv->getVehicle(); - $inv = $jo->getInvoice(); - $promo = $inv->getPromo(); + $period_date = $current_date; - // invoice items - $inv_items = []; - foreach ($inv->getItems() as $item) + $period_year = $period_date->format('Y'); + $period_month = $period_date->format('m'); + + // get number of days in month requested + $last_day = cal_days_in_month(CAL_GREGORIAN, $period_month, $period_year); + + $s_date = $period_year . '-' . $period_month . '-01 00:00:00'; + $e_date = $period_year . '-' . $period_month . '-' . $last_day . ' 23:59:59'; + + $qb = $this->em->getRepository(JobOrder::class)->createQueryBuilder('j'); + + $query = $qb->innerJoin('j.rider', 'r') + ->where('j.date_schedule >= :start') + ->andWhere('j.date_schedule <= :end') + ->andWhere('r.id = :rider_id') + ->setParameter('start', $s_date) + ->setParameter('end', $e_date) + ->setParameter('rider_id', $rider->getID()) + ->getQuery(); + + $jo_results = $query->getResult(); + + $jo_data = []; + + if (!(empty($jo_results))) + { + foreach ($jo_results as $jo) + { + // TODO: refactor this to call formatJobOrderData + $coord = $jo->getCoordinates(); + $cust = $jo->getCustomer(); + $cv = $jo->getCustomerVehicle(); + $v = $cv->getVehicle(); + $inv = $jo->getInvoice(); + $promo = $inv->getPromo(); + + // invoice items + $inv_items = []; + foreach ($inv->getItems() as $item) + { + // if more than 1, split it into one of each of the same item + $item_qty = $item->getQuantity(); + for ($i = 0; $i < $item_qty; $i++) + { + $item_batt = $item->getBattery(); + if ($item_batt == null) + $batt_id = null; + else + $batt_id = $item_batt->getID(); + + $inv_items[] = [ + 'id' => $item->getID(), + 'title' => $item->getTitle(), + 'qty' => 1, + 'price' => $item->getPrice(), + 'batt_id' => $batt_id, + ]; + } + } + + // promo + if ($promo != null) + { + $promo_data = [ + 'id' => $promo->getID(), + 'name' => $promo->getName(), + 'code' => $promo->getCode(), + 'discount_rate' => $promo->getDiscountRate(), + 'discount_apply' => $promo->getDiscountApply(), + ]; + } + else + { + $promo_data = null; + } + + $trade_in_type = $jo->getTradeInType(); + if (empty($trade_in_type)) + $trade_in_type = 'none'; + + // get time when JO was accepted by rider + $accept_event_type = CMBJOEventType::RIDER_ACCEPT; + $rider_id = $this->session->getRider()->getID(); + $jo_id = $jo->getID(); + $date_accept = ''; + + $accept_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $accept_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); + if ($accept_results != null) + { + $jo_event = current($accept_results); + $date_accept = $jo_event->getDateHappen()->format('Ymd H:i:s'); + } + + // get time when JO was started by rider + $start_event_type = CMBJOEventType::RIDER_START; + $date_start = ''; + $start_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $start_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); + if ($start_results != null) + { + $jo_event = current($start_results); + $date_start = $jo_event->getDateHappen()->format('Ymd H:i:s'); + } + + // get time when JO was completed by rider + $complete_event_type = CMBJOEventType::RIDER_FINISH; + $date_complete = ''; + $complete_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $complete_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); + if ($complete_results != null) + { + $jo_event = current($complete_results); + $date_complete = $jo_event->getDateHappen()->format('Ymd H:i:s'); + } + else + { + // find the time when photos were uploaded + $upload_event_type = CMBJOEventType::RIDER_UPLOAD_PHOTO; + $upload_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $upload_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); + if ($upload_results != null) + { + $jo_event = current($upload_results); + $date_complete = $jo_event->getDateHappen()->format('Ymd H:i:s'); + } + } + + $jo_data[] = [ + 'job_order' => [ + 'id' => $jo->getID(), + 'service_type' => $jo->getServiceType(), + 'date_schedule' => $jo->getDateSchedule()->format('Ymd H:i:s'), + 'longitude' => $coord->getLongitude(), + 'latitude' => $coord->getLatitude(), + 'status' => $jo->getStatus(), + 'customer' => [ + 'title' => $cust->getTitle(), + 'first_name' => $cust->getFirstName(), + 'last_name' => $cust->getLastName(), + 'phone_mobile' => $this->country_code . $cust->getPhoneMobile(), + 'phone_landline' => $this->country_code . $cust->getPhoneLandline(), + ], + 'vehicle' => [ + 'manufacturer' => $v->getManufacturer()->getName(), + 'make' => $v->getMake(), + 'model' => $cv->getModelYear(), + 'plate_number' => $cv->getPlateNumber(), + 'color' => $cv->getColor(), + ], + 'or_num' => $jo->getORNum(), + 'or_name' => $jo->getORName(), + 'delivery_instructions' => $jo->getDeliveryInstructions(), + 'delivery_address' => $jo->getDeliveryAddress(), + 'landmark' => $jo->getLandmark(), + 'invoice' => [ + 'discount' => $inv->getDiscount(), + 'trade_in' => $inv->getTradeIn(), + 'total_price' => $inv->getTotalPrice(), + 'vat' => $inv->getVat(), + 'items' => $inv_items, + ], + 'mode_of_payment' => $jo->getModeOfPayment(), + 'mode_of_payment_display' => CMBModeOfPayment::getName($jo->getModeOfPayment()), + 'trade_in_type' => $trade_in_type, + 'promo' => $promo_data, + // TODO: load the actual + 'has_warranty_doc' => false, + 'flag_coolant' => $jo->hasCoolant(), + 'has_motolite' => $cv->hasMotoliteBattery(), + // date and time accepted and started + 'date_accept' => $date_accept, + 'date_start' => $date_start, + 'date_complete' => $date_complete, + ] + ]; + } + } + + $data = [ + 'jo_history' => $jo_data, + ]; + + return $data; + } + + public function getAssignedJobOrders(Request $req) + { + $required_params = []; + $data = $this->checkParamsAndKey($req, $required_params); + if (isset($data['error'])) + { + $data['title'] = 'Failed Get Assigned Job Orders'; + return $data; + } + + // are we logged in? + if (!$this->session->hasRider()) + { + $data = [ + 'title' => 'Failed Get Assigned Job Orders', + 'error' => 'No logged in rider.' + ]; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + $rider = $this->session->getRider(); + + $qb = $this->em->getRepository(JobOrder::class)->createQueryBuilder('j'); + + $query = $qb->innerJoin('j.rider', 'r') + ->andWhere('r.id = :rider_id') + ->andWhere('j.status = :status') + ->setParameter('rider_id', $rider->getID()) + ->setParameter('status', JOStatus::ASSIGNED) + ->getQuery(); + + $jo_results = $query->getResult(); + + $jo_data = []; + + if (!(empty($jo_results))) + { + foreach ($jo_results as $jo) + { + // TODO: refactor this to call formatJobOrderData + $coord = $jo->getCoordinates(); + $cust = $jo->getCustomer(); + $cv = $jo->getCustomerVehicle(); + $v = $cv->getVehicle(); + $inv = $jo->getInvoice(); + $promo = $inv->getPromo(); + + // invoice items + $inv_items = []; + foreach ($inv->getItems() as $item) + { + // if more than 1, split it into one of each of the same item + $item_qty = $item->getQuantity(); + for ($i = 0; $i < $item_qty; $i++) + { + $item_batt = $item->getBattery(); + if ($item_batt == null) + $batt_id = null; + else + $batt_id = $item_batt->getID(); + + $inv_items[] = [ + 'id' => $item->getID(), + 'title' => $item->getTitle(), + 'qty' => 1, + 'price' => $item->getPrice(), + 'batt_id' => $batt_id, + ]; + } + } + + // promo + if ($promo != null) + { + $promo_data = [ + 'id' => $promo->getID(), + 'name' => $promo->getName(), + 'code' => $promo->getCode(), + 'discount_rate' => $promo->getDiscountRate(), + 'discount_apply' => $promo->getDiscountApply(), + ]; + } + else + { + $promo_data = null; + } + + $trade_in_type = $jo->getTradeInType(); + if (empty($trade_in_type)) + $trade_in_type = 'none'; + + $jo_data[] = [ + 'job_order' => [ + 'id' => $jo->getID(), + 'service_type' => $jo->getServiceType(), + 'date_schedule' => $jo->getDateSchedule()->format('Ymd H:i:s'), + 'longitude' => $coord->getLongitude(), + 'latitude' => $coord->getLatitude(), + 'status' => $jo->getStatus(), + 'customer' => [ + 'title' => $cust->getTitle(), + 'first_name' => $cust->getFirstName(), + 'last_name' => $cust->getLastName(), + 'phone_mobile' => $this->country_code . $cust->getPhoneMobile(), + 'phone_landline' => $this->country_code . $cust->getPhoneLandline(), + ], + 'vehicle' => [ + 'manufacturer' => $v->getManufacturer()->getName(), + 'make' => $v->getMake(), + 'model' => $cv->getModelYear(), + 'plate_number' => $cv->getPlateNumber(), + 'color' => $cv->getColor(), + ], + 'or_num' => $jo->getORNum(), + 'or_name' => $jo->getORName(), + 'delivery_instructions' => $jo->getDeliveryInstructions(), + 'delivery_address' => $jo->getDeliveryAddress(), + 'landmark' => $jo->getLandmark(), + 'invoice' => [ + 'discount' => $inv->getDiscount(), + 'trade_in' => $inv->getTradeIn(), + 'total_price' => $inv->getTotalPrice(), + 'vat' => $inv->getVat(), + 'items' => $inv_items, + ], + 'mode_of_payment' => $jo->getModeOfPayment(), + 'mode_of_payment_display' => CMBModeOfPayment::getName($jo->getModeOfPayment()), + 'trade_in_type' => $trade_in_type, + 'promo' => $promo_data, + // TODO: load the actual + 'has_warranty_doc' => false, + 'flag_coolant' => $jo->hasCoolant(), + 'has_motolite' => $cv->hasMotoliteBattery(), + ] + ]; + } + } + + $data = [ + 'assigned_jos' => $jo_data, + ]; + + return $data; + } + + protected function formatJobOrderData($req, $jo) + { + $coord = $jo->getCoordinates(); + $cust = $jo->getCustomer(); + $cv = $jo->getCustomerVehicle(); + $v = $cv->getVehicle(); + $inv = $jo->getInvoice(); + $promo = $inv->getPromo(); + + // invoice items + $inv_items = []; + foreach ($inv->getItems() as $item) + { + // if more than 1, split it into one of each of the same item + $item_qty = $item->getQuantity(); + for ($i = 0; $i < $item_qty; $i++) { $item_batt = $item->getBattery(); if ($item_batt == null) @@ -290,90 +764,258 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface else $batt_id = $item_batt->getID(); - $inv_items[] = [ + $inv_items[] = [ 'id' => $item->getID(), 'title' => $item->getTitle(), - 'qty' => $item->getQuantity(), + 'qty' => 1, 'price' => $item->getPrice(), 'batt_id' => $batt_id, ]; } + } - // promo - if ($promo != null) - { - $promo_data = [ - 'id' => $promo->getID(), - 'name' => $promo->getName(), - 'code' => $promo->getCode(), - 'discount_rate' => $promo->getDiscountRate(), - 'discount_apply' => $promo->getDiscountApply(), - ]; - } - else - { - $promo_data = null; - } - - $trade_in_type = $jo->getTradeInType(); - if (empty($trade_in_type)) - $trade_in_type = 'none'; - - $data = [ - 'job_order' => [ - 'id' => $jo->getID(), - 'service_type' => $jo->getServiceType(), - 'date_schedule' => $jo->getDateSchedule()->format('Ymd H:i:s'), - 'longitude' => $coord->getLongitude(), - 'latitude' => $coord->getLatitude(), - 'status' => $jo->getStatus(), - 'customer' => [ - 'title' => $cust->getTitle(), - 'first_name' => $cust->getFirstName(), - 'last_name' => $cust->getLastName(), - 'phone_mobile' => $this->country_code . $cust->getPhoneMobile(), - ], - 'vehicle' => [ - 'manufacturer' => $v->getManufacturer()->getName(), - 'make' => $v->getMake(), - 'model' => $cv->getModelYear(), - 'plate_number' => $cv->getPlateNumber(), - 'color' => $cv->getColor(), - ], - 'or_num' => $jo->getORNum(), - 'or_name' => $jo->getORName(), - 'delivery_instructions' => $jo->getDeliveryInstructions(), - 'delivery_address' => $jo->getDeliveryAddress(), - 'landmark' => $jo->getLandmark(), - 'invoice' => [ - 'discount' => $inv->getDiscount(), - 'trade_in' => $inv->getTradeIn(), - 'total_price' => $inv->getTotalPrice(), - 'vat' => $inv->getVat(), - 'items' => $inv_items, - ], - 'mode_of_payment' => $jo->getModeOfPayment(), - 'trade_in_type' => $trade_in_type, - 'promo' => $promo_data, - // TODO: load the actual - 'has_warranty_doc' => false, - 'flag_coolant' => $jo->hasCoolant(), - 'has_motolite' => $cv->hasMotoliteBattery(), - ] + // promo + if ($promo != null) + { + $promo_data = [ + 'id' => $promo->getID(), + 'name' => $promo->getName(), + 'code' => $promo->getCode(), + 'discount_rate' => $promo->getDiscountRate(), + 'discount_apply' => $promo->getDiscountApply(), ]; } + else + { + $promo_data = null; + } + + $trade_in_type = $jo->getTradeInType(); + if (empty($trade_in_type)) + $trade_in_type = 'none'; + + // get date of status last change + if ($jo->getDateStatusChange() == null) + $date_status_change = null; + else + $date_status_change = $jo->getDateStatusChange()->format('Ymd H:i:s'); + + // get odometer reading + $odo = $jo->getMeta('odometer'); + if ($odo <= 0) + $odo = 0; + + $images = [ + 'image_1' => null, + 'image_2' => null, + 'image_3' => null, + 'image_4' => null, + 'others' => [], + ]; + $jo_extra = $jo->getJOExtra(); + if ($jo_extra != null) + { + $images['image_1'] = $this->getURLExtraImage($req, $jo_extra->getImage1Filename()); + $images['image_2'] = $this->getURLExtraImage($req, $jo_extra->getImage2Filename()); + $images['image_3'] = $this->getURLExtraImage($req, $jo_extra->getImage3Filename()); + $images['image_4'] = $this->getURLExtraImage($req, $jo_extra->getImage4Filename()); + + // other images + $other_images = []; + foreach ($jo_extra->getOtherImages() as $others) + { + $other_images[] = $this->getURLExtraImage($req, $others); + } + $images['others'] = $other_images; + } + + // customer email + if ($jo->getMeta('customer_email') == null) + $cust_email = ''; + else + $cust_email = $jo->getMeta('customer_email'); + + // get time when JO was accepted by rider + $accept_event_type = CMBJOEventType::RIDER_ACCEPT; + $rider_id = $this->session->getRider()->getID(); + $jo_id = $jo->getID(); + $date_accept = ''; + + $accept_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $accept_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); + if ($accept_results != null) + { + $jo_event = current($accept_results); + $date_accept = $jo_event->getDateHappen()->format('Ymd H:i:s'); + } + + // get time when JO was started by rider + $start_event_type = CMBJOEventType::RIDER_START; + $date_start = ''; + $start_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $start_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); + if ($start_results != null) + { + $jo_event = current($start_results); + $date_start = $jo_event->getDateHappen()->format('Ymd H:i:s'); + } + + // get time when JO was completed by rider + $complete_event_type = CMBJOEventType::RIDER_FINISH; + $date_complete = ''; + $complete_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $complete_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); + if ($complete_results != null) + { + $jo_event = current($complete_results); + $date_complete = $jo_event->getDateHappen()->format('Ymd H:i:s'); + } + else + { + // find the time when photos were uploaded + $upload_event_type = CMBJOEventType::RIDER_UPLOAD_PHOTO; + $upload_results = $this->em->getRepository(JOEvent::class)->findby(['type_id' => $upload_event_type, 'rider' => $rider_id, 'job_order' => $jo_id], ['date_happen' => 'DESC']); + if ($upload_results != null) + { + $jo_event = current($upload_results); + $date_complete = $jo_event->getDateHappen()->format('Ymd H:i:s'); + } + } + + $data = [ + 'id' => $jo->getID(), + 'service_type' => $jo->getServiceType(), + 'date_schedule' => $jo->getDateSchedule()->format('Ymd H:i:s'), + 'longitude' => $coord->getLongitude(), + 'latitude' => $coord->getLatitude(), + 'status' => $jo->getStatus(), + 'date_status_change' => $date_status_change, + 'customer' => [ + 'title' => $cust->getTitle(), + 'first_name' => $cust->getFirstName(), + 'last_name' => $cust->getLastName(), + 'phone_mobile' => $this->country_code . $cust->getPhoneMobile(), + 'phone_landline' => $this->country_code . $cust->getPhoneLandline(), + ], + 'vehicle' => [ + 'manufacturer' => $v->getManufacturer()->getName(), + 'make' => $v->getMake(), + 'model' => $cv->getModelYear(), + 'plate_number' => $cv->getPlateNumber(), + 'color' => $cv->getColor(), + ], + 'or_num' => $jo->getORNum(), + 'or_name' => $jo->getORName(), + 'delivery_instructions' => $jo->getDeliveryInstructions(), + 'delivery_address' => $jo->getDeliveryAddress(), + 'landmark' => $jo->getLandmark(), + 'invoice' => [ + 'discount' => $inv->getDiscount(), + 'trade_in' => $inv->getTradeIn(), + 'total_price' => $inv->getTotalPrice(), + 'vat' => $inv->getVat(), + 'items' => $inv_items, + ], + 'mode_of_payment' => $jo->getModeOfPayment(), + 'mode_of_payment_display' => CMBModeOfPayment::getName($jo->getModeOfPayment()), + 'trade_in_type' => $trade_in_type, + 'promo' => $promo_data, + // TODO: load the actual + 'has_warranty_doc' => false, + 'flag_coolant' => $jo->hasCoolant(), + 'has_motolite' => $cv->hasMotoliteBattery(), + + // BEGIN: cmb specific details + + // odometer + 'odometer' => $odo, + + // images + 'finish_photos' => $images, + + // customer email + 'customer_email' => $cust_email, + + // date and time accepted and started + 'date_accept' => $date_accept, + 'date_start' => $date_start, + 'date_complete' => $date_complete, + + // END: cmb specific details + ]; + + return $data; + } + + public function getJobOrder(Request $req) + { + $required_params = [ + 'jo_id' + ]; + $data = $this->checkJO($req, $required_params, $jo); + if (isset($data['error'])) + { + $data['title'] = 'Failed Get Job Order'; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + $jo_data = $this->formatJobOrderData($req, $jo); + + $data = [ + 'job_order' => $jo_data + ]; return $data; } public function acceptJobOrder(Request $req) { - $required_params = ['jo_id']; + $required_params = [ + 'jo_id' + ]; $data = $this->checkJO($req, $required_params, $jo); if (isset($data['error'])) + { + $data['title'] = 'Failed Accept Job Order'; return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + // TODO: put JO in job queue // TODO: refactor this into a jo handler class, so we don't have to repeat for control center + // TODO: send mqtt event (?) + // add event log + $rider = $this->session->getRider(); + $event = new JOEvent(); + $event->setDateHappen(new DateTime()) + ->setTypeID(CMBJOEventType::RIDER_ACCEPT) + ->setJobOrder($jo) + ->setRider($rider); + $this->em->persist($event); + + $this->em->flush(); + + return $data; + } + + public function setJobOrderInTransit(Request $req) + { + $required_params = ['jo_id']; + $data = $this->checkActiveJO($req, $required_params, $jo); + if (isset($data['error'])) + { + $data['title'] = 'Failed Set Job Order in Transit'; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); // set jo status to in transit $jo->setStatus(JOStatus::IN_TRANSIT); @@ -384,7 +1026,43 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $rider = $this->session->getRider(); $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::RIDER_ACCEPT) + ->setTypeID(CMBJOEventType::RIDER_IN_TRANSIT) + ->setJobOrder($jo) + ->setRider($rider); + $this->em->persist($event); + + $this->em->flush(); + + return $data; + + } + + public function cancelJobOrder(Request $req) + { + $required_params = [ + 'jo_id', + 'cancel_reason' + ]; + $data = $this->checkJO($req, $required_params, $jo); + if (isset($data['error'])) + { + $data['title'] = 'Failed Job Order Cancellation'; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + $cancel_reason = $req->request->get('cancel_reason'); + + $jo->cancel($cancel_reason); + + // add event log + $rider = $this->session->getRider(); + $event = new JOEvent(); + $event->setDateHappen(new DateTime()) + ->setTypeID(CMBJOEventType::REQUEUE) ->setJobOrder($jo) ->setRider($rider); $this->em->persist($event); @@ -394,28 +1072,74 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface return $data; } - public function cancelJobOrder(Request $req) + public function performJobOrder(Request $req) { - $required_params = ['jo_id']; + $required_params = [ + 'jo_id', + ]; + $data = $this->checkJO($req, $required_params, $jo); if (isset($data['error'])) + { + $data['title'] = 'Failed Job Order Perform'; return $data; + } - // $jo->cancel("rider cancelled"); - // requeue it, instead of cancelling it - $jo->requeue(); + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + $jo->perform(); // add event log $rider = $this->session->getRider(); $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::REQUEUE) + ->setTypeID(CMBJOEventType::PERFORM) ->setJobOrder($jo) ->setRider($rider); $this->em->persist($event); $this->em->flush(); + return $data; + } + + public function rejectJobOrder(Request $req) + { + $required_params = [ + 'jo_id' + ]; + $data = $this->checkJO($req, $required_params, $jo); + if (isset($data['error'])) + { + $data['title'] = 'Failed Job Order Rejection'; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + $jo->requeue(); + + // set rider to null + $jo->clearRider(); + + // add event log + $rider = $this->session->getRider(); + $event = new JOEvent(); + $event->setDateHappen(new DateTime()) + ->setTypeID(CMBJOEventType::REQUEUE) + ->setJobOrder($jo) + ->setRider($rider); + $this->em->persist($event); + + // set rider's active JO to null + $rider->setActiveJobOrder(); + + $this->em->flush(); + // send mqtt event // send outlet assign since order should go back to hub and await reassignment to another rider $payload = [ @@ -424,15 +1148,28 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface ]; $this->mclient->sendEvent($jo, $payload); + // send available event to change rider icon status + $channel = 'rider/' . $rider->getID() . '/status'; + $rider_status = 'available'; + + $this->mclient->publish($channel, $rider_status); + return $data; } public function arrive(Request $req) { $required_params = ['jo_id']; - $data = $this->checkJO($req, $required_params, $jo); + $data = $this->checkActiveJO($req, $required_params, $jo); if (isset($data['error'])) + { + $data['title'] = 'Failed Arrive'; return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); // TODO: refactor this into a jo handler class, so we don't have to repeat for control center @@ -443,7 +1180,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $rider = $this->session->getRider(); $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::RIDER_ARRIVE) + ->setTypeID(CMBJOEventType::RIDER_ARRIVE) ->setJobOrder($jo) ->setRider($rider); $this->em->persist($event); @@ -484,7 +1221,9 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface return $data; } - // TODO: tag rider as available + // tag rider as available + $rider = $this->session->getRider(); + $rider->setAvailable(true); $this->em->flush(); @@ -493,91 +1232,43 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface public function payment(Request $req) { - $required_params = ['jo_id']; - $data = $this->checkJO($req, $required_params, $jo); + $required_params = [ + 'jo_id', + 'mode_of_payment', + ]; + $data = $this->checkActiveJO($req, $required_params, $jo); if (isset($data['error'])) + { + $data['title'] = 'Failed Payment'; return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + // add mode of payment + $mode = $req->request->get('mode_of_payment'); + $jo->setModeOfPayment($mode); + + // set status to paid + $jo->setStatus(JOStatus::PAID); + // set invoice to paid $jo->getInvoice()->setStatus(InvoiceStatus::PAID); - /* - // set jo status to fulfilled - $jo->setStatus(JOStatus::FULFILLED); - */ - $jo->fulfill(); - // add event log $rider = $this->session->getRider(); $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::FULFILL) + ->setTypeID(CMBJOEventType::PAID) ->setJobOrder($jo) ->setRider($rider); $this->em->persist($event); - // TODO: tag rider as unavailable - - // save to customer vehicle battery record - $this->jo_handler->updateVehicleBattery($jo); - $this->em->flush(); - // create warranty - if($this->jo_handler->checkIfNewBattery($jo)) - { - $serial = $jo->getCustomerVehicle()->getWarrantyCode(); - $warranty_class = $jo->getWarrantyClass(); - $first_name = $jo->getCustomer()->getFirstName(); - $last_name = $jo->getCustomer()->getLastName(); - $mobile_number = $jo->getCustomer()->getPhoneMobile(); - - // check if date fulfilled is null - if ($jo->getDateFulfill() == null) - $date_purchase = $jo->getDateCreate(); - else - $date_purchase = $jo->getDateFulfill(); - - // validate plate number - // $plate_number = $this->wh->cleanPlateNumber($jo->getCustomerVehicle()->getPlateNumber()); - $plate_number = Warranty::cleanPlateNumber($jo->getCustomerVehicle()->getPlateNumber()); - if ($plate_number != false) - { - $batt_list = array(); - $invoice = $jo->getInvoice(); - if (!empty($invoice)) - { - // get battery - $invoice_items = $invoice->getItems(); - foreach ($invoice_items as $item) - { - $battery = $item->getBattery(); - if ($battery != null) - { - $batt_list[] = $item->getBattery(); - } - } - } - - $this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class); - } - } - - // send mqtt event (fulfilled) - $rider = $this->session->getRider(); - $image_url = $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/assets/images/user.gif'; - if ($rider->getImageFile() != null) - $image_url = $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/uploads/' . $rider->getImageFile(); - - $payload = [ - 'event' => 'fulfilled', - 'jo_id' => $jo->getID(), - 'driver_image' => $image_url, - 'driver_name' => $rider->getFullName(), - 'driver_id' => $rider->getID(), - ]; - $this->mclient->sendEvent($jo, $payload); - return $data; } @@ -586,7 +1277,10 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $required_params = []; $data = $this->checkParamsAndKey($req, $required_params); if (isset($data['error'])) + { + $data['title'] = 'Failed Available Rider'; return $data; + } // make rider available $this->session->getRider()->setAvailable(true); @@ -602,7 +1296,10 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $required_params = []; $data = $this->checkParamsAndKey($req, $required_params); if (isset($data['error'])) + { + $data['title'] = 'Failed Get Promos'; return $data; + } $promos = $this->em->getRepository(Promo::class)->findAll(); @@ -629,7 +1326,10 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $required_params = []; $data = $this->checkParamsAndKey($req, $required_params); if (isset($data['error'])) + { + $data['title'] = 'Failed Get Batteries'; return $data; + } $batts = $this->em->getRepository(Battery::class)->findAll(); $models = $this->em->getRepository(BatteryModel::class)->findAll(); @@ -678,17 +1378,21 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $this->debugRequest($req); // allow rider to change service, promo, battery and trade-in options - $required_params = ['jo_id', 'stype_id', 'promo_id']; + $required_params = ['jo_id', 'service_type', 'promo_id']; $data = $this->checkJO($req, $required_params, $jo); if (isset($data['error'])) + { + $data['title'] = 'Failed Service Change'; return $data; + } // check service type - $stype_id = $req->request->get('stype_id'); - if (!CMBServiceType::validate($stype_id)) + $service_type = $req->request->get('service_type'); + if (!CMBServiceType::validate($service_type)) { $data = [ - 'error' => 'Invalid service type - ' . $stype_id + 'title' => 'Failed Service Change', + 'error' => 'Invalid service type - ' . $service_type ]; return $data; } @@ -704,6 +1408,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface if ($promo == null) { $data = [ + 'title' => 'Failed Service Change', 'error' => 'Invalid promo id - ' . $promo_id ]; return $data; @@ -742,6 +1447,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface if ($battery == null) { $data = [ + 'title' => 'Failed Service Change', 'error' => 'Invalid battery id - ' . $batt_id ]; return $data; @@ -750,18 +1456,19 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface // check trade in $trade_in = $req->request->get('trade_in'); - if (!CMBTradeInType::validate($trade_in)) + if (!TradeInType::validate($trade_in)) $trade_in = null; // check mode of payment + // TODO: defaulting to credit_card for now if mode of payment is invalid $mode = $req->request->get('mode_of_payment'); - if (!ModeOfPayment::validate($mode)) - $mode = ModeOfPayment::CASH; + if (!CMBModeOfPayment::validate($mode)) + $mode = CMBModeOfPayment::CASH; $jo->setModeOfPayment($mode); // generate new invoice $crit = new InvoiceCriteria(); - $crit->setServiceType($stype_id); + $crit->setServiceType($service_type); $crit->setCustomerVehicle($cv); $crit->setHasCoolant($jo->hasCoolant()); @@ -782,7 +1489,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $this->em->flush(); // save job order - $jo->setServiceType($stype_id); + $jo->setServiceType($service_type); // save invoice $jo->setInvoice($invoice); @@ -792,7 +1499,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $rider = $this->session->getRider(); $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::RIDER_EDIT) + ->setTypeID(CMBJOEventType::RIDER_EDIT) ->setJobOrder($jo) ->setRider($rider); $this->em->persist($event); @@ -803,6 +1510,680 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface return $data; } + public function generateInvoice(Request $req) + { + $required_params = ['jo_id']; + $data = $this->checkActiveJO($req, $required_params, $jo); + if (isset($data['error'])) + { + $data['title'] = 'Failed Invoice Generation'; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + $inv = $jo->getInvoice(); + $promo = $inv->getPromo(); + + // invoice items + $inv_items = []; + foreach ($inv->getItems() as $item) + { + // if more than 1, split it into one of each of the same item + $item_qty = $item->getQuantity(); + for ($i = 0; $i < $item_qty; $i++) + { + $item_batt = $item->getBattery(); + if ($item_batt == null) + $batt_id = null; + else + $batt_id = $item_batt->getID(); + + $inv_items[] = [ + 'id' => $item->getID(), + 'title' => $item->getTitle(), + 'qty' => 1, + 'price' => $item->getPrice(), + 'batt_id' => $batt_id, + ]; + } + } + + // promo + if ($promo != null) + { + $promo_data = [ + 'id' => $promo->getID(), + 'name' => $promo->getName(), + 'code' => $promo->getCode(), + 'discount_rate' => $promo->getDiscountRate(), + 'discount_apply' => $promo->getDiscountApply(), + ]; + } + else + { + $promo_data = null; + } + + $trade_in_type = $jo->getTradeInType(); + if (empty($trade_in_type)) + $trade_in_type = 'none'; + + $data = [ + 'invoice' => [ + 'id' => $inv->getID(), + 'discount' => $inv->getDiscount(), + 'trade_in' => $inv->getTradeIn(), + 'total_price' => $inv->getTotalPrice(), + 'vat' => $inv->getVat(), + 'items' => $inv_items, + 'trade_in_type' => $trade_in_type, + 'promo' => $promo_data, + ] + ]; + + return $data; + } + + public function startJobOrder(Request $req) + { + $required_params = ['jo_id']; + $data = $this->checkActiveJO($req, $required_params, $jo); + if (isset($data['error'])) + { + $data['title'] = 'Failed Job Order Start'; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + // set jo status to in progress + $jo->setStatus(JOStatus::IN_PROGRESS); + + // add event log + $rider = $this->session->getRider(); + $event = new JOEvent(); + $event->setDateHappen(new DateTime()) + ->setTypeID(CMBJOEventType::RIDER_START) + ->setJobOrder($jo) + ->setRider($rider); + $this->em->persist($event); + + $this->em->flush(); + + return $data; + } + + public function completeJobOrder(Request $req) + { + $required_params = ['jo_id']; + $data = $this->checkActiveJO($req, $required_params, $jo); + if (isset($data['error'])) + { + $data['title'] = 'Failed Job Order Completion'; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + // set customer signature + $jo_extra = $jo->getJOExtra(); + $sig_file = $this->handleFileUpload($req, 'signature'); + if ($sig_file) + $jo_extra->setCustomerSignature($sig_file); + + // set email + $cust_email = $req->request->get('customer_email', ''); + $jo->addMeta('customer_email', $cust_email); + + + /* + // set jo status to fulfilled + $jo->setStatus(JOStatus::FULFILLED); + */ + //$jo->fulfill(); + $jo->setStatus(JOStatus::FULFILLED) + ->setDateFulfill(new DateTime()); + + // add event log + $rider = $this->session->getRider(); + $event = new JOEvent(); + $event->setDateHappen(new DateTime()) + ->setTypeID(CMBJOEventType::FULFILL) + ->setJobOrder($jo) + ->setRider($rider); + $this->em->persist($event); + + $rider_event = new JOEvent(); + $rider_event->setDateHappen(new DateTime()) + ->setTypeID(CMBJOEventType::RIDER_FINISH) + ->setJobOrder($jo) + ->setRider($rider); + $this->em->persist($rider_event); + + // save to customer vehicle battery record + $this->jo_handler->updateVehicleBattery($jo); + + $this->em->flush(); + + // create warranty + if($this->jo_handler->checkIfNewBattery($jo)) + { + $serial = null; + $warranty_class = $jo->getWarrantyClass(); + $first_name = $jo->getCustomer()->getFirstName(); + $last_name = $jo->getCustomer()->getLastName(); + $mobile_number = $jo->getCustomer()->getPhoneMobile(); + + // check if date fulfilled is null + //if ($jo->getDateFulfill() == null) + // $date_purchase = $jo->getDateCreate(); + //else + // $date_purchase = $jo->getDateFulfill(); + + // use date_schedule for warranty expiration computation + $date_purchase = $jo->getDateSchedule(); + + $plate_number = $this->wh->cleanPlateNumber($jo->getCustomerVehicle()->getPlateNumber()); + + $batt_list = array(); + $invoice = $jo->getInvoice(); + if (!empty($invoice)) + { + // get battery + $invoice_items = $invoice->getItems(); + foreach ($invoice_items as $item) + { + $battery = $item->getBattery(); + if ($battery != null) + { + $batt_list[] = $item->getBattery(); + } + } + } + + $this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class); + } + + // TODO: Need to verify if needed. + // send mqtt event (fulfilled) + $image_url = $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/assets/images/user.gif'; + if ($rider->getImageFile() != null) + $image_url = $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/uploads/' . $rider->getImageFile(); + + $payload = [ + 'event' => 'fulfilled', + 'jo_id' => $jo->getID(), + 'driver_image' => $image_url, + 'driver_name' => $rider->getFullName(), + 'driver_id' => $rider->getID(), + ]; + $this->mclient->sendEvent($jo, $payload); + + return $data; + } + + public function setActiveJobOrder(Request $req) + { + $required_params = [ + 'jo_id' + ]; + $data = $this->checkJO($req, $required_params, $jo); + if (isset($data['error'])) + { + $data['title'] = 'Failed Set Active Job Order'; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + $rider = $this->session->getRider(); + $rider->setActiveJobOrder($jo); + + $this->em->persist($rider); + $this->em->flush(); + + return $data; + } + + public function setOdometer(Request $req) + { + $required_params = [ + 'jo_id', + 'odometer' + ]; + $data = $this->checkActiveJO($req, $required_params, $jo); + if (isset($data['error'])) + { + $data['title'] = 'Failed Set Odometer'; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + $odometer_reading = $req->request->get('odometer'); + + if ($odometer_reading > 999999) + { + $data = [ + 'title' => 'Failed Set Odometer', + 'error' => 'Odometer cannot be more than 6 figures.', + ]; + return $data; + } + + $jo->addMeta('odometer', $odometer_reading); + + $this->em->flush(); + + return $data; + } + + protected function handleFileUpload($req, $name) + { + $file = $req->files->get($name); + if (empty($file)) + return false; + + $orig_filename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME); + + // generate prefix to assure uniqueness + $prefix = uniqid() . '_'; + $new_filename = $prefix . $orig_filename . '.' . $file->guessClientExtension(); + + // move to our upload dir + $dest = $this->upload_dir; + try + { + $file->move($dest, $new_filename); + } + catch (FileException $e) + { + return false; + } + + return $new_filename; + } + + public function uploadFinishPhotos(Request $req) + { + $required_params = [ + 'jo_id', + ]; + $data = $this->checkActiveJO($req, $required_params, $jo); + if (isset($data['error'])) + { + $data['title'] = 'Failed Upload Finish Photos'; + return $data; + } + + $rider = $this->session->getRider(); + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + $dest = $this->upload_dir; + + $img_1_file = $req->files->get('img_1'); + $img_2_file = $req->files->get('img_2'); + $img_3_file = $req->files->get('img_3'); + $img_4_file = $req->files->get('img_4'); + $other_img_files[]= $req->files->get('other_images'); + + if ((empty($img_1_file)) && + (empty($img_2_file)) && + (empty($img_3_file)) && + (empty($img_4_file))) + { + $data = [ + 'title' => 'Failed Upload Arrive Photos', + 'error' => 'No image files received.' + ]; + return $data; + } + else + { + $new_img1_filename = ''; + $new_img2_filename = ''; + $new_img3_filename = ''; + $new_img4_filename = ''; + $other_filenames = []; + + if (!empty($img_1_file)) + { + $orig_img1_filename = pathinfo($img_1_file->getClientOriginalName(), PATHINFO_FILENAME); + $new_img1_filename = uniqid() . '-'. $orig_img1_filename . '.' . $img_1_file->guessClientExtension(); + + try + { + $img_1_file->move($dest, $new_img1_filename); + } + catch (FileException $e) + { + $data = [ + 'error' => 'Error saving image files.' + ]; + return $data; + } + } + if (!empty($img_2_file)) + { + $orig_img2_filename = pathinfo($img_2_file->getClientOriginalName(), PATHINFO_FILENAME); + $new_img2_filename = uniqid() . '-' . $orig_img2_filename . '.' . $img_2_file->guessClientExtension(); + + try + { + $img_2_file->move($dest, $new_img2_filename); + } + catch (FileException $e) + { + $data = [ + 'error' => 'Error saving image files.' + ]; + return $data; + } + } + if (!empty($img_3_file)) + { + $orig_img3_filename = pathinfo($img_3_file->getClientOriginalName(), PATHINFO_FILENAME); + $new_img3_filename = uniqid() . '-' . $orig_img3_filename . '.' . $img_3_file->guessClientExtension(); + + try + { + $img_3_file->move($dest, $new_img3_filename); + } + catch (FileException $e) + { + $data = [ + 'error' => 'Error saving image files.' + ]; + return $data; + } + } + + if (!empty($img_4_file)) + { + $orig_img4_filename = pathinfo($img_4_file->getClientOriginalName(), PATHINFO_FILENAME); + $new_img4_filename = uniqid() . '-' . $orig_img4_filename . '.' . $img_4_file->guessClientExtension(); + + try + { + $img_4_file->move($dest, $new_img4_filename); + } + catch (FileException $e) + { + $data = [ + 'error' => 'Error saving image files.' + ]; + return $data; + } + } + + foreach ($other_img_files as $other_img_file) + { + if (!(empty($other_img_file))) + { + foreach($other_img_file as $other_img) + { + $orig_other_filename = pathinfo($other_img->getClientOriginalName(), PATHINFO_FILENAME); + $new_other_filename = uniqid() . '-'. $orig_other_filename . '.' . $other_img->guessClientExtension(); + + $other_filenames[] = $new_other_filename; + + try + { + $other_img->move($dest, $new_other_filename); + } + catch (FileException $e) + { + $data = [ + 'error' => 'Error saving image files.' + ]; + return $data; + } + } + } + } + + $jo_extra = $jo->getJOExtra(); + if ($jo_extra == null) + { + // create JOExtra entity + $jo_extra = new JOExtra(); + + $jo_extra->setImage1Filename($new_img1_filename); + $jo_extra->setImage2Filename($new_img2_filename); + $jo_extra->setImage3Filename($new_img3_filename); + $jo_extra->setImage4Filename($new_img4_filename); + + if (empty($other_filenames)) + { + $jo_extra->clearOtherImages(); + } + else + { + $jo_extra->setOtherImages($other_filenames); + } + + $jo->setJOExtra($jo_extra); + + $this->em->persist($jo_extra); + } + else + { + $jo_extra->setImage1Filename($new_img1_filename); + $jo_extra->setImage2Filename($new_img2_filename); + $jo_extra->setImage3Filename($new_img3_filename); + $jo_extra->setImage4Filename($new_img4_filename); + + if (empty($other_filenames)) + { + $jo_extra->clearOtherImages(); + } + else + { + $jo_extra->setOtherImages($other_filenames); + } + } + + // create event for upload photo + $rider_event = new JOEvent(); + $rider_event->setDateHappen(new DateTime()) + ->setTypeID(CMBJOEventType::RIDER_UPLOAD_PHOTO) + ->setJobOrder($jo) + ->setRider($rider); + $this->em->persist($rider_event); + + $this->em->flush(); + } + + return $data; + } + + public function getStatus(Request $req) + { + $required_params = []; + $data = $this->checkParamsAndKey($req, $required_params); + if (isset($data['error'])) + { + $data['title'] = 'Failed Get Status'; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + $rider = $this->session->getRider(); + + $rider_status = $rider->isAvailable(); + + $status = 'Offline'; + if ($rider_status) + $status = 'Online'; + + $data = [ + 'status' => $status, + ]; + + return $data; + } + + public function getOngoingJobOrder(Request $req) + { + $required_params = []; + $data = $this->checkParamsAndKey($req, $required_params); + if (isset($data['error'])) + { + $data['title'] = 'Failed Get Ongoing Job Order'; + $data['job_order'] = []; + return $data; + } + + // are we logged in? + if (!$this->session->hasRider()) + { + $data = [ + 'title' => 'Failed Get Ongoing Job Order', + 'error' => 'No logged in rider.', + 'job_order' => null, + ]; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + $rider = $this->session->getRider(); + + // check if we have an active JO + $jo = $rider->getRiderActiveJobOrder(); + if ($jo == null) + { + $data = [ + //'title' => 'Failed Get Ongoing Job Order', + //'error' => 'No active job order.', + 'job_order' => [], + ]; + return $data; + } + + $jo_data = []; + // check if JO status is in_progress, in_transit, performed, paid + switch($jo->getStatus()) + { + case JOStatus::IN_TRANSIT: + case JOStatus::IN_PROGRESS: + case JOStatus::PERFORMED: + case JOStatus::PAID: + $jo_data = $this->formatJobOrderData($req, $jo); + break; + } + + $data = [ + 'job_order' => $jo_data + ]; + + return $data; + } + + public function getPaymentMethods(Request $req) + { + $required_params = []; + $data = $this->checkParamsAndKey($req, $required_params); + if (isset($data['error'])) + { + $data['title'] = 'Failed Get Payment Methods'; + return $data; + } + + $data = [ + 'payment_methods' => CMBModeOfPayment::getCollection(), + ]; + + return $data; + + } + + public function getCancelReasons(Request $req) + { + $required_params = []; + $data = $this->checkParamsAndKey($req, $required_params); + if (isset($data['error'])) + { + $data['title'] = 'Failed Get Cancel Reasons'; + return $data; + } + + $data = [ + 'cancel_reasons' => CMBCancelReason::getCollection(), + ]; + + return $data; + + } + + public function verifyJobOrder(Request $req) + { + $required_params = [ + 'jo_id' + ]; + $data = $this->checkJOForVerify($req, $required_params, $jo); + if (isset($data['error'])) + { + $data['title'] = 'Failed Verify Job Order'; + return $data; + } + + // get longitude and latitude + // TODO: right now, we're just checking if we get the coordinates + $this->getHeaderCoordinates($req); + + $rider = $this->session->getRider(); + // check if rider is assigned to JO + if ($jo->getRider() != null) + { + if ($rider->getID() != $jo->getRider()->getID()) + { + $data = [ + 'assigned' => false, + 'available' => false, + ]; + return $data; + } + } + + // check if JO status is not fulfilled and not cancelled + if (($jo->getStatus() == JOStatus::FULFILLED) || + ($jo->getStatus() == JOStatus::CANCELLED)) + { + $data = [ + 'assigned' => true, + 'available' => false + ]; + return $data; + } + + $data = [ + 'assigned' => true, + 'available' => true, + ]; + + return $data; + } + protected function checkMissingParameters(Request $req, $params = []) { $missing = []; @@ -880,7 +2261,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface return $session; } - protected function checkJO(Request $req, $required_params, &$jo = null) + protected function checkActiveJO(Request $req, $required_params, &$jo = null) { // set jo status to in transit $data = $this->checkParamsAndKey($req, $required_params); @@ -899,7 +2280,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface $rider = $this->session->getRider(); // check if we have an active JO - $jo = $rider->getActiveJobOrder(); + $jo = $rider->getRiderActiveJobOrder(); if ($jo == null) { $data = [ @@ -907,9 +2288,14 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface ]; return $data; } + $jo_id = ''; + if ($req->getMethod() == 'GET') + $jo_id = $req->query->get('jo_id'); + else + $jo_id = $req->request->get('jo_id'); // check if the jo_id sent is the same as our active jo - if ($req->request->get('jo_id') != $jo->getID()) + if ($jo_id != $jo->getID()) { $data = [ 'error' => 'Job order selected is not active job order.' @@ -920,9 +2306,142 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface return $data; } + protected function checkJO(Request $req, $required_params, &$jo = null) + { + // set jo status to in transit + $data = $this->checkParamsAndKey($req, $required_params); + if (isset($data['error'])) + return $data; + + // are we logged in? + if (!$this->session->hasRider()) + { + $data = [ + 'error' => 'No logged in rider.' + ]; + return $data; + } + + $rider = $this->session->getRider(); + + // get jo + $jo_id = ''; + if ($req->getMethod() == 'GET') + $jo_id = $req->query->get('jo_id'); + else + $jo_id = $req->request->get('jo_id'); + + $jo = $this->em->getRepository(JobOrder::class)->find($jo_id); + if ($jo == null) + { + $data = [ + 'error' => 'No job order found.' + ]; + return $data; + + } + + // check if rider assigned to jo is our rider + if ($jo->getRider() == null) + { + $data = [ + 'error' => 'Job order selected has no rider assigned.' + ]; + return $data; + } + + // check if rider is assigned to JO + if ($rider->getID() != $jo->getRider()->getID()) + { + $data = [ + 'error' => 'Job order selected is not assigned to rider' + ]; + return $data; + } + + return $data; + } + + protected function checkJOForVerify(Request $req, $required_params, &$jo = null) + { + // set jo status to in transit + $data = $this->checkParamsAndKey($req, $required_params); + if (isset($data['error'])) + return $data; + + // are we logged in? + if (!$this->session->hasRider()) + { + $data = [ + 'error' => 'No logged in rider.' + ]; + return $data; + } + + $rider = $this->session->getRider(); + + // get jo + $jo_id = ''; + if ($req->getMethod() == 'GET') + $jo_id = $req->query->get('jo_id'); + else + $jo_id = $req->request->get('jo_id'); + + $jo = $this->em->getRepository(JobOrder::class)->find($jo_id); + if ($jo == null) + { + $data = [ + 'error' => 'No job order found.' + ]; + return $data; + + } + + // check if rider assigned to jo is our rider + if ($jo->getRider() == null) + { + $data = [ + 'error' => 'Job order selected has no rider assigned.' + ]; + return $data; + } + + /* + // check if rider is assigned to JO + if ($rider->getID() != $jo->getRider()->getID()) + { + $data = [ + 'error' => 'Job order selected is not assigned to rider' + ]; + return $data; + } */ + + return $data; + } + protected function debugRequest(Request $req) { $all = $req->request->all(); error_log(print_r($all, true)); } + + protected function getURLExtraImage(Request $req, $filename) + { + // return null if blank filename + if (strlen(trim($filename)) <= 0) + return null; + + return $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/uploads/jo_extra/' . $filename; + } + + protected function getHeaderCoordinates(Request $req) + { + $x_lng = $req->headers->get('x-longitude'); + $x_lat = $req->headers->get('x-latitude'); + + // TODO: this is still unfinished + + //error_log('rider_longitude ' . $x_lng); + //error_log('rider_latitude ' . $x_lat); + } } diff --git a/templates/customer/cmb.form.html.twig b/templates/customer/cmb.form.html.twig index e417f3bb..c979b7d7 100644 --- a/templates/customer/cmb.form.html.twig +++ b/templates/customer/cmb.form.html.twig @@ -663,9 +663,18 @@ // display create vehicle form $("#add-vehicle").click(function() { - $("#vehicle-form").data('mode', 'create'); - $("#vehicle-form-title").html("Add Vehicle"); - $("#vehicle-form-modal").modal('show'); + // check if there are already 2 vehicles in list + if (vehicleRows.length == 2) + { + swal({ + text: 'Customer is limited to only 2 vehicles..', + type: 'info', + }); + } else { + $("#vehicle-form").data('mode', 'create'); + $("#vehicle-form-title").html("Add Vehicle"); + $("#vehicle-form-modal").modal('show'); + } }); // find vehicle row by index diff --git a/templates/job-order/cmb.form.onestep.html.twig b/templates/job-order/cmb.form.onestep.html.twig index 7d2344f2..d6d5ba20 100644 --- a/templates/job-order/cmb.form.onestep.html.twig +++ b/templates/job-order/cmb.form.onestep.html.twig @@ -92,57 +92,57 @@
- - - + + +
- - - + + +
- +
{% trans %}country_code_prefix{% endtrans %} - - + +
- +
{% trans %}country_code_prefix{% endtrans %} - - + +
- +
{% trans %}country_code_prefix{% endtrans %} - - + +
- +
{% trans %}country_code_prefix{% endtrans %} - - + +
- - - + + +
@@ -178,17 +178,26 @@
- +
-
@@ -462,14 +474,13 @@ Last Name Contact No. Plate Number - Action {% if mode in ['onestep-edit', 'view-all', 'update-fulfillment'] %} {% set avail_riders = obj.getHub.getAvailableRiders|default([]) %} - + No riders available. @@ -495,6 +506,73 @@
+ {% if mode in ['onestep-edit'] %} +
+
+
+

+ Other Information +

+
+
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+ +
+ {% for key, picture in jo_pictures %} + {% if key == 'image_1' %} +
+
+
+ {% endif %} + {% if key == 'image_2' %} +
+
+
+ {% endif %} + {% if key == 'image_3' %} +
+
+
+ {% endif %} + {% if key == 'image_4' %} +
+
+
+ {% endif %} + + {% endfor %} +
+ +
+ {% endif %} +
@@ -544,7 +622,7 @@
-
+ @@ -178,17 +178,26 @@
- +
-
+
+
+
+

+ Job Orders (Behind Schedule) +

+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+
+ + + + +
+
+
+
+
+ +
+
+
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+ +
+ +
+
+
+
+
+{% endblock %} + +{% block scripts %} + +{% endblock %} diff --git a/templates/job-order/cmb.list.open.html.twig b/templates/job-order/cmb.list.open.html.twig index a575e645..4fa85c70 100644 --- a/templates/job-order/cmb.list.open.html.twig +++ b/templates/job-order/cmb.list.open.html.twig @@ -93,12 +93,12 @@ }, rows: { beforeTemplate: function (row, data, index) { - if (data.flag_advance) { - $(row).addClass('m-table__row--danger'); + if (data.status == 'In Progress') { + $(row).addClass('m-table__row--is_in_progress'); } - if (data.is_mobile) { - $(row).addClass('m-table__row--is_mobile'); + if (data.status == 'Assigned') { + $(row).addClass('m-table__row--is_assigned'); } } }, @@ -131,6 +131,10 @@ field: 'type', title: 'Schedule' }, + { + field: 'date_start', + title: 'Start Date' + }, { field: 'date_schedule', title: 'Scheduled Date' diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index c0fb8ca1..3e12543b 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -1,27 +1,27 @@ # text -title_login: Motolite Res-Q | Login -block_title: Motolite Res-Q +title_login: Res-Q for CMB | Login +block_title: Res-Q for CMB control_panel_sign_in: Sign-in to Control Panel -alt_image_logo_login: Res-Q -alt_image_dashboard: Motolite -copyright: Motolite Res-Q +alt_image_logo_login: Res-Q for CMB +alt_image_dashboard: Res-Q for CMB +copyright: Res-Q for CMB battery_size_tradein_brand: Trade-in Motolite battery_size_tradein_premium: Trade-in Premium battery_size_tradein_other: Trade-in Other add_cust_vehicle_battery_info: This vehicle is using a Motolite battery -jo_title_pdf: Motolite Res-Q Job Order -country_code_prefix: '+63' -delivery_instructions_label: Delivery Instructions +jo_title_pdf: Res-Q for CMB Job Order +country_code_prefix: '+60' +delivery_instructions_label: 'CarFix Details' # images -image_logo_login: /assets/images/logo-resq.png -icon_login: /assets/demo/default/media/img/logo/favicon.ico -icon_base_32x32: /assets/images/favicon/favicon-32x32.png -icon_base_16x16: /assets/images/favicon/favicon-16x16.png -image_dashboard: /assets/images/logo-motolite.png -image_jo_pdf: /public/assets/images/logo-resq.png +image_logo_login: /assets/images/black-text-logo-01.png +icon_login: /assets/images/battery-assist-bm-logo-32x32.png +icon_base_32x32: /assets/images/black-text-logo-01-32x32.png +icon_base_16x16: /assets/images/black-text-logo-01-16x16.png +image_dashboard: /assets/images/century_logo.png +image_jo_pdf: /public/assets/images/black-text-logo-01-115x115.png # default point for maps -default_lat: 14.6091 -default_long: 121.0223 -default_region: ph +default_lat: 3.084216 +default_long: 101.6129996 +default_region: my