Compare commits
104 commits
master
...
498-cmb-re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a863a5e34b | ||
|
|
25c399eeb2 | ||
|
|
d286ace684 | ||
|
|
6dd3068e70 | ||
| 8068a662f6 | |||
| 331d483606 | |||
| 7152b0f610 | |||
| 1e23764452 | |||
| 2c4167a093 | |||
| 97d8b9e147 | |||
| 928d5412e5 | |||
|
|
8bcd9b9546 | ||
|
|
2b07a89544 | ||
|
|
9ad9de61c7 | ||
|
|
dbb05b16d9 | ||
| 5661bb4daf | |||
|
|
32f2b21dbf | ||
| 59ecc19ef7 | |||
| 0880a75fa7 | |||
| 40b28e6e4d | |||
|
|
9019c4b450 | ||
| b822829b38 | |||
|
|
d69330e744 | ||
| 1c1096da17 | |||
|
|
77bc17d41e | ||
|
|
51cdc6ff15 | ||
|
|
4de3277030 | ||
|
|
c46fa82b68 | ||
|
|
dacd9efe01 | ||
|
|
818277159c | ||
|
|
5b70085162 | ||
|
|
92a7380b4f | ||
|
|
9052f8102c | ||
|
|
0fb08002e8 | ||
|
|
399cf23f29 | ||
|
|
ad77e20bd3 | ||
|
|
4703cd5080 | ||
|
|
ce8e8974bd | ||
|
|
171fa14e40 | ||
|
|
5185043934 | ||
|
|
8eebf6ee1c | ||
|
|
089bced14c | ||
|
|
8c32792c38 | ||
|
|
49ee85898e | ||
|
|
b8885edaaa | ||
|
|
9b7fa2048a | ||
|
|
d0fcbe8cf3 | ||
|
|
885d1911a2 | ||
|
|
4e9c503eb2 | ||
|
|
ecbd83e3a3 | ||
|
|
b31f254c82 | ||
|
|
f5fa74f945 | ||
|
|
ce79354f5d | ||
|
|
b150c5ed29 | ||
|
|
663e28c403 | ||
|
|
24a75378c3 | ||
|
|
aa6ec44e27 | ||
|
|
3f0cca1fc9 | ||
|
|
3157ce7edc | ||
|
|
ab11e8aee5 | ||
|
|
309605da24 | ||
|
|
832d96c171 | ||
|
|
deacd5876c | ||
|
|
08b4b25f4e | ||
|
|
f5f771c4ed | ||
|
|
2d24a7b84a | ||
|
|
1f6ee02390 | ||
|
|
0aa3780c77 | ||
| e4ad0169d7 | |||
|
|
9fe4098ac4 | ||
| 28ded5faa8 | |||
|
|
ed22eebdc2 | ||
| 198406a5ec | |||
| c2e10a12e6 | |||
| 678dfcc65d | |||
| 01f5717c1c | |||
| 0bd968d753 | |||
| c8c3ffef42 | |||
| 885665f9d3 | |||
| 4e6bc0d95f | |||
| b6d2726d41 | |||
| 78554ec9c6 | |||
|
|
108d49ca5f | ||
|
|
4bfbfbf995 | ||
|
|
4796a9be14 | ||
|
|
eed91a413a | ||
|
|
ae2a22b159 | ||
|
|
a2245fef2b | ||
|
|
a05f53fd88 | ||
|
|
763d141860 | ||
|
|
a864b6b3eb | ||
|
|
4866d01eb3 | ||
|
|
2f60c28068 | ||
|
|
526296c8a3 | ||
|
|
4874791fed | ||
|
|
166c4942f1 | ||
|
|
b1d397c127 | ||
|
|
b284cb7b64 | ||
|
|
66e46c4bad | ||
|
|
b20c61a830 | ||
|
|
b9706ede89 | ||
|
|
90918c49ef | ||
|
|
8006545242 | ||
|
|
74039a8011 |
71 changed files with 7934 additions and 1209 deletions
|
|
@ -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
|
||||
|
|
|
|||
14
composer.lock
generated
14
composer.lock
generated
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)%"
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
156
config/routes/cmb_rider_api.yaml
Normal file
156
config/routes/cmb_rider_api.yaml
Normal file
|
|
@ -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]
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
9
config/routes/notification.yaml
Normal file
9
config/routes/notification.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
notification_ajax_list:
|
||||
path: /ajax/notifications
|
||||
controller: App\Controller\NotificationController::ajaxList
|
||||
methods: [GET]
|
||||
|
||||
notification_ajax_update:
|
||||
path: /ajax/notifications
|
||||
controller: App\Controller\NotificationController::ajaxUpdate
|
||||
methods: [POST]
|
||||
|
|
@ -56,3 +56,14 @@ 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/{id}/name
|
||||
controller: App\Controller\RiderController::ajaxRiderName
|
||||
methods: [GET]
|
||||
|
||||
|
|
|
|||
|
|
@ -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: ~
|
||||
|
|
@ -219,6 +221,12 @@ services:
|
|||
event: 'postPersist'
|
||||
entity: 'App\Entity\JobOrder'
|
||||
|
||||
App\Service\NotificationManager:
|
||||
arguments:
|
||||
$redis_prov: "@App\\Service\\RedisClientProvider"
|
||||
$redis_mqtt_key: "mqtt_events"
|
||||
$em: "@doctrine.orm.entity_manager"
|
||||
|
||||
App\Service\JobOrderCache:
|
||||
arguments:
|
||||
$redis_prov: "@App\\Service\\RedisClientProvider"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ class DashboardMap {
|
|||
this.options = options;
|
||||
this.rider_markers = rider_markers;
|
||||
this.cust_markers = cust_markers;
|
||||
this.rider_availability = {};
|
||||
this.rider_names = {};
|
||||
|
||||
// layer groups
|
||||
this.layer_groups = {
|
||||
|
|
@ -146,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,
|
||||
|
|
@ -170,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) {
|
||||
|
|
@ -185,27 +232,37 @@ class DashboardMap {
|
|||
}
|
||||
|
||||
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
|
||||
);
|
||||
var my = this;
|
||||
|
||||
my.getRiderName(id, function(name) {
|
||||
my.putMarkerWithLabel(
|
||||
id,
|
||||
lat,
|
||||
lng,
|
||||
my.rider_markers,
|
||||
my.options.icons.rider_available,
|
||||
my.layer_groups.rider_available,
|
||||
my.options.rider_popup_url,
|
||||
name
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
var my = this;
|
||||
|
||||
my.getRiderName(id, function(name) {
|
||||
my.putMarkerWithLabel(
|
||||
id,
|
||||
lat,
|
||||
lng,
|
||||
my.rider_markers,
|
||||
my.options.icons.rider_active_jo,
|
||||
my.layer_groups.rider_active_jo,
|
||||
my.options.rider_popup_url,
|
||||
name
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
removeRiderMarker(id) {
|
||||
|
|
@ -219,6 +276,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) {
|
||||
|
|
@ -252,6 +311,7 @@ class DashboardMap {
|
|||
$.each(riders, function(id, data) {
|
||||
var lat = data.latitude;
|
||||
var lng = data.longitude;
|
||||
var name = '';
|
||||
|
||||
if (data.has_jo)
|
||||
my.putRiderActiveJOMarker(id, lat, lng);
|
||||
|
|
@ -262,4 +322,31 @@ class DashboardMap {
|
|||
// console.log(rider_markers);
|
||||
});
|
||||
}
|
||||
|
||||
getRiderName(id, callback) {
|
||||
var name = '';
|
||||
var rider_url = this.options.rider_name_url.replace('[id]', id);
|
||||
|
||||
var my = this;
|
||||
|
||||
console.log('getting rider name for rider ' + id);
|
||||
|
||||
// check if we have it in cache
|
||||
if (this.rider_names.hasOwnProperty(id)) {
|
||||
name = this.rider_names[id];
|
||||
callback(name);
|
||||
} else {
|
||||
// ajax call to get it
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
url: rider_url
|
||||
}).done(function(response) {
|
||||
name = response.rider_name;
|
||||
|
||||
// set name in cache
|
||||
my.rider_names[id] = name;
|
||||
callback(name);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
@ -9,20 +10,32 @@ class MapEventHandler {
|
|||
var client_id = "dash-" + user_id + "-" + d.getMonth() + "-" + d.getDate() + "-" + d.getHours() + "-" + d.getMinutes() + "-" + d.getSeconds() + "-" + d.getMilliseconds();
|
||||
console.log(client_id);
|
||||
|
||||
this.mqtt = new Paho.MQTT.Client(host, port, client_id);
|
||||
let protocol = 'ws';
|
||||
if (this.ssl)
|
||||
protocol = 'wss';
|
||||
|
||||
this.mqtt = new Paho.Client(protocol + '://' + host + ':' + port + '/mqtt', client_id);
|
||||
var options = {
|
||||
// useSSL: true,
|
||||
timeout: 3,
|
||||
useSSL: this.ssl,
|
||||
timeout: 10,
|
||||
keepAliveInterval: 10,
|
||||
invocationContext: this,
|
||||
onSuccess: this.onConnect.bind(this),
|
||||
reconnect: true
|
||||
};
|
||||
|
||||
this.mqtt.onMessageArrived = this.onMessage.bind(this);
|
||||
this.mqtt.onConnectionLost = this.onConnectionLost;
|
||||
|
||||
console.log('connecting to mqtt server...');
|
||||
this.mqtt.connect(options);
|
||||
}
|
||||
|
||||
onConnectionLost(err) {
|
||||
console.log('mqtt connection lost');
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
onConnect(icontext) {
|
||||
console.log('mqtt connected!');
|
||||
var my = icontext.invocationContext;
|
||||
|
|
@ -35,6 +48,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 +72,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('/');
|
||||
|
|
@ -73,13 +90,55 @@ class MapEventHandler {
|
|||
}
|
||||
|
||||
handleRider(chan_split, payload) {
|
||||
console.log("rider message");
|
||||
//console.log("rider message");
|
||||
var rider_id = chan_split[1];
|
||||
//console.log('url ' + this.dashmap.options.rider_availability_url);
|
||||
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);
|
||||
case "availability":
|
||||
console.log("got availability for rider " + chan_split[1] + " - " + payload);
|
||||
var obj = JSON.parse(payload);
|
||||
|
||||
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;
|
||||
var url = dashmap.options.rider_availability_url;
|
||||
var rider_availability_url = url.replace('[id]', chan_split[1]);
|
||||
//console.log(rider_availability_url);
|
||||
$.get(rider_availability_url).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);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
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)
|
||||
break;
|
||||
|
|
@ -87,8 +146,22 @@ class MapEventHandler {
|
|||
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);
|
||||
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');
|
||||
display_marker = false;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
break;
|
||||
case "status":
|
||||
console.log("got status for rider " + chan_split[1] + " - " + payload);
|
||||
|
|
|
|||
111
public/assets/js/notification.js
Normal file
111
public/assets/js/notification.js
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
class NotificationHandler {
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
clearAll() {
|
||||
// clear notification count
|
||||
document.getElementById('notif-count').innerHTML = '';
|
||||
|
||||
// remove notifications
|
||||
document.getElementById('notif-body').innerHTML = '';
|
||||
}
|
||||
|
||||
loadAll() {
|
||||
console.log('loading notifications');
|
||||
// ajax load
|
||||
var self = this;
|
||||
var notif_update_url = this.options['notif_ajax_update_url'];
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', this.options['notif_ajax_url']);
|
||||
xhr.onload = function() {
|
||||
if (xhr.status === 200) {
|
||||
var data = JSON.parse(xhr.responseText);
|
||||
var notifs = data.notifications;
|
||||
|
||||
// update notification unread count
|
||||
var count_html = data.unread_count;
|
||||
document.getElementById('notif-count').innerHTML = count_html;
|
||||
|
||||
// do we have any notifications?
|
||||
if (notifs.length <= 0)
|
||||
return;
|
||||
|
||||
// add actual notifications
|
||||
var notif_body = document.getElementById('notif-body');
|
||||
var notif_index = 0;
|
||||
notifs.forEach(function(notif) {
|
||||
var notif_date = moment(notif.date).fromNow();
|
||||
|
||||
var notif_html = '<div class="m-list-timeline__item">';
|
||||
notif_html += '<span class="m-list-timeline__badge -m-list-timeline__badge--state-success"></span>';
|
||||
notif_html += '<span class="m-list-timeline__text">';
|
||||
notif_html += '<a href="">' + notif.text + '</a>'
|
||||
notif_html += '</span>';
|
||||
notif_html += '<span class="m-list-timeline__time">';
|
||||
notif_html += notif_date;
|
||||
notif_html += '</span>';
|
||||
notif_html += '</div>';
|
||||
|
||||
notif_body.insertAdjacentHTML('beforeend', notif_html);
|
||||
|
||||
document.getElementsByClassName('m-list-timeline__item')[notif_index].addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: notif_update_url,
|
||||
data: {id: notif.id}
|
||||
}).done(function(response) {
|
||||
window.location.href = notif.link;
|
||||
});
|
||||
});
|
||||
|
||||
notif_index++;
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
listen(user_id, host, port, use_ssl = false) {
|
||||
var d = new Date();
|
||||
var client_id = "dash-" + user_id + "-" + d.getMonth() + "-" + d.getDate() + "-" + d.getHours() + "-" + d.getMinutes() + "-" + d.getSeconds() + "-" + d.getMilliseconds();
|
||||
|
||||
this.mqtt = new Paho.MQTT.Client(host, port, client_id);
|
||||
var options = {
|
||||
useSSL: use_ssl,
|
||||
timeout: 3,
|
||||
invocationContext: this,
|
||||
onSuccess: this.onConnect.bind(this)
|
||||
}
|
||||
|
||||
this.mqtt.onMessageArrived = this.onMessage.bind(this);
|
||||
|
||||
this.mqtt.connect(options);
|
||||
}
|
||||
|
||||
onConnect(icontext) {
|
||||
console.log('notification mqtt connected');
|
||||
var my = icontext.invocationContext;
|
||||
|
||||
// subscribe to general notifications
|
||||
my.mqtt.subscribe('user/0/notification');
|
||||
}
|
||||
|
||||
onMessage(msg) {
|
||||
console.log('notification event received');
|
||||
// we don't care about messasge, we update
|
||||
this.clearAll();
|
||||
this.loadAll();
|
||||
}
|
||||
|
||||
getIcon(type_id) {
|
||||
if (type_id in this.options['icons']) {
|
||||
return this.options['icons'][type_id];
|
||||
}
|
||||
|
||||
return this.options['default_icon'];
|
||||
}
|
||||
|
||||
}
|
||||
179
resq_settings/cmb/menu.yaml
Normal file
179
resq_settings/cmb/menu.yaml
Normal file
|
|
@ -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
|
||||
27
resq_settings/cmb/messages.en.yaml
Normal file
27
resq_settings/cmb/messages.en.yaml
Normal file
|
|
@ -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
|
||||
246
resq_settings/cmb/services.yaml
Normal file
246
resq_settings/cmb/services.yaml
Normal file
|
|
@ -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)%"
|
||||
186
resq_settings/resq/menu.yaml
Normal file
186
resq_settings/resq/menu.yaml
Normal file
|
|
@ -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
|
||||
27
resq_settings/resq/messages.en.yaml
Normal file
27
resq_settings/resq/messages.en.yaml
Normal file
|
|
@ -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
|
||||
244
resq_settings/resq/services.yaml
Normal file
244
resq_settings/resq/services.yaml
Normal file
|
|
@ -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)%"
|
||||
55
src/Command/ConfigureResqCommand.php
Normal file
55
src/Command/ConfigureResqCommand.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
class ConfigureResqCommand extends Command
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
}
|
||||
173
src/Command/CreateJOTestDataCommand.php
Normal file
173
src/Command/CreateJOTestDataCommand.php
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
||||
|
||||
use DateTime;
|
||||
use DateInterval;
|
||||
|
||||
use App\Entity\JobOrder;
|
||||
use App\Entity\Rider;
|
||||
use App\Entity\CustomerVehicle;
|
||||
use App\Entity\Invoice;
|
||||
use App\Entity\InvoiceItem;
|
||||
use App\Entity\Battery;
|
||||
|
||||
use App\Ramcar\CMBServiceType;
|
||||
use App\Ramcar\TransactionOrigin;
|
||||
use App\Ramcar\WarrantyClass;
|
||||
use App\Ramcar\ModeOfPayment;
|
||||
use App\Ramcar\JOStatus;
|
||||
use App\Ramcar\InvoiceStatus;
|
||||
|
||||
class CreateJOTestDataCommand extends Command
|
||||
{
|
||||
protected $em;
|
||||
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->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();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -70,8 +70,8 @@ class ImportCMBBatteryDataCommand extends Command
|
|||
error_log('Processing battery csv file...');
|
||||
while (($fields = fgetcsv($fh)) !== false)
|
||||
{
|
||||
// data starts at row 2
|
||||
if ($row_num < 2)
|
||||
// data starts at row 1
|
||||
if ($row_num < 1)
|
||||
{
|
||||
$row_num++;
|
||||
continue;
|
||||
|
|
@ -90,22 +90,42 @@ class ImportCMBBatteryDataCommand extends Command
|
|||
// [0] = battery manufacturer
|
||||
// [1] = battery model
|
||||
// [2] = battery size
|
||||
// if only 2, get both
|
||||
// [0] = battery manufacturer and battery model
|
||||
// [1] = battery size
|
||||
// if 4,
|
||||
// [0] = battery manufacturer
|
||||
// concatenate [1] and [2] for the battery model
|
||||
// [1] = battery model
|
||||
// [2] = extra info
|
||||
// [3] = battery size
|
||||
// OR
|
||||
// [0] = battery manufacturer
|
||||
// [1] = battery model
|
||||
// [2] = battery size
|
||||
// [3] = battery size --> this one would have ()
|
||||
// if 5,
|
||||
// [0] = battery manufacturer
|
||||
// [1] = battery model
|
||||
// [2] = extra info
|
||||
// [3] = extra info
|
||||
// [4] = battery size
|
||||
$battery_manufacturer = '';
|
||||
$battery_model = '';
|
||||
$battery_size = '';
|
||||
if (count($battery_info) == 3)
|
||||
{
|
||||
// sample: Century Marathoner 120-7L
|
||||
// sample: Century Marathoner M42(60B20L)
|
||||
$battery_manufacturer = trim($battery_info[0]);
|
||||
$battery_model = trim($battery_info[1]);
|
||||
$battery_size = trim($battery_info[2]);
|
||||
|
||||
// check for parenthesis in battery_info[2]
|
||||
if (strpos($battery_info[2], '(') === false)
|
||||
{
|
||||
// no parenthesis found
|
||||
$battery_size = trim($battery_info[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$battery_size = trim(str_replace('(', ' (', $battery_info[2]));
|
||||
}
|
||||
}
|
||||
if (count($battery_info) == 2)
|
||||
{
|
||||
|
|
@ -117,13 +137,32 @@ class ImportCMBBatteryDataCommand extends Command
|
|||
if (count($battery_info) == 4)
|
||||
{
|
||||
// sample: Motolite Classic Wetcharged DIN100L
|
||||
// sample: Century Excel NS60LS (60B24LS)
|
||||
$battery_manufacturer = trim($battery_info[0]);
|
||||
$battery_model = trim($battery_info[1]) . ' ' . trim($battery_info[2]);
|
||||
$battery_size = trim($battery_info[3]);
|
||||
$battery_model = trim($battery_info[1]);
|
||||
// check for parenthesis in battery_info[3]
|
||||
if (strpos($battery_info[3], '(') === false)
|
||||
{
|
||||
// no parenthesis found
|
||||
$battery_size = trim($battery_info[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// need to concatenate [2] and [3]
|
||||
$battery_size = trim($battery_info[2]) . ' ' . trim($battery_info[3]);
|
||||
}
|
||||
}
|
||||
if (count($battery_info) == 5)
|
||||
{
|
||||
// sample: Century Marathoner Max Wet NS40ZL
|
||||
$battery_manufacturer = trim($battery_info[0]);
|
||||
$battery_model = trim($battery_info[1]);
|
||||
$battery_size = trim($battery_info[4]);
|
||||
}
|
||||
|
||||
// check if battery size has ()
|
||||
// if so, trim it to ignore the parenthesis and what's after (.
|
||||
/*
|
||||
$pos = stripos($battery_size, '(');
|
||||
if ($pos == true)
|
||||
{
|
||||
|
|
@ -133,7 +172,7 @@ class ImportCMBBatteryDataCommand extends Command
|
|||
else
|
||||
{
|
||||
$clean_size = $battery_size;
|
||||
}
|
||||
} */
|
||||
|
||||
//error_log('battery manufacturer ' . $battery_manufacturer);
|
||||
//error_log('battery model ' . $battery_model);
|
||||
|
|
@ -143,24 +182,24 @@ class ImportCMBBatteryDataCommand extends Command
|
|||
// when we add to db for manufacturer, model, and size, we do not use the normalized versions
|
||||
$normalized_manu = $this->normalizeName($battery_manufacturer);
|
||||
$normalized_model = $this->normalizeName($battery_model);
|
||||
$normalized_size = $this->normalizeName($clean_size);
|
||||
$normalized_size = $this->normalizeName($battery_size);
|
||||
|
||||
// save battery manufacturer if not yet in system
|
||||
if (!isset($this->bmanu_hash[$normalized_manu]))
|
||||
{
|
||||
$this->addBatteryManufacturer($battery_manufacturer);
|
||||
$this->addBatteryManufacturer(strtoupper($battery_manufacturer));
|
||||
}
|
||||
|
||||
// save battery model if not yet in system
|
||||
if (!isset($this->bmodel_hash[$normalized_model]))
|
||||
{
|
||||
$this->addBatteryModel($battery_model);
|
||||
$this->addBatteryModel(strtoupper($battery_model));
|
||||
}
|
||||
|
||||
// save battery size if not yet in system
|
||||
if (!isset($this->bsize_hash[$normalized_size]))
|
||||
{
|
||||
$this->addBatterySize($clean_size);
|
||||
$this->addBatterySize(strtoupper($battery_size));
|
||||
}
|
||||
|
||||
// save battery if not yet in system
|
||||
|
|
|
|||
365
src/Command/ImportCMBBatteryModelSizeCommand.php
Normal file
365
src/Command/ImportCMBBatteryModelSizeCommand.php
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use App\Entity\BatteryManufacturer;
|
||||
use App\Entity\BatteryModel;
|
||||
use App\Entity\BatterySize;
|
||||
use App\Entity\Battery;
|
||||
use App\Entity\VehicleManufacturer;
|
||||
use App\Entity\Vehicle;
|
||||
|
||||
class ImportCMBBatteryModelSizeCommand extends Command
|
||||
{
|
||||
// CENTURY MARATHONER BATTERY
|
||||
const F_BATT_MARATHONER_SIZE = 4;
|
||||
const F_BATT_MARATHONER_PRICE = 5;
|
||||
const F_BATT_MARATHONER_TRADEIN_PRICE = 6;
|
||||
const F_BATT_MARATHONER_DISCOUNT = 7;
|
||||
|
||||
// MOTOLITE CLASSIC BATTERY
|
||||
const F_BATT_CLASSIC_SIZE = 8;
|
||||
const F_BATT_CLASSIC_PRICE = 9;
|
||||
const F_BATT_CLASSIC_TRADEIN_PRICE = 10;
|
||||
const F_BATT_CLASSIC_DISCOUNT = 11;
|
||||
|
||||
// CENTURY EXCEL BATTERY
|
||||
const F_BATT_EXCEL_SIZE = 12;
|
||||
const F_BATT_EXCEL_PRICE = 13;
|
||||
const F_BATT_EXCEL_TRADEIN_PRICE = 14;
|
||||
const F_BATT_EXCEL_DISCOUNT = 15;
|
||||
|
||||
// CENTURY SDFC BATTERY
|
||||
const F_BATT_SDFC_SIZE = 16;
|
||||
const F_BATT_SDFC_PRICE = 17;
|
||||
const F_BATT_SDFC_TRADEIN_PRICE = 18;
|
||||
const F_BATT_SDFC_DISCOUNT = 19;
|
||||
|
||||
protected $em;
|
||||
|
||||
protected $bmanu_hash;
|
||||
protected $bmodel_hash;
|
||||
protected $bsize_hash;
|
||||
protected $batt_hash;
|
||||
|
||||
// array for battery manufacturer
|
||||
protected $batt_manufacturers = [
|
||||
'CENTURY',
|
||||
'MOTOLITE',
|
||||
];
|
||||
|
||||
// array for battery models
|
||||
protected $batt_models = [
|
||||
'EXCEL', // CENTURY
|
||||
'SDFC', // CENTURY
|
||||
'MARATHONER', // CENTURY
|
||||
'CLASSIC', // MOTOLITE
|
||||
];
|
||||
|
||||
public function __construct(EntityManagerInterface $om)
|
||||
{
|
||||
$this->em = $om;
|
||||
|
||||
// load existing battery data
|
||||
$this->loadBatteryManufacturers();
|
||||
$this->loadBatteryModels();
|
||||
$this->loadBatterySizes();
|
||||
$this->loadBatteries();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('cmbbatterymodelsize:import')
|
||||
->setDescription('Retrieve from a CSV file battery information.')
|
||||
->setHelp('Creates battery manufacturers, models, sizes based on data from imported CSV.')
|
||||
->addArgument('input_file', InputArgument::REQUIRED, 'Path to the CSV file.')
|
||||
->addArgument('output_file', InputArgument::REQUIRED, 'Path to the output CSV file for entries not added.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
// check if battery manufacturers have been created
|
||||
if (count($this->bmanu_hash) == 0)
|
||||
{
|
||||
// create the manufacturers
|
||||
$this->createBatteryManufacturerData();
|
||||
|
||||
// reload the hash
|
||||
$this->loadBatteryManufacturers();
|
||||
}
|
||||
|
||||
// check if battery models have been created
|
||||
if (count($this->bmodel_hash) == 0)
|
||||
{
|
||||
// create the battery models
|
||||
$this->createBatteryModelData();
|
||||
|
||||
// reload the hash
|
||||
$this->loadBatteryModels();
|
||||
}
|
||||
|
||||
// get the sizes, vehicles, battery prices from the csv file
|
||||
$csv_file = $input->getArgument('input_file');
|
||||
|
||||
// attempt to open file
|
||||
try
|
||||
{
|
||||
$fh = fopen($csv_file, "r");
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception('The file "' . $csv_file . '" could not be read.');
|
||||
}
|
||||
|
||||
$output_file = $input->getArgument('output_file');
|
||||
|
||||
// attempt to open file
|
||||
try
|
||||
{
|
||||
$out_fh = fopen($output_file, "w");
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception('The file "' . $output_file . '" could not be read.');
|
||||
}
|
||||
|
||||
// get entity manager
|
||||
$em = $this->em;
|
||||
|
||||
$row_num = 0;
|
||||
$not_added = [];
|
||||
error_log('Processing battery model and size file...');
|
||||
while (($fields = fgetcsv($fh)) !== false)
|
||||
{
|
||||
if ($row_num < 2)
|
||||
{
|
||||
$row_num++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// get battery info from file
|
||||
$marathoner_size = $this->normalizeName(trim($fields[self::F_BATT_MARATHONER_SIZE]));
|
||||
$marathoner_price = trim($fields[self::F_BATT_MARATHONER_PRICE]);
|
||||
$marathoner_tradein_price = trim($fields[self::F_BATT_MARATHONER_TRADEIN_PRICE]);
|
||||
|
||||
$classic_size = $this->normalizeName(trim($fields[self::F_BATT_CLASSIC_SIZE]));
|
||||
$classic_price = trim($fields[self::F_BATT_CLASSIC_PRICE]);
|
||||
$classic_tradein_price = trim($fields[self::F_BATT_CLASSIC_TRADEIN_PRICE]);
|
||||
|
||||
$excel_size = $this->normalizeName(trim($fields[self::F_BATT_EXCEL_SIZE]));
|
||||
$excel_price = trim($fields[self::F_BATT_EXCEL_PRICE]);
|
||||
$excel_tradein_price = trim($fields[self::F_BATT_EXCEL_TRADEIN_PRICE]);
|
||||
|
||||
$sdfc_size = $this->normalizeName(trim($fields[self::F_BATT_SDFC_SIZE]));
|
||||
$sdfc_price = trim($fields[self::F_BATT_SDFC_PRICE]);
|
||||
$sdfc_tradein_price = trim($fields[self::F_BATT_SDFC_TRADEIN_PRICE]);
|
||||
|
||||
// add the battery sizes
|
||||
// check if size is empty or if price and tradein prices are N/A
|
||||
if (!isset($this->bsize_hash[$marathoner_size]))
|
||||
{
|
||||
// ignore blank sizes
|
||||
if ((strlen($marathoner_size) > 0) &&
|
||||
(strlen($marathoner_price) > 0))
|
||||
{
|
||||
// non-numeric entries are ignored since these are N/A == they don't sell it
|
||||
if ((is_numeric($marathoner_price)) &&
|
||||
(is_numeric($marathoner_tradein_price)))
|
||||
{
|
||||
$this->addBatterySize($marathoner_size, $marathoner_price, $marathoner_tradein_price);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isset($this->bsize_hash[$classic_size]))
|
||||
{
|
||||
if ((strlen($classic_size) > 0) &&
|
||||
(strlen($classic_price) > 0))
|
||||
{
|
||||
// non-numeric entries are ignored since these are N/A == they don't sell it
|
||||
if ((is_numeric($classic_price)) &&
|
||||
(is_numeric($classic_tradein_price)))
|
||||
{
|
||||
$this->addBatterySize($classic_size, $classic_price, $classic_tradein_price);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isset($this->bsize_hash[$excel_size]))
|
||||
{
|
||||
if ((strlen($excel_size) > 0) &&
|
||||
(strlen($excel_price) > 0))
|
||||
{
|
||||
// non-numeric entries are ignored since these are N/A == they don't sell it
|
||||
if ((is_numeric($excel_price)) &&
|
||||
(is_numeric($excel_tradein_price)))
|
||||
{
|
||||
$this->addBatterySize($excel_size, $excel_price, $excel_tradein_price);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (!isset($this->bsize_hash[$sdfc_size]))
|
||||
{
|
||||
if ((strlen($sdfc_size) > 0) &&
|
||||
(strlen($sdfc_price) > 0))
|
||||
{
|
||||
// non-numeric entries are ignored since these are N/A == they don't sell it
|
||||
if ((is_numeric($sdfc_price)) &&
|
||||
(is_numeric($sdfc_tradein_price)))
|
||||
{
|
||||
$this->addBatterySize($sdfc_size, $sdfc_price, $sdfc_tradein_price);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$row_num++;
|
||||
}
|
||||
|
||||
// output the battery sizes that were not added
|
||||
if (count($not_added) > 0)
|
||||
{
|
||||
fputcsv($out_fh, [
|
||||
'Battery Model',
|
||||
'Battery Size',
|
||||
'Price',
|
||||
'Trade In Price',
|
||||
'Reason',
|
||||
]);
|
||||
foreach($not_added as $row)
|
||||
{
|
||||
fputcsv($out_fh, $row);
|
||||
}
|
||||
}
|
||||
|
||||
fclose($out_fh);
|
||||
}
|
||||
|
||||
protected function createBatteryManufacturerData()
|
||||
{
|
||||
foreach ($this->batt_manufacturers as $name)
|
||||
{
|
||||
$new_bmanu = new BatteryManufacturer();
|
||||
$new_bmanu->setName($name);
|
||||
|
||||
$this->em->persist($new_bmanu);
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
protected function createBatteryModelData()
|
||||
{
|
||||
foreach ($this->batt_models as $name)
|
||||
{
|
||||
$new_bmodel = new BatteryModel();
|
||||
$new_bmodel->setName($name);
|
||||
|
||||
$this->em->persist($new_bmodel);
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
protected function addBatterySize($size, $price, $tradein_price)
|
||||
{
|
||||
$new_bsize = new BatterySize();
|
||||
|
||||
$clean_size = strtoupper($size);
|
||||
// check if size is M-42, if so, we need to change it to M42
|
||||
if (strpos($clean_size, 'M-42') !== false)
|
||||
{
|
||||
$clean_size = strtoupper(str_replace('-', '', $size));
|
||||
}
|
||||
|
||||
$new_bsize->setName(strtoupper($clean_size));
|
||||
$new_bsize->setTIPriceMotolite($tradein_price);
|
||||
|
||||
$this->em->persist($new_bsize);
|
||||
|
||||
// add to hash
|
||||
$this->bsize_hash[$size] = $new_bsize;
|
||||
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
protected function addInvalidEntry($model, $size, $price,
|
||||
$tradein_price, $reason)
|
||||
{
|
||||
$entry = [
|
||||
$model,
|
||||
$size,
|
||||
$price,
|
||||
$tradein_price,
|
||||
$reason,
|
||||
];
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
|
||||
protected function loadBatteryManufacturers()
|
||||
{
|
||||
$this->bmanu_hash = [];
|
||||
|
||||
$batt_manufacturers = $this->em->getRepository(BatteryManufacturer::class)->findAll();
|
||||
foreach ($batt_manufacturers as $batt_manu)
|
||||
{
|
||||
$name = $this->normalizeName($batt_manu->getName());
|
||||
$this->bmanu_hash[$name] = $batt_manu;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadBatteryModels()
|
||||
{
|
||||
$this->bmodel_hash = [];
|
||||
|
||||
$batt_models = $this->em->getRepository(BatteryModel::class)->findAll();
|
||||
foreach ($batt_models as $batt_model)
|
||||
{
|
||||
$name = $this->normalizeName($batt_model->getName());
|
||||
$this->bmodel_hash[$name] = $batt_model;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadBatterySizes()
|
||||
{
|
||||
$this->bsize_hash = [];
|
||||
|
||||
$batt_sizes = $this->em->getRepository(BatterySize::class)->findAll();
|
||||
foreach ($batt_sizes as $batt_size)
|
||||
{
|
||||
$name = $this->normalizeName($batt_size->getName());
|
||||
$this->bsize_hash[$name] = $batt_size;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadBatteries()
|
||||
{
|
||||
$this->batt_hash = [];
|
||||
|
||||
$batts = $this->em->getRepository(Battery::class)->findAll();
|
||||
foreach ($batts as $batt)
|
||||
{
|
||||
$brand = $this->normalizeName($batt->getManufacturer()->getName());
|
||||
$model = $this->normalizeName($batt->getModel()->getName());
|
||||
$size = $this->normalizeName($batt->getSize()->getName());
|
||||
|
||||
$this->batt_hash[$brand][$model][$size] = $batt;
|
||||
}
|
||||
}
|
||||
|
||||
protected function normalizeName($name)
|
||||
{
|
||||
$normalized_key = trim(strtolower($name));
|
||||
|
||||
return $normalized_key;
|
||||
}
|
||||
}
|
||||
373
src/Command/ImportCMBBatteryVehicleCompatibilityCommand.php
Normal file
373
src/Command/ImportCMBBatteryVehicleCompatibilityCommand.php
Normal file
|
|
@ -0,0 +1,373 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use App\Entity\BatteryManufacturer;
|
||||
use App\Entity\BatteryModel;
|
||||
use App\Entity\BatterySize;
|
||||
use App\Entity\Battery;
|
||||
use App\Entity\VehicleManufacturer;
|
||||
use App\Entity\Vehicle;
|
||||
|
||||
class ImportCMBBatteryVehicleCompatibilityCommand extends Command
|
||||
{
|
||||
// field index in csv file
|
||||
// vehicle info
|
||||
const F_VEHICLE_MANUFACTURER = 1;
|
||||
const F_VEHICLE_MAKE = 2;
|
||||
const F_VEHICLE_YEAR = 3;
|
||||
|
||||
// CENTURY MARATHONER BATTERY
|
||||
const F_BATT_MARATHONER_SIZE = 4;
|
||||
const F_BATT_MARATHONER_PRICE = 5;
|
||||
const F_BATT_MARATHONER_TRADEIN_PRICE = 6;
|
||||
const F_BATT_MARATHONER_DISCOUNT = 7;
|
||||
|
||||
// MOTOLITE CLASSIC BATTERY
|
||||
const F_BATT_CLASSIC_SIZE = 8;
|
||||
const F_BATT_CLASSIC_PRICE = 9;
|
||||
const F_BATT_CLASSIC_TRADEIN_PRICE = 10;
|
||||
const F_BATT_CLASSIC_DISCOUNT = 11;
|
||||
|
||||
// CENTURY EXCEL BATTERY
|
||||
const F_BATT_EXCEL_SIZE = 12;
|
||||
const F_BATT_EXCEL_PRICE = 13;
|
||||
const F_BATT_EXCEL_TRADEIN_PRICE = 14;
|
||||
const F_BATT_EXCEL_DISCOUNT = 15;
|
||||
|
||||
// CENTURY SDFC BATTERY
|
||||
const F_BATT_SDFC_SIZE = 16;
|
||||
const F_BATT_SDFC_PRICE = 17;
|
||||
const F_BATT_SDFC_TRADEIN_PRICE = 18;
|
||||
const F_BATT_SDFC_DISCOUNT = 19;
|
||||
|
||||
// constants for battery manufacturer names
|
||||
const STR_CENTURY = 'century';
|
||||
const STR_MOTOLITE = 'motolite';
|
||||
|
||||
// constants for battery models
|
||||
const STR_MARATHONER = 'marathoner';
|
||||
const STR_CLASSIC = 'classic';
|
||||
const STR_EXCEL = 'excel';
|
||||
const STR_SDFC = 'sdfc';
|
||||
|
||||
// special case for battery size
|
||||
const STR_M_42 = 'M-42';
|
||||
const STR_M42 = 'M42';
|
||||
|
||||
// for the model year
|
||||
const STR_PRESENT = 'Present';
|
||||
|
||||
protected $em;
|
||||
|
||||
protected $bmanu_hash;
|
||||
protected $bmodel_hash;
|
||||
protected $bsize_hash;
|
||||
protected $batt_hash;
|
||||
|
||||
protected $vmanu_hash;
|
||||
protected $vmake_hash;
|
||||
|
||||
public function __construct(EntityManagerInterface $om)
|
||||
{
|
||||
$this->em = $om;
|
||||
|
||||
// load existing battery data
|
||||
$this->loadBatteryManufacturers();
|
||||
$this->loadBatteryModels();
|
||||
$this->loadBatterySizes();
|
||||
$this->loadBatteries();
|
||||
|
||||
// load existing vehicle data
|
||||
$this->loadVehicleManufacturers();
|
||||
$this->loadVehicleMakes();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('cmbbatteryvehiclecompatibility:import')
|
||||
->setDescription('Retrieve from a CSV file vehicle and battery compatibility information.')
|
||||
->setHelp('Creates vehicles and their compatible batteries based on data from imported CSV.')
|
||||
->addArgument('file', InputArgument::REQUIRED, 'Path to the CSV file.')
|
||||
->addArgument('output_file', InputArgument::REQUIRED, 'Path to output file for vehicles not added.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
// get the sizes, vehicles, battery prices from the csv file
|
||||
$csv_file = $input->getArgument('file');
|
||||
|
||||
// attempt to open file
|
||||
try
|
||||
{
|
||||
$fh = fopen($csv_file, "r");
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception('The file "' . $csv_file . '" could be read.');
|
||||
}
|
||||
|
||||
$output_file = $input->getArgument('output_file');
|
||||
|
||||
// attempt to open file
|
||||
try
|
||||
{
|
||||
$output_fh = fopen($output_file, "w");
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception('The file "' . $output_file . '" could be read.');
|
||||
}
|
||||
|
||||
|
||||
// get entity manager
|
||||
$em = $this->em;
|
||||
|
||||
$row_num = 0;
|
||||
error_log('Processing vehicle and battery compatibility file...');
|
||||
while (($fields = fgetcsv($fh)) !== false)
|
||||
{
|
||||
$comp_batteries = [];
|
||||
if ($row_num < 2)
|
||||
{
|
||||
$row_num++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// get vehicle info from file
|
||||
$manufacturer = trim(strtolower($fields[self::F_VEHICLE_MANUFACTURER]));
|
||||
$make = trim(strtolower($fields[self::F_VEHICLE_MAKE]));
|
||||
$year = trim($fields[self::F_VEHICLE_YEAR]);
|
||||
|
||||
// get battery info from file
|
||||
$marathoner_size = $this->normalizeName(trim($fields[self::F_BATT_MARATHONER_SIZE]));
|
||||
$marathoner_price = trim($fields[self::F_BATT_MARATHONER_PRICE]);
|
||||
$marathoner_tradein_price = trim($fields[self::F_BATT_MARATHONER_TRADEIN_PRICE]);
|
||||
|
||||
$classic_size = $this->normalizeName(trim($fields[self::F_BATT_CLASSIC_SIZE]));
|
||||
$classic_price = trim($fields[self::F_BATT_CLASSIC_PRICE]);
|
||||
$classic_tradein_price = trim($fields[self::F_BATT_CLASSIC_TRADEIN_PRICE]);
|
||||
|
||||
$excel_size = $this->normalizeName(trim($fields[self::F_BATT_EXCEL_SIZE]));
|
||||
$excel_price = trim($fields[self::F_BATT_EXCEL_PRICE]);
|
||||
$excel_tradein_price = trim($fields[self::F_BATT_EXCEL_TRADEIN_PRICE]);
|
||||
|
||||
$sdfc_size = $this->normalizeName(trim($fields[self::F_BATT_SDFC_SIZE]));
|
||||
$sdfc_price = trim($fields[self::F_BATT_SDFC_PRICE]);
|
||||
$sdfc_tradein_price = trim($fields[self::F_BATT_SDFC_TRADEIN_PRICE]);
|
||||
|
||||
// get the compatible batteries
|
||||
// get marathoner battery
|
||||
if (strlen($marathoner_size) > 0)
|
||||
{
|
||||
// check if battery in system
|
||||
if (isset($this->batt_hash[self::STR_CENTURY][self::STR_MARATHONER][$marathoner_size]))
|
||||
$comp_batteries[] = $this->batt_hash[self::STR_CENTURY][self::STR_MARATHONER][$marathoner_size];
|
||||
}
|
||||
|
||||
// get classic battery
|
||||
if (strlen($classic_size) > 0)
|
||||
{
|
||||
// check if battery in system
|
||||
if (isset($this->batt_hash[self::STR_MOTOLITE][self::STR_CLASSIC][$classic_size]))
|
||||
$comp_batteries[] = $this->batt_hash[self::STR_MOTOLITE][self::STR_CLASSIC][$classic_size];
|
||||
}
|
||||
|
||||
// get excel battery
|
||||
if (strlen($excel_size) > 0)
|
||||
{
|
||||
// check if battery in system
|
||||
if (isset($this->batt_hash[self::STR_CENTURY][self::STR_EXCEL][$excel_size]))
|
||||
$comp_batteries[] = $this->batt_hash[self::STR_CENTURY][self::STR_EXCEL][$excel_size];
|
||||
}
|
||||
|
||||
// get sdfc battery
|
||||
if (strlen($sdfc_size) > 0)
|
||||
{
|
||||
// check if battery in system
|
||||
if (isset($this->batt_hash[self::STR_CENTURY][self::STR_SDFC][$sdfc_size]))
|
||||
$comp_batteries[] = $this->batt_hash[self::STR_CENTURY][self::STR_SDFC][$sdfc_size];
|
||||
}
|
||||
|
||||
// check if vehicle manufacturer has been added
|
||||
if (!isset($this->vmanu_hash[$manufacturer]))
|
||||
$this->addVehicleManufacturer($manufacturer);
|
||||
|
||||
// check if vehicle make has been added
|
||||
if (!isset($this->vmake_hash[$manufacturer][$make]))
|
||||
{
|
||||
$this->addVehicleMake($manufacturer, $make, $year, $comp_batteries);
|
||||
}
|
||||
|
||||
$row_num++;
|
||||
}
|
||||
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
protected function addVehicleManufacturer($name)
|
||||
{
|
||||
// save to db
|
||||
$vehicle_manufacturer = new VehicleManufacturer();
|
||||
|
||||
$vehicle_manufacturer->setName(strtoupper($name));
|
||||
|
||||
$this->em->persist($vehicle_manufacturer);
|
||||
$this->em->flush();
|
||||
|
||||
// add to hash
|
||||
$this->vmanu_hash[$name] = $vehicle_manufacturer;
|
||||
}
|
||||
|
||||
protected function addVehicleMake($manufacturer, $make, $year, $batteries)
|
||||
{
|
||||
// save to db
|
||||
$vehicle = new Vehicle();
|
||||
|
||||
$vmanu = $this->vmanu_hash[$manufacturer];
|
||||
|
||||
// parse year from and year to
|
||||
$year_from = '';
|
||||
$year_to = '';
|
||||
|
||||
if (!empty($year))
|
||||
{
|
||||
$model_years = explode('-', $year);
|
||||
$year_from = $model_years[0];
|
||||
if (!empty($year_to))
|
||||
$year_to = $model_years[1];
|
||||
|
||||
// check if $year_to is the string "Present"
|
||||
// if so, set to 0, for now
|
||||
if ($year_to == self::STR_PRESENT)
|
||||
$year_to = 0;
|
||||
}
|
||||
|
||||
$vehicle->setManufacturer($vmanu)
|
||||
->setMake(strtoupper($make))
|
||||
->setModelYearFrom($year_from)
|
||||
->setModelYearTo($year_to);
|
||||
|
||||
// add vehicle to battery
|
||||
foreach ($batteries as $battery)
|
||||
{
|
||||
$battery->addVehicle($vehicle);
|
||||
$this->em->persist($battery);
|
||||
}
|
||||
|
||||
// add vehicle to manufacturer
|
||||
$vmanu->addVehicle($vehicle);
|
||||
|
||||
$this->em->persist($vmanu);
|
||||
$this->em->persist($vehicle);
|
||||
$this->em->flush();
|
||||
|
||||
// add to hash
|
||||
$this->vmake_hash[$manufacturer][$make] = $vehicle;
|
||||
}
|
||||
|
||||
protected function loadBatteryManufacturers()
|
||||
{
|
||||
$this->bmanu_hash = [];
|
||||
|
||||
$batt_manufacturers = $this->em->getRepository(BatteryManufacturer::class)->findAll();
|
||||
foreach ($batt_manufacturers as $batt_manu)
|
||||
{
|
||||
$name = $this->normalizeName($batt_manu->getName());
|
||||
$this->bmanu_hash[$name] = $batt_manu;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadBatteryModels()
|
||||
{
|
||||
$this->bmodel_hash = [];
|
||||
|
||||
$batt_models = $this->em->getRepository(BatteryModel::class)->findAll();
|
||||
foreach ($batt_models as $batt_model)
|
||||
{
|
||||
$name = $this->normalizeName($batt_model->getName());
|
||||
$this->bmodel_hash[$name] = $batt_model;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadBatterySizes()
|
||||
{
|
||||
$this->bsize_hash = [];
|
||||
|
||||
$batt_sizes = $this->em->getRepository(BatterySize::class)->findAll();
|
||||
foreach ($batt_sizes as $batt_size)
|
||||
{
|
||||
$name = $this->normalizeName($batt_size->getName());
|
||||
$this->bsize_hash[$name] = $batt_size;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadBatteries()
|
||||
{
|
||||
$this->batt_hash = [];
|
||||
|
||||
$batts = $this->em->getRepository(Battery::class)->findAll();
|
||||
foreach ($batts as $batt)
|
||||
{
|
||||
$brand = $this->normalizeName($batt->getManufacturer()->getName());
|
||||
$model = $this->normalizeName($batt->getModel()->getName());
|
||||
$size = $this->normalizeName($batt->getSize()->getName());
|
||||
|
||||
$this->batt_hash[$brand][$model][$size] = $batt;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadVehicleManufacturers()
|
||||
{
|
||||
$this->vmanu_hash = [];
|
||||
|
||||
$vmanus = $this->em->getRepository(VehicleManufacturer::class)->findAll();
|
||||
foreach ($vmanus as $vmanu)
|
||||
{
|
||||
$name = $this->normalizeName($vmanu->getName());
|
||||
$this->vmanu_hash[$name] = $vmanu;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadVehicleMakes()
|
||||
{
|
||||
$this->vmake_hash = [];
|
||||
|
||||
$vmakes = $this->em->getRepository(Vehicle::class)->findAll();
|
||||
foreach ($vmakes as $vmake)
|
||||
{
|
||||
$manufacturer = $vmake->getManufacturer()->getName();
|
||||
$make = $this->normalizeName($vmake->getMake());
|
||||
|
||||
$this->vmake_hash[$manufacturer][$make] = $vmake;
|
||||
}
|
||||
}
|
||||
|
||||
protected function normalizeName($name)
|
||||
{
|
||||
// check if name contains M-42. Need to convert to M42
|
||||
if (strpos($name, self::STR_M_42) !== false)
|
||||
{
|
||||
// contains M-42
|
||||
$changed_name = str_replace(self::STR_M_42, self::STR_M42, $name);
|
||||
$normalized_key = strtolower($changed_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
$normalized_key = trim(strtolower($name));
|
||||
}
|
||||
|
||||
$normalized_key = trim(strtolower($name));
|
||||
|
||||
return $normalized_key;
|
||||
}
|
||||
}
|
||||
164
src/Command/ImportCMBLegacyJobOrderCommand.php
Normal file
164
src/Command/ImportCMBLegacyJobOrderCommand.php
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use App\Entity\CMBLegacyJobOrderRow;
|
||||
|
||||
class ImportCMBLegacyJobOrderCommand extends Command
|
||||
{
|
||||
// field index in csv file
|
||||
const F_INDEX = 0;
|
||||
const F_CREATED_DATE = 1;
|
||||
const F_CASE_NO = 2;
|
||||
const F_INSURER = 3;
|
||||
const F_VEHICLE_NO = 4;
|
||||
const F_CAR_MODEL = 5;
|
||||
const F_NATURE_OF_CALL = 6;
|
||||
const F_SERVICE_NEEDED = 7;
|
||||
const F_LOCATION = 8;
|
||||
const F_STATE = 9;
|
||||
const F_DRIVER = 10;
|
||||
const F_TRUCK = 11;
|
||||
const F_WORKSHOP_ARRIVAL_TIME = 12;
|
||||
const F_STATUS = 13;
|
||||
const F_CUSTOMER_NAME = 14;
|
||||
const F_CUSTOMER_PHONE_NO = 15;
|
||||
const F_OUR_REFERENCE = 16;
|
||||
const F_ODOMETER = 17;
|
||||
const F_BATT_MODEL = 18;
|
||||
const F_BATT_SIZE = 19;
|
||||
const F_BATT_TRADE_IN = 20;
|
||||
const F_REPLACED_BY = 21;
|
||||
const F_REMARK = 22;
|
||||
const F_SATISFACTION = 23;
|
||||
|
||||
protected $em;
|
||||
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function configure()
|
||||
{
|
||||
$this->setName('cmblegacyjoborderdata:import')
|
||||
->setDescription('Retrieve from a CSV file CarFix data.')
|
||||
->setHelp('Creates legacy job order entries based on data from imported CSV.')
|
||||
->addArgument('file', InputArgument::REQUIRED, 'Path to the CSV file.');
|
||||
}
|
||||
|
||||
public function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$csv_file = $input->getArgument('file');
|
||||
|
||||
// attempt to open file
|
||||
try
|
||||
{
|
||||
$fh = fopen($csv_file, "r");
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception('The file "' . $csv_file . '" could be read.');
|
||||
}
|
||||
|
||||
// get entity manager
|
||||
$em = $this->em;
|
||||
|
||||
$row_num = 0;
|
||||
error_log('Processing CarFix data csv file...');
|
||||
while (($fields = fgetcsv($fh)) !== false)
|
||||
{
|
||||
if ($row_num < 1)
|
||||
{
|
||||
$row_num++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the information
|
||||
$entry_num = trim($fields[self::F_INDEX]);
|
||||
$date_create = trim($fields[self::F_CREATED_DATE]);
|
||||
$case_number = trim($fields[self::F_CASE_NO]);
|
||||
$insurer = trim($fields[self::F_INSURER]);
|
||||
$vehicle_number = trim($fields[self::F_VEHICLE_NO]);
|
||||
$car_model = trim($fields[self::F_CAR_MODEL]);
|
||||
$nature_of_call = trim($fields[self::F_NATURE_OF_CALL]);
|
||||
$service_needed = trim($fields[self::F_SERVICE_NEEDED]);
|
||||
$location = trim($fields[self::F_LOCATION]);
|
||||
$state = trim($fields[self::F_STATE]);
|
||||
$driver = trim($fields[self::F_DRIVER]);
|
||||
$truck = trim($fields[self::F_TRUCK]);
|
||||
$workshop_arrival_time = trim($fields[self::F_WORKSHOP_ARRIVAL_TIME]);
|
||||
$status = trim($fields[self::F_STATUS]);
|
||||
$customer_name = trim($fields[self::F_CUSTOMER_NAME]);
|
||||
$customer_mobile = trim($fields[self::F_CUSTOMER_PHONE_NO]);
|
||||
$reference = trim($fields[self::F_OUR_REFERENCE]);
|
||||
$odometer = trim($fields[self::F_ODOMETER]);
|
||||
$batt_model = trim($fields[self::F_BATT_MODEL]);
|
||||
$batt_size = trim($fields[self::F_BATT_SIZE]);
|
||||
$trade_in = trim($fields[self::F_BATT_TRADE_IN]);
|
||||
$replaced_by = trim($fields[self::F_REPLACED_BY]);
|
||||
$remark = trim($fields[self::F_REMARK]);
|
||||
$satisfaction = trim($fields[self::F_SATISFACTION]);
|
||||
|
||||
$data_entry = $this->processEntry($entry_num, $date_create, $case_number, $insurer, $vehicle_number, $car_model,
|
||||
$nature_of_call, $service_needed, $location, $state, $driver, $truck, $workshop_arrival_time,
|
||||
$status, $customer_name, $customer_mobile, $reference, $odometer, $batt_model, $batt_size,
|
||||
$trade_in, $replaced_by, $remark, $satisfaction);
|
||||
|
||||
$legacy_data = new CMBLegacyJobOrderRow();
|
||||
$legacy_data->setData($data_entry);
|
||||
|
||||
$this->em->persist($legacy_data);
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
$this->em->clear();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected function processEntry($entry_num, $date_create, $case_number, $insurer, $vehicle_number, $car_model,
|
||||
$nature_of_call, $service_needed, $location, $state, $driver, $truck, $workshop_arrival_time,
|
||||
$status, $customer_name, $customer_mobile, $reference, $odometer, $batt_model, $batt_size,
|
||||
$trade_in, $replaced_by, $remark, $satisfaction)
|
||||
{
|
||||
$data_entry = [
|
||||
'entry_num' => $entry_num,
|
||||
'created_date' => $date_create,
|
||||
'case_number' => $case_number,
|
||||
'insurer' => $insurer,
|
||||
'vehicle_number' => $vehicle_number,
|
||||
'car_model' => $car_model,
|
||||
'nature_of_call' => $nature_of_call,
|
||||
'service_needed' => $service_needed,
|
||||
'location' => $location,
|
||||
'state' => $state,
|
||||
'driver' => $driver,
|
||||
'truck' => $truck,
|
||||
'workshop_arrival_time' => $workshop_arrival_time,
|
||||
'status' => $status,
|
||||
'customer_name' => $customer_name,
|
||||
'customer_phone_number' => $customer_mobile,
|
||||
'reference' => $reference,
|
||||
'odometer' => $odometer,
|
||||
'batt_model' => $batt_model,
|
||||
'batt_size' => $batt_size,
|
||||
'batt_trade_in' => $trade_in,
|
||||
'replaced_by' => $replaced_by,
|
||||
'remark' => $remark,
|
||||
'satisfaction' => $satisfaction,
|
||||
];
|
||||
|
||||
return $data_entry;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,449 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use App\Entity\BatteryManufacturer;
|
||||
use App\Entity\BatteryModel;
|
||||
use App\Entity\BatterySize;
|
||||
use App\Entity\Battery;
|
||||
use App\Entity\VehicleManufacturer;
|
||||
use App\Entity\Vehicle;
|
||||
|
||||
class ImportCMBVehicleCompatibilityCommand extends Command
|
||||
{
|
||||
// field index in csv file
|
||||
const F_VEHICLE_MANUFACTURER = 1;
|
||||
const F_VEHICLE_MAKE = 2;
|
||||
const F_VEHICLE_YEAR = 3;
|
||||
const F_BATT_SDFC = 4;
|
||||
const F_BATT_ULTRAMAX = 5;
|
||||
const F_BATT_MOTOLITE = 6;
|
||||
const F_BATT_MARATHONER = 7;
|
||||
const F_BATT_EXCEL = 8;
|
||||
|
||||
const STR_CENTURY = 'Century';
|
||||
const STR_MOTOLITE = 'Motolite';
|
||||
const STR_MARSHALL = 'Marshall';
|
||||
const STR_SDFC = 'SDFC';
|
||||
const STR_MARATHONER = 'Marathoner';
|
||||
const STR_WETCHARGED = 'Classic WetCharged';
|
||||
const STR_ULTRAMAX = 'ULTRAMAX';
|
||||
const STR_EXCEL = 'Excel';
|
||||
const STR_PRESENT = 'Present';
|
||||
const STR_M_42 = 'M-42';
|
||||
const STR_M42 = 'M42';
|
||||
|
||||
protected $em;
|
||||
|
||||
protected $bmanu_hash;
|
||||
protected $bmodel_hash;
|
||||
protected $bsize_hash;
|
||||
protected $batt_hash;
|
||||
|
||||
protected $vmanu_hash;
|
||||
protected $vmake_hash;
|
||||
|
||||
public function __construct(EntityManagerInterface $om)
|
||||
{
|
||||
$this->em = $om;
|
||||
|
||||
// load existing battery data
|
||||
$this->loadBatteryManufacturers();
|
||||
$this->loadBatteryModels();
|
||||
$this->loadBatterySizes();
|
||||
$this->loadBatteries();
|
||||
|
||||
// load existing vehicle data
|
||||
$this->loadVehicleManufacturers();
|
||||
$this->loadVehicleMakes();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('cmbvehiclecompatibility:import')
|
||||
->setDescription('Retrieve from a CSV file battery and vehicle information.')
|
||||
->setHelp('Creates battery manufacturers, models, sizes, vehicle makes, and models based on data from imported CSV.')
|
||||
->addArgument('file', InputArgument::REQUIRED, 'Path to the CSV file.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$csv_file = $input->getArgument('file');
|
||||
|
||||
// attempt to open file
|
||||
try
|
||||
{
|
||||
$fh = fopen($csv_file, "r");
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception('The file "' . $csv_file . '" could be read.');
|
||||
}
|
||||
|
||||
// get entity manager
|
||||
$em = $this->em;
|
||||
|
||||
$row_num = 0;
|
||||
error_log('Processing vehicle compatibility csv file...');
|
||||
while (($fields = fgetcsv($fh)) !== false)
|
||||
{
|
||||
$comp_batteries = [];
|
||||
if ($row_num < 2)
|
||||
{
|
||||
$row_num++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// initialize size battery array for cases where the battery size has '/'
|
||||
$sdfc_sizes = [];
|
||||
$ultramax_sizes = [];
|
||||
$motolite_sizes = [];
|
||||
$marathoner_sizes = [];
|
||||
$excel_sizes = [];
|
||||
|
||||
// battery info
|
||||
$sdfc_size = trim($fields[self::F_BATT_SDFC]);
|
||||
$ultramax_size = trim($fields[self::F_BATT_ULTRAMAX]);
|
||||
$motolite_size = trim($fields[self::F_BATT_MOTOLITE]);
|
||||
$marathoner_size = trim($fields[self::F_BATT_MARATHONER]);
|
||||
$excel_size = trim($fields[self::F_BATT_EXCEL]);
|
||||
|
||||
// check the sizes for '/'
|
||||
$pos = stripos($sdfc_size, '/');
|
||||
if ($pos == false)
|
||||
{
|
||||
// no '/' in size
|
||||
$sdfc_sizes[] = $this->normalizeName($sdfc_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have '/' in size so we have to explode
|
||||
$sizes = explode('/', $sdfc_size);
|
||||
foreach ($sizes as $size)
|
||||
{
|
||||
$sdfc_sizes[] = $this->normalizeName($size);
|
||||
}
|
||||
}
|
||||
|
||||
$pos = stripos($motolite_size, '/');
|
||||
if ($pos == false)
|
||||
{
|
||||
// no '/' in size
|
||||
$motolite_sizes[] = $this->normalizeName($motolite_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have '/' in size so we have to explode
|
||||
$sizes = explode('/', $motolite_size);
|
||||
foreach ($sizes as $size)
|
||||
{
|
||||
$motolite_sizes[] = $this->normalizeName($size);
|
||||
}
|
||||
}
|
||||
|
||||
$pos = stripos($marathoner_size, '/');
|
||||
if ($pos == false)
|
||||
{
|
||||
// no '/' in size
|
||||
$marathoner_sizes[] = $this->normalizeName($marathoner_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have '/' in size so we have to explode
|
||||
$sizes = explode('/', $marathoner_size);
|
||||
foreach ($sizes as $size)
|
||||
{
|
||||
$marathoner_sizes[] = $this->normalizeName($size);
|
||||
}
|
||||
}
|
||||
|
||||
$pos = stripos($ultramax_size, '/');
|
||||
if ($pos == false)
|
||||
{
|
||||
// no '/' in size
|
||||
$ultramax_sizes[] = $this->normalizeName($ultramax_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have '/' in size so we have to explode
|
||||
$sizes = explode('/', $ultramax_size);
|
||||
foreach ($sizes as $size)
|
||||
{
|
||||
$ultramax_sizes[] = $this->normalizeName($size);
|
||||
}
|
||||
}
|
||||
|
||||
$pos = stripos($excel_size, '/');
|
||||
if ($pos == false)
|
||||
{
|
||||
// no '/' in size
|
||||
$excel_sizes[] = $this->normalizeName($excel_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have '/' in size so we have to explode
|
||||
$sizes = explode('/', $excel_size);
|
||||
foreach ($sizes as $size)
|
||||
{
|
||||
$excel_sizes[] = $this->normalizeName($size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// normalize the battery manufacturers and battery models
|
||||
$norm_century = $this->normalizeName(self::STR_CENTURY);
|
||||
$norm_sdfc = $this->normalizeName(self::STR_SDFC);
|
||||
$norm_motolite = $this->normalizeName(self::STR_MOTOLITE);
|
||||
$norm_wetcharged = $this->normalizeName(self::STR_WETCHARGED);
|
||||
$norm_marathoner = $this->normalizeName(self::STR_MARATHONER);
|
||||
$norm_ultramax = $this->normalizeName(self::STR_ULTRAMAX);
|
||||
$norm_excel = $this->normalizeName(self::STR_EXCEL);
|
||||
|
||||
//foreach($sdfc_sizes as $size)
|
||||
//{
|
||||
// error_log('sdfc size ' . $size);
|
||||
//}
|
||||
//foreach($motolite_sizes as $size)
|
||||
//{
|
||||
// error_log('motolite size ' . $size);
|
||||
//}
|
||||
//foreach($marathoner_sizes as $size)
|
||||
//{
|
||||
// error_log('marathoner size ' . $size);
|
||||
//}
|
||||
|
||||
// vehicle info
|
||||
$manufacturer = trim($fields[self::F_VEHICLE_MANUFACTURER]);
|
||||
$make = trim($fields[self::F_VEHICLE_MAKE]);
|
||||
$year = trim($fields[self::F_VEHICLE_YEAR]);
|
||||
|
||||
// vehicle data
|
||||
// check if vehicle manufacturer has been added
|
||||
if (!isset($this->vmanu_hash[$manufacturer]))
|
||||
$this->addVehicleManufacturer($manufacturer);
|
||||
|
||||
// check if vehicle make has been added
|
||||
if (!isset($this->vmake_hash[$manufacturer][$make]))
|
||||
{
|
||||
foreach($sdfc_sizes as $size)
|
||||
{
|
||||
if (!(empty($size)))
|
||||
{
|
||||
if (isset($this->batt_hash[$norm_century][$norm_sdfc][$size]))
|
||||
$comp_batteries[] = $this->batt_hash[$norm_century][$norm_sdfc][$size];
|
||||
else
|
||||
error_log('Not in the system: ' . $norm_century . ' ' . $norm_sdfc . ' ' . $size);
|
||||
}
|
||||
}
|
||||
foreach($ultramax_sizes as $size)
|
||||
{
|
||||
if (!(empty($size)))
|
||||
{
|
||||
if (isset($this->batt_hash[$norm_ultramax][$norm_ultramax][$size]))
|
||||
$comp_batteries[] = $this->batt_hash[$norm_ultramax][$norm_ultramax][$size];
|
||||
else
|
||||
error_log('Not in the system: ' . $norm_ultramax . ' ' . $norm_ultramax . ' ' . $size);
|
||||
}
|
||||
}
|
||||
foreach($motolite_sizes as $size)
|
||||
{
|
||||
if (!(empty($size)))
|
||||
{
|
||||
if (isset($this->batt_hash[$norm_motolite][$norm_wetcharged][$size]))
|
||||
$comp_batteries[] = $this->batt_hash[$norm_motolite][$norm_wetcharged][$size];
|
||||
else
|
||||
error_log('Not in the system: ' . $norm_motolite . ' ' . $norm_wetcharged . ' ' . $size);
|
||||
}
|
||||
}
|
||||
foreach($marathoner_sizes as $size)
|
||||
{
|
||||
if (!(empty($size)))
|
||||
{
|
||||
if (isset($this->batt_hash[$norm_century][$norm_marathoner][$size]))
|
||||
$comp_batteries[] = $this->batt_hash[$norm_century][$norm_marathoner][$size];
|
||||
else
|
||||
error_log('Not in the system: ' . $norm_century . ' ' . $norm_marathoner . ' ' . $size);
|
||||
}
|
||||
}
|
||||
foreach($excel_sizes as $size)
|
||||
{
|
||||
if (!(empty($size)))
|
||||
{
|
||||
if (isset($this->batt_hash[$norm_excel][$norm_excel][$size]))
|
||||
$comp_batteries[] = $this->batt_hash[$norm_excel][$norm_excel][$size];
|
||||
else
|
||||
error_log('Not in the system: ' . $norm_excel . ' ' . $norm_excel . ' ' . $size);
|
||||
}
|
||||
}
|
||||
$this->addVehicleMake($manufacturer, $make, $year, $comp_batteries);
|
||||
}
|
||||
|
||||
$row_num++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected function addVehicleManufacturer($name)
|
||||
{
|
||||
// save to db
|
||||
$vehicle_manufacturer = new VehicleManufacturer();
|
||||
|
||||
$vehicle_manufacturer->setName($name);
|
||||
|
||||
$this->em->persist($vehicle_manufacturer);
|
||||
$this->em->flush();
|
||||
|
||||
// add to hash
|
||||
$this->vmanu_hash[$name] = $vehicle_manufacturer;
|
||||
}
|
||||
|
||||
protected function addVehicleMake($manufacturer, $make, $year, $batteries)
|
||||
{
|
||||
// save to db
|
||||
$vehicle = new Vehicle();
|
||||
|
||||
$vmanu = $this->vmanu_hash[$manufacturer];
|
||||
|
||||
// parse year from and year to
|
||||
$year_from = '';
|
||||
$year_to = '';
|
||||
|
||||
if (!empty($year))
|
||||
{
|
||||
$model_years = explode('-', $year);
|
||||
$year_from = $model_years[0];
|
||||
if (!empty($year_to))
|
||||
$year_to = $model_years[1];
|
||||
|
||||
// check if $year_to is the string "Present"
|
||||
// if so, set to 0, for now
|
||||
if ($year_to == self::STR_PRESENT)
|
||||
$year_to = 0;
|
||||
}
|
||||
|
||||
$vehicle->setManufacturer($vmanu)
|
||||
->setMake($make)
|
||||
->setModelYearFrom($year_from)
|
||||
->setModelYearTo($year_to);
|
||||
|
||||
// add vehicle to battery
|
||||
foreach ($batteries as $battery)
|
||||
{
|
||||
$battery->addVehicle($vehicle);
|
||||
$this->em->persist($battery);
|
||||
}
|
||||
|
||||
// add vehicle to manufacturer
|
||||
$vmanu->addVehicle($vehicle);
|
||||
|
||||
$this->em->persist($vmanu);
|
||||
$this->em->persist($vehicle);
|
||||
$this->em->flush();
|
||||
|
||||
// add to hash
|
||||
$this->vmake_hash[$manufacturer][$make] = $vehicle;
|
||||
}
|
||||
|
||||
protected function loadBatteryManufacturers()
|
||||
{
|
||||
$this->bmanu_hash = [];
|
||||
|
||||
$batt_manufacturers = $this->em->getRepository(BatteryManufacturer::class)->findAll();
|
||||
foreach ($batt_manufacturers as $batt_manu)
|
||||
{
|
||||
$name = $this->normalizeName($batt_manu->getName());
|
||||
$this->bmanu_hash[$name] = $batt_manu;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadBatteryModels()
|
||||
{
|
||||
$this->bmodel_hash = [];
|
||||
|
||||
$batt_models = $this->em->getRepository(BatteryModel::class)->findAll();
|
||||
foreach ($batt_models as $batt_model)
|
||||
{
|
||||
$name = $this->normalizeName($batt_model->getName());
|
||||
$this->bmodel_hash[$name] = $batt_model;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadBatterySizes()
|
||||
{
|
||||
$this->bsize_hash = [];
|
||||
|
||||
$batt_sizes = $this->em->getRepository(BatterySize::class)->findAll();
|
||||
foreach ($batt_sizes as $batt_size)
|
||||
{
|
||||
$name = $this->normalizeName($batt_size->getName());
|
||||
$this->bsize_hash[$name] = $batt_size;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadBatteries()
|
||||
{
|
||||
$this->batt_hash = [];
|
||||
|
||||
$batts = $this->em->getRepository(Battery::class)->findAll();
|
||||
foreach ($batts as $batt)
|
||||
{
|
||||
$brand = $this->normalizeName($batt->getManufacturer()->getName());
|
||||
$model = $this->normalizeName($batt->getModel()->getName());
|
||||
$size = $this->normalizeName($batt->getSize()->getName());
|
||||
|
||||
$this->batt_hash[$brand][$model][$size] = $batt;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadVehicleManufacturers()
|
||||
{
|
||||
$this->vmanu_hash = [];
|
||||
|
||||
$vmanus = $this->em->getRepository(VehicleManufacturer::class)->findAll();
|
||||
foreach ($vmanus as $vmanu)
|
||||
{
|
||||
$name = $vmanu->getName();
|
||||
$this->vmanu_hash[$name] = $vmanu;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadVehicleMakes()
|
||||
{
|
||||
$this->vmake_hash = [];
|
||||
|
||||
$vmakes = $this->em->getRepository(Vehicle::class)->findAll();
|
||||
foreach ($vmakes as $vmake)
|
||||
{
|
||||
$manufacturer = $vmake->getManufacturer()->getName();
|
||||
$make = $vmake->getMake();
|
||||
|
||||
$this->vmake_hash[$manufacturer][$make] = $vmake;
|
||||
}
|
||||
}
|
||||
|
||||
protected function normalizeName($name)
|
||||
{
|
||||
// check for M-42. Need to convert to M42
|
||||
if (strcasecmp($name, self::STR_M_42) == 0)
|
||||
{
|
||||
$normalized_key = strtolower(self::STR_M42);
|
||||
}
|
||||
else
|
||||
{
|
||||
$normalized_key = trim(strtolower($name));
|
||||
}
|
||||
|
||||
return $normalized_key;
|
||||
}
|
||||
|
||||
}
|
||||
563
src/Command/MigrateCMBLegacyJobOrderCommand.php
Normal file
563
src/Command/MigrateCMBLegacyJobOrderCommand.php
Normal file
|
|
@ -0,0 +1,563 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use App\Entity\CMBLegacyJobOrderRow;
|
||||
use App\Entity\CMBLegacyJobOrder;
|
||||
use App\Entity\VehicleManufacturer;
|
||||
use App\Entity\Vehicle;
|
||||
use App\Entity\BatteryManufacturer;
|
||||
use App\Entity\BatteryModel;
|
||||
use App\Entity\BatterySize;
|
||||
use App\Entity\Battery;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\CustomerVehicle;
|
||||
|
||||
use App\Ramcar\CMBServiceType;
|
||||
use App\Ramcar\JOStatus;
|
||||
use App\Ramcar\FuelType;
|
||||
use App\Ramcar\VehicleStatusCondition;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class MigrateCMBLegacyJobOrderCommand extends Command
|
||||
{
|
||||
/*
|
||||
id = 'entry_num'
|
||||
trans_date = 'created_date'
|
||||
case_number = 'case_number'
|
||||
insurer = 'insurer'
|
||||
plate_number = 'vehicle_number'
|
||||
car_brand and car_make = split the 'car_model'
|
||||
nature_of_call = nature_of_call
|
||||
trans_type = 'service_needed'
|
||||
address = 'location'
|
||||
address = 'state'
|
||||
driver = 'driver'
|
||||
truck = 'truck'
|
||||
workshop_arrival_time => 'workshop_arrival_time'
|
||||
status = 'status'
|
||||
cust_name = 'customer_name'
|
||||
cust_mobile = 'customer_phone_number'
|
||||
reference = 'reference'
|
||||
odometer = 'odometer'
|
||||
batt_model = 'batt_model'
|
||||
batt_size = 'batt_size'
|
||||
is_trade_in = 'batt_trade_in'
|
||||
replaced_by = 'replaced_by'
|
||||
remarks = 'remark'
|
||||
satisfaction => 'satisfaction'
|
||||
*/
|
||||
|
||||
const STR_LAST_NAME = 'LEGACY';
|
||||
|
||||
protected $em;
|
||||
|
||||
protected $bmanu_hash;
|
||||
protected $bmodel_hash;
|
||||
protected $bsize_hash;
|
||||
protected $batt_hash;
|
||||
|
||||
protected $vmanu_hash;
|
||||
protected $vmake_hash;
|
||||
|
||||
protected $cv_hash;
|
||||
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
|
||||
// load existing battery data
|
||||
$this->loadBatteryManufacturers();
|
||||
$this->loadBatteryModels();
|
||||
$this->loadBatterySizes();
|
||||
$this->loadBatteries();
|
||||
|
||||
// load existing vehicle data
|
||||
$this->loadVehicleManufacturers();
|
||||
$this->loadVehicleMakes();
|
||||
|
||||
// load existing customer vehicle data
|
||||
$this->loadCustomerVehicles();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function configure()
|
||||
{
|
||||
$this->setName('cmblegacyjoborderdata:migrate')
|
||||
->setDescription('Retrieve database cmb legacy job orders and insert into job order.')
|
||||
->setHelp('Creates job orders based on data from imported CSV.')
|
||||
->addArgument('output_file', InputArgument::REQUIRED, 'Path to the output CSV file of the entries not added.');
|
||||
}
|
||||
|
||||
public function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$csv_file = $input->getArgument('output_file');
|
||||
|
||||
// attempt to open file
|
||||
try
|
||||
{
|
||||
$fh = fopen($csv_file, "w");
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception('The file "' . $csv_file . '" could be opened.');
|
||||
}
|
||||
|
||||
// get all legacy job orders
|
||||
$query = $this->em->createQuery('SELECT legacy_jo_row FROM App\Entity\CMBLegacyJobOrderRow legacy_jo_row');
|
||||
$result = $query->iterate();
|
||||
|
||||
$invalid_entries = [];
|
||||
$added_entries = 0;
|
||||
$total_entries = 0;
|
||||
$total_inv_entries = 0;
|
||||
foreach ($result as $row)
|
||||
{
|
||||
$entry = $row[0];
|
||||
$jo_entry = $entry->getData();
|
||||
|
||||
$total_entries++;
|
||||
|
||||
// get the entry information
|
||||
$entry_num = $jo_entry['entry_num'];
|
||||
$date_create = $jo_entry['created_date'];
|
||||
$case_number = $jo_entry['case_number'];
|
||||
$insurer = $jo_entry['insurer'];
|
||||
$plate_number = $this->cleanPlateNumber($jo_entry['vehicle_number']);
|
||||
$car_model = $this->normalizeName($jo_entry['car_model']);
|
||||
$nature_of_call = $jo_entry['nature_of_call'];
|
||||
$service_needed = $jo_entry['service_needed'];
|
||||
$location = $jo_entry['location'];
|
||||
$state = $jo_entry['state'];
|
||||
$driver = $jo_entry['driver'];
|
||||
$truck = $jo_entry['truck'];
|
||||
$workshop_arrival_time = $jo_entry['workshop_arrival_time'];
|
||||
$status = $jo_entry['status'];
|
||||
$customer_name = $jo_entry['customer_name'];
|
||||
$customer_mobile = $jo_entry['customer_phone_number'];
|
||||
$reference = $jo_entry['reference'];
|
||||
$odometer = $jo_entry['odometer'];
|
||||
$batt_model = $this->normalizeName($jo_entry['batt_model']);
|
||||
$batt_size = $this->normalizeName($jo_entry['batt_size']);
|
||||
$batt_trade_in = $jo_entry['batt_trade_in'];
|
||||
$replaced_by = $jo_entry['replaced_by'];
|
||||
$remark = $jo_entry['remark'];
|
||||
$satisfaction = $jo_entry['satisfaction'];
|
||||
|
||||
// check vehicle info if valid
|
||||
$v_status = $this->processVehicleInfo($car_model);
|
||||
if ($v_status != null)
|
||||
{
|
||||
//error_log($v_status . ' ' . $car_model);
|
||||
$invalid_entries[] = $this->addInvalidEntry($entry_num, $date_create, $case_number, $insurer, $plate_number, $car_model,
|
||||
$nature_of_call, $service_needed, $location, $state, $driver, $truck, $workshop_arrival_time,
|
||||
$status, $customer_name, $customer_mobile, $reference, $odometer, $batt_model, $batt_size,
|
||||
$batt_trade_in, $replaced_by, $remark, $satisfaction, $v_status);
|
||||
|
||||
$total_inv_entries++;
|
||||
// move to next entry
|
||||
continue;
|
||||
}
|
||||
|
||||
// check battery info if valid
|
||||
$batt_status = $this->processBatteryInfo($batt_model, $batt_size);
|
||||
if ($batt_status != null)
|
||||
{
|
||||
//error_log($batt_status . ' ' . $batt_model . ' ' . $batt_size);
|
||||
$invalid_entries[] = $this->addInvalidEntry($entry_num, $date_create, $case_number, $insurer, $plate_number, $car_model,
|
||||
$nature_of_call, $service_needed, $location, $state, $driver, $truck, $workshop_arrival_time,
|
||||
$status, $customer_name, $customer_mobile, $reference, $odometer, $batt_model, $batt_size,
|
||||
$batt_trade_in, $replaced_by, $remark, $satisfaction, $batt_status);
|
||||
|
||||
$total_inv_entries++;
|
||||
// move to next entry
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if mobile phone number has letters or spaces or special characters
|
||||
if (!(preg_match('/^\d+$/', $customer_mobile)))
|
||||
{
|
||||
// not a valid mobile number
|
||||
//error_log('invalid number ' . $customer_mobile);
|
||||
$invalid_entries[] = $this->addInvalidEntry($entry_num, $date_create, $case_number, $insurer, $plate_number, $car_model,
|
||||
$nature_of_call, $service_needed, $location, $state, $driver, $truck, $workshop_arrival_time,
|
||||
$status, $customer_name, $customer_mobile, $reference, $odometer, $batt_model, $batt_size,
|
||||
$batt_trade_in, $replaced_by, $remark, $satisfaction, 'Invalid mobile number');
|
||||
|
||||
$total_inv_entries++;
|
||||
// move to next entry
|
||||
continue;
|
||||
}
|
||||
|
||||
// create job order
|
||||
$cmb_legacy_jo = new CMBLegacyJobOrder();
|
||||
|
||||
// date_create
|
||||
$created_date = DateTime::createFromFormat("d-m-Y H:i", $date_create);
|
||||
$cmb_legacy_jo->setTransDate($created_date);
|
||||
|
||||
// parse vehicle info
|
||||
// get vehicle from hash
|
||||
$v_array = explode(' ', $car_model);
|
||||
|
||||
// manufacturer
|
||||
$v_manufacturer = trim($v_array[0]);
|
||||
|
||||
// get model
|
||||
$model_info = '';
|
||||
$v_model = '';
|
||||
for ($i = 1; $i < count($v_array); $i++)
|
||||
{
|
||||
$model_info = $model_info . ' ' . trim($v_array[$i]);
|
||||
}
|
||||
|
||||
$v_model = trim($model_info);
|
||||
|
||||
// delivery address = location + state
|
||||
$delivery_address = $location . ', ' . $state;
|
||||
|
||||
// check if trade in
|
||||
$trade_in = false;
|
||||
if (strtolower($batt_trade_in) == 'yes')
|
||||
$trade_in = true;
|
||||
|
||||
$cmb_legacy_jo->setCaseNumber($case_number)
|
||||
->setInsurer($insurer)
|
||||
->setNatureOfCall($nature_of_call)
|
||||
->setTransType($service_needed)
|
||||
->setCarBrand(strtoupper($v_manufacturer))
|
||||
->setCarMake(strtoupper($v_model))
|
||||
->setCustName($customer_name)
|
||||
->setCustMobile($customer_mobile)
|
||||
->setAddress($delivery_address)
|
||||
->setDriver($driver)
|
||||
->setTruck($truck)
|
||||
->setWorkshopArrivalTime($workshop_arrival_time)
|
||||
->setPlateNumber($plate_number)
|
||||
->setStatus($status)
|
||||
->setReference($reference)
|
||||
->setOdometer($odometer)
|
||||
->setBatteryModel(strtoupper($batt_model))
|
||||
->setBatterySize(strtoupper($batt_size))
|
||||
->setIsTradeIn($trade_in)
|
||||
->setReplacedBy($replaced_by)
|
||||
->setSatisfaction($satisfaction);
|
||||
|
||||
// plate number == vehicle_number. Use as key to cv_hash
|
||||
// check if plate number has been added
|
||||
if (!isset($this->cv_hash[$plate_number]))
|
||||
{
|
||||
$cust = $this->addCustomer($customer_name, $customer_mobile);
|
||||
$cv = $this->addCustomerVehicle($plate_number, $car_model, $cust);
|
||||
}
|
||||
|
||||
$this->em->persist($cmb_legacy_jo);
|
||||
$this->em->detach($row[0]);
|
||||
|
||||
$added_entries++;
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
$this->em->clear();
|
||||
|
||||
// output the entries that were not added
|
||||
if (count($invalid_entries) > 0)
|
||||
{
|
||||
fputcsv($fh, [
|
||||
'Entry Num',
|
||||
'Created Date',
|
||||
'Case Number',
|
||||
'Insurer',
|
||||
'Vehicle Number',
|
||||
'Car Model',
|
||||
'Nature of Call',
|
||||
'Service Needed',
|
||||
'Location',
|
||||
'State',
|
||||
'Driver',
|
||||
'Truck',
|
||||
'Workshop Arrival Time',
|
||||
'Status',
|
||||
'Customer Name',
|
||||
'Customer Phone Number',
|
||||
'Reference',
|
||||
'Odometer',
|
||||
'Batt Model',
|
||||
'Batt Size',
|
||||
'Batt Trade In',
|
||||
'Replaced By',
|
||||
'Remark',
|
||||
'Satisfaction',
|
||||
'Reason',
|
||||
|
||||
]);
|
||||
|
||||
foreach($invalid_entries as $row)
|
||||
{
|
||||
fputcsv($fh, $row);
|
||||
}
|
||||
}
|
||||
|
||||
fclose($fh);
|
||||
|
||||
error_log('Processed ' . $total_entries . ' entries.');
|
||||
error_log('Added ' . $added_entries . ' entries.');
|
||||
error_log('Did not add ' . $total_inv_entries . ' entries.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected function processVehicleInfo($car_model)
|
||||
{
|
||||
// vehicle manufacturer is the first entry
|
||||
// vehicle model is the 2nd entry + whatever follows
|
||||
$v_array = explode(' ', $car_model);
|
||||
|
||||
// manufacturer
|
||||
$v_manufacturer = trim($v_array[0]);
|
||||
|
||||
// get model
|
||||
$model_info = '';
|
||||
$v_model = '';
|
||||
for ($i = 1; $i < count($v_array); $i++)
|
||||
{
|
||||
$model_info = $model_info . ' ' . trim($v_array[$i]);
|
||||
}
|
||||
|
||||
$v_model = trim($model_info);
|
||||
//error_log($v_manufacturer . ' ' . $v_model);
|
||||
|
||||
// check if manufacturer is in hash
|
||||
if (!isset($this->vmanu_hash[$v_manufacturer]))
|
||||
{
|
||||
//error_log($v_manufacturer . ' invalid.');
|
||||
return 'Vehicle manufacturer not in system.';
|
||||
}
|
||||
|
||||
// check if manufacturer and make is in hash
|
||||
if (!isset($this->vmake_hash[$v_manufacturer][$v_model]))
|
||||
{
|
||||
//error_log($v_model . ' invalid.');
|
||||
return 'Vehicle model not in system.';
|
||||
}
|
||||
// car model info valid
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function processBatteryInfo($batt_model, $batt_size)
|
||||
{
|
||||
// check if battery model is in hash
|
||||
if (!isset($this->bmodel_hash[$batt_model]))
|
||||
return 'Battery model not in system.';
|
||||
|
||||
// check if battery size is in hash
|
||||
if (!isset($this->bsize_hash[$batt_size]))
|
||||
return 'Battery size not in system.';
|
||||
|
||||
// battery info valid
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function addInvalidEntry($entry_num, $date_create, $case_number, $insurer, $plate_number, $car_model,
|
||||
$nature_of_call, $service_needed, $location, $state, $driver, $truck, $workshop_arrival_time,
|
||||
$status, $customer_name, $customer_mobile, $reference, $odometer, $batt_model, $batt_size,
|
||||
$batt_trade_in, $replaced_by, $remark, $satisfaction, $v_status)
|
||||
{
|
||||
$inv_entry = [
|
||||
'number' => $entry_num,
|
||||
'created_date' => $date_create,
|
||||
'case_number' => $case_number,
|
||||
'insurer' => $insurer,
|
||||
'vehicle_number' => $plate_number,
|
||||
'car_model' => $car_model,
|
||||
'nature_of_call' => $nature_of_call,
|
||||
'service_needed' => $service_needed,
|
||||
'location' => $location,
|
||||
'state' => $state,
|
||||
'driver' => $driver,
|
||||
'truck' => $truck,
|
||||
'workshop_arrival_time' => $workshop_arrival_time,
|
||||
'status' => $status,
|
||||
'customer_name' => $customer_name,
|
||||
'customer_phone_number' => $customer_mobile,
|
||||
'reference' => $reference,
|
||||
'odometer' => $odometer,
|
||||
'batt_model' => $batt_model,
|
||||
'batt_size' => $batt_size,
|
||||
'batt_trade_in' => $batt_trade_in,
|
||||
'replaced_by' => $replaced_by,
|
||||
'remark' => $remark,
|
||||
'satisfaction' => $satisfaction,
|
||||
'reason' => $v_status,
|
||||
];
|
||||
|
||||
return $inv_entry;
|
||||
}
|
||||
|
||||
protected function addCustomer($name, $mobile)
|
||||
{
|
||||
$new_cust = new Customer();
|
||||
|
||||
$new_cust->setFirstName($name)
|
||||
->setLastName(self::STR_LAST_NAME)
|
||||
->setPhoneMobile($mobile);
|
||||
|
||||
$this->em->persist($new_cust);
|
||||
|
||||
return $new_cust;
|
||||
}
|
||||
|
||||
protected function addCustomerVehicle($plate_num, $car_model, $customer)
|
||||
{
|
||||
$new_cv = new CustomerVehicle();
|
||||
|
||||
// get vehicle from hash
|
||||
$v_array = explode(' ', $car_model);
|
||||
|
||||
// manufacturer
|
||||
$v_manufacturer = trim($v_array[0]);
|
||||
|
||||
// get model
|
||||
$model_info = '';
|
||||
$v_model = '';
|
||||
for ($i = 1; $i < count($v_array); $i++)
|
||||
{
|
||||
$model_info = $model_info . ' ' . trim($v_array[$i]);
|
||||
}
|
||||
|
||||
$v_model = trim($model_info);
|
||||
|
||||
$vehicle = $this->vmake_hash[$v_manufacturer][$v_model];
|
||||
|
||||
$new_cv->setCustomer($customer)
|
||||
->setPlateNumber($plate_num)
|
||||
->setStatusCondition(VehicleStatusCondition::BRAND_NEW)
|
||||
->setModelYear('')
|
||||
->setColor('')
|
||||
->setFuelType(FuelType::GAS)
|
||||
->setHasMotoliteBattery(true)
|
||||
->setVehicle($vehicle);
|
||||
|
||||
$this->em->persist($new_cv);
|
||||
|
||||
// add customer vehicle to cv_hash
|
||||
$this->cv_hash[$plate_num] = $new_cv;
|
||||
|
||||
return $new_cv;
|
||||
}
|
||||
|
||||
protected function loadBatteryManufacturers()
|
||||
{
|
||||
$this->bmanu_hash = [];
|
||||
|
||||
$batt_manufacturers = $this->em->getRepository(BatteryManufacturer::class)->findAll();
|
||||
foreach ($batt_manufacturers as $batt_manu)
|
||||
{
|
||||
$name = $this->normalizeName($batt_manu->getName());
|
||||
$this->bmanu_hash[$name] = $batt_manu;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadBatteryModels()
|
||||
{
|
||||
$this->bmodel_hash = [];
|
||||
|
||||
$batt_models = $this->em->getRepository(BatteryModel::class)->findAll();
|
||||
foreach ($batt_models as $batt_model)
|
||||
{
|
||||
$name = $this->normalizeName($batt_model->getName());
|
||||
$this->bmodel_hash[$name] = $batt_model;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadBatterySizes()
|
||||
{
|
||||
$this->bsize_hash = [];
|
||||
|
||||
$batt_sizes = $this->em->getRepository(BatterySize::class)->findAll();
|
||||
foreach ($batt_sizes as $batt_size)
|
||||
{
|
||||
$name = $this->normalizeName($batt_size->getName());
|
||||
$this->bsize_hash[$name] = $batt_size;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadBatteries()
|
||||
{
|
||||
$this->batt_hash = [];
|
||||
|
||||
$batts = $this->em->getRepository(Battery::class)->findAll();
|
||||
foreach ($batts as $batt)
|
||||
{
|
||||
$brand = $this->normalizeName($batt->getManufacturer()->getName());
|
||||
$model = $this->normalizeName($batt->getModel()->getName());
|
||||
$size = $this->normalizeName($batt->getSize()->getName());
|
||||
|
||||
$this->batt_hash[$brand][$model][$size] = $batt;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadVehicleManufacturers()
|
||||
{
|
||||
$this->vmanu_hash = [];
|
||||
|
||||
$vmanus = $this->em->getRepository(VehicleManufacturer::class)->findAll();
|
||||
foreach ($vmanus as $vmanu)
|
||||
{
|
||||
$name = $this->normalizeName($vmanu->getName());
|
||||
$this->vmanu_hash[$name] = $vmanu;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadVehicleMakes()
|
||||
{
|
||||
$this->vmake_hash = [];
|
||||
|
||||
$vmakes = $this->em->getRepository(Vehicle::class)->findAll();
|
||||
foreach ($vmakes as $vmake)
|
||||
{
|
||||
$manufacturer = $this->normalizeName($vmake->getManufacturer()->getName());
|
||||
$make = $this->normalizeName($vmake->getMake());
|
||||
|
||||
$this->vmake_hash[$manufacturer][$make] = $vmake;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadCustomerVehicles()
|
||||
{
|
||||
$this->cv_hash = [];
|
||||
|
||||
$cvs = $this->em->getRepository(CustomerVehicle::class)->findAll();
|
||||
foreach ($cvs as $cv)
|
||||
{
|
||||
$plate_number = $this->cleanPlateNumber($cv->getPlateNumber());
|
||||
|
||||
$this->cv_hash[$plate_number] = $cv;
|
||||
}
|
||||
}
|
||||
|
||||
protected function normalizeName($name)
|
||||
{
|
||||
$normalized_key = trim(strtolower($name));
|
||||
|
||||
return $normalized_key;
|
||||
}
|
||||
|
||||
protected function cleanPlateNumber($plate_number)
|
||||
{
|
||||
// remove spaces and make upper case
|
||||
$clean_plate_number = strtoupper(str_replace(' ' , '', $plate_number));
|
||||
|
||||
return $clean_plate_number;
|
||||
}
|
||||
|
||||
}
|
||||
54
src/Command/UpdateCMBMigratedCustomerCommand.php
Normal file
54
src/Command/UpdateCMBMigratedCustomerCommand.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use App\Entity\Customer;
|
||||
|
||||
class UpdateCMBMigratedCustomerCommand extends Command
|
||||
{
|
||||
// last name to set
|
||||
const STR_LAST_NAME = 'LEGACY';
|
||||
|
||||
protected $em;
|
||||
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('cmbcustomer:updatecustomer')
|
||||
->setDescription('Set customer last name.')
|
||||
->setHelp('Set the customer last name. ');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
error_log('Updating customer last name...');
|
||||
|
||||
// get all customers
|
||||
$cust_results = $this->em->getRepository(Customer::class)->findBy(['last_name' => '']);
|
||||
|
||||
foreach ($cust_results as $cust)
|
||||
{
|
||||
$cust->setLastName(self::STR_LAST_NAME);
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
$this->em->clear();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
169
src/Command/UpdateCMBMigratedCustomerVehicleBatteryCommand.php
Normal file
169
src/Command/UpdateCMBMigratedCustomerVehicleBatteryCommand.php
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use App\Entity\CustomerVehicle;
|
||||
use App\Entity\CMBLegacyJobOrder;
|
||||
use App\Entity\Battery;
|
||||
|
||||
class UpdateCMBMigratedCustomerVehicleBatteryCommand extends Command
|
||||
{
|
||||
// constants for battery manufacturer names
|
||||
const STR_CENTURY = 'century';
|
||||
const STR_MOTOLITE = 'motolite';
|
||||
|
||||
// constants for battery models
|
||||
const STR_MARATHONER = 'marathoner';
|
||||
const STR_CLASSIC = 'classic';
|
||||
const STR_EXCEL = 'excel';
|
||||
const STR_SDFC = 'sdfc';
|
||||
|
||||
protected $em;
|
||||
protected $batt_hash;
|
||||
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
|
||||
// load existing batteries
|
||||
$this->loadBatteries();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('cmbcustomervehicle:updatebattery')
|
||||
->setDescription('Update customer vehicle battery information.')
|
||||
->setHelp('Updates the customer vehicle battery based on migrated data. ')
|
||||
->addArgument('output_file', InputArgument::REQUIRED, 'Path to the output CSV file of the entries not updated.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$csv_file = $input->getArgument('output_file');
|
||||
|
||||
// attempt to open file
|
||||
try
|
||||
{
|
||||
$fh = fopen($csv_file, "w");
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception('The file "' . $csv_file . '" could be opened.');
|
||||
}
|
||||
|
||||
error_log('Updating customer vehicles...');
|
||||
|
||||
// get all customer vehicles
|
||||
$cv_results = $this->em->getRepository(CustomerVehicle::class)->findAll();
|
||||
|
||||
$not_updated = [];
|
||||
foreach ($cv_results as $cv)
|
||||
{
|
||||
$plate_number = $cv->getPlateNumber();
|
||||
|
||||
// find cmb legacy job order using plate number
|
||||
$cmb_legacy_results = $this->em->getRepository(CMBLegacyJobOrder::class)->findBy(['plate_number' => $plate_number], ['trans_date' => 'DESC']);
|
||||
if ($cmb_legacy_results != null)
|
||||
{
|
||||
// get the latest entry
|
||||
$cmb_legacy = current($cmb_legacy_results);
|
||||
|
||||
// get battery model and size
|
||||
$battery_model = $this->normalizeName($cmb_legacy->getBatteryModel());
|
||||
$battery_size = $this->normalizeName($cmb_legacy->getBatterySize());
|
||||
|
||||
// figure out manufacturer using model
|
||||
// century = marathoner, excel, sdfc
|
||||
// motolite = classic
|
||||
$battery_manu = self::STR_CENTURY;
|
||||
if ($battery_model == self::STR_CLASSIC)
|
||||
$battery_manu = self::STR_MOTOLITE;
|
||||
|
||||
// get battery
|
||||
$cv_battery = null;
|
||||
if (isset($this->batt_hash[$battery_manu][$battery_model][$battery_size]))
|
||||
$cv_battery = $this->batt_hash[$battery_manu][$battery_model][$battery_size];
|
||||
|
||||
if ($cv_battery != null)
|
||||
{
|
||||
//error_log('found battery for ' . $plate_number . ' battery ' . $cv_battery->getModel()->getName() . ' ' . $cv_battery->getSize()->getName());
|
||||
$cv->setCurrentBattery($cv_battery);
|
||||
}
|
||||
else
|
||||
{
|
||||
//error_log('no battery for ' . $battery_model . ' ' . $battery_size);
|
||||
$not_updated[] = $this->addNotUpdatedEntry($cv, $battery_manu, $battery_model, $battery_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
$this->em->clear();
|
||||
|
||||
// output the entries that were not added
|
||||
if (count($not_updated) > 0)
|
||||
{
|
||||
fputcsv($fh, [
|
||||
'Customer Vehicle ID',
|
||||
'Plate Number',
|
||||
'Battery Manufacturer',
|
||||
'Battery Model',
|
||||
'Battery Size',
|
||||
'Reason',
|
||||
]);
|
||||
|
||||
foreach($not_updated as $row)
|
||||
{
|
||||
fputcsv($fh, $row);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected function loadBatteries()
|
||||
{
|
||||
$this->batt_hash = [];
|
||||
|
||||
$batts = $this->em->getRepository(Battery::class)->findAll();
|
||||
foreach ($batts as $batt)
|
||||
{
|
||||
$brand = $this->normalizeName($batt->getManufacturer()->getName());
|
||||
$model = $this->normalizeName($batt->getModel()->getName());
|
||||
$size = $this->normalizeName($batt->getSize()->getName());
|
||||
|
||||
$this->batt_hash[$brand][$model][$size] = $batt;
|
||||
}
|
||||
}
|
||||
|
||||
protected function addNotUpdatedEntry($cv, $manu, $model, $size)
|
||||
{
|
||||
$entry = [
|
||||
$cv->getID(),
|
||||
$cv->getPlateNumber(),
|
||||
strtoupper($manu),
|
||||
strtoupper($model),
|
||||
strtoupper($size),
|
||||
'Battery not in system.',
|
||||
];
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
protected function normalizeName($name)
|
||||
{
|
||||
$normalized_key = trim(strtolower($name));
|
||||
|
||||
return $normalized_key;
|
||||
}
|
||||
|
||||
}
|
||||
317
src/Controller/CMBRAPIController.php
Normal file
317
src/Controller/CMBRAPIController.php
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
|
||||
use App\Ramcar\NewAPIResult;
|
||||
|
||||
use App\Service\RiderAPIHandlerInterface;
|
||||
|
||||
// Rider API controller for CMB
|
||||
class CMBRAPIController extends Controller
|
||||
{
|
||||
public function register(Request $req, RiderAPIHandlerInterface $rapi_handler)
|
||||
{
|
||||
$data = $rapi_handler->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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -346,7 +346,7 @@ class HubController extends Controller
|
|||
$riders = [];
|
||||
|
||||
// TODO: remove this later when we don't get all available riders
|
||||
$riders_limit = 5;
|
||||
$riders_limit = 50;
|
||||
$num_riders = 0;
|
||||
|
||||
foreach ($available_riders as $rider)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
111
src/Controller/NotificationController.php
Normal file
111
src/Controller/NotificationController.php
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Catalyst\MenuBundle\Annotation\Menu;
|
||||
use DateTime;
|
||||
use DateInterval;
|
||||
use App\Entity\Notification;
|
||||
|
||||
class NotificationController extends AbstractController
|
||||
{
|
||||
// TODO: security
|
||||
public function ajaxList(EntityManagerInterface $em)
|
||||
{
|
||||
/*
|
||||
$date = new DateTime();
|
||||
$date->sub(new DateInterval('PT10M'));
|
||||
$notifs = [
|
||||
[
|
||||
'id' => 1,
|
||||
'type' => 'jo_new',
|
||||
'date' => $date->format('Y-m-d\TH:i:s.000P'),
|
||||
'text' => 'Sample incoming job order',
|
||||
'link' => '#',
|
||||
], [
|
||||
'id' => 2,
|
||||
'type' => 'rider_accept',
|
||||
'date' => $date->format('Y-m-d\TH:i:s.000P'),
|
||||
'text' => 'Sample rider has accepted job order',
|
||||
'link' => '#',
|
||||
], [
|
||||
'id' => 3,
|
||||
'type' => 'jo_cancel',
|
||||
'date' => $date->format('Y-m-d\TH:i:s.000P'),
|
||||
'text' => 'Customer has cancelled job order.',
|
||||
'link' => '#',
|
||||
], [
|
||||
'id' => 3,
|
||||
'type' => 'rider_reject',
|
||||
'date' => $date->format('Y-m-d\TH:i:s.000P'),
|
||||
'text' => 'Rider has rejected job order. Job order needs to be reassigned.',
|
||||
'link' => '#',
|
||||
],
|
||||
];
|
||||
$sample_data = [
|
||||
'count' => 4,
|
||||
'notifications' => $notifs,
|
||||
];
|
||||
*/
|
||||
|
||||
$notifs = $em->getRepository(Notification::class)->findBy(['user_id' => 0]);
|
||||
$notif_data = [];
|
||||
|
||||
$unread_count = 0;
|
||||
foreach ($notifs as $notif)
|
||||
{
|
||||
if (!($notif->isRead()))
|
||||
$unread_count++;
|
||||
|
||||
$notif_data[] = [
|
||||
'id' => $notif->getID(),
|
||||
'type' => 'jo_new',
|
||||
'is_read' => $notif->isRead(),
|
||||
'is_fresh' => $notif->isFresh(),
|
||||
'date' => $notif->getDateCreate()->format('Y-m-d\TH:i:s.000P'),
|
||||
'text' => $notif->getMessage(),
|
||||
'link' => $notif->getURL(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
$sample_data = [
|
||||
'count' => count($notif_data),
|
||||
'unread_count' => $unread_count,
|
||||
'notifications' => $notif_data,
|
||||
];
|
||||
|
||||
$res = new JsonResponse($sample_data);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
// TODO: security
|
||||
public function ajaxUpdate(EntityManagerInterface $em, Request $req)
|
||||
{
|
||||
$notif_id = $req->request->get('id');
|
||||
error_log($notif_id);
|
||||
|
||||
$notif = $em->getRepository(Notification::class)->find($notif_id);
|
||||
|
||||
if ($notif != null)
|
||||
{
|
||||
// TODO: fresh is if unread and still within x hours
|
||||
// but for now fresh and unread are both the same
|
||||
$notif->setIsRead(true);
|
||||
$notif->setIsFresh(false);
|
||||
|
||||
$em->persist($notif);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
$res = new JsonResponse();
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
|
@ -596,4 +596,38 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ParamConverter("rider", class="App\Entity\Rider")
|
||||
*/
|
||||
public function ajaxRiderName(EntityManagerInterface $em, Rider $rider)
|
||||
{
|
||||
$rider_name = '';
|
||||
if ($rider != null)
|
||||
$rider_name = $rider->getFullName();
|
||||
|
||||
return $this->json([
|
||||
'rider_name' => $rider_name,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
395
src/Entity/CMBLegacyJobOrder.php
Normal file
395
src/Entity/CMBLegacyJobOrder.php
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="cmb_legacy_job_order")
|
||||
*/
|
||||
class CMBLegacyJobOrder
|
||||
{
|
||||
// legacy internal id
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
protected $trans_date;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=30, nullable=true)
|
||||
*/
|
||||
protected $case_number;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=30, nullable=true)
|
||||
*/
|
||||
protected $insurer;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=20, nullable=true)
|
||||
*/
|
||||
protected $plate_number;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=50, nullable=true)
|
||||
*/
|
||||
protected $trans_type;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=20, nullable=true)
|
||||
*/
|
||||
protected $car_brand;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=50, nullable=true)
|
||||
*/
|
||||
protected $car_make;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=30, nullable=true)
|
||||
*/
|
||||
protected $nature_of_call;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=400, nullable=true)
|
||||
*/
|
||||
protected $address;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=50, nullable=true)
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=20, nullable=true)
|
||||
*/
|
||||
protected $truck;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer", nullable=true)
|
||||
*/
|
||||
protected $workshop_arrival_time;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=50, nullable=true)
|
||||
*/
|
||||
protected $status;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=100, nullable=true)
|
||||
*/
|
||||
protected $cust_name;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=50, nullable=true)
|
||||
*/
|
||||
protected $cust_mobile;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=20, nullable=true)
|
||||
*/
|
||||
protected $reference;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer", nullable=true)
|
||||
*/
|
||||
protected $odometer;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=50, nullable=true)
|
||||
*/
|
||||
protected $batt_model;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=50, nullable=true)
|
||||
*/
|
||||
protected $batt_size;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default":false})
|
||||
*/
|
||||
protected $flag_trade_in;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=50, nullable=true)
|
||||
*/
|
||||
protected $replaced_by;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=4000, nullable=true)
|
||||
*/
|
||||
protected $remarks;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=50, nullable=true)
|
||||
*/
|
||||
protected $satisfaction;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->trans_date = new DateTime();
|
||||
}
|
||||
|
||||
public function setID($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getID()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setTransDate(DateTime $trans_date)
|
||||
{
|
||||
$this->trans_date = $trans_date;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTransDate()
|
||||
{
|
||||
return $this->trans_date;
|
||||
}
|
||||
|
||||
public function setTransType($trans_type)
|
||||
{
|
||||
$this->trans_type = $trans_type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTransType()
|
||||
{
|
||||
return $this->trans_type;
|
||||
}
|
||||
|
||||
public function setCaseNumber($case_number)
|
||||
{
|
||||
$this->case_number = $case_number;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCaseNumber()
|
||||
{
|
||||
return $this->case_number;
|
||||
}
|
||||
|
||||
public function setInsurer($insurer)
|
||||
{
|
||||
$this->insurer = $insurer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getInsurer()
|
||||
{
|
||||
return $this->insurer;
|
||||
}
|
||||
|
||||
public function setNatureOfCall($nature_of_call)
|
||||
{
|
||||
$this->nature_of_call = $nature_of_call;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getNatureOfCall()
|
||||
{
|
||||
return $this->nature_of_call;
|
||||
}
|
||||
|
||||
public function setPlateNumber($plate_number)
|
||||
{
|
||||
$this->plate_number = $plate_number;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPlateNumber()
|
||||
{
|
||||
return $this->plate_number;
|
||||
}
|
||||
|
||||
public function setCarBrand($car_brand)
|
||||
{
|
||||
$this->car_brand = $car_brand;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCarBrand()
|
||||
{
|
||||
return $this->car_brand;
|
||||
}
|
||||
|
||||
public function setCarMake($car_make)
|
||||
{
|
||||
$this->car_make = $car_make;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCarMake()
|
||||
{
|
||||
return $this->car_make;
|
||||
}
|
||||
|
||||
public function setAddress($address)
|
||||
{
|
||||
$this->address = $address;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAddress()
|
||||
{
|
||||
return $this->address;
|
||||
}
|
||||
|
||||
public function setDriver($driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDriver()
|
||||
{
|
||||
return $this->driver;
|
||||
}
|
||||
|
||||
public function setTruck($truck)
|
||||
{
|
||||
$this->truck = $truck;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTruck()
|
||||
{
|
||||
return $this->truck;
|
||||
}
|
||||
|
||||
public function setWorkshopArrivalTime($workshop_arrival_time)
|
||||
{
|
||||
$this->workshop_arrival_time = $workshop_arrival_time;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getWorkshopArrivalTime()
|
||||
{
|
||||
return $this->workshop_arrival_time;
|
||||
}
|
||||
|
||||
public function setStatus($status)
|
||||
{
|
||||
$this->status = $status;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function setCustName($cust_name)
|
||||
{
|
||||
$this->cust_name = $cust_name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCustName()
|
||||
{
|
||||
return $this->cust_name;
|
||||
}
|
||||
|
||||
public function setCustMobile($cust_mobile)
|
||||
{
|
||||
$this->cust_mobile = $cust_mobile;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCustMobile()
|
||||
{
|
||||
return $this->cust_mobile;
|
||||
}
|
||||
|
||||
public function setReference($reference)
|
||||
{
|
||||
$this->reference = $reference;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReference()
|
||||
{
|
||||
return $this->reference;
|
||||
}
|
||||
|
||||
public function setOdometer($odometer)
|
||||
{
|
||||
$this->odometer = $odometer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOdometer()
|
||||
{
|
||||
return $this->odometer;
|
||||
}
|
||||
|
||||
public function setBatteryModel($batt_model)
|
||||
{
|
||||
$this->batt_model = $batt_model;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBatteryModel()
|
||||
{
|
||||
return $this->batt_model;
|
||||
}
|
||||
|
||||
public function setBatterySize($batt_size)
|
||||
{
|
||||
$this->batt_size = $batt_size;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBatterySize()
|
||||
{
|
||||
return $this->batt_size;
|
||||
}
|
||||
|
||||
public function setIsTradeIn($flag_trade_in = true)
|
||||
{
|
||||
$this->flag_trade_in = $flag_trade_in;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isTradeIn()
|
||||
{
|
||||
return $this->flag_trade_in;
|
||||
}
|
||||
|
||||
public function setReplacedBy($replaced_by)
|
||||
{
|
||||
$this->replaced_by = $replaced_by;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReplacedBy()
|
||||
{
|
||||
return $this->replaced_by;
|
||||
}
|
||||
|
||||
public function setSatisfaction($satisfaction)
|
||||
{
|
||||
$this->satisfaction = $satisfaction;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSatisfaction()
|
||||
{
|
||||
return $this->satisfaction;
|
||||
}
|
||||
|
||||
}
|
||||
57
src/Entity/CMBLegacyJobOrderRow.php
Normal file
57
src/Entity/CMBLegacyJobOrderRow.php
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="cmb_legacy_job_order_row")
|
||||
*/
|
||||
class CMBLegacyJobOrderRow
|
||||
{
|
||||
// unique id
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
// data from csv file
|
||||
/**
|
||||
* @ORM\Column(type="json")
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->data = [];
|
||||
}
|
||||
|
||||
public function addData($id, $value)
|
||||
{
|
||||
$this->data[$id] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setData(array $data_array)
|
||||
{
|
||||
$this->data = $data_array;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDataById($id)
|
||||
{
|
||||
// return null if we don't have it
|
||||
if (!isset($this->data[$id]))
|
||||
return null;
|
||||
|
||||
return $this->data[$id];
|
||||
}
|
||||
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ class Customer
|
|||
|
||||
// first name
|
||||
/**
|
||||
* @ORM\Column(type="string", length=80)
|
||||
* @ORM\Column(type="string", length=100)
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $first_name;
|
||||
|
|
@ -42,7 +42,6 @@ class Customer
|
|||
// last name
|
||||
/**
|
||||
* @ORM\Column(type="string", length=80)
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $last_name;
|
||||
|
||||
|
|
@ -66,7 +65,7 @@ class Customer
|
|||
|
||||
// mobile phone
|
||||
/**
|
||||
* @ORM\Column(type="string", length=30)
|
||||
* @ORM\Column(type="string", length=50)
|
||||
*/
|
||||
protected $phone_mobile;
|
||||
|
||||
|
|
|
|||
140
src/Entity/JOExtra.php
Normal file
140
src/Entity/JOExtra.php
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="jo_extra")
|
||||
*/
|
||||
class JOExtra
|
||||
{
|
||||
// unique id
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", nullable=true)
|
||||
*/
|
||||
protected $image_1_filename;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", nullable=true)
|
||||
*/
|
||||
protected $image_2_filename;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", nullable=true)
|
||||
*/
|
||||
protected $image_3_filename;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", nullable=true)
|
||||
*/
|
||||
protected $image_4_filename;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="array", nullable=true)
|
||||
*/
|
||||
protected $other_images;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", nullable=true)
|
||||
*/
|
||||
protected $cust_signature;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
}
|
||||
|
|
@ -334,6 +334,30 @@ 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;
|
||||
|
||||
// rider plate number since rider can change vehicles
|
||||
/**
|
||||
* @ORM\Column(type="string", length=10, nullable=true)
|
||||
*/
|
||||
protected $rider_plate_num;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->date_create = new DateTime();
|
||||
|
|
@ -583,6 +607,7 @@ class JobOrder
|
|||
{
|
||||
// TODO: validate status
|
||||
$this->status = $status;
|
||||
$this->date_status_change = new DateTime();
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
@ -596,6 +621,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 +826,11 @@ class JobOrder
|
|||
$this->makeRiderAvailable();
|
||||
}
|
||||
|
||||
public function perform()
|
||||
{
|
||||
$this->setStatus(JOStatus::PERFORMED);
|
||||
}
|
||||
|
||||
public function fulfill()
|
||||
{
|
||||
$this->setStatus(JOStatus::FULFILLED)
|
||||
|
|
@ -962,5 +997,38 @@ 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;
|
||||
}
|
||||
|
||||
public function setRiderPlateNum($rider_plate_num)
|
||||
{
|
||||
$this->rider_plate_num = $rider_plate_num;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRiderPlateNum()
|
||||
{
|
||||
return $this->rider_plate_num;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
148
src/Entity/Notification.php
Normal file
148
src/Entity/Notification.php
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="notification", indexes={@ORM\Index(columns={"user_id"})})
|
||||
*/
|
||||
class Notification
|
||||
{
|
||||
// unique id
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
// date / time created
|
||||
/**
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
protected $date_create;
|
||||
|
||||
// index by user for fast fetching
|
||||
// user id (don't link, don't need to)
|
||||
/**
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
protected $user_id;
|
||||
|
||||
// icon
|
||||
/**
|
||||
* @ORM\Column(type="string", length=25)
|
||||
*/
|
||||
protected $icon;
|
||||
|
||||
// message text
|
||||
/**
|
||||
* @ORM\Column(type="string", length=300)
|
||||
*/
|
||||
protected $message;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=180)
|
||||
*/
|
||||
protected $url;
|
||||
|
||||
// has user read the notification
|
||||
/**
|
||||
* @ORM\Column(type="boolean")
|
||||
*/
|
||||
protected $flag_read;
|
||||
|
||||
// is this still a fresh notification for the user
|
||||
/**
|
||||
* @ORM\Column(type="boolean")
|
||||
*/
|
||||
protected $flag_fresh;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->date_create = new DateTime();
|
||||
$this->flag_read = false;
|
||||
$this->flag_fresh = true;
|
||||
}
|
||||
|
||||
public function getID()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getDateCreate()
|
||||
{
|
||||
return $this->date_create;
|
||||
}
|
||||
|
||||
public function setUserID($user_id)
|
||||
{
|
||||
$this->user_id = $user_id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUserID()
|
||||
{
|
||||
return $this->user_id;
|
||||
}
|
||||
|
||||
public function setIcon($icon)
|
||||
{
|
||||
$this->icon = $icon;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIcon()
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function setMessage($message)
|
||||
{
|
||||
$this->message = $message;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
public function setURL($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getURL()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function setIsRead($bool = true)
|
||||
{
|
||||
$this->flag_read = $bool;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isRead()
|
||||
{
|
||||
return $this->flag_read;
|
||||
}
|
||||
|
||||
public function setIsFresh($bool = true)
|
||||
{
|
||||
$this->flag_fresh = $bool;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isFresh()
|
||||
{
|
||||
return $this->flag_fresh;
|
||||
}
|
||||
}
|
||||
|
|
@ -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 = [
|
||||
|
|
|
|||
22
src/Ramcar/CMBCancelReason.php
Normal file
22
src/Ramcar/CMBCancelReason.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Ramcar;
|
||||
|
||||
class CMBCancelReason extends NameValue
|
||||
{
|
||||
const ACCIDENT = 'accident';
|
||||
const BREAKDOWN = 'breakdown';
|
||||
const FUEL_RUNOUT = 'fuel_runout';
|
||||
const WRONG_BATTERY_SIZE = 'wrong_battery_size';
|
||||
const CUSTOMER_CANCEL = 'customer_cancel';
|
||||
const OTHERS = 'others';
|
||||
|
||||
const COLLECTION = [
|
||||
'accident' => 'Accident',
|
||||
'breakdown' => 'Breakdown',
|
||||
'fuel_runout' => 'Fuel Runout',
|
||||
'wrong_battery_size' => 'Wrong Battery Size',
|
||||
'customer_cancel' => 'Cancelled by Customer',
|
||||
'others' => 'Others'
|
||||
];
|
||||
}
|
||||
42
src/Ramcar/CMBJOEventType.php
Normal file
42
src/Ramcar/CMBJOEventType.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Ramcar;
|
||||
|
||||
class CMBJOEventType extends NameValue
|
||||
{
|
||||
const CREATE = 'create';
|
||||
const HUB_ASSIGN = 'hub_assign';
|
||||
const RIDER_ASSIGN = 'rider_assign';
|
||||
const CANCEL = 'cancel';
|
||||
const FULFILL = 'fulfill';
|
||||
const OPEN_EDIT = 'open_edit';
|
||||
const REQUEUE = 'requeue';
|
||||
const RIDER_ACCEPT = 'accept';
|
||||
const RIDER_IN_TRANSIT = 'rider_in_transit';
|
||||
const RIDER_ARRIVE = 'arrive';
|
||||
const RIDER_START = 'rider_start';
|
||||
const RIDER_EDIT = 'rider_edit';
|
||||
const PAID = 'paid';
|
||||
const PERFORM = 'perform';
|
||||
const RIDER_FINISH = 'finish';
|
||||
const RIDER_UPLOAD_PHOTO = 'rider_upload_photo';
|
||||
|
||||
const COLLECTION = [
|
||||
'create' => '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',
|
||||
];
|
||||
}
|
||||
|
|
@ -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',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@ class CMBServiceType extends NameValue
|
|||
{
|
||||
const BATTERY_REPLACEMENT_NEW = 'battery_new';
|
||||
const BATTERY_REPLACEMENT_WARRANTY = 'battery_warranty';
|
||||
const WARRANTY_CLAIM = 'warranty_claim';
|
||||
const JUMPSTART = 'jumpstart';
|
||||
|
||||
const COLLECTION = [
|
||||
'battery_new' => 'Battery Sales',
|
||||
'battery_warranty' => 'Under Warranty',
|
||||
'battery_warranty' => 'Warranty Replacement',
|
||||
'warranty_claim' => 'Warranty Claim',
|
||||
'jumpstart' => 'Jumpstart',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
25
src/Ramcar/CMBTransactionOrigin.php
Normal file
25
src/Ramcar/CMBTransactionOrigin.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Ramcar;
|
||||
|
||||
class CMBTransactionOrigin extends NameValue
|
||||
{
|
||||
const CALL = 'call';
|
||||
const ONLINE = 'online';
|
||||
const FACEBOOK = 'facebook';
|
||||
const VIP = 'vip';
|
||||
const MOBILE_APP = 'mobile_app';
|
||||
const WALK_IN = 'walk_in';
|
||||
const WHATSAPP = 'whatsapp';
|
||||
|
||||
// TODO: for now, resq also gets the walk-in option
|
||||
const COLLECTION = [
|
||||
'call' => 'Hotline',
|
||||
'online' => 'Online',
|
||||
'facebook' => 'Facebook',
|
||||
'vip' => 'VIP',
|
||||
'mobile_app' => 'Mobile App',
|
||||
'walk_in' => 'Walk-in',
|
||||
'whatsapp' => 'Whatsapp',
|
||||
];
|
||||
}
|
||||
|
|
@ -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',
|
||||
];
|
||||
|
|
|
|||
92
src/Ramcar/NewAPIResult.php
Normal file
92
src/Ramcar/NewAPIResult.php
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace App\Ramcar;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class NewAPIResult
|
||||
{
|
||||
protected $err_title;
|
||||
protected $err_flag;
|
||||
protected $err_message;
|
||||
protected $data;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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"));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,10 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface
|
|||
case CMBServiceType::BATTERY_REPLACEMENT_WARRANTY:
|
||||
$this->processWarranty($total, $criteria, $invoice);
|
||||
break;
|
||||
case CMBServiceType::WARRANTY_CLAIM:
|
||||
// TODO: this will change once we confirm what needs to be computed
|
||||
$this->processOtherServices($total, $invoice, $stype);
|
||||
break;
|
||||
//case ServiceType::POST_RECHARGED:
|
||||
// $this->processRecharge($total, $invoice);
|
||||
// break;
|
||||
|
|
@ -270,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);
|
||||
|
|
@ -363,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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
@ -147,7 +147,8 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|||
$order = $datatable['sort']['sort'] ?? 'asc';
|
||||
$query->orderBy('q.' . $datatable['sort']['field'], $order);
|
||||
} else {
|
||||
$query->orderBy('q.date_schedule', 'asc');
|
||||
//$query->orderBy('q.date_schedule', 'asc');
|
||||
$query->orderBy('q.date_schedule', 'desc');
|
||||
}
|
||||
|
||||
// get rows for this page
|
||||
|
|
@ -177,13 +178,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,16 +217,18 @@ 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)
|
||||
$row['processor'] = '';
|
||||
$creator = $orow->getCreatedBy();
|
||||
if ($creator == null)
|
||||
$row['creator'] = '';
|
||||
else
|
||||
$row['processor'] = $orow->getProcessedBy()->getFullName();
|
||||
$row['creator'] = $orow->getCreatedBy()->getFullName();
|
||||
|
||||
$assignor = $orow->getAssignedBy();
|
||||
if ($assignor == null)
|
||||
|
|
@ -350,7 +375,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 +425,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 +441,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,33 +449,40 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|||
$em = $this->em;
|
||||
|
||||
$jo = $em->getRepository(JobOrder::class)->find($id);
|
||||
$old_jo_status = null;
|
||||
$old_rider = null;
|
||||
if (empty($jo))
|
||||
{
|
||||
// new job order
|
||||
$jo = new JobOrder();
|
||||
}
|
||||
else
|
||||
{
|
||||
// need to get old values of rider and status to see if we need to change JO status or not
|
||||
$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'))) {
|
||||
$error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.';
|
||||
}
|
||||
|
||||
// check if responsible party is present
|
||||
if (empty($req->request->get('responsible_party')))
|
||||
$error_array['responsible_party'] = 'Responsible party is required.';
|
||||
|
||||
// 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 +496,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('')
|
||||
|
|
@ -526,6 +558,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|||
}
|
||||
|
||||
// check if hub AND rider is selected
|
||||
$rider_plate_number = '';
|
||||
if ((empty($req->request->get('hub_id'))) &&
|
||||
(empty($req->request->get('rider_id')))) {
|
||||
$error_array['hub'] = 'No hub selected.';
|
||||
|
|
@ -544,36 +577,47 @@ 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.';
|
||||
|
||||
$rider_plate_number = $rider->getPlateNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
// delivery address
|
||||
if (empty($req->request->get('delivery_address')))
|
||||
$error_array['delivery_address'] = 'Delivery address is required.';
|
||||
|
||||
// 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 +633,47 @@ 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', ''))
|
||||
->setRiderPlateNum($rider_plate_number);
|
||||
|
||||
$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
|
||||
// check old rider if it is also a reassignment
|
||||
// old_rider should be null if JO has been rejected
|
||||
if (($old_rider == null) && ($old_jo_status == null))
|
||||
$jo->setStatus(JOStatus::ASSIGNED);
|
||||
else
|
||||
{
|
||||
error_log('not a new JO');
|
||||
$new_rider = $jo->getRider();
|
||||
if ($new_rider != $old_rider)
|
||||
{
|
||||
// reassignment
|
||||
$jo->setStatus(JOStatus::ASSIGNED);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($old_jo_status != null)
|
||||
$jo->setStatus($old_jo_status);
|
||||
}
|
||||
}
|
||||
|
||||
// check if user is null, meaning call to create came from API
|
||||
if ($user != null)
|
||||
{
|
||||
|
|
@ -651,7 +720,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 +730,21 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|||
|
||||
$em->persist($event);
|
||||
$em->flush();
|
||||
|
||||
// check if JO has been reassigned
|
||||
if ($old_rider != $jo->getRider())
|
||||
//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 +859,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 +958,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 +1029,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
|
||||
|
|
@ -1029,21 +1113,30 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|||
// cancel job order
|
||||
public function cancelJobOrder(Request $req, int $id, MQTTClient $mclient)
|
||||
{
|
||||
// get object data
|
||||
// get jo data
|
||||
$em = $this->em;
|
||||
$obj = $em->getRepository(JobOrder::class)->find($id);
|
||||
|
||||
// make sure this object exists
|
||||
// make sure this exists
|
||||
if (empty($obj))
|
||||
throw new NotFoundHttpException('The item does not exist');
|
||||
|
||||
$cancel_reason = $req->request->get('cancel_reason');
|
||||
$obj->cancel($cancel_reason);
|
||||
|
||||
// get assigned rider. If not null, clear rider's active JO
|
||||
$rider = $obj->getRider();
|
||||
if ($rider != null)
|
||||
{
|
||||
$active_jo = $rider->getActiveJobOrder();
|
||||
if ($active_jo != null && $active_jo->getID() == $obj->getID())
|
||||
$rider->setActiveJobOrder(null);
|
||||
}
|
||||
|
||||
// the event
|
||||
$event = new JOEvent();
|
||||
$event->setDateHappen(new DateTime())
|
||||
->setTypeID(JOEventType::CANCEL)
|
||||
->setTypeID(CMBJOEventType::CANCEL)
|
||||
->setJobOrder($obj);
|
||||
|
||||
// get current user
|
||||
|
|
@ -1065,9 +1158,15 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|||
'event' => 'cancelled',
|
||||
'reason' => $cancel_reason,
|
||||
'jo_id' => $obj->getID(),
|
||||
'msg' => 'Job order #' . $obj->getID() . ' has been cancelled.',
|
||||
];
|
||||
/*
|
||||
$mclient->sendEvent($obj, $payload);
|
||||
$mclient->sendRiderEvent($obj, $payload);
|
||||
*/
|
||||
$channel = 'rider/' . $rider->getID() . '/events';
|
||||
error_log('sending mqtt to rider - ' . $channel);
|
||||
$mclient->publish($channel, json_encode($payload));
|
||||
}
|
||||
|
||||
// set hub for job order
|
||||
|
|
@ -1103,7 +1202,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|||
}
|
||||
|
||||
if (empty($error_array))
|
||||
{
|
||||
{
|
||||
// rider mqtt event
|
||||
// NOTE: need to send this before saving because rider will be cleared
|
||||
$rider_payload = [
|
||||
|
|
@ -1153,7 +1252,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 +1452,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 +1524,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 +1557,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 +1575,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 +1744,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 +2584,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);
|
||||
|
|
@ -2454,22 +2622,21 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|||
$jo = new JobOrder();
|
||||
}
|
||||
|
||||
// check if responsible party is present
|
||||
if (empty($req->request->get('responsible_party')))
|
||||
$error_array['responsible_party'] = 'Responsible party is required.';
|
||||
|
||||
// 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 +2651,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 +2730,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 +2751,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 +2808,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 +2887,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 +2925,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 +3015,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 +3071,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 +3209,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 +3270,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"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
48
src/Service/NotificationManager.php
Normal file
48
src/Service/NotificationManager.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use App\Service\RedisClientProvider;
|
||||
use App\Entity\Notification;
|
||||
|
||||
class NotificationManager
|
||||
{
|
||||
protected $redis;
|
||||
protected $redis_mqtt_key;
|
||||
protected $em;
|
||||
|
||||
const NOTIF_KEY = 'user/{user_id}/notification';
|
||||
|
||||
public function __construct(RedisClientProvider $redis_prov, EntityManagerInterface $em, $redis_mqtt_key)
|
||||
{
|
||||
$this->redis = $redis_prov->getRedisClient();
|
||||
$this->redis_mqtt_key = $redis_mqtt_key;
|
||||
$this->em = $em;
|
||||
}
|
||||
|
||||
// set user_id to 0 for all
|
||||
public function sendNotification($user_id, $msg, $url)
|
||||
{
|
||||
// send mqtt
|
||||
$chan = $this->getChannel($user_id);
|
||||
$data = $chan . '|' . $msg;
|
||||
$this->redis->lpush($this->redis_mqtt_key, $data);
|
||||
|
||||
// create notif
|
||||
$notif = new Notification();
|
||||
$notif->setUserID($user_id)
|
||||
->setIcon('')
|
||||
->setMessage($msg)
|
||||
->setURL($url);
|
||||
|
||||
// save to db
|
||||
$this->em->persist($notif);
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
protected function getChannel($user_id)
|
||||
{
|
||||
return str_replace('{user_id}', $user_id, self::NOTIF_KEY );
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Service;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use App\Service\RedisClientProvider;
|
||||
use App\Entity\Rider;
|
||||
|
||||
|
|
@ -10,12 +12,14 @@ class RiderCache
|
|||
protected $redis;
|
||||
protected $loc_key;
|
||||
protected $status_key;
|
||||
protected $em;
|
||||
|
||||
public function __construct(RedisClientProvider $redis_prov, $loc_key, $status_key)
|
||||
public function __construct(EntityManagerInterface $em, RedisClientProvider $redis_prov, $loc_key, $status_key)
|
||||
{
|
||||
$this->redis = $redis_prov->getRedisClient();
|
||||
$this->loc_key = $loc_key;
|
||||
$this->status_key = $status_key;
|
||||
$this->em = $em;
|
||||
}
|
||||
|
||||
public function addActiveRider($id, $lat, $lng)
|
||||
|
|
@ -46,10 +50,15 @@ class RiderCache
|
|||
$lng = $data[1][0];
|
||||
$lat = $data[1][1];
|
||||
|
||||
$locs[$id] = [
|
||||
'longitude' => $lng,
|
||||
'latitude' => $lat,
|
||||
];
|
||||
// get rider details so we can check for availability
|
||||
$rider = $this->getRiderDetails($id);
|
||||
if ($rider != null)
|
||||
{
|
||||
$locs[$id] = [
|
||||
'longitude' => $lng,
|
||||
'latitude' => $lat,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// error_log(print_r($all_riders, true));
|
||||
|
|
@ -73,4 +82,17 @@ class RiderCache
|
|||
{
|
||||
$this->redis->hincrby($this->status_key, $id, -1);
|
||||
}
|
||||
|
||||
protected function getRiderDetails($id)
|
||||
{
|
||||
$rider = $this->em->getRepository(Rider::class)->find($id);
|
||||
if ($rider == null)
|
||||
return null;
|
||||
|
||||
// return only if available
|
||||
if ($rider->isAvailable())
|
||||
return $rider;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -448,217 +448,50 @@
|
|||
<div id="m_header_topbar" class="m-topbar m-stack m-stack--ver m-stack--general">
|
||||
<div class="m-stack__item m-topbar__nav-wrapper">
|
||||
<ul class="m-topbar__nav m-nav m-nav--inline">
|
||||
<!--
|
||||
<li class="m-nav__item m-topbar__notifications m-topbar__notifications--img m-dropdown m-dropdown--large m-dropdown--header-bg-fill m-dropdown--arrow m-dropdown--align-center m-dropdown--mobile-full-width" data-dropdown-toggle="click" data-dropdown-persistent="true">
|
||||
<a href="#" class="m-nav__link m-dropdown__toggle" id="m_topbar_notification_icon">
|
||||
<span class="m-nav__link-badge m-badge m-badge--dot m-badge--dot-small m-badge--danger"></span>
|
||||
<span class="m-nav__link-icon">
|
||||
<i class="flaticon-music-2"></i>
|
||||
</span>
|
||||
</a>
|
||||
<div class="m-dropdown__wrapper">
|
||||
<span class="m-dropdown__arrow m-dropdown__arrow--center"></span>
|
||||
<div class="m-dropdown__inner">
|
||||
<div class="m-dropdown__header m--align-center" style="background: url(assets/app/media/img/misc/notification_bg.jpg); background-size: cover;">
|
||||
<span class="m-dropdown__header-title">
|
||||
9 New
|
||||
</span>
|
||||
<span class="m-dropdown__header-subtitle">
|
||||
User Notifications
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-dropdown__body">
|
||||
<div class="m-dropdown__content">
|
||||
<ul class="nav nav-tabs m-tabs m-tabs-line m-tabs-line--brand" role="tablist">
|
||||
<li class="nav-item m-tabs__item">
|
||||
<a class="nav-link m-tabs__link active" data-toggle="tab" href="#topbar_notifications_notifications" role="tab">
|
||||
Alerts
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item m-tabs__item">
|
||||
<a class="nav-link m-tabs__link" data-toggle="tab" href="#topbar_notifications_events" role="tab">
|
||||
Events
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item m-tabs__item">
|
||||
<a class="nav-link m-tabs__link" data-toggle="tab" href="#topbar_notifications_logs" role="tab">
|
||||
Logs
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="topbar_notifications_notifications" role="tabpanel">
|
||||
<div class="m-scrollable" data-scrollable="true" data-max-height="250" data-mobile-max-height="200">
|
||||
<div class="m-list-timeline m-list-timeline--skin-light">
|
||||
<div class="m-list-timeline__items">
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge -m-list-timeline__badge--state-success"></span>
|
||||
<span class="m-list-timeline__text">
|
||||
12 new users registered
|
||||
</span>
|
||||
<span class="m-list-timeline__time">
|
||||
Just now
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge"></span>
|
||||
<span class="m-list-timeline__text">
|
||||
System shutdown
|
||||
<span class="m-badge m-badge--success m-badge--wide">
|
||||
pending
|
||||
</span>
|
||||
</span>
|
||||
<span class="m-list-timeline__time">
|
||||
14 mins
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge"></span>
|
||||
<span class="m-list-timeline__text">
|
||||
New invoice received
|
||||
</span>
|
||||
<span class="m-list-timeline__time">
|
||||
20 mins
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge"></span>
|
||||
<span class="m-list-timeline__text">
|
||||
DB overloaded 80%
|
||||
<span class="m-badge m-badge--info m-badge--wide">
|
||||
settled
|
||||
</span>
|
||||
</span>
|
||||
<span class="m-list-timeline__time">
|
||||
1 hr
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge"></span>
|
||||
<span class="m-list-timeline__text">
|
||||
System error -
|
||||
<a href="#" class="m-link">
|
||||
Check
|
||||
</a>
|
||||
</span>
|
||||
<span class="m-list-timeline__time">
|
||||
2 hrs
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-list-timeline__item m-list-timeline__item--read">
|
||||
<span class="m-list-timeline__badge"></span>
|
||||
<span href="" class="m-list-timeline__text">
|
||||
New order received
|
||||
<span class="m-badge m-badge--danger m-badge--wide">
|
||||
urgent
|
||||
</span>
|
||||
</span>
|
||||
<span class="m-list-timeline__time">
|
||||
7 hrs
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-list-timeline__item m-list-timeline__item--read">
|
||||
<span class="m-list-timeline__badge"></span>
|
||||
<span class="m-list-timeline__text">
|
||||
Production server down
|
||||
</span>
|
||||
<span class="m-list-timeline__time">
|
||||
3 hrs
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge"></span>
|
||||
<span class="m-list-timeline__text">
|
||||
Production server up
|
||||
</span>
|
||||
<span class="m-list-timeline__time">
|
||||
5 hrs
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" id="topbar_notifications_events" role="tabpanel">
|
||||
<div class="m-scrollable" m-scrollabledata-scrollable="true" data-max-height="250" data-mobile-max-height="200">
|
||||
<div class="m-list-timeline m-list-timeline--skin-light">
|
||||
<div class="m-list-timeline__items">
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge m-list-timeline__badge--state1-success"></span>
|
||||
<a href="" class="m-list-timeline__text">
|
||||
New order received
|
||||
</a>
|
||||
<span class="m-list-timeline__time">
|
||||
Just now
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge m-list-timeline__badge--state1-danger"></span>
|
||||
<a href="" class="m-list-timeline__text">
|
||||
New invoice received
|
||||
</a>
|
||||
<span class="m-list-timeline__time">
|
||||
20 mins
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge m-list-timeline__badge--state1-success"></span>
|
||||
<a href="" class="m-list-timeline__text">
|
||||
Production server up
|
||||
</a>
|
||||
<span class="m-list-timeline__time">
|
||||
5 hrs
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge m-list-timeline__badge--state1-info"></span>
|
||||
<a href="" class="m-list-timeline__text">
|
||||
New order received
|
||||
</a>
|
||||
<span class="m-list-timeline__time">
|
||||
7 hrs
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge m-list-timeline__badge--state1-info"></span>
|
||||
<a href="" class="m-list-timeline__text">
|
||||
System shutdown
|
||||
</a>
|
||||
<span class="m-list-timeline__time">
|
||||
11 mins
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge m-list-timeline__badge--state1-info"></span>
|
||||
<a href="" class="m-list-timeline__text">
|
||||
Production server down
|
||||
</a>
|
||||
<span class="m-list-timeline__time">
|
||||
3 hrs
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" id="topbar_notifications_logs" role="tabpanel">
|
||||
<div class="m-stack m-stack--ver m-stack--general" style="min-height: 180px;">
|
||||
<div class="m-stack__item m-stack__item--center m-stack__item--middle">
|
||||
<span class="">
|
||||
All caught up!
|
||||
<br>
|
||||
No new logs.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
-->
|
||||
|
||||
<li class="m-nav__item m-topbar__notifications m-topbar__notifications--img m-dropdown m-dropdown--large m-dropdown--header-bg-fill m-dropdown--arrow m-dropdown--align-right m-dropdown--mobile-full-width" data-dropdown-toggle="click" data-dropdown-persistent="true">
|
||||
<a href="#" class="m-nav__link m-dropdown__toggle" id="m_topbar_notification_icon">
|
||||
<span class="m-nav__link-badge m-badge m-badge--dot m-badge--dot-small m-badge--danger"></span>
|
||||
<span class="m-nav__link-icon">
|
||||
<i class="flaticon-music-2"></i>
|
||||
</span>
|
||||
</a>
|
||||
<div class="m-dropdown__wrapper">
|
||||
<span class="m-dropdown__arrow m-dropdown__arrow--right m-dropdown__arrow--adjust"></span>
|
||||
<div class="m-dropdown__inner">
|
||||
<div class="m-dropdown__header m--align-center" style="background: url(/assets/app/media/img/misc/notification_bg.jpg); background-size: cover;">
|
||||
<span class="m-dropdown__header-title">
|
||||
<span id="notif-count">-</span> New
|
||||
</span>
|
||||
<span class="m-dropdown__header-subtitle">
|
||||
User Notifications
|
||||
</span>
|
||||
</div>
|
||||
<div class="m-dropdown__body">
|
||||
<div class="m-dropdown__content">
|
||||
<div class="m-scrollable" data-scrollable="true" data-max-height="250" data-mobile-max-height="200">
|
||||
<div class="m-list-timeline m-list-timeline--skin-light">
|
||||
<div id="notif-body" class="m-list-timeline__items">
|
||||
<div class="m-list-timeline__item">
|
||||
<span class="m-list-timeline__badge -m-list-timeline__badge--state-success"></span>
|
||||
<span class="m-list-timeline__text">
|
||||
<a href="#">This is a notification</a>
|
||||
</span>
|
||||
<span class="m-list-timeline__time">
|
||||
Just now
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
<li class="m-nav__item m-topbar__user-profile m-topbar__user-profile--img m-dropdown m-dropdown--medium m-dropdown--arrow m-dropdown--header-bg-fill m-dropdown--align-right m-dropdown--mobile-full-width m-dropdown--skin-light" data-dropdown-toggle="click">
|
||||
<a href="#" class="m-nav__link m-dropdown__toggle">
|
||||
<span class="m-topbar__userpic">
|
||||
|
|
@ -718,6 +551,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -770,6 +605,26 @@
|
|||
<!--end::Page Snippets -->
|
||||
|
||||
<!--begin::Extra Scripts -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>
|
||||
<script src="/assets/js/moment.min.js" type="text/javascript"></script>
|
||||
<script src="/assets/js/notification.js" type="text/javascript"></script>
|
||||
<script>
|
||||
// notifications
|
||||
var notif = new NotificationHandler({
|
||||
'notif_ajax_url': '{{ url('notification_ajax_list') }}',
|
||||
'notif_ajax_update_url': '{{ url('notification_ajax_update') }}',
|
||||
'icons': {
|
||||
'jo_new': 'flaticon-placeholder-3 kt-font-brand',
|
||||
'jo_cancel': 'fa fa-times-circle kt-font-danger',
|
||||
'rider_accept': 'fa fa-motorcycle kt-font-success',
|
||||
'rider_reject': 'fa fa-exclamation-triangle kt-font-danger'
|
||||
},
|
||||
'default_icon': 'fa fa-asterisk kt-font-brand',
|
||||
});
|
||||
notif.clearAll();
|
||||
notif.loadAll();
|
||||
notif.listen('{{ app.user.id }}', '{{ mqtt_host }}', {{ mqtt_port }}, {{ ssl_enable }});
|
||||
</script>
|
||||
{% block scripts %}{% endblock %}
|
||||
<!--end::Extra Scripts -->
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
|
||||
{% block scripts %}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.1.0/paho-mqtt.min.js" type="text/javascript"></script>
|
||||
<script src="{{ asset('assets/js/dashboard_map.js') }}"></script>
|
||||
<script src="{{ asset('assets/js/map_mqtt.js') }}"></script>
|
||||
{% if dashboard_enable == 'true' %}
|
||||
|
|
@ -35,7 +35,9 @@ function initMap(r_markers, c_markers, icons) {
|
|||
'zoom': 13,
|
||||
'rider_popup_url': '/riders/[id]/popup',
|
||||
'cust_popup_url': '/job-order/[id]/popup',
|
||||
'icons': icons
|
||||
'icons': icons,
|
||||
'rider_name_url': '/riders/[id]/name',
|
||||
'rider_availability_url': '{{ absolute_url('/riders/[id]/available')|raw }}'
|
||||
};
|
||||
|
||||
var dashmap = new DashboardMap(options, r_markers, c_markers);
|
||||
|
|
@ -45,7 +47,7 @@ function initMap(r_markers, c_markers, icons) {
|
|||
return dashmap;
|
||||
}
|
||||
|
||||
function initEventHandler(dashmap) {
|
||||
function initEventHandler(dashmap, icons, ssl) {
|
||||
var options = {
|
||||
'track_jo': true,
|
||||
'track_rider': true,
|
||||
|
|
@ -54,11 +56,12 @@ function initEventHandler(dashmap) {
|
|||
'rider_status': 'rider/+/status',
|
||||
'jo_location': 'jo/+/location',
|
||||
'jo_status': 'jo/+/status',
|
||||
'jo_origin': 'jo/+/origin'
|
||||
'jo_origin': 'jo/+/origin',
|
||||
'rider_availability': 'rider/+/availability',
|
||||
},
|
||||
};
|
||||
|
||||
var event_handler = new MapEventHandler(options, dashmap);
|
||||
var event_handler = new MapEventHandler(options, dashmap, ssl);
|
||||
event_handler.connect('{{ app.user.getID }}', '{{ mqtt_host }}', {{ mqtt_port }});
|
||||
}
|
||||
|
||||
|
|
@ -94,8 +97,13 @@ 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);
|
||||
initEventHandler(dashmap, icons, ssl);
|
||||
{% endif %}
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -23,9 +23,15 @@
|
|||
<span class="m-portlet__head-icon">
|
||||
<i class="flaticon-transport"></i>
|
||||
</span>
|
||||
<h3 class="m-portlet__head-text">
|
||||
One-step Job Order
|
||||
</h3>
|
||||
{% if mode == "onestep" %}
|
||||
<h3 class="m-portlet__head-text">
|
||||
One-step Job Order
|
||||
</h3>
|
||||
{% else %}
|
||||
<h3 class="m-portlet__head-text">
|
||||
One-step Job Order #{{ obj.getID }} - {{ obj.getStatusText }}
|
||||
</h3>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -92,57 +98,57 @@
|
|||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_first_name">First Name</label>
|
||||
<input type="text" name="customer_first_name" id="customer-first-name" class="form-control m-input cust_field" value="{{ obj.getCustomer.getFirstName|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="customer_first_name"></div>
|
||||
<label data-field="first_name">First Name</label>
|
||||
<input type="text" name="first_name" id="customer-first-name" class="form-control m-input cust_field" value="{{ obj.getCustomer.getFirstName|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="first_name"></div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_last_name">Last Name</label>
|
||||
<input type="text" name="customer_last_name" id="customer-last-name" class="form-control m-input cust_field" value="{{ obj.getCustomer.getLastName|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="customer_last_name"></div>
|
||||
<label data-field="last_name">Last Name</label>
|
||||
<input type="text" name="last_name" id="customer-last-name" class="form-control m-input cust_field" value="{{ obj.getCustomer.getLastName|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="last_name"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_phone_mobile">Mobile Phone</label>
|
||||
<label data-field="phone_mobile">Mobile Phone</label>
|
||||
<div class="input-group m-input-group">
|
||||
<span class="input-group-addon">{% trans %}country_code_prefix{% endtrans %}</span>
|
||||
<input type="text" name="customer_phone_mobile" id="customer-phone-mobile" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneMobile|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="customer_phone_mobile"></div>
|
||||
<input type="text" name="phone_mobile" id="customer-phone-mobile" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneMobile|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="phone_mobile"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_phone_landline">Landline</label>
|
||||
<label data-field="phone_landline">Landline</label>
|
||||
<div class="input-group m-input-group">
|
||||
<span class="input-group-addon">{% trans %}country_code_prefix{% endtrans %}</span>
|
||||
<input type="text" name="customer_phone_landline" id="customer-phone-landline" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneLandline|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="customer_phone_landline"></div>
|
||||
<input type="text" name="phone_landline" id="customer-phone-landline" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneLandline|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="phone_landline"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_phone_office">Office Phone</label>
|
||||
<label data-field="phone_office">Office Phone</label>
|
||||
<div class="input-group m-input-group">
|
||||
<span class="input-group-addon">{% trans %}country_code_prefix{% endtrans %}</span>
|
||||
<input type="text" name="customer_phone_office" id="customer-phone-office" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneOffice|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="customer_phone_office"></div>
|
||||
<input type="text" name="phone_office" id="customer-phone-office" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneOffice|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="phone_office"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_phone_fax">Fax</label>
|
||||
<label data-field="phone_fax">Fax</label>
|
||||
<div class="input-group m-input-group">
|
||||
<span class="input-group-addon">{% trans %}country_code_prefix{% endtrans %}</span>
|
||||
<input type="text" name="customer_phone_fax" id="customer-phone-fax" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneFax|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="customer_phone_fax"></div>
|
||||
<input type="text" name="phone_fax" id="customer-phone-fax" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneFax|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="phone_fax"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_customer_notes">Customer Notes</label>
|
||||
<textarea name="customer_customer_notes" id="customer-customer-notes" class="form-control m-input cust_field" data-vehicle-field="1" rows="4" disabled>{{ obj.getCustomer ? obj.getCustomer.getCustomerNotes }}</textarea>
|
||||
<div class="form-control-feedback hide" data-field="customer_customer_notes"></div>
|
||||
<label data-field="customer_notes">Customer Notes</label>
|
||||
<textarea name="customer_notes" id="customer-customer-notes" class="form-control m-input cust_field" data-vehicle-field="1" rows="4" disabled>{{ obj.getCustomer ? obj.getCustomer.getCustomerNotes }}</textarea>
|
||||
<div class="form-control-feedback hide" data-field="customer_notes"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -178,17 +184,26 @@
|
|||
</div>
|
||||
<div class="col-lg-3">
|
||||
<label data-field="cv_year">Model Year</label>
|
||||
<input type="text" name="cv_year" id="cv-year" class="form-control m-input cv_field" value="{{ obj.getCustomerVehicle ? obj.getCustomerVehicle.getModelYear }}" data-vehicle-field="1" disabled>
|
||||
<select name="cv_year" class="form-control m-input cv_field" id="cv-year" data-required="0" disabled>
|
||||
<option value="">Select a year</option>
|
||||
{% for year in model_years %}
|
||||
{% if obj.getCustomerVehicle %}
|
||||
<option value="{{ year }}"{{ obj.getCustomerVehicle.getModelYear == year ? ' selected' }}>{{ year }}</option>
|
||||
{% else %}
|
||||
<option value="{{ year }}">{{ year }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="form-control-feedback hide" data-field="cv_year"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-3">
|
||||
<label data-field="cv_plate">Plate #
|
||||
<label data-field="plate_number">Plate #
|
||||
<span style="color:red"> *</span>
|
||||
</label>
|
||||
<input type="text" name="cv_plate" id="cv-plate" class="form-control m-input cv_field" value="{{ obj.getCustomerVehicle.getPlateNumber|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="cv_plate"></div>
|
||||
<input type="text" name="plate_number" id="cv-plate" class="form-control m-input cv_field" value="{{ obj.getCustomerVehicle.getPlateNumber|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="plate_number"></div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="col-lg-3">
|
||||
|
|
@ -278,7 +293,7 @@
|
|||
<div class="col-lg-3">
|
||||
<label data-field="date_schedule">Scheduled Date</label>
|
||||
<div class="input-group date dp">
|
||||
<input type="text" name="date_schedule_date" class="form-control m-input" data-default-value="{{ obj.getDateSchedule|default("now")|date('Y-m-d') }}" value="{{ obj.getDateSchedule|default("now")|date('d M Y') }}" readonly placeholder="Select a date" disabled>
|
||||
<input type="text" id="date-schedule-date" name="date_schedule_date" class="form-control m-input" data-default-value="{{ obj.getDateSchedule|default("now")|date('Y-m-d') }}" value="{{ obj.getDateSchedule|default("now")|date('d M Y') }}" readonly placeholder="Select a date" disabled>
|
||||
<span class="input-group-addon">
|
||||
<i class="la la-calendar glyphicon-th"></i>
|
||||
</span>
|
||||
|
|
@ -288,7 +303,7 @@
|
|||
<div class="col-lg-3">
|
||||
<label data-field="date_schedule">Scheduled Time</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="date_schedule_time" class="form-control m-input tp" data-default-value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" readonly placeholder="Select a time" disabled>
|
||||
<input type="text" id="date-schedule-time" name="date_schedule_time" class="form-control m-input tp" data-default-value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" readonly placeholder="Select a time" disabled>
|
||||
<span class="input-group-addon">
|
||||
<i class="la la-clock-o glyphicon-th"></i>
|
||||
</span>
|
||||
|
|
@ -324,8 +339,22 @@
|
|||
<label data-field="delivery_instructions">{% trans %}delivery_instructions_label{% endtrans %}</label>
|
||||
<textarea name="delivery_instructions" class="form-control m-input" rows="4">{{ obj.getDeliveryInstructions }}</textarea>
|
||||
</div>
|
||||
<br>
|
||||
<!-- <div class="col-lg-12 form-group-inner">
|
||||
<label data-field="rider_plate_number">Rider Plate Number</label>
|
||||
<input type="text" id="rider-plate-number" name="rider_plate_number" class="form-control m-input" value="{{ obj.getRiderPlateNum|default('') }}" >
|
||||
<div class="form-control-feedback hide" data-field="rider_plate_number"></div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="col-lg-12 form-group-inner">
|
||||
<label>
|
||||
Responsible Party
|
||||
<span style="color:red"> *</span>
|
||||
</label>
|
||||
<input type="text" name="responsible_party" class="form-control m-input" value="{{ obj.getResponsibleParty|default('') }}" >
|
||||
<div class="form-control-feedback hide" data-field="responsible_party"></div>
|
||||
</div>
|
||||
<div class="col-lg-12 form-group-inner">
|
||||
<label>Prepared By</label>
|
||||
<input type="text" name="created_by" class="form-control m-input" value="{{ obj.getCreatedBy.getFullName|default('') }}" disabled>
|
||||
|
|
@ -415,7 +444,6 @@
|
|||
<th>Branch</th>
|
||||
<th>Contact Numbers</th>
|
||||
<th>Distance in KM</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="nearest_hubs">
|
||||
|
|
@ -425,7 +453,6 @@
|
|||
<td>{{ hub.hub.getName }}</td>
|
||||
<td>{{ hub.hub.getBranch }}</td>
|
||||
<td>{{ hub.hub.getContactNumbers }}</td>
|
||||
<td></span></td>
|
||||
<td></td>
|
||||
{% endfor %}
|
||||
{% endif %} -->
|
||||
|
|
@ -462,14 +489,13 @@
|
|||
<th>Last Name</th>
|
||||
<th>Contact No.</th>
|
||||
<th>Plate Number</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="riders">
|
||||
{% if mode in ['onestep-edit', 'view-all', 'update-fulfillment'] %}
|
||||
{% set avail_riders = obj.getHub.getAvailableRiders|default([]) %}
|
||||
<tr class="placeholder-row{{ obj.getHub and avail_riders|length > 0 ? ' hide' }}">
|
||||
<td colspan="5">
|
||||
<td colspan="4">
|
||||
No riders available.
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -495,6 +521,100 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{% if mode in ['onestep-edit'] %}
|
||||
<div class="m-form__seperator m-form__seperator--dashed"></div>
|
||||
<div class="m-form__section">
|
||||
<div class="m-form__heading">
|
||||
<h3 class="m-form__heading-title">
|
||||
Other Information
|
||||
</h3>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-3">
|
||||
<label data-field="odometer">Odometer Reading</label>
|
||||
<input type="text" name="odometer" id="odometer" class="form-control m-input other_info_field" value="{{ odometer }}" disabled>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<label data-field="email">Email Address</label>
|
||||
<input type="text" name="email" id="email" class="form-control m-input other_info_field" value="{{ email }}" disabled>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<label> Customer Signature </label>
|
||||
<div class="portrait-box" style="background-image: url('{{ signature ? '/uploads/jo_extra/' ~ signature : '/assets/images/user.gif' }}');" ></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-12">
|
||||
<label> Pictures</label>
|
||||
</div>
|
||||
{% for key, picture in jo_pictures %}
|
||||
{% if key == 'image_1' %}
|
||||
<div class="col-lg-2">
|
||||
<a href="#" class="image-pop">
|
||||
<img id="image-1-source" src="{{ asset('/uploads/jo_extra/' ~ picture) }}" style="width: 150px; height: 150px;" />
|
||||
</a>
|
||||
<br>
|
||||
<label>Windscreen Sticker</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if key == 'image_2' %}
|
||||
<div class="col-lg-2">
|
||||
<a href="#" class="image-pop">
|
||||
<img id="image-2-source" src="{{ asset('/uploads/jo_extra/' ~ picture) }}" style="width: 150px; height: 150px;" />
|
||||
</a>
|
||||
<br>
|
||||
<label>Battery</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if key == 'image_3' %}
|
||||
<div class="col-lg-2">
|
||||
<a href="#" class="image-pop">
|
||||
<img id="image-3-source" src="{{ asset('/uploads/jo_extra/' ~ picture) }}" style="width: 150px; height: 150px;" />
|
||||
</a>
|
||||
<br>
|
||||
<label>Odometer Reading</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if key == 'image_4' %}
|
||||
<div class="col-lg-2">
|
||||
<a href="#" class="image-pop">
|
||||
<img id="image-4-source" src="{{ asset('/uploads/jo_extra/' ~ picture) }}" style="width: 150px; height: 150px;" />
|
||||
</a>
|
||||
<br>
|
||||
<label>Proof of Payment</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- <div class="form-group m-form__group row">
|
||||
<div class="col-lg-12">
|
||||
<label> Other Images</label>
|
||||
</div>
|
||||
{% for key, picture in jo_pictures %}
|
||||
{% if key == 'other_images' %}
|
||||
{% for pic in jo_pictures['other_images'] %}
|
||||
<div class="col-lg-2">
|
||||
<div class="portrait-box" style="background-image: url('{{ '/uploads/jo_extra/' ~ pic }}');" ></div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- modal for images -->
|
||||
<div class="modal fade" id="image-modal" tabindex="-1" role="dialog" aria-labelledby="imageModal" aria-hidden="true">
|
||||
<div class="modal-dialog" data-dismiss="modal">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
||||
<img src="" class="image-preview" style="width: 100%;" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="m-form__seperator m-form__seperator--dashed"></div>
|
||||
<div class="m-form__section" id="sc-section">
|
||||
<div class="m-form__heading">
|
||||
|
|
@ -544,7 +664,7 @@
|
|||
<input type="text" name="or_name" id="or_name" class="form-control m-input" value="{{ obj.getORName|default('') }}">
|
||||
<div class="form-control-feedback hide" data-field="or_name"></div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div style="display:none" class="col-lg-6">
|
||||
<label data-field="promo_detail">Employee ID / Card Number / Referred By</label>
|
||||
<input type="text" name="promo_detail" id="promo_detail" class="form-control m-input" value="{{ obj.getPromoDetail|default('') }}">
|
||||
<div class="form-control-feedback hide" data-field="promo_detail"></div>
|
||||
|
|
@ -554,10 +674,29 @@
|
|||
<div class="col-lg-6">
|
||||
<label>Discount</label>
|
||||
{% if ftags.invoice_edit %}
|
||||
<input type="number" id="invoice-discount" name="invoice_discount" class="form-control m-input min = "0" max="50" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount }}">
|
||||
<select class="form-control m-input" id="invoice-discount" name="invoice_discount">
|
||||
<option value=""></option>
|
||||
{% for discount in discounts %}
|
||||
{% if obj.getInvoice %}
|
||||
<option value="{{ discount }}"{{ obj.getInvoice.getDiscount|number_format(2) == discount ? ' selected' }}>{{ discount }}</option>
|
||||
{% else %}
|
||||
<option value="{{ discount }}">{{ discount }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="form-control-feedback hide" data-field="invoice_discount"></div>
|
||||
{% else %}
|
||||
<input type="number" id="invoice-discount" name="invoice_discount" class="form-control m-input min="0" max="50" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount }}" disabled>
|
||||
<select class="form-control m-input" id="invoice-discount" name="invoice_discount">
|
||||
<option value=""></option>
|
||||
{% for discount in discounts %}
|
||||
{% if obj.getInvoice %}
|
||||
<option value="{{ discount }}"{{ obj.getInvoice.getDiscount|number_format(2) == discount ? ' selected' }} disabled>{{ discount }}</option>
|
||||
{% else %}
|
||||
<option value="{{ discount }}" disabled>{{ discount }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="form-control-feedback hide" data-field="invoice_discount"></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
|
|
@ -753,6 +892,7 @@ $(function() {
|
|||
{% if mode in ['onestep'] %}
|
||||
// get nearest hubs ajax
|
||||
var hub_table = '';
|
||||
var rider_table = '';
|
||||
$.getJSON("{{ url('hub_nearest') }}?lat=" + lat + "&long=" + lng, function(data) {
|
||||
var hubs = data['hubs'];
|
||||
for (i in hubs) {
|
||||
|
|
@ -765,18 +905,29 @@ $(function() {
|
|||
hub_table += '<td>' + hub['branch'] + '</td>';
|
||||
hub_table += '<td>' + hub['cnum'] + '</td>';
|
||||
hub_table += '<td>' + hub['distance'] + '</td>';
|
||||
hub_table += '<td></td>';
|
||||
hub_table += '</tr>';
|
||||
}
|
||||
|
||||
$('#nearest_hubs').html(hub_table);
|
||||
|
||||
});
|
||||
|
||||
// clear rider table
|
||||
rider_table += '<tr>';
|
||||
rider_table += '<td>' + '</td>';
|
||||
rider_table += '<td>' + '</td>';
|
||||
rider_table += '<td>' + '</td>';
|
||||
rider_table += '<td>' + '</td>';
|
||||
rider_table += '</tr>';
|
||||
|
||||
$('#riders').html(rider_table);
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if mode in ['onestep-edit'] %}
|
||||
// get nearest hubs ajax
|
||||
var hub_table = '';
|
||||
var rider_table = '';
|
||||
$.getJSON("{{ url('hub_nearest') }}?lat=" + lat + "&long=" + lng, function(data) {
|
||||
var hubs = data['hubs'];
|
||||
for (i in hubs) {
|
||||
|
|
@ -794,13 +945,26 @@ $(function() {
|
|||
hub_table += '<td>' + hub['branch'] + '</td>';
|
||||
hub_table += '<td>' + hub['cnum'] + '</td>';
|
||||
hub_table += '<td>' + hub['distance'] + '</td>';
|
||||
hub_table += '<td></td>';
|
||||
hub_table += '</tr>';
|
||||
|
||||
}
|
||||
|
||||
$('#nearest_hubs').html(hub_table);
|
||||
$('#nearest_hubs').html(hub_table);
|
||||
|
||||
});
|
||||
|
||||
if (selected_rider == '') {
|
||||
// clear rider table
|
||||
rider_table += '<tr>';
|
||||
rider_table += '<td>' + '</td>';
|
||||
rider_table += '<td>' + '</td>';
|
||||
rider_table += '<td>' + '</td>';
|
||||
rider_table += '<td>' + '</td>';
|
||||
rider_table += '</tr>';
|
||||
|
||||
$('#riders').html(rider_table);
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if mode in ['view-all', 'update-fulfillment'] %}
|
||||
|
|
@ -820,7 +984,6 @@ $(function() {
|
|||
hub_table += '<td>' + hub['branch'] + '</td>';
|
||||
hub_table += '<td>' + hub['cnum'] + '</td>';
|
||||
hub_table += '<td>' + hub['distance'] + '</td>';
|
||||
hub_table += '<td></td>';
|
||||
hub_table += '</tr>';
|
||||
}
|
||||
}
|
||||
|
|
@ -855,6 +1018,9 @@ $(function() {
|
|||
});
|
||||
|
||||
osm_map.on('click', function(e) {
|
||||
// clear selected hub and riders
|
||||
selected_hub = '';
|
||||
selected_rider = '';
|
||||
selectPoint(e.latlng.lat, e.latlng.lng);
|
||||
});
|
||||
|
||||
|
|
@ -911,6 +1077,7 @@ $(function() {
|
|||
|
||||
// clear rider field
|
||||
$('#rider-field').val('');
|
||||
$('#rider-plate-number').val('');
|
||||
selected_rider = '';
|
||||
|
||||
// get riders of hub
|
||||
|
|
@ -931,7 +1098,6 @@ $(function() {
|
|||
rider_table += '<td>' + rider['last_name'] + '</td>';
|
||||
rider_table += '<td>' + rider['contact_num'] + '</td>';
|
||||
rider_table += '<td>' + rider['plate_num'] + '</td>';
|
||||
rider_table += '<td></td>';
|
||||
rider_table += '</tr>';
|
||||
}
|
||||
|
||||
|
|
@ -961,6 +1127,8 @@ $(function() {
|
|||
// set rider
|
||||
selected_rider = id;
|
||||
$('#rider-field').val(selected_rider);
|
||||
//var rider_plate_num = $(this).find('td:nth-child(4)').text();
|
||||
//$('#rider-plate-number').val(rider_plate_num);
|
||||
});
|
||||
{% endif %}
|
||||
});
|
||||
|
|
@ -1029,6 +1197,7 @@ $(function() {
|
|||
{% endif %}
|
||||
|
||||
$("#row-form").submit(function(e) {
|
||||
e.preventDefault();
|
||||
if (form_in_process) {
|
||||
alert("Cannot submit form twice. First submission still in progress.");
|
||||
return false;
|
||||
|
|
@ -1191,6 +1360,7 @@ $(function() {
|
|||
} else {
|
||||
$("#current-battery, #warranty-expiration").val("No current battery").css('color', '#f4516c');
|
||||
}
|
||||
$("#or_name").val(vdata.customer.first_name + ' ' + vdata.customer.last_name);
|
||||
})
|
||||
}).focus();
|
||||
{% endif %}
|
||||
|
|
@ -1414,7 +1584,8 @@ $(function() {
|
|||
|
||||
// update invoice when promo is changed
|
||||
$("#invoice-discount").change(function() {
|
||||
generateInvoice();
|
||||
console.log('discount ' + $("#invoice-discount").val());
|
||||
generateInvoice();
|
||||
});
|
||||
|
||||
// trigger update when service type is changed
|
||||
|
|
@ -1758,6 +1929,59 @@ $(function() {
|
|||
generateInvoice();
|
||||
});
|
||||
|
||||
$("#customer-first-name, #customer-last-name").change(function() {
|
||||
// autopopulate OR name with customer name
|
||||
var cust_name = $("#customer-first-name").val() + ' ' + $("#customer-last-name").val();
|
||||
$("#or_name").val(cust_name);
|
||||
});
|
||||
|
||||
$('.dp').on('changeDate', function() {
|
||||
// check date schedule if it's earlier
|
||||
// if so, show an alert to let user know
|
||||
var date_time = $('#date-schedule-date').val() + ' ' + $('#date-schedule-time').val()
|
||||
var date_schedule = new Date(date_time);
|
||||
var current_date = new Date('{{ current_date|date('Y-m-d g:i A') }}');
|
||||
|
||||
// check if date is earlier than current
|
||||
if (date_schedule < current_date)
|
||||
{
|
||||
swal({
|
||||
title: 'Warning!',
|
||||
text: 'Schedule date and time is before today\'s date and time.',
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('.tp').on('changeTime.timepicker', function(e) {
|
||||
// set the schedule time what the user selects
|
||||
$('#date-schedule-time').val(e.time.value);
|
||||
});
|
||||
|
||||
$('.tp').on('hide.timepicker', function(e) {
|
||||
// check time schedule along with date if it's earlier than current date
|
||||
var date_time = $('#date-schedule-date').val() + ' ' + $('#date-schedule-time').val()
|
||||
var date_schedule = new Date(date_time);
|
||||
var current_date = new Date('{{ current_date|date('Y-m-d g:i A') }}');
|
||||
|
||||
// check if date is earlier than current
|
||||
if (date_schedule < current_date)
|
||||
{
|
||||
swal({
|
||||
title: 'Warning!',
|
||||
text: 'Schedule date and time is before today\'s date and time.',
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// image modal
|
||||
$('.image-pop').on('click', function() {
|
||||
$('.image-preview').attr('src', $(this).find('img').attr('src'));
|
||||
$('#image-modal').modal('show');
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,15 @@
|
|||
<span class="m-portlet__head-icon">
|
||||
<i class="flaticon-transport"></i>
|
||||
</span>
|
||||
<h3 class="m-portlet__head-text">
|
||||
Walk-in Job Order
|
||||
</h3>
|
||||
{% if mode == "walk-in" %}
|
||||
<h3 class="m-portlet__head-text">
|
||||
Walk-in Job Order
|
||||
</h3>
|
||||
{% else %}
|
||||
<h3 class="m-portlet__head-text">
|
||||
Walk-in Job Order #{{ obj.getID }} - {{ obj.getStatusText }}
|
||||
</h3>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -92,57 +98,57 @@
|
|||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_first_name">First Name</label>
|
||||
<input type="text" name="customer_first_name" id="customer-first-name" class="form-control m-input cust_field" value="{{ obj.getCustomer.getFirstName|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="customer_first_name"></div>
|
||||
<label data-field="first_name">First Name</label>
|
||||
<input type="text" name="first_name" id="customer-first-name" class="form-control m-input cust_field" value="{{ obj.getCustomer.getFirstName|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="first_name"></div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_last_name">Last Name</label>
|
||||
<input type="text" name="customer_last_name" id="customer-last-name" class="form-control m-input cust_field" value="{{ obj.getCustomer.getLastName|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="customer_last_name"></div>
|
||||
<label data-field="last_name">Last Name</label>
|
||||
<input type="text" name="last_name" id="customer-last-name" class="form-control m-input cust_field" value="{{ obj.getCustomer.getLastName|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="last_name"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_phone_mobile">Mobile Phone</label>
|
||||
<label data-field="phone_mobile">Mobile Phone</label>
|
||||
<div class="input-group m-input-group">
|
||||
<span class="input-group-addon">{% trans %}country_code_prefix{% endtrans %}</span>
|
||||
<input type="text" name="customer_phone_mobile" id="customer-phone-mobile" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneMobile|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="customer_phone_mobile"></div>
|
||||
<input type="text" name="phone_mobile" id="customer-phone-mobile" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneMobile|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="phone_mobile"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_phone_landline">Landline</label>
|
||||
<label data-field="phone_landline">Landline</label>
|
||||
<div class="input-group m-input-group">
|
||||
<span class="input-group-addon">{% trans %}country_code_prefix{% endtrans %}</span>
|
||||
<input type="text" name="customer_phone_landline" id="customer-phone-landline" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneLandline|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="customer_phone_landline"></div>
|
||||
<input type="text" name="phone_landline" id="customer-phone-landline" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneLandline|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="phone_landline"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_phone_office">Office Phone</label>
|
||||
<label data-field="phone_office">Office Phone</label>
|
||||
<div class="input-group m-input-group">
|
||||
<span class="input-group-addon">{% trans %}country_code_prefix{% endtrans %}</span>
|
||||
<input type="text" name="customer_phone_office" id="customer-phone-office" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneOffice|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="customer_phone_office"></div>
|
||||
<input type="text" name="phone_office" id="customer-phone-office" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneOffice|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="phone_office"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_phone_fax">Fax</label>
|
||||
<label data-field="phone_fax">Fax</label>
|
||||
<div class="input-group m-input-group">
|
||||
<span class="input-group-addon">{% trans %}country_code_prefix{% endtrans %}</span>
|
||||
<input type="text" name="customer_phone_fax" id="customer-phone-fax" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneFax|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="customer_phone_fax"></div>
|
||||
<input type="text" name="phone_fax" id="customer-phone-fax" class="form-control m-input cust_field" value="{{ obj.getCustomer.getPhoneFax|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="phone_fax"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="customer_customer_notes">Customer Notes</label>
|
||||
<textarea name="customer_customer_notes" id="customer-customer-notes" class="form-control m-input cust_field" data-vehicle-field="1" rows="4" disabled>{{ obj.getCustomer ? obj.getCustomer.getCustomerNotes }}</textarea>
|
||||
<div class="form-control-feedback hide" data-field="customer_customer_notes"></div>
|
||||
<label data-field="customer_notes">Customer Notes</label>
|
||||
<textarea name="customer_notes" id="customer-customer-notes" class="form-control m-input cust_field" data-vehicle-field="1" rows="4" disabled>{{ obj.getCustomer ? obj.getCustomer.getCustomerNotes }}</textarea>
|
||||
<div class="form-control-feedback hide" data-field="customer_notes"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -178,17 +184,26 @@
|
|||
</div>
|
||||
<div class="col-lg-3">
|
||||
<label data-field="cv_year">Model Year</label>
|
||||
<input type="text" name="cv_year" id="cv-year" class="form-control m-input cv_field" value="{{ obj.getCustomerVehicle ? obj.getCustomerVehicle.getModelYear }}" data-vehicle-field="1" disabled>
|
||||
<select name="cv_year" class="form-control m-input cv_field" id="cv-year" data-required="0" disabled>
|
||||
<option value="">Select a year</option>
|
||||
{% for year in model_years %}
|
||||
{% if obj.getCustomerVehicle %}
|
||||
<option value="{{ year }}"{{ obj.getCustomerVehicle.getModelYear == year ? ' selected' }}>{{ year }}</option>
|
||||
{% else %}
|
||||
<option value="{{ year }}">{{ year }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="form-control-feedback hide" data-field="cv_year"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-3">
|
||||
<label data-field="cv_plate">Plate #
|
||||
<label data-field="plate_number">Plate #
|
||||
<span style="color:red"> *</span>
|
||||
</label>
|
||||
<input type="text" name="cv_plate" id="cv-plate" class="form-control m-input cv_field" value="{{ obj.getCustomerVehicle.getPlateNumber|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="cv_plate"></div>
|
||||
<input type="text" name="plate_number" id="cv-plate" class="form-control m-input cv_field" value="{{ obj.getCustomerVehicle.getPlateNumber|default('') }}" data-vehicle-field="1" disabled>
|
||||
<div class="form-control-feedback hide" data-field="plate_number"></div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="col-lg-3">
|
||||
|
|
@ -278,7 +293,7 @@
|
|||
<div class="col-lg-3">
|
||||
<label data-field="date_schedule">Scheduled Date</label>
|
||||
<div class="input-group date dp">
|
||||
<input type="text" name="date_schedule_date" class="form-control m-input" data-default-value="{{ obj.getDateSchedule|default("now")|date('Y-m-d') }}" value="{{ obj.getDateSchedule|default("now")|date('d M Y') }}" readonly placeholder="Select a date" disabled>
|
||||
<input type="text" id="date-schedule-date" name="date_schedule_date" class="form-control m-input" data-default-value="{{ obj.getDateSchedule|default("now")|date('Y-m-d') }}" value="{{ obj.getDateSchedule|default("now")|date('d M Y') }}" readonly placeholder="Select a date" disabled>
|
||||
<span class="input-group-addon">
|
||||
<i class="la la-calendar glyphicon-th"></i>
|
||||
</span>
|
||||
|
|
@ -288,7 +303,7 @@
|
|||
<div class="col-lg-3">
|
||||
<label data-field="date_schedule">Scheduled Time</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="date_schedule_time" class="form-control m-input tp" data-default-value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" readonly placeholder="Select a time" disabled>
|
||||
<input type="text" id="date-schedule-time" name="date_schedule_time" class="form-control m-input tp" data-default-value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" readonly placeholder="Select a time" disabled>
|
||||
<span class="input-group-addon">
|
||||
<i class="la la-clock-o glyphicon-th"></i>
|
||||
</span>
|
||||
|
|
@ -323,13 +338,22 @@
|
|||
</select>
|
||||
<div class="form-control-feedback hide" data-field="mode_of_payment"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<br>
|
||||
<div class="col-lg-12 form-group-inner">
|
||||
<label>Prepared By</label>
|
||||
<input type="text" name="created_by" class="form-control m-input" value="{{ obj.getCreatedBy.getFullName|default('') }}" disabled>
|
||||
<div class="form-control-feedback hide" data-field="date_transaction"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="col-lg-12 form-group-inner">
|
||||
<label>
|
||||
Responsible Party
|
||||
<span style="color:red"> *</span>
|
||||
</label>
|
||||
<input type="text" name="responsible_party" class="form-control m-input" value="{{ obj.getResponsibleParty|default('') }}" >
|
||||
<div class="form-control-feedback hide" data-field="responsible_party"></div>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -357,8 +381,6 @@
|
|||
<th>Hub</th>
|
||||
<th>Branch</th>
|
||||
<th>Contact Numbers</th>
|
||||
<th>Distance in KM</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="nearest_hubs">
|
||||
|
|
@ -367,16 +389,12 @@
|
|||
<td>{{ obj.getHub.getName }}</td>
|
||||
<td>{{ obj.getHub.getBranch }}</td>
|
||||
<td>{{ obj.getHub.getContactNumbers }}</td>
|
||||
<td></span></td>
|
||||
<td></td>
|
||||
{% else %}
|
||||
{% for hub in hubs %}
|
||||
<tr data-id="{{ hub.getID }}"{{ obj.getHub and obj.getHub.getID == hub.getID ? ' class="m-table__row--primary"' }}>
|
||||
<td>{{ hub.getName }}</td>
|
||||
<td>{{ hub.getBranch }}</td>
|
||||
<td>{{ hub.getContactNumbers }}</td>
|
||||
<td></span></td>
|
||||
<td></td>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
|
|
@ -398,7 +416,7 @@
|
|||
<input type="text" name="or_name" id="or_name" class="form-control m-input" value="{{ obj.getORName|default('') }}">
|
||||
<div class="form-control-feedback hide" data-field="or_name"></div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div style="display:none" class="col-lg-6">
|
||||
<label data-field="promo_detail">Employee ID / Card Number / Referred By</label>
|
||||
<input type="text" name="promo_detail" id="promo_detail" class="form-control m-input" value="{{ obj.getPromoDetail|default('') }}">
|
||||
<div class="form-control-feedback hide" data-field="promo_detail"></div>
|
||||
|
|
@ -408,10 +426,28 @@
|
|||
<div class="col-lg-6">
|
||||
<label>Discount</label>
|
||||
{% if ftags.invoice_edit %}
|
||||
<input type="number" id="invoice-discount" name="invoice_discount" class="form-control m-input min = "0" max="50" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount }}">
|
||||
<select class="form-control m-input" id="invoice-discount" name="invoice_discount">
|
||||
<option value=""></option>
|
||||
{% for discount in discounts %}
|
||||
{% if obj.getInvoice %}
|
||||
<option value="{{ discount }}"{{ obj.getInvoice.getDiscount|number_format(0) == discount ? ' selected' }}>{{ discount }}</option>
|
||||
{% else %}
|
||||
<option value="{{ discount }}">{{ discount }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="form-control-feedback hide" data-field="invoice_discount"></div>
|
||||
{% else %}
|
||||
<input type="number" id="invoice-discount" name="invoice_discount" class="form-control m-input min="0" max="50" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount }}" disabled>
|
||||
<select class="form-control m-input" id="invoice-discount" name="invoice_discount">
|
||||
<option value=""></option>
|
||||
{% for discount in discounts %}
|
||||
{% if obj.getInvoice %}
|
||||
<option value="{{ discount }}"{{ obj.getInvoice.getDiscount == discount ? ' selected' }} disabled>{{ discount }}</option>
|
||||
{% else %}
|
||||
<option value="{{ discount }}" disabled>{{ discount }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
|
|
@ -727,6 +763,8 @@ var vdata = false;
|
|||
} else {
|
||||
$("#current-battery, #warranty-expiration").val("No current battery").css('color', '#f4516c');
|
||||
}
|
||||
|
||||
$("#or_name").val(vdata.customer.first_name + ' ' + vdata.customer.last_name);
|
||||
})
|
||||
}).focus();
|
||||
{% endif %}
|
||||
|
|
@ -1093,6 +1131,54 @@ var vdata = false;
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
$("#customer-first-name, #customer-last-name").change(function() {
|
||||
// autopopulate OR name with customer name
|
||||
var cust_name = $("#customer-first-name").val() + ' ' + $("#customer-last-name").val();
|
||||
$("#or_name").val(cust_name);
|
||||
});
|
||||
|
||||
$('.dp').on('changeDate', function() {
|
||||
// check date schedule if it's earlier
|
||||
// if so, show an alert to let user know
|
||||
var date_time = $('#date-schedule-date').val() + ' ' + $('#date-schedule-time').val()
|
||||
var date_schedule = new Date(date_time);
|
||||
var current_date = new Date('{{ current_date|date('Y-m-d g:i A') }}');
|
||||
|
||||
// check if date is earlier than current
|
||||
if (date_schedule < current_date)
|
||||
{
|
||||
swal({
|
||||
title: 'Warning!',
|
||||
text: 'Schedule date and time is before today\'s date and time.',
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('.tp').on('changeTime.timepicker', function(e) {
|
||||
// set the schedule time what the user selects
|
||||
$('#date-schedule-time').val(e.time.value);
|
||||
});
|
||||
|
||||
$('.tp').on('hide.timepicker', function(e) {
|
||||
// check time schedule along with date if it's earlier than current date
|
||||
var date_time = $('#date-schedule-date').val() + ' ' + $('#date-schedule-time').val()
|
||||
var date_schedule = new Date(date_time);
|
||||
var current_date = new Date('{{ current_date|date('Y-m-d g:i A') }}');
|
||||
|
||||
// check if date is earlier than current
|
||||
if (date_schedule < current_date)
|
||||
{
|
||||
swal({
|
||||
title: 'Warning!',
|
||||
text: 'Schedule date and time is before today\'s date and time.',
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -94,8 +94,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.status == 'Assigned') {
|
||||
$(row).addClass('m-table__row--is_assigned');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -104,6 +108,27 @@
|
|||
field: 'id',
|
||||
title: 'JO Number'
|
||||
},
|
||||
{
|
||||
field: 'Actions',
|
||||
width: 110,
|
||||
title: 'Actions',
|
||||
sortable: false,
|
||||
overflow: 'visible',
|
||||
template: function (row, index, datatable) {
|
||||
var actions = '<a href="' + row.meta.update_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit" title="View"><i class="la la-edit"></i></a>';
|
||||
actions += '<a href="' + row.meta.pdf_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit" title="PDF" target="_blank"><i class="la la-file-o"></i></a>';
|
||||
|
||||
return actions;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
title: 'Schedule'
|
||||
},
|
||||
{
|
||||
field: 'date_schedule',
|
||||
title: 'Scheduled Date'
|
||||
},
|
||||
{
|
||||
field: 'plate_number',
|
||||
title: 'Plate #'
|
||||
|
|
@ -125,12 +150,12 @@
|
|||
title: 'Customer Area'
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
title: 'Schedule'
|
||||
field: 'date_start',
|
||||
title: 'Start Date'
|
||||
},
|
||||
{
|
||||
field: 'date_schedule',
|
||||
title: 'Scheduled Date'
|
||||
field: 'date_finish',
|
||||
title: 'Finish Date'
|
||||
},
|
||||
{
|
||||
field: 'rider_name',
|
||||
|
|
@ -145,21 +170,8 @@
|
|||
title: 'Status'
|
||||
},
|
||||
{
|
||||
field: 'processor',
|
||||
title: 'Dispatcher'
|
||||
},
|
||||
{
|
||||
field: 'Actions',
|
||||
width: 110,
|
||||
title: 'Actions',
|
||||
sortable: false,
|
||||
overflow: 'visible',
|
||||
template: function (row, index, datatable) {
|
||||
var actions = '<a href="' + row.meta.update_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit" title="View"><i class="la la-edit"></i></a>';
|
||||
actions += '<a href="' + row.meta.pdf_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit" title="PDF" target="_blank"><i class="la la-file-o"></i></a>';
|
||||
|
||||
return actions;
|
||||
},
|
||||
field: 'creator',
|
||||
title: 'Agent'
|
||||
}
|
||||
],
|
||||
search: {
|
||||
|
|
|
|||
199
templates/job-order/cmb.list.behindschedule.html.twig
Normal file
199
templates/job-order/cmb.list.behindschedule.html.twig
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
<!-- BEGIN: Subheader -->
|
||||
<div class="m-subheader">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="mr-auto">
|
||||
<h3 class="m-subheader__title">
|
||||
Job Orders (Behind Schedule)
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END: Subheader -->
|
||||
<div class="m-content">
|
||||
<!--Begin::Section-->
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<div class="m-portlet m-portlet--mobile">
|
||||
<div class="m-portlet__body">
|
||||
<div class="m-form m-form--label-align-right m--margin-top-20 m--margin-bottom-30">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-xl-12">
|
||||
<div class="form-group m-form__group row align-items-center">
|
||||
<div class="col-md-4">
|
||||
<div class="m-input-icon m-input-icon--left">
|
||||
<input type="text" class="form-control m-input m-input--solid" placeholder="Search..." id="data-rows-search">
|
||||
<span class="m-input-icon__icon m-input-icon__icon--left">
|
||||
<span><i class="la la-search"></i></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="m-input-icon m-input-icon--left">
|
||||
<div>
|
||||
<select class="form-control m-input" id="rider_list" name="rider_list">
|
||||
<option value="">All Riders</option>
|
||||
{% for rider in riders %}
|
||||
<option value="{{ rider.getID }}">{{ rider.getFirstName ~ ' ' ~ rider.getLastName }} </option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="m-input-icon m-input-icon--left">
|
||||
<div class="input-daterange input-group" id="date-range">
|
||||
<input role="presentation" type="text" class="form-control m-input" id="date_start" name="date_start" placeholder="Start date" />
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text"><i class="la la-ellipsis-h"></i></span>
|
||||
</div>
|
||||
<input role="presentation" type="text" class="form-control" id="date_end" name="date_end" placeholder="End date" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--begin: Datatable -->
|
||||
<div id="data-rows"></div>
|
||||
<!--end: Datatable -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
$(function() {
|
||||
$("#date-range").datepicker({
|
||||
orientation: "bottom"
|
||||
});
|
||||
var options = {
|
||||
data: {
|
||||
type: 'remote',
|
||||
source: {
|
||||
read: {
|
||||
url: '{{ url('jo_behind_schedule_rows') }}',
|
||||
method: 'POST'
|
||||
}
|
||||
},
|
||||
saveState: {
|
||||
cookie: false,
|
||||
webstorage: false
|
||||
},
|
||||
pageSize: 10,
|
||||
serverPaging: true,
|
||||
serverFiltering: true,
|
||||
serverSorting: true
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
field: 'id',
|
||||
title: 'JO #'
|
||||
},
|
||||
{
|
||||
field: 'Actions',
|
||||
width: 110,
|
||||
title: 'Actions',
|
||||
sortable: false,
|
||||
overflow: 'visible',
|
||||
template: function (row, index, datatable) {
|
||||
{% if is_granted('jo_onestep.edit') %}
|
||||
var actions = '<a href="' + row.meta.onestep_edit_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-reassign-hub" title="Edit"><i class="la la-edit"></i></a>';
|
||||
{% endif %}
|
||||
|
||||
return actions;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
title: 'Schedule'
|
||||
},
|
||||
{
|
||||
field: 'date_schedule',
|
||||
title: 'Scheduled Date'
|
||||
},
|
||||
{
|
||||
field: 'plate_number',
|
||||
title: 'Plate #'
|
||||
},
|
||||
{
|
||||
field: 'car_model',
|
||||
title: 'Car Model'
|
||||
},
|
||||
{
|
||||
field: 'customer_name',
|
||||
title: 'Customer'
|
||||
},
|
||||
{
|
||||
field: 'service_type',
|
||||
title: 'Service Type',
|
||||
},
|
||||
{
|
||||
field: 'delivery_address',
|
||||
title: 'Area'
|
||||
},
|
||||
{
|
||||
field: 'date_start',
|
||||
title: 'Start Date'
|
||||
},
|
||||
{
|
||||
field: 'rider_name',
|
||||
title: 'Rider'
|
||||
},
|
||||
{
|
||||
field: 'rider_plate_number',
|
||||
title: 'Rider Plate #'
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
title: 'Status'
|
||||
},
|
||||
{
|
||||
field: 'processor',
|
||||
title: 'Dispatcher'
|
||||
}
|
||||
],
|
||||
search: {
|
||||
onEnter: false,
|
||||
input: $('#data-rows-search'),
|
||||
delay: 400
|
||||
}
|
||||
};
|
||||
|
||||
var table = $("#data-rows").mDatatable(options);
|
||||
|
||||
// auto refresh table
|
||||
setInterval(function() {
|
||||
table.reload();
|
||||
}, {{ table_refresh_rate }});
|
||||
|
||||
$("#rider_list").on("change", function() {
|
||||
table.search($(this).val(), "rider");
|
||||
});
|
||||
|
||||
$("#date_start").on("change", function() {
|
||||
var date_start = $(this).val();
|
||||
var date_end = $("[name='date_end']").val();
|
||||
var date_array = [date_start, date_end];
|
||||
|
||||
table.search(date_array, "schedule_date");
|
||||
});
|
||||
|
||||
$("#date_end").on("change", function() {
|
||||
console.log($(this).val());
|
||||
|
||||
var date_end = $(this).val();
|
||||
var date_start = $("[name='date_start']").val();
|
||||
var date_array = [date_start, date_end];
|
||||
|
||||
table.search(date_array, "schedule_date");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -107,6 +107,28 @@
|
|||
field: 'id',
|
||||
title: 'JO #'
|
||||
},
|
||||
{
|
||||
field: 'Actions',
|
||||
width: 110,
|
||||
title: 'Actions',
|
||||
sortable: false,
|
||||
overflow: 'visible',
|
||||
template: function (row, index, datatable) {
|
||||
{% if is_granted('jo_onestep.edit') %}
|
||||
var actions = '<a href="' + row.meta.onestep_edit_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-reassign-hub" title="Edit"><i class="la la-edit"></i></a>';
|
||||
{% endif %}
|
||||
|
||||
return actions;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
title: 'Schedule'
|
||||
},
|
||||
{
|
||||
field: 'date_schedule',
|
||||
title: 'Scheduled Date'
|
||||
},
|
||||
{
|
||||
field: 'plate_number',
|
||||
title: 'Plate #'
|
||||
|
|
@ -128,12 +150,8 @@
|
|||
title: 'Area'
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
title: 'Schedule'
|
||||
},
|
||||
{
|
||||
field: 'date_schedule',
|
||||
title: 'Scheduled Date'
|
||||
field: 'date_start',
|
||||
title: 'Start Date'
|
||||
},
|
||||
{
|
||||
field: 'rider_name',
|
||||
|
|
@ -148,22 +166,8 @@
|
|||
title: 'Status'
|
||||
},
|
||||
{
|
||||
field: 'processor',
|
||||
title: 'Dispatcher'
|
||||
},
|
||||
{
|
||||
field: 'Actions',
|
||||
width: 110,
|
||||
title: 'Actions',
|
||||
sortable: false,
|
||||
overflow: 'visible',
|
||||
template: function (row, index, datatable) {
|
||||
{% if is_granted('jo_onestep.edit') %}
|
||||
var actions = '<a href="' + row.meta.onestep_edit_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-reassign-hub" title="Edit"><i class="fa fa-file"></i></a>';
|
||||
{% endif %}
|
||||
|
||||
return actions;
|
||||
},
|
||||
field: 'creator',
|
||||
title: 'Agent'
|
||||
}
|
||||
],
|
||||
search: {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
15
utils/clear_jo_data.sql
Normal file
15
utils/clear_jo_data.sql
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
delete from jo_event;
|
||||
delete from invoice_item;
|
||||
delete from invoice;
|
||||
delete from ticket;
|
||||
|
||||
set foreign_key_checks = 0;
|
||||
delete from job_order;
|
||||
set foreign_key_checks = 1;
|
||||
|
||||
delete from mobile_session;
|
||||
delete from customer_vehicle;
|
||||
delete from customer;
|
||||
delete from warranty;
|
||||
|
||||
update rider set active_jo_id = null;
|
||||
18
utils/delete_selected_hub_riders.sql
Normal file
18
utils/delete_selected_hub_riders.sql
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
delete from rider_session where rider_id=12;
|
||||
delete from rider_session where rider_id=2;
|
||||
delete from rider_session where rider_id=13;
|
||||
delete from rider_session where rider_id=11;
|
||||
|
||||
delete from rider_schedule where rider_id=12;
|
||||
delete from rider_schedule where rider_id=2;
|
||||
delete from rider_schedule where rider_id=13;
|
||||
delete from rider_schedule where rider_id=11;
|
||||
|
||||
delete from rider where id=12;
|
||||
delete from rider where id=2;
|
||||
delete from rider where id=13;
|
||||
delete from rider where id=11;
|
||||
|
||||
delete from hub where id=1;
|
||||
delete from hub where id=2;
|
||||
delete from hub where id=4;
|
||||
Loading…
Reference in a new issue