Merge branch '424-cmb-release' of gitlab.com:jankstudio/resq into 432-cmb-display-details-in-jo

This commit is contained in:
Korina Cordero 2020-06-29 02:56:08 +00:00
commit e9981b24fa
36 changed files with 3931 additions and 389 deletions

View file

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

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

View file

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

View file

@ -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,10 +118,6 @@ main_menu:
acl: jo_all.list
label: View All
parent: joborder
- id: jo_hub_view
acl: jo_hub.list
label: Hub View
parent: joborder
- id: support
acl: support.menu
@ -185,12 +177,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

View file

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

View file

@ -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)%"

View file

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

View file

@ -0,0 +1,161 @@
# 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_arrive_photos_upload:
path: /cmbrapi/uploadarrivephotos
controller: App\Controller\CMBRAPIController::uploadArrivePhotos
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]

View file

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

View file

@ -1,7 +1,8 @@
class MapEventHandler {
constructor(options, dashmap) {
constructor(options, dashmap, ssl) {
this.options = options;
this.dashmap = dashmap;
this.ssl = ssl;
}
connect(user_id, host, port) {
@ -11,7 +12,7 @@ class MapEventHandler {
this.mqtt = new Paho.MQTT.Client(host, port, client_id);
var options = {
// useSSL: true,
useSSL: this.ssl,
timeout: 3,
invocationContext: this,
onSuccess: this.onConnect.bind(this),

179
resq_settings/cmb/menu.yaml Normal file
View 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

View 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

View 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)%"

View 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

View 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

View 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)%"

View 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;
}
}

View 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();
}
}

View file

@ -0,0 +1,326 @@
<?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 uploadArrivePhotos(Request $req, RiderAPIHandlerInterface $rapi_handler)
{
$data = $rapi_handler->uploadArrivePhotos($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;
}
}

View file

@ -867,14 +867,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 +913,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)) {

200
src/Entity/JOExtra.php Normal file
View file

@ -0,0 +1,200 @@
<?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 $before_speed_image_filename;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $before_plate_num_image_filename;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $before_batt_image_filename;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $after_speed_image_filename;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $after_plate_num_image_filename;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $after_batt_image_filename;
/**
* @ORM\Column(type="array", nullable=true)
*/
protected $before_other_images;
/**
* @ORM\Column(type="array", nullable=true)
*/
protected $after_other_images;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $cust_signature;
public function __construct()
{
$this->before_other_images = new ArrayCollection();
$this->after_other_images = new ArrayCollection();
}
public function getID()
{
return $this->id;
}
public function setBeforeSpeedImageFilename($image_filename)
{
$this->before_speed_image_filename = $image_filename;
return $this;
}
public function getBeforeSpeedImageFilename()
{
return $this->before_speed_image_filename;
}
public function setBeforePlateNumImageFilename($image_filename)
{
$this->before_plate_num_image_filename = $image_filename;
return $this;
}
public function getBeforePlateNumImageFilename()
{
return $this->before_plate_num_image_filename;
}
public function setBeforeBattImageFilename($image_filename)
{
$this->before_batt_image_filename = $image_filename;
return $this;
}
public function getBeforeBattImageFilename()
{
return $this->before_batt_image_filename;
}
public function setAfterSpeedImageFilename($image_filename)
{
$this->after_speed_image_filename = $image_filename;
return $this;
}
public function getAfterSpeedImageFilename()
{
return $this->after_speed_image_filename;
}
public function setAfterPlateNumImageFilename($image_filename)
{
$this->after_plate_num_image_filename = $image_filename;
return $this;
}
public function getAfterPlateNumImageFilename()
{
return $this->after_plate_num_image_filename;
}
public function setAfterBattImageFilename($image_filename)
{
$this->after_batt_image_filename = $image_filename;
return $this;
}
public function getAfterBattImageFilename()
{
return $this->after_batt_image_filename;
}
public function getBeforeOtherImages()
{
return $this->before_other_images;
}
public function setBeforeOtherImages(array $images)
{
$this->before_other_images = new ArrayCollection();
foreach ($images as $image_filename)
{
$this->before_other_images->add($image_filename);
}
return $this;
}
public function clearBeforeOtherImages()
{
$this->before_other_images = new ArrayCollection();
return $this;
}
public function getAfterOtherImages()
{
return $this->after_other_images;
}
public function setAfterOtherImages(array $images)
{
$this->after_other_images = new ArrayCollection();
foreach ($images as $image_filename)
{
$this->after_other_images->add($image_filename);
}
return $this;
}
public function clearAfterOtherImages()
{
$this->after_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;
}
}

View file

@ -334,6 +334,18 @@ 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;
public function __construct()
{
$this->date_create = new DateTime();
@ -583,6 +595,7 @@ class JobOrder
{
// TODO: validate status
$this->status = $status;
$this->date_status_change = new DateTime();
return $this;
}
@ -596,6 +609,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 +814,11 @@ class JobOrder
$this->makeRiderAvailable();
}
public function perform()
{
$this->setStatus(JOStatus::PERFORMED);
}
public function fulfill()
{
$this->setStatus(JOStatus::FULFILLED)
@ -962,5 +985,15 @@ 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;
}
}

View file

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

View 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'
];
}

View file

@ -0,0 +1,38 @@
<?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 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',
];
}

View file

@ -5,12 +5,16 @@ 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 COLLECTION = [
'cash' => 'Cash',
'shopee' => 'Shopee',
'lazada' => 'Lazada',
'credit_card' => 'Credit Card',
'bank_transfer' => 'Bank Transfer',
'online_transfer' => 'Online Transfer',
];
}

View file

@ -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',
];

View 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;
}
}

View file

@ -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('')

View file

@ -416,7 +416,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
return $error_array;
}
public function processOneStepJobOrder(Request $req, $id)
public function processOneStepJobOrder(Request $req, $id, MQTTClient $mclient)
{
// initialize error list
$error_array = [];
@ -424,11 +424,16 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$em = $this->em;
$jo = $em->getRepository(JobOrder::class)->find($id);
$old_rider = null;
if (empty($jo))
{
// new job order
$jo = new JobOrder();
}
else
{
$old_rider = $jo->getRider();
}
// check if lat and lng are provided
if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) {
@ -438,19 +443,19 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
// check if new customer
if ($req->request->get('new_customer', false))
{
if (empty($req->request->get('customer_customer_notes')))
if (empty($req->request->get('customer_notes')))
{
$error_array['customer_customer_notes'] = 'Customer notes cannot be null.';
$error_array['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 +469,17 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$new_cust = new Customer();
$new_cv = new CustomerVehicle();
$new_cust->setLastName($req->request->get('customer_last_name'))
->setFirstName($req->request->get('customer_first_name'))
->setPhoneMobile($req->request->get('customer_phone_mobile'))
->setPhoneLandline($req->request->get('customer_phone_landline'))
->setPhoneOffice($req->request->get('customer_phone_office'))
->setPhoneFax($req->request->get('customer_phone_fax'))
->setCustomerNotes($req->request->get('customer_customer_notes'));
$new_cust->setLastName($req->request->get('last_name'))
->setFirstName($req->request->get('first_name'))
->setPhoneMobile($req->request->get('phone_mobile'))
->setPhoneLandline($req->request->get('phone_landline'))
->setPhoneOffice($req->request->get('phone_office'))
->setPhoneFax($req->request->get('phone_fax'))
->setCustomerNotes($req->request->get('customer_notes'));
$new_cv->setCustomer($new_cust)
->setVehicle($new_vehicle)
->setPlateNumber($req->request->get('cv_plate'))
->setPlateNumber(trim($req->request->get('plate_number')))
->setModelYear($req->request->get('cv_year'))
->setColor('')
->setStatusCondition('')
@ -544,24 +549,15 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
if (empty($rider)) {
$error_array['rider'] = 'Invalid rider specified.';
} else {
// check if rider is still available
if (!($rider->isAvailable()))
$error_array['rider'] = 'Selected rider is unavailable.';
}
}
}
}
// set priority based on rider's existing open job orders
$rider_jos = $rider->getOpenJobOrders();
// get maximum priority then add 1
// NOTE: this can be a bit buggy due to concurrency issues
// ideally have to lock jo table, but that isn't feasible right now
$priority = 0;
foreach ($rider_jos as $rider_jo)
{
if ($priority < $rider_jo->getPriority())
$priority = $rider_jo->getPriority() + 1;
}
// get discount and set to meta
$discount = $req->request->get('invoice_discount', []);
@ -574,6 +570,19 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
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();
@ -661,6 +670,19 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$em->persist($event);
$em->flush();
// check if JO has been reassigned
if ($old_rider != $rider)
{
// TODO: refactor later
$channel = 'rider/' . $rider->getID() . '/events';
$payload = [
'event' => 'new_jo',
'jo_id' => $jo->getID(),
];
$mclient->publish($channel, json_encode($payload));
}
}
}
@ -2457,19 +2479,19 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
// check if new customer
if ($req->request->get('new_customer', false))
{
if (empty($req->request->get('customer_customer_notes')))
if (empty($req->request->get('customer_notes')))
{
$error_array['customer_customer_notes'] = 'Customer notes cannot be null.';
$error_array['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 +2506,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('')

View file

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

File diff suppressed because it is too large Load diff

View file

@ -45,7 +45,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,
@ -58,7 +58,7 @@ function initEventHandler(dashmap) {
},
};
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 +94,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>

View file

@ -92,57 +92,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>
@ -184,11 +184,11 @@
</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">
@ -415,7 +415,6 @@
<th>Branch</th>
<th>Contact Numbers</th>
<th>Distance in KM</th>
<th>Action</th>
</tr>
</thead>
<tbody id="nearest_hubs">
@ -425,7 +424,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 +460,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>
@ -753,6 +750,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 +763,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 +803,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 +842,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 +876,9 @@ $(function() {
});
osm_map.on('click', function(e) {
// clear selected hub and riders
selected_hub = '';
selected_rider = '';
selectPoint(e.latlng.lat, e.latlng.lng);
});
@ -931,7 +955,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>';
}

View file

@ -92,57 +92,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>
@ -184,11 +184,11 @@
</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">
@ -357,8 +357,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 +365,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>

View file

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