Compare commits
No commits in common. "master" and "781-fix-character-length-for-motolite-events-title" have entirely different histories.
master
...
781-fix-ch
96 changed files with 636 additions and 6011 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -12,6 +12,3 @@
|
||||||
|
|
||||||
*.swp
|
*.swp
|
||||||
/public/warranty_uploads/*
|
/public/warranty_uploads/*
|
||||||
.vscode
|
|
||||||
*__pycache__
|
|
||||||
/public/assets/images/insurance-premiums.png
|
|
||||||
|
|
@ -634,45 +634,6 @@ catalyst_auth:
|
||||||
- id: service_offering.delete
|
- id: service_offering.delete
|
||||||
label: Delete
|
label: Delete
|
||||||
|
|
||||||
- id: price_tier
|
|
||||||
label: Price Tier
|
|
||||||
acls:
|
|
||||||
- id: price_tier.menu
|
|
||||||
label: Menu
|
|
||||||
- id: price_tier.list
|
|
||||||
label: List
|
|
||||||
- id: price_tier.add
|
|
||||||
label: Add
|
|
||||||
- id: price_tier.update
|
|
||||||
label: Update
|
|
||||||
- id: price_tier.delete
|
|
||||||
label: Delete
|
|
||||||
|
|
||||||
- id: item_type
|
|
||||||
label: Item Type
|
|
||||||
acls:
|
|
||||||
- id: item_type.menu
|
|
||||||
label: Menu
|
|
||||||
- id: item_type.list
|
|
||||||
label: List
|
|
||||||
- id: item_type.add
|
|
||||||
label: Add
|
|
||||||
- id: item_type.update
|
|
||||||
label: Update
|
|
||||||
- id: item_type.delete
|
|
||||||
label: Delete
|
|
||||||
|
|
||||||
- id: item
|
|
||||||
label: Item
|
|
||||||
acls:
|
|
||||||
- id: item.menu
|
|
||||||
label: Menu
|
|
||||||
- id: item_pricing
|
|
||||||
label: Item Pricing
|
|
||||||
acls:
|
|
||||||
- id: item_pricing.update
|
|
||||||
label: Update
|
|
||||||
|
|
||||||
api:
|
api:
|
||||||
user_entity: "App\\Entity\\ApiUser"
|
user_entity: "App\\Entity\\ApiUser"
|
||||||
acl_data:
|
acl_data:
|
||||||
|
|
@ -751,16 +712,6 @@ catalyst_auth:
|
||||||
acls:
|
acls:
|
||||||
- id: warrantyserial.upload
|
- id: warrantyserial.upload
|
||||||
label: Upload
|
label: Upload
|
||||||
- id: hub
|
|
||||||
label: Hub Access
|
|
||||||
acls:
|
|
||||||
- id: hub.list
|
|
||||||
label: List
|
|
||||||
- id: joborder
|
|
||||||
label: Job Order Access
|
|
||||||
acls:
|
|
||||||
- id: joborder.find
|
|
||||||
label: Find Job Order
|
|
||||||
|
|
||||||
- id: tapi_vmanufacturer
|
- id: tapi_vmanufacturer
|
||||||
label: Third Party Vehicle Manufacturer Access
|
label: Third Party Vehicle Manufacturer Access
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ catalyst_menu:
|
||||||
acl: support.menu
|
acl: support.menu
|
||||||
label: '[menu.support]'
|
label: '[menu.support]'
|
||||||
icon: flaticon-support
|
icon: flaticon-support
|
||||||
order: 11
|
order: 10
|
||||||
- id: customer_list
|
- id: customer_list
|
||||||
acl: customer.list
|
acl: customer.list
|
||||||
label: '[menu.support.customers]'
|
label: '[menu.support.customers]'
|
||||||
|
|
@ -223,7 +223,7 @@ catalyst_menu:
|
||||||
acl: service.menu
|
acl: service.menu
|
||||||
label: '[menu.service]'
|
label: '[menu.service]'
|
||||||
icon: flaticon-squares
|
icon: flaticon-squares
|
||||||
order: 12
|
order: 11
|
||||||
- id: service_list
|
- id: service_list
|
||||||
acl: service.list
|
acl: service.list
|
||||||
label: '[menu.service.services]'
|
label: '[menu.service.services]'
|
||||||
|
|
@ -233,7 +233,7 @@ catalyst_menu:
|
||||||
acl: partner.menu
|
acl: partner.menu
|
||||||
label: '[menu.partner]'
|
label: '[menu.partner]'
|
||||||
icon: flaticon-network
|
icon: flaticon-network
|
||||||
order: 13
|
order: 12
|
||||||
- id: partner_list
|
- id: partner_list
|
||||||
acl: partner.list
|
acl: partner.list
|
||||||
label: '[menu.partner.partners]'
|
label: '[menu.partner.partners]'
|
||||||
|
|
@ -247,7 +247,7 @@ catalyst_menu:
|
||||||
acl: motolite_event.menu
|
acl: motolite_event.menu
|
||||||
label: '[menu.motolite_event]'
|
label: '[menu.motolite_event]'
|
||||||
icon: flaticon-event-calendar-symbol
|
icon: flaticon-event-calendar-symbol
|
||||||
order: 14
|
order: 13
|
||||||
- id: motolite_event_list
|
- id: motolite_event_list
|
||||||
acl: motolite_event.list
|
acl: motolite_event.list
|
||||||
label: '[menu.motolite_event.events]'
|
label: '[menu.motolite_event.events]'
|
||||||
|
|
@ -257,7 +257,7 @@ catalyst_menu:
|
||||||
acl: analytics.menu
|
acl: analytics.menu
|
||||||
label: '[menu.analytics]'
|
label: '[menu.analytics]'
|
||||||
icon: flaticon-graphic
|
icon: flaticon-graphic
|
||||||
order: 15
|
order: 14
|
||||||
- id: analytics_forecast_form
|
- id: analytics_forecast_form
|
||||||
acl: analytics.forecast
|
acl: analytics.forecast
|
||||||
label: '[menu.analytics.forecasting]'
|
label: '[menu.analytics.forecasting]'
|
||||||
|
|
@ -267,7 +267,7 @@ catalyst_menu:
|
||||||
acl: database.menu
|
acl: database.menu
|
||||||
label: '[menu.database]'
|
label: '[menu.database]'
|
||||||
icon: fa fa-database
|
icon: fa fa-database
|
||||||
order: 16
|
order: 15
|
||||||
- id: ticket_type_list
|
- id: ticket_type_list
|
||||||
acl: ticket_type.menu
|
acl: ticket_type.menu
|
||||||
label: '[menu.database.tickettypes]'
|
label: '[menu.database.tickettypes]'
|
||||||
|
|
@ -288,21 +288,3 @@ catalyst_menu:
|
||||||
acl: service_offering.menu
|
acl: service_offering.menu
|
||||||
label: '[menu.database.serviceofferings]'
|
label: '[menu.database.serviceofferings]'
|
||||||
parent: database
|
parent: database
|
||||||
- id: item_type_list
|
|
||||||
acl: item_type.menu
|
|
||||||
label: '[menu.database.itemtypes]'
|
|
||||||
parent: database
|
|
||||||
|
|
||||||
- id: item
|
|
||||||
acl: item.menu
|
|
||||||
label: Item Management
|
|
||||||
icon: fa fa-boxes
|
|
||||||
order: 10
|
|
||||||
- id: price_tier_list
|
|
||||||
acl: price_tier.list
|
|
||||||
label: Price Tiers
|
|
||||||
parent: item
|
|
||||||
- id: item_pricing
|
|
||||||
acl: item_pricing.update
|
|
||||||
label: Item Pricing
|
|
||||||
parent: item
|
|
||||||
|
|
|
||||||
|
|
@ -303,13 +303,3 @@ apiv2_insurance_application_create:
|
||||||
path: /apiv2/insurance/application
|
path: /apiv2/insurance/application
|
||||||
controller: App\Controller\CustomerAppAPI\InsuranceController::createApplication
|
controller: App\Controller\CustomerAppAPI\InsuranceController::createApplication
|
||||||
methods: [POST]
|
methods: [POST]
|
||||||
|
|
||||||
apiv2_insurance_premiums_banner:
|
|
||||||
path: /apiv2/insurance/premiums_banner
|
|
||||||
controller: App\Controller\CustomerAppAPI\InsuranceController::getPremiumsBanner
|
|
||||||
methods: [GET]
|
|
||||||
|
|
||||||
apiv2_insurance_body_types:
|
|
||||||
path: /apiv2/insurance/body_types
|
|
||||||
controller: App\Controller\CustomerAppAPI\InsuranceController::getBodyTypes
|
|
||||||
methods: [GET]
|
|
||||||
|
|
@ -194,16 +194,3 @@ capi_warranty_serial_upload:
|
||||||
path: /capi/warranty_serial/upload
|
path: /capi/warranty_serial/upload
|
||||||
controller: App\Controller\CAPI\WarrantySerialController::uploadWarrantySerialFile
|
controller: App\Controller\CAPI\WarrantySerialController::uploadWarrantySerialFile
|
||||||
methods: [POST]
|
methods: [POST]
|
||||||
|
|
||||||
# pullout form system
|
|
||||||
# hub
|
|
||||||
capi_hub_list:
|
|
||||||
path: /capi/hubs
|
|
||||||
controller: App\Controller\CAPI\HubController::getAll
|
|
||||||
methods: [GET]
|
|
||||||
|
|
||||||
# job order details
|
|
||||||
capi_job_order:
|
|
||||||
path: /capi/job_order/{id}
|
|
||||||
controller: App\Controller\CAPI\JobOrderController::getJobOrder
|
|
||||||
methods: [GET]
|
|
||||||
|
|
|
||||||
|
|
@ -94,24 +94,3 @@ capi_rider_jo_start:
|
||||||
path: /rider_api/start
|
path: /rider_api/start
|
||||||
controller: App\Controller\CAPI\RiderAppController::startJobOrder
|
controller: App\Controller\CAPI\RiderAppController::startJobOrder
|
||||||
methods: [POST]
|
methods: [POST]
|
||||||
|
|
||||||
# trade-ins
|
|
||||||
capi_rider_battery_sizes:
|
|
||||||
path: /rider_api/battery_sizes
|
|
||||||
controller: App\Controller\CAPI\RiderAppController::getBatterySizes
|
|
||||||
methods: [GET]
|
|
||||||
|
|
||||||
capi_rider_trade_in_types:
|
|
||||||
path: /rider_api/trade_in_types
|
|
||||||
controller: App\Controller\CAPI\RiderAppController::getTradeInTypes
|
|
||||||
methods: [GET]
|
|
||||||
|
|
||||||
capi_rider_battery_info:
|
|
||||||
path: /rider_api/battery/{serial}
|
|
||||||
controller: App\Controller\CAPI\RiderAppController::getBatteryInfo
|
|
||||||
methods: [GET]
|
|
||||||
|
|
||||||
capi_rider_update_jo:
|
|
||||||
path: /rider_api/job_order/update
|
|
||||||
controller: App\Controller\CAPI\RiderAppController::updateJobOrder
|
|
||||||
methods: [POST]
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
item_pricing:
|
|
||||||
path: /item-pricing
|
|
||||||
controller: App\Controller\ItemPricingController::index
|
|
||||||
methods: [GET]
|
|
||||||
|
|
||||||
item_pricing_update:
|
|
||||||
path: /item-pricing
|
|
||||||
controller: App\Controller\ItemPricingController::formSubmit
|
|
||||||
methods: [POST]
|
|
||||||
|
|
||||||
item_pricing_prices:
|
|
||||||
path: /item-pricing/{pt_id}/{it_id}/prices
|
|
||||||
controller: App\Controller\ItemPricingController::itemPrices
|
|
||||||
methods: [GET]
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
item_type_list:
|
|
||||||
path: /item-types
|
|
||||||
controller: App\Controller\ItemTypeController::index
|
|
||||||
methods: [GET]
|
|
||||||
|
|
||||||
item_type_rows:
|
|
||||||
path: /item-types/rowdata
|
|
||||||
controller: App\Controller\ItemTypeController::datatableRows
|
|
||||||
methods: [POST]
|
|
||||||
|
|
||||||
item_type_add_form:
|
|
||||||
path: /item-types/newform
|
|
||||||
controller: App\Controller\ItemTypeController::addForm
|
|
||||||
methods: [GET]
|
|
||||||
|
|
||||||
item_type_add_submit:
|
|
||||||
path: /item-types
|
|
||||||
controller: App\Controller\ItemTypeController::addSubmit
|
|
||||||
methods: [POST]
|
|
||||||
|
|
||||||
item_type_update_form:
|
|
||||||
path: /item-types/{id}
|
|
||||||
controller: App\Controller\ItemTypeController::updateForm
|
|
||||||
methods: [GET]
|
|
||||||
|
|
||||||
item_type_update_submit:
|
|
||||||
path: /item-types/{id}
|
|
||||||
controller: App\Controller\ItemTypeController::updateSubmit
|
|
||||||
methods: [POST]
|
|
||||||
|
|
||||||
item_type_delete:
|
|
||||||
path: /item-types/{id}
|
|
||||||
controller: App\Controller\ItemTypeController::deleteSubmit
|
|
||||||
methods: [DELETE]
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
price_tier_list:
|
|
||||||
path: /price-tiers
|
|
||||||
controller: App\Controller\PriceTierController::index
|
|
||||||
methods: [GET]
|
|
||||||
|
|
||||||
price_tier_rows:
|
|
||||||
path: /price-tiers/rows
|
|
||||||
controller: App\Controller\PriceTierController::datatableRows
|
|
||||||
methods: [POST]
|
|
||||||
|
|
||||||
price_tier_add_form:
|
|
||||||
path: /price-tiers/newform
|
|
||||||
controller: App\Controller\PriceTierController::addForm
|
|
||||||
methods: [GET]
|
|
||||||
|
|
||||||
price_tier_add_submit:
|
|
||||||
path: /price-tiers
|
|
||||||
controller: App\Controller\PriceTierController::addSubmit
|
|
||||||
methods: [POST]
|
|
||||||
|
|
||||||
price_tier_update_form:
|
|
||||||
path: /price-tiers/{id}
|
|
||||||
controller: App\Controller\PriceTierController::updateForm
|
|
||||||
methods: [GET]
|
|
||||||
|
|
||||||
price_tier_update_submit:
|
|
||||||
path: /price-tiers/{id}
|
|
||||||
controller: App\Controller\PriceTierController::updateSubmit
|
|
||||||
methods: [POST]
|
|
||||||
|
|
||||||
price_tier_delete:
|
|
||||||
path: /price-tiers/{id}
|
|
||||||
controller: App\Controller\PriceTierController::deleteSubmit
|
|
||||||
methods: [DELETE]
|
|
||||||
|
|
@ -51,7 +51,7 @@ tapi_vehicle_make_list:
|
||||||
tapi_battery_list:
|
tapi_battery_list:
|
||||||
path: /tapi/vehicles/{vid}/compatible_batteries
|
path: /tapi/vehicles/{vid}/compatible_batteries
|
||||||
controller: App\Controller\TAPI\BatteryController::getCompatibleBatteries
|
controller: App\Controller\TAPI\BatteryController::getCompatibleBatteries
|
||||||
methods: [POST]
|
methods: [GET]
|
||||||
|
|
||||||
# promos
|
# promos
|
||||||
tapi_promo_list:
|
tapi_promo_list:
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,6 @@ parameters:
|
||||||
api_version: "%env(API_VERSION)%"
|
api_version: "%env(API_VERSION)%"
|
||||||
android_app_version: "%env(ANDROID_APP_VERSION)%"
|
android_app_version: "%env(ANDROID_APP_VERSION)%"
|
||||||
ios_app_version: "%env(IOS_APP_VERSION)%"
|
ios_app_version: "%env(IOS_APP_VERSION)%"
|
||||||
insurance_premiums_banner_url: "%env(INSURANCE_PREMIUMS_BANNER_URL)%"
|
|
||||||
enabled_hub_filters: "%env(ENABLED_HUB_FILTERS)%"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# default configuration for services in *this* file
|
# default configuration for services in *this* file
|
||||||
|
|
@ -110,12 +108,6 @@ services:
|
||||||
arguments:
|
arguments:
|
||||||
$callback_url: "%env(WARRANTY_SERIAL_CALLBACK_URL)%"
|
$callback_url: "%env(WARRANTY_SERIAL_CALLBACK_URL)%"
|
||||||
|
|
||||||
App\Command\ProcessLatePaymongoTransactionsCommand:
|
|
||||||
arguments:
|
|
||||||
$em: "@doctrine.orm.entity_manager"
|
|
||||||
$paymongo: "@App\\Service\\PayMongoConnector"
|
|
||||||
$webhook_id: "%env(PAYMONGO_WEBHOOK_ID)%"
|
|
||||||
|
|
||||||
# rider tracker service
|
# rider tracker service
|
||||||
App\Service\RiderTracker:
|
App\Service\RiderTracker:
|
||||||
arguments:
|
arguments:
|
||||||
|
|
@ -318,41 +310,3 @@ services:
|
||||||
arguments:
|
arguments:
|
||||||
$server_key: "%env(FCM_SERVER_KEY)%"
|
$server_key: "%env(FCM_SERVER_KEY)%"
|
||||||
$sender_id: "%env(FCM_SENDER_ID)%"
|
$sender_id: "%env(FCM_SENDER_ID)%"
|
||||||
|
|
||||||
# price tier manager
|
|
||||||
App\Service\PriceTierManager:
|
|
||||||
arguments:
|
|
||||||
$em: "@doctrine.orm.entity_manager"
|
|
||||||
|
|
||||||
# hub filters
|
|
||||||
App\Service\HubFilter\BaseHubFilter:
|
|
||||||
arguments:
|
|
||||||
$hub_filter_logger: "@App\\Service\\HubFilterLogger"
|
|
||||||
$em: "@doctrine.orm.entity_manager"
|
|
||||||
$rt: "@App\\Service\\RisingTideGateway"
|
|
||||||
$trans: "@Symfony\\Contracts\\Translation\\TranslatorInterface"
|
|
||||||
|
|
||||||
App\Service\HubFilter\Filters\DateAndTimeHubFilter:
|
|
||||||
public: true
|
|
||||||
|
|
||||||
App\Service\HubFilter\Filters\JoTypeHubFilter:
|
|
||||||
public: true
|
|
||||||
|
|
||||||
App\Service\HubFilter\Filters\MaxResultsHubFilter:
|
|
||||||
public: true
|
|
||||||
|
|
||||||
App\Service\HubFilter\Filters\PaymentMethodHubFilter:
|
|
||||||
public: true
|
|
||||||
|
|
||||||
App\Service\HubFilter\Filters\RiderAvailabilityHubFilter:
|
|
||||||
public: true
|
|
||||||
|
|
||||||
App\Service\HubFilter\Filters\InventoryHubFilter:
|
|
||||||
public: true
|
|
||||||
arguments:
|
|
||||||
$im: "@App\\Service\\InventoryManager"
|
|
||||||
|
|
||||||
App\Service\HubFilter\Filters\RoundRobinHubFilter:
|
|
||||||
public: true
|
|
||||||
arguments:
|
|
||||||
$hub_distributor: "@App\\Service\\HubDistributor"
|
|
||||||
|
|
|
||||||
|
|
@ -1,136 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Command;
|
|
||||||
|
|
||||||
use Symfony\Component\Console\Command\Command;
|
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
|
|
||||||
use App\Ramcar\TransactionStatus;
|
|
||||||
use App\Entity\GatewayTransaction;
|
|
||||||
use App\Service\PayMongoConnector;
|
|
||||||
|
|
||||||
use DateTime;
|
|
||||||
|
|
||||||
class ProcessLatePaymongoTransactionsCommand extends Command
|
|
||||||
{
|
|
||||||
protected $em;
|
|
||||||
protected $paymongo;
|
|
||||||
|
|
||||||
protected $webhook_id;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, PayMongoConnector $paymongo, $webhook_id)
|
|
||||||
{
|
|
||||||
$this->em = $em;
|
|
||||||
$this->paymongo = $paymongo;
|
|
||||||
$this->webhook_id = $webhook_id;
|
|
||||||
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function configure()
|
|
||||||
{
|
|
||||||
$this->setName('paymongo:checkpending')
|
|
||||||
->setDescription('Check for any late PayMongo transactions and process if needed.')
|
|
||||||
->setHelp('Check for any late PayMongo transactions and process if needed.')
|
|
||||||
->addOption('force', 'f', InputOption::VALUE_NONE, 'Ignore webhook status and process anyway.');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
|
||||||
{
|
|
||||||
$force = $input->getOption('force');
|
|
||||||
|
|
||||||
// if we aren't forcing, check webhook status first
|
|
||||||
if (!$force) {
|
|
||||||
$output->writeln('Checking webhook status...');
|
|
||||||
|
|
||||||
// check if webhook is disabled
|
|
||||||
$webhook = $this->paymongo->getWebhook($this->webhook_id);
|
|
||||||
|
|
||||||
if ($webhook['success'] && $webhook['response']['data']['attributes']['status'] === 'enabled') {
|
|
||||||
$output->writeln('<info>Webhook is enabled, no need to do anything.</info>');
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
$output->writeln('<comment>Webhook is disabled! Logging event and attempting to re-enable...</comment>');
|
|
||||||
|
|
||||||
// attempt re-enabling of webhook
|
|
||||||
$result = $this->paymongo->enableWebhook($this->webhook_id);
|
|
||||||
if ($result['success'] && $result['response']['data']['attributes']['status'] ?? null === 'enabled') {
|
|
||||||
$output->writeln('<info>Webhook ' . $this->webhook_id . ' re-enabled!</info>');
|
|
||||||
|
|
||||||
// log event
|
|
||||||
$this->paymongo->log('WEBHOOK RE-ENABLED', "[]", json_encode($result['response'], JSON_PRETTY_PRINT), 'webhook');
|
|
||||||
} else {
|
|
||||||
$output->writeln('<comment>Webhook ' . $this->webhook_id . ' could not be re-enabled.</comment>');
|
|
||||||
|
|
||||||
// log event
|
|
||||||
$this->paymongo->log('WEBHOOK FAILURE', "[]", json_encode($result['response'], JSON_PRETTY_PRINT), 'webhook');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$output->writeln('Fetching all late pending transactions...');
|
|
||||||
|
|
||||||
// set date threshold to 24 hours ago
|
|
||||||
$date_threshold = (new DateTime())->modify('-24 hours');
|
|
||||||
|
|
||||||
$transactions = $this->em->getRepository(GatewayTransaction::class)
|
|
||||||
->createQueryBuilder('t')
|
|
||||||
->select('t')
|
|
||||||
->where('t.status = :status')
|
|
||||||
->andWhere('t.date_create <= :date_threshold')
|
|
||||||
->setParameter('status', TransactionStatus::PENDING)
|
|
||||||
->setParameter('date_threshold', $date_threshold)
|
|
||||||
->getQuery()
|
|
||||||
->getResult();
|
|
||||||
|
|
||||||
$output->writeln('Found '. count($transactions) . ' rows matching criteria.');
|
|
||||||
|
|
||||||
$x = 0;
|
|
||||||
|
|
||||||
foreach ($transactions as $trans) {
|
|
||||||
// check paymongo status
|
|
||||||
$checkout = $this->paymongo->getCheckout($trans->getExtTransactionId());
|
|
||||||
|
|
||||||
if ($checkout['success']) {
|
|
||||||
// check if we have any payments made
|
|
||||||
$payments = $checkout['response']['data']['attributes']['payments'] ?? [];
|
|
||||||
|
|
||||||
if (!empty($payments)) {
|
|
||||||
$amount_paid = 0;
|
|
||||||
|
|
||||||
// for good measure, we get all successful payments and add them up
|
|
||||||
foreach ($payments as $payment) {
|
|
||||||
if ($payment['attributes']['status'] === TransactionStatus::PAID) {
|
|
||||||
$amount_paid = bcadd($amount_paid, $payment['attributes']['amount']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this transaction is fully paid, so we mark it as paid
|
|
||||||
if (bccomp($trans->getAmount(), $amount_paid) <= 0) {
|
|
||||||
$trans->setStatus(TransactionStatus::PAID);
|
|
||||||
$trans->setDatePay(new DateTime());
|
|
||||||
$this->em->flush();
|
|
||||||
|
|
||||||
$output->writeln('Marked transaction '. $trans->getID() . ' as paid.');
|
|
||||||
$x++;
|
|
||||||
} else {
|
|
||||||
$output->writeln('<comment>Insufficient payment amount (' . $amount_paid . '/' . $trans->getAmount() . ') for this transaction: ' . $trans->getID() . '</comment>');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$output->writeln('<comment>No payments found for transaction: ' . $trans->getID() . '</comment>');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$output->writeln('<comment>Checkout not found: ' . $checkout['error']['message'] . '</comment>');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$output->writeln('<info>Done! Processed ' . $x . ' rows.</info>');
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -50,7 +50,6 @@ use App\Service\HubFilterLogger;
|
||||||
use App\Service\HubFilteringGeoChecker;
|
use App\Service\HubFilteringGeoChecker;
|
||||||
use App\Service\HashGenerator;
|
use App\Service\HashGenerator;
|
||||||
use App\Service\JobOrderManager;
|
use App\Service\JobOrderManager;
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
use App\Entity\MobileSession;
|
use App\Entity\MobileSession;
|
||||||
use App\Entity\Customer;
|
use App\Entity\Customer;
|
||||||
|
|
@ -2912,10 +2911,6 @@ class APIController extends Controller implements LoggedController
|
||||||
// old app doesn't have separate jumpstart
|
// old app doesn't have separate jumpstart
|
||||||
$icrit->setSource(TransactionOrigin::CALL);
|
$icrit->setSource(TransactionOrigin::CALL);
|
||||||
|
|
||||||
// set price tier
|
|
||||||
$pt_id = $this->pt_manager->getPriceTier($jo->getCoordinates());
|
|
||||||
$icrit->setPriceTier($pt_id);
|
|
||||||
|
|
||||||
// check promo
|
// check promo
|
||||||
$promo_id = $req->request->get('promo_id');
|
$promo_id = $req->request->get('promo_id');
|
||||||
if (!empty($promo_id))
|
if (!empty($promo_id))
|
||||||
|
|
|
||||||
|
|
@ -326,7 +326,7 @@ class APIRoleController extends Controller
|
||||||
protected function padAPIACLHierarchy(&$params)
|
protected function padAPIACLHierarchy(&$params)
|
||||||
{
|
{
|
||||||
// get acl keys hierarchy
|
// get acl keys hierarchy
|
||||||
$api_acl_data = $this->api_acl_gen->getACL('api');
|
$api_acl_data = $this->api_acl_gen->getACL();
|
||||||
$params['api_acl_hierarchy'] = $api_acl_data['hierarchy'];
|
$params['api_acl_hierarchy'] = $api_acl_data['hierarchy'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\CAPI;
|
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Doctrine\ORM\Query;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Catalyst\ApiBundle\Controller\ApiController;
|
|
||||||
use Catalyst\ApiBundle\Component\Response as APIResponse;
|
|
||||||
|
|
||||||
use App\Entity\Hub;
|
|
||||||
|
|
||||||
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
|
|
||||||
|
|
||||||
class HubController extends ApiController
|
|
||||||
{
|
|
||||||
protected $acl_gen;
|
|
||||||
|
|
||||||
public function __construct(ACLGenerator $acl_gen)
|
|
||||||
{
|
|
||||||
$this->acl_gen = $acl_gen;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAll(EntityManagerInterface $em)
|
|
||||||
{
|
|
||||||
// get all hub data order by name
|
|
||||||
$this->denyAccessUnlessGranted('hub.list', null, 'No access.');
|
|
||||||
|
|
||||||
$results = $em->getRepository(Hub::class)->findBy([], ['name' => 'ASC']);
|
|
||||||
|
|
||||||
$hubs = [];
|
|
||||||
foreach($results as $res)
|
|
||||||
{
|
|
||||||
$hub_id = $res->getId();
|
|
||||||
$hub_name = $res->getName();
|
|
||||||
$hub_address = $res->getAddress();
|
|
||||||
$hub_branch_code = $res->getBranchCode();
|
|
||||||
|
|
||||||
$hubs[$hub_id] = [
|
|
||||||
'id' => $hub_id,
|
|
||||||
'name' => $hub_name,
|
|
||||||
'address' => $hub_address,
|
|
||||||
'branch_code' => $hub_branch_code,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
'hubs' => $hubs,
|
|
||||||
];
|
|
||||||
return new APIResponse(true, 'Hubs loaded.', $data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,139 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\CAPI;
|
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Doctrine\ORM\Query;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Catalyst\ApiBundle\Controller\ApiController;
|
|
||||||
use Catalyst\ApiBundle\Component\Response as APIResponse;
|
|
||||||
|
|
||||||
use App\Entity\JobOrder;
|
|
||||||
use App\Entity\Warranty;
|
|
||||||
|
|
||||||
use App\Ramcar\JOStatus;
|
|
||||||
|
|
||||||
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
|
|
||||||
|
|
||||||
class JobOrderController extends ApiController
|
|
||||||
{
|
|
||||||
protected $acl_gen;
|
|
||||||
|
|
||||||
public function __construct(ACLGenerator $acl_gen)
|
|
||||||
{
|
|
||||||
$this->acl_gen = $acl_gen;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getJobOrder($id, EntityManagerInterface $em)
|
|
||||||
{
|
|
||||||
$this->denyAccessUnlessGranted('joborder.find', null, 'No access.');
|
|
||||||
|
|
||||||
$jo = $em->getRepository(JobOrder::class)->find($id);
|
|
||||||
|
|
||||||
if ($jo == null)
|
|
||||||
return new APIResponse(false, 'No job order found with that number.', null, 404);
|
|
||||||
|
|
||||||
$data = $this->generateJobOrderData($jo, $em);
|
|
||||||
|
|
||||||
return new APIResponse(true, 'Job order found.', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function generateJobOrderData($jo, EntityManagerInterface $em)
|
|
||||||
{
|
|
||||||
// customer vehicle
|
|
||||||
$cv = $jo->getCustomerVehicle();
|
|
||||||
|
|
||||||
// customer information
|
|
||||||
$customer = $jo->getCustomer();
|
|
||||||
|
|
||||||
// hub
|
|
||||||
$hub_name = '';
|
|
||||||
$hub = $jo->getHub();
|
|
||||||
if ($hub != null)
|
|
||||||
$hub_name = $hub->getName();
|
|
||||||
|
|
||||||
// check if JO is fulfilled, if not, we leave date_purchase blank
|
|
||||||
$date_purchase = '';
|
|
||||||
$serial = '';
|
|
||||||
$status = $jo->getStatus();
|
|
||||||
if ($status == JOStatus::FULFILLED)
|
|
||||||
{
|
|
||||||
if ($jo->getDateFulfill() != null)
|
|
||||||
$date_purchase = $jo->getDateFulfill()->format('M d, Y H:i');
|
|
||||||
|
|
||||||
// find warranty to get the serial using plate number
|
|
||||||
$serial = $this->getSerialFromWarranty($cv->getPlateNumber(), $em);
|
|
||||||
}
|
|
||||||
|
|
||||||
$jo_data = [
|
|
||||||
'id' => $jo->getID(),
|
|
||||||
'first_name' => $customer->getFirstName(),
|
|
||||||
'last_name' => $customer->getLastName(),
|
|
||||||
'mobile_number' => $customer->getPhoneMobile(),
|
|
||||||
'email' => $customer->getEmail(),
|
|
||||||
'plate_number' => $cv->getPlateNumber(),
|
|
||||||
'date_purchase' => $date_purchase,
|
|
||||||
'address' => $jo->getDeliveryAddress(),
|
|
||||||
'hub' => $hub_name,
|
|
||||||
'serial' => $serial,
|
|
||||||
];
|
|
||||||
|
|
||||||
// invoice items
|
|
||||||
$items = [];
|
|
||||||
$jo_items = $jo->getInvoice()->getItems();
|
|
||||||
$non_battery_item_titles = ['Promo discount', 'Trade-in', 'Service'];
|
|
||||||
foreach ($jo_items as $item)
|
|
||||||
{
|
|
||||||
$item_title = $item->getTitle();
|
|
||||||
|
|
||||||
// check if title has Promo discount, Trade-in, or Service
|
|
||||||
$flag_battery = $this->checkIfBatteryInvoiceItem($item_title, $non_battery_item_titles);
|
|
||||||
if ($flag_battery == true)
|
|
||||||
{
|
|
||||||
$items[] = [
|
|
||||||
'title' => $item->getTitle(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$jo_data['items'] = $items;
|
|
||||||
|
|
||||||
return $jo_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function checkIfBatteryInvoiceItem($item_title, $non_battery_item_titles)
|
|
||||||
{
|
|
||||||
foreach ($non_battery_item_titles as $nb_item_title)
|
|
||||||
{
|
|
||||||
$pos_result = stripos($item_title, $nb_item_title);
|
|
||||||
|
|
||||||
// if found, invoice item is not a battery item
|
|
||||||
if ($pos_result !== false)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getSerialFromWarranty($plate_number, EntityManagerInterface $em)
|
|
||||||
{
|
|
||||||
// NOTE: Modify the search for the latest warranty. This seems hacky.
|
|
||||||
// get latest warranty using plate number
|
|
||||||
$warranty_results = $em->getRepository(Warranty::class)->findBy(
|
|
||||||
['plate_number' => $plate_number],
|
|
||||||
['date_create' => 'desc']
|
|
||||||
);
|
|
||||||
|
|
||||||
$serial = '';
|
|
||||||
if (!empty($warranty_results))
|
|
||||||
{
|
|
||||||
// get first entry
|
|
||||||
$warranty = current($warranty_results);
|
|
||||||
|
|
||||||
$serial = $warranty->getSerial();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $serial;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -23,9 +23,7 @@ use App\Entity\BatterySize;
|
||||||
use App\Entity\RiderAPISession;
|
use App\Entity\RiderAPISession;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Entity\ApiUser as APIUser;
|
use App\Entity\ApiUser as APIUser;
|
||||||
use App\Entity\JobOrder;
|
|
||||||
use App\Entity\SAPBattery;
|
|
||||||
use App\Entity\WarrantySerial;
|
|
||||||
use App\Service\RedisClientProvider;
|
use App\Service\RedisClientProvider;
|
||||||
use App\Service\RiderCache;
|
use App\Service\RiderCache;
|
||||||
use App\Service\MQTTClient;
|
use App\Service\MQTTClient;
|
||||||
|
|
@ -36,7 +34,6 @@ use App\Service\JobOrderHandlerInterface;
|
||||||
use App\Service\InvoiceGeneratorInterface;
|
use App\Service\InvoiceGeneratorInterface;
|
||||||
use App\Service\RisingTideGateway;
|
use App\Service\RisingTideGateway;
|
||||||
use App\Service\RiderTracker;
|
use App\Service\RiderTracker;
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
use App\Ramcar\ServiceType;
|
use App\Ramcar\ServiceType;
|
||||||
use App\Ramcar\TradeInType;
|
use App\Ramcar\TradeInType;
|
||||||
|
|
@ -289,9 +286,8 @@ class RiderAppController extends ApiController
|
||||||
|
|
||||||
// do we have a job order?
|
// do we have a job order?
|
||||||
// $jo = $rider->getActiveJobOrder();
|
// $jo = $rider->getActiveJobOrder();
|
||||||
// NOTE: we do not include job orders that have been cancelled
|
|
||||||
$jo = $rider->getCurrentJobOrder();
|
$jo = $rider->getCurrentJobOrder();
|
||||||
if ($jo == null || $jo->getStatus() == JOStatus::CANCELLED)
|
if ($jo == null)
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
'job_order' => null
|
'job_order' => null
|
||||||
|
|
@ -386,7 +382,6 @@ class RiderAppController extends ApiController
|
||||||
'flag_coolant' => $jo->hasCoolant(),
|
'flag_coolant' => $jo->hasCoolant(),
|
||||||
'has_motolite' => $cv->hasMotoliteBattery(),
|
'has_motolite' => $cv->hasMotoliteBattery(),
|
||||||
'delivery_status' => $jo->getDeliveryStatus(),
|
'delivery_status' => $jo->getDeliveryStatus(),
|
||||||
'flag_sealant' => $jo->hasSealant(),
|
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
@ -413,11 +408,6 @@ class RiderAppController extends ApiController
|
||||||
if (!empty($msg))
|
if (!empty($msg))
|
||||||
return new APIResponse(false, $msg);
|
return new APIResponse(false, $msg);
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: refactor this into a jo handler class, so we don't have to repeat for control center
|
// TODO: refactor this into a jo handler class, so we don't have to repeat for control center
|
||||||
|
|
||||||
// set jo status to in transit
|
// set jo status to in transit
|
||||||
|
|
@ -468,11 +458,6 @@ class RiderAppController extends ApiController
|
||||||
// TODO: this is a workaround for requeue, because rider app gets stuck in accept / decline screen
|
// TODO: this is a workaround for requeue, because rider app gets stuck in accept / decline screen
|
||||||
return new APIResponse(true, $msg);
|
return new APIResponse(true, $msg);
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// requeue it, instead of cancelling it
|
// requeue it, instead of cancelling it
|
||||||
$jo->requeue();
|
$jo->requeue();
|
||||||
|
|
||||||
|
|
@ -531,11 +516,6 @@ class RiderAppController extends ApiController
|
||||||
// get rider's current job order
|
// get rider's current job order
|
||||||
$jo = $rider->getCurrentJobOrder();
|
$jo = $rider->getCurrentJobOrder();
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// set delivery status
|
// set delivery status
|
||||||
$jo->setDeliveryStatus(DeliveryStatus::RIDER_DEPART_HUB);
|
$jo->setDeliveryStatus(DeliveryStatus::RIDER_DEPART_HUB);
|
||||||
|
|
||||||
|
|
@ -576,11 +556,6 @@ class RiderAppController extends ApiController
|
||||||
// get rider's current job order
|
// get rider's current job order
|
||||||
$jo = $rider->getCurrentJobOrder();
|
$jo = $rider->getCurrentJobOrder();
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// set delivery status
|
// set delivery status
|
||||||
$jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE_HUB_PRE_JO);
|
$jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE_HUB_PRE_JO);
|
||||||
|
|
||||||
|
|
@ -621,11 +596,6 @@ class RiderAppController extends ApiController
|
||||||
// get rider's current job order
|
// get rider's current job order
|
||||||
$jo = $rider->getCurrentJobOrder();
|
$jo = $rider->getCurrentJobOrder();
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// set delivery status
|
// set delivery status
|
||||||
$jo->setDeliveryStatus(DeliveryStatus::RIDER_DEPART_HUB_PRE_JO);
|
$jo->setDeliveryStatus(DeliveryStatus::RIDER_DEPART_HUB_PRE_JO);
|
||||||
|
|
||||||
|
|
@ -666,11 +636,6 @@ class RiderAppController extends ApiController
|
||||||
// get rider's current job order
|
// get rider's current job order
|
||||||
$jo = $rider->getCurrentJobOrder();
|
$jo = $rider->getCurrentJobOrder();
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// set delivery status
|
// set delivery status
|
||||||
$jo->setDeliveryStatus(DeliveryStatus::RIDER_START);
|
$jo->setDeliveryStatus(DeliveryStatus::RIDER_START);
|
||||||
|
|
||||||
|
|
@ -712,11 +677,6 @@ class RiderAppController extends ApiController
|
||||||
// set jo status to in progress
|
// set jo status to in progress
|
||||||
$jo->setStatus(JOStatus::IN_PROGRESS);
|
$jo->setStatus(JOStatus::IN_PROGRESS);
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// set delivery status
|
// set delivery status
|
||||||
$jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE);
|
$jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE);
|
||||||
|
|
||||||
|
|
@ -775,11 +735,6 @@ class RiderAppController extends ApiController
|
||||||
// get rider's current job order
|
// get rider's current job order
|
||||||
$jo = $rider->getCurrentJobOrder();
|
$jo = $rider->getCurrentJobOrder();
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// set delivery status
|
// set delivery status
|
||||||
$jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE_HUB);
|
$jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE_HUB);
|
||||||
|
|
||||||
|
|
@ -803,54 +758,6 @@ class RiderAppController extends ApiController
|
||||||
return new APIResponse(true, 'Rider arrive at hub.', $data);
|
return new APIResponse(true, 'Rider arrive at hub.', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBatterySizes(Request $req, EntityManagerInterface $em)
|
|
||||||
{
|
|
||||||
// get capi user
|
|
||||||
$capi_user = $this->getUser();
|
|
||||||
if ($capi_user == null)
|
|
||||||
return new APIResponse(false, 'User not found.');
|
|
||||||
|
|
||||||
// get rider id from capi user metadata
|
|
||||||
$rider = $this->getRiderFromCAPI($capi_user, $em);
|
|
||||||
if ($rider == null)
|
|
||||||
return new APIResponse(false, 'No rider found.');
|
|
||||||
|
|
||||||
// get sizes
|
|
||||||
$qb = $em->getRepository(BatterySize::class)
|
|
||||||
->createQueryBuilder('bs');
|
|
||||||
|
|
||||||
$sizes = $qb->select('bs.id, bs.name')
|
|
||||||
->orderBy('bs.name', 'asc')
|
|
||||||
->getQuery()
|
|
||||||
->getResult();
|
|
||||||
|
|
||||||
// response
|
|
||||||
return new APIResponse(true, '', [
|
|
||||||
'sizes' => $sizes,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTradeInTypes(Request $req, EntityManagerInterface $em)
|
|
||||||
{
|
|
||||||
// get capi user
|
|
||||||
$capi_user = $this->getUser();
|
|
||||||
if ($capi_user == null)
|
|
||||||
return new APIResponse(false, 'User not found.');
|
|
||||||
|
|
||||||
// get rider id from capi user metadata
|
|
||||||
$rider = $this->getRiderFromCAPI($capi_user, $em);
|
|
||||||
if ($rider == null)
|
|
||||||
return new APIResponse(false, 'No rider found.');
|
|
||||||
|
|
||||||
// get trade-in types
|
|
||||||
$types = TradeInType::getCollection();
|
|
||||||
|
|
||||||
// response
|
|
||||||
return new APIResponse(true, '', [
|
|
||||||
'types' => $types,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function payment(Request $req, EntityManagerInterface $em, JobOrderHandlerInterface $jo_handler,
|
public function payment(Request $req, EntityManagerInterface $em, JobOrderHandlerInterface $jo_handler,
|
||||||
RisingTideGateway $rt, WarrantyHandler $wh, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient, TranslatorInterface $translator)
|
RisingTideGateway $rt, WarrantyHandler $wh, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient, TranslatorInterface $translator)
|
||||||
{
|
{
|
||||||
|
|
@ -870,22 +777,6 @@ class RiderAppController extends ApiController
|
||||||
if (!empty($msg))
|
if (!empty($msg))
|
||||||
return new APIResponse(false, $msg);
|
return new APIResponse(false, $msg);
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// need to check if service type is battery sales
|
|
||||||
// if so, serial is a required parameter
|
|
||||||
$serial = $req->request->get('serial', '');
|
|
||||||
if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if (empty($serial))
|
|
||||||
return new APIResponse(false, 'Missing parameter(s): serial');
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// set invoice to paid
|
// set invoice to paid
|
||||||
$jo->getInvoice()->setStatus(InvoiceStatus::PAID);
|
$jo->getInvoice()->setStatus(InvoiceStatus::PAID);
|
||||||
|
|
||||||
|
|
@ -937,6 +828,7 @@ class RiderAppController extends ApiController
|
||||||
// create warranty
|
// create warranty
|
||||||
if($jo_handler->checkIfNewBattery($jo))
|
if($jo_handler->checkIfNewBattery($jo))
|
||||||
{
|
{
|
||||||
|
$serial = null;
|
||||||
$warranty_class = $jo->getWarrantyClass();
|
$warranty_class = $jo->getWarrantyClass();
|
||||||
$first_name = $jo->getCustomer()->getFirstName();
|
$first_name = $jo->getCustomer()->getFirstName();
|
||||||
$last_name = $jo->getCustomer()->getLastName();
|
$last_name = $jo->getCustomer()->getLastName();
|
||||||
|
|
@ -1020,11 +912,6 @@ class RiderAppController extends ApiController
|
||||||
// get rider's current job order
|
// get rider's current job order
|
||||||
$jo = $rider->getCurrentJobOrder();
|
$jo = $rider->getCurrentJobOrder();
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// set delivery status
|
// set delivery status
|
||||||
$jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE_HUB_POST_JO);
|
$jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE_HUB_POST_JO);
|
||||||
|
|
||||||
|
|
@ -1066,11 +953,6 @@ class RiderAppController extends ApiController
|
||||||
// get rider's current job order
|
// get rider's current job order
|
||||||
$jo = $rider->getCurrentJobOrder();
|
$jo = $rider->getCurrentJobOrder();
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// set delivery status
|
// set delivery status
|
||||||
$jo->setDeliveryStatus(DeliveryStatus::RIDER_DEPART_HUB_POST_JO);
|
$jo->setDeliveryStatus(DeliveryStatus::RIDER_DEPART_HUB_POST_JO);
|
||||||
|
|
||||||
|
|
@ -1217,178 +1099,7 @@ class RiderAppController extends ApiController
|
||||||
return new APIResponse(true, 'Batteries found.', $data);
|
return new APIResponse(true, 'Batteries found.', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBatteryInfo(Request $req, $serial, EntityManagerInterface $em)
|
public function changeService(Request $req, EntityManagerInterface $em, InvoiceGeneratorInterface $ic)
|
||||||
{
|
|
||||||
if (empty($serial))
|
|
||||||
{
|
|
||||||
return new APIResponse(false, 'Missing parameter(s): serial');
|
|
||||||
}
|
|
||||||
|
|
||||||
// get capi user
|
|
||||||
$capi_user = $this->getUser();
|
|
||||||
if ($capi_user == null)
|
|
||||||
return new APIResponse(false, 'User not found.');
|
|
||||||
|
|
||||||
// get rider id from capi user metadata
|
|
||||||
$rider = $this->getRiderFromCAPI($capi_user, $em);
|
|
||||||
if ($rider == null)
|
|
||||||
return new APIResponse(false, 'No rider found.');
|
|
||||||
|
|
||||||
// find battery given serial/sap_code and flag_active is true
|
|
||||||
$serial = $em->getRepository(WarrantySerial::class)->find($serial);
|
|
||||||
|
|
||||||
if (empty($serial)) {
|
|
||||||
return new APIResponse(false, 'Warranty serial number not found.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$sap_battery = $em->getRepository(SAPBattery::class)->find($serial->getSKU());
|
|
||||||
|
|
||||||
if (empty($sap_battery)) {
|
|
||||||
return new APIResponse(false, 'No battery info found.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$battery = [
|
|
||||||
'id' => $sap_battery->getID(),
|
|
||||||
'brand' => $sap_battery->getBrand()->getName(),
|
|
||||||
'size' => $sap_battery->getSize()->getName(),
|
|
||||||
'size_id' => $sap_battery->getSize()->getID(),
|
|
||||||
'trade_in_type' => TradeInType::MOTOLITE,
|
|
||||||
'container_size' => $sap_battery->getContainerSize()->getName(),
|
|
||||||
];
|
|
||||||
|
|
||||||
return new APIResponse(true, 'Battery info found.', [
|
|
||||||
'battery' => $battery,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateJobOrder(Request $req, EntityManagerInterface $em, InvoiceGeneratorInterface $ic, PriceTierManager $pt_manager)
|
|
||||||
{
|
|
||||||
$items = json_decode(file_get_contents('php://input'), true);
|
|
||||||
|
|
||||||
// get job order id
|
|
||||||
if (!isset($items['jo_id']))
|
|
||||||
return new APIResponse(false, 'Missing parameter(s): jo_id');
|
|
||||||
|
|
||||||
// validate jo_id
|
|
||||||
$jo_id = $items['jo_id'];
|
|
||||||
if (empty($jo_id) || $jo_id == null)
|
|
||||||
return new APIResponse(false, 'Missing parameter(s): jo_id');
|
|
||||||
|
|
||||||
// get capi user
|
|
||||||
$capi_user = $this->getUser();
|
|
||||||
if ($capi_user == null)
|
|
||||||
return new APIResponse(false, 'User not found.');
|
|
||||||
|
|
||||||
// get rider id from capi user metadata
|
|
||||||
$rider = $this->getRiderFromCAPI($capi_user, $em);
|
|
||||||
if ($rider == null)
|
|
||||||
return new APIResponse(false, 'No rider found.');
|
|
||||||
|
|
||||||
// get the job order
|
|
||||||
$jo = $em->getRepository(JobOrder::class)->find($jo_id);
|
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if we have trade in items
|
|
||||||
$ti_items = [];
|
|
||||||
if (isset($items['trade_in_items']))
|
|
||||||
{
|
|
||||||
// validate the trade in items first
|
|
||||||
$ti_items = $items['trade_in_items'];
|
|
||||||
$msg = $this->validateTradeInItems($em, $ti_items);
|
|
||||||
if (!empty($msg))
|
|
||||||
return new APIResponse(false, $msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the service type
|
|
||||||
if (!isset($items['stype_id']))
|
|
||||||
return new APIResponse(false, 'Missing parameter(s): stype_id');
|
|
||||||
|
|
||||||
// validate service type
|
|
||||||
$stype_id = $items['stype_id'];
|
|
||||||
if (!ServiceType::validate($stype_id))
|
|
||||||
return new APIResponse(false, 'Invalid service type - ' . $stype_id);
|
|
||||||
|
|
||||||
// save service type
|
|
||||||
$jo->setServiceType($stype_id);
|
|
||||||
|
|
||||||
// validate promo if any. Promo not required
|
|
||||||
$promo = null;
|
|
||||||
if (isset($items['promo_id']))
|
|
||||||
{
|
|
||||||
$promo_id = $items['promo_id'];
|
|
||||||
$promo = $em->getRepository(Promo::class)->find($promo_id);
|
|
||||||
if ($promo == null)
|
|
||||||
return new APIResponse(false, 'Invalid promo id - ' . $promo_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get other parameters, if any: has motolite battery, has warranty doc, with coolant, payment method, with sealant
|
|
||||||
if (isset($items['flag_motolite_battery']))
|
|
||||||
{
|
|
||||||
// get customer vehicle from jo
|
|
||||||
$cv = $jo->getCustomerVehicle();
|
|
||||||
$has_motolite = $items['flag_motolite_battery'];
|
|
||||||
if ($has_motolite == 'true')
|
|
||||||
$cv->setHasMotoliteBattery(true);
|
|
||||||
else
|
|
||||||
$cv->setHasMotoliteBattery(false);
|
|
||||||
|
|
||||||
$em->persist($cv);
|
|
||||||
|
|
||||||
}
|
|
||||||
if (isset($items['flag_warranty_doc']))
|
|
||||||
{
|
|
||||||
// TODO: what do we do?
|
|
||||||
}
|
|
||||||
if (isset($items['flag_coolant']))
|
|
||||||
{
|
|
||||||
$has_coolant = $items['flag_coolant'];
|
|
||||||
if ($has_coolant == 'true')
|
|
||||||
$jo->setHasCoolant(true);
|
|
||||||
else
|
|
||||||
$jo->setHasCoolant(false);
|
|
||||||
|
|
||||||
}
|
|
||||||
if (isset($items['mode_of_payment']))
|
|
||||||
{
|
|
||||||
$payment_method = $items['payment_method'];
|
|
||||||
if (!ModeOfPayment::validate($payment_method))
|
|
||||||
$payment_method = ModeOfPayment::CASH;
|
|
||||||
$jo->setModeOfPayment($payment_method);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($items['flag_sealant']))
|
|
||||||
{
|
|
||||||
$has_sealant = $items['flag_sealant'];
|
|
||||||
if ($has_sealant == 'true')
|
|
||||||
$jo->setHasSealant(true);
|
|
||||||
else
|
|
||||||
$jo->setHasSealant(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get capi user
|
|
||||||
$capi_user = $this->getUser();
|
|
||||||
if ($capi_user == null)
|
|
||||||
return new APIResponse(false, 'User not found.');
|
|
||||||
|
|
||||||
// get rider id from capi user metadata
|
|
||||||
$rider = $this->getRiderFromCAPI($capi_user, $em);
|
|
||||||
if ($rider == null)
|
|
||||||
return new APIResponse(false, 'No rider found.');
|
|
||||||
|
|
||||||
// need to get the existing invoice items using jo id and invoice id
|
|
||||||
$existing_ii = $this->getInvoiceItems($em, $jo);
|
|
||||||
|
|
||||||
$this->generateUpdatedInvoice($em, $ic, $jo, $existing_ii, $ti_items, $promo, $pt_manager);
|
|
||||||
|
|
||||||
$data = [];
|
|
||||||
return new APIResponse(true, 'Job order updated.', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function changeService(Request $req, EntityManagerInterface $em, InvoiceGeneratorInterface $ic, PriceTierManager $pt_manager)
|
|
||||||
{
|
{
|
||||||
// $this->debugRequest($req);
|
// $this->debugRequest($req);
|
||||||
|
|
||||||
|
|
@ -1409,11 +1120,6 @@ class RiderAppController extends ApiController
|
||||||
if (!empty($msg))
|
if (!empty($msg))
|
||||||
return new APIResponse(false, $msg);
|
return new APIResponse(false, $msg);
|
||||||
|
|
||||||
// check if JO can be modified first
|
|
||||||
if (!$this->checkJOProgressionAllowed($em, $jo, $rider)) {
|
|
||||||
return new APIResponse(false, 'Job order can no longer be modified.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// check service type
|
// check service type
|
||||||
$stype_id = $req->request->get('stype_id');
|
$stype_id = $req->request->get('stype_id');
|
||||||
if (!ServiceType::validate($stype_id))
|
if (!ServiceType::validate($stype_id))
|
||||||
|
|
@ -1453,13 +1159,6 @@ class RiderAppController extends ApiController
|
||||||
else
|
else
|
||||||
$jo->setHasCoolant(false);
|
$jo->setHasCoolant(false);
|
||||||
|
|
||||||
// sealant
|
|
||||||
$flag_sealant = $req->request->get('flag_sealant', 'false');
|
|
||||||
if ($flag_sealant == 'true')
|
|
||||||
$jo->setHasSealant(true);
|
|
||||||
else
|
|
||||||
$jo->setHasSealant(false);
|
|
||||||
|
|
||||||
// has motolite battery
|
// has motolite battery
|
||||||
$cv = $jo->getCustomerVehicle();
|
$cv = $jo->getCustomerVehicle();
|
||||||
$has_motolite = $req->request->get('has_motolite', 'false');
|
$has_motolite = $req->request->get('has_motolite', 'false');
|
||||||
|
|
@ -1504,10 +1203,6 @@ class RiderAppController extends ApiController
|
||||||
$crit->setHasCoolant($jo->hasCoolant());
|
$crit->setHasCoolant($jo->hasCoolant());
|
||||||
$crit->setIsTaxable();
|
$crit->setIsTaxable();
|
||||||
|
|
||||||
// set price tier
|
|
||||||
$pt_id = $pt_manager->getPriceTier($jo->getCoordinates());
|
|
||||||
$crit->setPriceTier($pt_id);
|
|
||||||
|
|
||||||
if ($promo != null)
|
if ($promo != null)
|
||||||
$crit->addPromo($promo);
|
$crit->addPromo($promo);
|
||||||
|
|
||||||
|
|
@ -1546,168 +1241,6 @@ class RiderAppController extends ApiController
|
||||||
return new APIResponse(true, 'Job order service changed.', $data);
|
return new APIResponse(true, 'Job order service changed.', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function generateUpdatedInvoice(EntityManagerInterface $em, InvoiceGeneratorInterface $ic, JobOrder $jo, $existing_ii, $trade_in_items, $promo, PriceTierManager $pt_manager)
|
|
||||||
{
|
|
||||||
// get the service type
|
|
||||||
$stype = $jo->getServiceType();
|
|
||||||
|
|
||||||
// get the source
|
|
||||||
$source = $jo->getSource();
|
|
||||||
|
|
||||||
// get the customer vehicle
|
|
||||||
$cv = $jo->getCustomerVehicle();
|
|
||||||
|
|
||||||
// get coolant if any
|
|
||||||
$flag_coolant = $jo->hasCoolant();
|
|
||||||
|
|
||||||
// get sealant if any
|
|
||||||
$flag_sealant = $jo->hasSealant();
|
|
||||||
|
|
||||||
// check if new promo is null
|
|
||||||
if ($promo == null)
|
|
||||||
{
|
|
||||||
// promo not updated from app so check existing invoice
|
|
||||||
// get the promo id from existing invoice item
|
|
||||||
$promo_id = $existing_ii['promo_id'];
|
|
||||||
if ($promo_id == null)
|
|
||||||
$promo = null;
|
|
||||||
else
|
|
||||||
$promo = $em->getRepository(Promo::class)->find($promo_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// populate Invoice Criteria
|
|
||||||
$icrit = new InvoiceCriteria();
|
|
||||||
$icrit->setServiceType($stype)
|
|
||||||
->setCustomerVehicle($cv)
|
|
||||||
->setSource($source)
|
|
||||||
->setHasCoolant($flag_coolant)
|
|
||||||
->setHasSealant($flag_sealant)
|
|
||||||
->setIsTaxable();
|
|
||||||
|
|
||||||
// set price tier
|
|
||||||
$pt_id = $pt_manager->getPriceTier($jo->getCoordinates());
|
|
||||||
$icrit->setPriceTier($pt_id);
|
|
||||||
|
|
||||||
// at this point, all information should be valid
|
|
||||||
// assuming JO information is already valid since this
|
|
||||||
// is in the system already
|
|
||||||
// add promo if any to criteria
|
|
||||||
if ($promo != null)
|
|
||||||
$icrit->addPromo($promo);
|
|
||||||
|
|
||||||
// get the battery purchased from existing invoice items
|
|
||||||
// add the batteries ordered to criteria
|
|
||||||
$ii_items = $existing_ii['invoice_items'];
|
|
||||||
foreach ($ii_items as $ii_item)
|
|
||||||
{
|
|
||||||
$batt_id = $ii_item['batt_id'];
|
|
||||||
$qty = $ii_item['qty'];
|
|
||||||
|
|
||||||
$battery = $em->getRepository(Battery::class)->find($batt_id);
|
|
||||||
|
|
||||||
$icrit->addEntry($battery, null, $qty);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the trade in items to the criteria
|
|
||||||
foreach ($trade_in_items as $ti_item)
|
|
||||||
{
|
|
||||||
$batt_size_id = $ti_item['battery_size_id'];
|
|
||||||
$qty = $ti_item['qty'];
|
|
||||||
$trade_in_type = $ti_item['trade_in_type'];
|
|
||||||
|
|
||||||
$batt_size = $em->getRepository(BatterySize::class)->find($batt_size_id);
|
|
||||||
|
|
||||||
$icrit->addTradeInEntry($batt_size, $trade_in_type, $qty);
|
|
||||||
}
|
|
||||||
|
|
||||||
// call generateInvoice
|
|
||||||
$invoice = $ic->generateInvoice($icrit);
|
|
||||||
|
|
||||||
// remove previous invoice
|
|
||||||
$old_invoice = $jo->getInvoice();
|
|
||||||
$em->remove($old_invoice);
|
|
||||||
$em->flush();
|
|
||||||
|
|
||||||
// save new invoice
|
|
||||||
$jo->setInvoice($invoice);
|
|
||||||
$em->persist($invoice);
|
|
||||||
|
|
||||||
// log event?
|
|
||||||
$event = new JOEvent();
|
|
||||||
$event->setDateHappen(new DateTime())
|
|
||||||
->setTypeID(JOEventType::RIDER_EDIT)
|
|
||||||
->setJobOrder($jo)
|
|
||||||
->setRider($jo->getRider());
|
|
||||||
$em->persist($event);
|
|
||||||
|
|
||||||
$em->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getInvoiceItems(EntityManagerInterface $em, JobOrder $jo)
|
|
||||||
{
|
|
||||||
$jo_id = $jo->getID();
|
|
||||||
$conn = $em->getConnection();
|
|
||||||
|
|
||||||
// need to get the ordered battery id and quantity from invoice item
|
|
||||||
// and the promo from invoice
|
|
||||||
$query_sql = 'SELECT ii.battery_id AS battery_id, ii.qty AS qty, i.promo_id AS promo_id
|
|
||||||
FROM invoice_item ii, invoice i
|
|
||||||
WHERE ii.invoice_id = i.id
|
|
||||||
AND i.job_order_id = :jo_id
|
|
||||||
AND ii.battery_id IS NOT NULL';
|
|
||||||
|
|
||||||
$query_stmt = $conn->prepare($query_sql);
|
|
||||||
$query_stmt->bindValue('jo_id', $jo_id);
|
|
||||||
|
|
||||||
$results = $query_stmt->executeQuery();
|
|
||||||
|
|
||||||
$promo_id = null;
|
|
||||||
$invoice_items = [];
|
|
||||||
while ($row = $results->fetchAssociative())
|
|
||||||
{
|
|
||||||
$promo_id = $row['promo_id'];
|
|
||||||
$invoice_items[] = [
|
|
||||||
'batt_id' => $row['battery_id'],
|
|
||||||
'qty' => $row['qty'],
|
|
||||||
'trade_in' => ''
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
'promo_id' => $promo_id,
|
|
||||||
'invoice_items' => $invoice_items
|
|
||||||
];
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function validateTradeInItems(EntityManagerInterface $em, $ti_items)
|
|
||||||
{
|
|
||||||
$msg = '';
|
|
||||||
foreach ($ti_items as $ti_item)
|
|
||||||
{
|
|
||||||
$bs_id = $ti_item['battery_size_id'];
|
|
||||||
$ti_type = $ti_item['trade_in_type'];
|
|
||||||
|
|
||||||
// validate the battery size id
|
|
||||||
$batt_size = $em->getRepository(BatterySize::class)->find($bs_id);
|
|
||||||
if ($batt_size == null)
|
|
||||||
{
|
|
||||||
$msg = 'Invalid battery size for trade in: ' . $bs_id;
|
|
||||||
return $msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
// validate the trade in type
|
|
||||||
if (!TradeInType::validate($ti_type))
|
|
||||||
{
|
|
||||||
$msg = 'Invalid trade in type: ' . $ti_type;
|
|
||||||
return $msg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getCAPIUser($id, EntityManagerInterface $em)
|
protected function getCAPIUser($id, EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$capi_user = $em->getRepository(APIUser::class)->find($id);
|
$capi_user = $em->getRepository(APIUser::class)->find($id);
|
||||||
|
|
@ -1787,42 +1320,6 @@ class RiderAppController extends ApiController
|
||||||
return $msg;
|
return $msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function checkJOProgressionAllowed(EntityManagerInterface $em, JobOrder $jo, &$rider)
|
|
||||||
{
|
|
||||||
$allowed = true;
|
|
||||||
|
|
||||||
error_log("JO delivery status is " . $jo->getDeliveryStatus() . " (not allowed: " . DeliveryStatus::CANCELLED . ")");
|
|
||||||
error_log("JO status is " . $jo->getStatus() . " (not allowed: " . JOStatus::CANCELLED . ")");
|
|
||||||
|
|
||||||
// TODO: add more statuses to block if needed, hence. this is a failsafe in case MQTT is not working.
|
|
||||||
// check delivery status
|
|
||||||
switch ($jo->getDeliveryStatus())
|
|
||||||
{
|
|
||||||
case DeliveryStatus::CANCELLED:
|
|
||||||
$allowed = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check JO status as well
|
|
||||||
switch ($jo->getStatus())
|
|
||||||
{
|
|
||||||
case JOStatus::CANCELLED:
|
|
||||||
$allowed = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if this is the rider's current JO, set to null
|
|
||||||
if (!$allowed) {
|
|
||||||
if ($rider->getCurrentJobOrder() === $jo) {
|
|
||||||
$rider->setCurrentJobOrder();
|
|
||||||
$em->persist($rider);
|
|
||||||
$em->flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function debugRequest(Request $req)
|
protected function debugRequest(Request $req)
|
||||||
{
|
{
|
||||||
$all = $req->request->all();
|
$all = $req->request->all();
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,6 @@ class ApiController extends BaseApiController
|
||||||
|
|
||||||
protected function getGeoErrorMessage()
|
protected function getGeoErrorMessage()
|
||||||
{
|
{
|
||||||
return 'Our services are currently limited to some areas in Metro Manila, Baguio, Batangas, Laguna, Cavite, Pampanga, and Palawan. We will update you as soon as we are available in your area. Thank you for understanding. Keep safe!';
|
return 'Oops! Our service is limited to some areas in Metro Manila, Laguna, Cavite, Pampanga and Baguio only. We will update you as soon as we are able to cover your area';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ use App\Ramcar\InsuranceApplicationStatus;
|
||||||
use App\Ramcar\InsuranceMVType;
|
use App\Ramcar\InsuranceMVType;
|
||||||
use App\Ramcar\InsuranceClientType;
|
use App\Ramcar\InsuranceClientType;
|
||||||
use App\Ramcar\TransactionStatus;
|
use App\Ramcar\TransactionStatus;
|
||||||
use App\Ramcar\InsuranceBodyType;
|
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
|
@ -294,45 +293,6 @@ class InsuranceController extends ApiController
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPremiumsBanner(Request $req)
|
|
||||||
{
|
|
||||||
// validate params
|
|
||||||
$validity = $this->validateRequest($req);
|
|
||||||
|
|
||||||
if (!$validity['is_valid']) {
|
|
||||||
return new ApiResponse(false, $validity['error']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ApiResponse(true, '', [
|
|
||||||
'url' => $this->getParameter('insurance_premiums_banner_url'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBodyTypes(Request $req)
|
|
||||||
{
|
|
||||||
// validate params
|
|
||||||
$validity = $this->validateRequest($req);
|
|
||||||
|
|
||||||
if (!$validity['is_valid']) {
|
|
||||||
return new ApiResponse(false, $validity['error']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$bt_collection = InsuranceBodyType::getCollection();
|
|
||||||
$body_types = [];
|
|
||||||
|
|
||||||
// NOTE: formatting it this way to match how insurance third party API returns their own stuff, so it's all handled one way on the app
|
|
||||||
foreach ($bt_collection as $bt_key => $bt_name) {
|
|
||||||
$body_types[] = [
|
|
||||||
'id' => $bt_key,
|
|
||||||
'name' => $bt_name,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ApiResponse(true, '', [
|
|
||||||
'body_types' => $body_types,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getLineType($mv_type_id, $vehicle_use_type, $is_public = false)
|
protected function getLineType($mv_type_id, $vehicle_use_type, $is_public = false)
|
||||||
{
|
{
|
||||||
$line = '';
|
$line = '';
|
||||||
|
|
|
||||||
|
|
@ -4,23 +4,18 @@ namespace App\Controller\CustomerAppAPI;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Catalyst\ApiBundle\Component\Response as ApiResponse;
|
use Catalyst\ApiBundle\Component\Response as ApiResponse;
|
||||||
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
|
||||||
|
|
||||||
use App\Service\InvoiceGeneratorInterface;
|
use App\Service\InvoiceGeneratorInterface;
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
use App\Ramcar\InvoiceCriteria;
|
use App\Ramcar\InvoiceCriteria;
|
||||||
use App\Ramcar\TradeInType;
|
use App\Ramcar\TradeInType;
|
||||||
use App\Ramcar\TransactionOrigin;
|
use App\Ramcar\TransactionOrigin;
|
||||||
use App\Entity\CustomerVehicle;
|
use App\Entity\CustomerVehicle;
|
||||||
use App\Entity\Promo;
|
use App\Entity\Promo;
|
||||||
use App\Entity\Battery;
|
use App\Entity\Battery;
|
||||||
use App\Entity\BatterySize;
|
|
||||||
use App\Entity\Customer;
|
|
||||||
use App\Entity\CustomerMetadata;
|
|
||||||
|
|
||||||
class InvoiceController extends ApiController
|
class InvoiceController extends ApiController
|
||||||
{
|
{
|
||||||
public function getEstimate(Request $req, InvoiceGeneratorInterface $ic, PriceTierManager $pt_manager)
|
public function getEstimate(Request $req, InvoiceGeneratorInterface $ic)
|
||||||
{
|
{
|
||||||
// $this->debugRequest($req);
|
// $this->debugRequest($req);
|
||||||
|
|
||||||
|
|
@ -41,18 +36,6 @@ class InvoiceController extends ApiController
|
||||||
return new ApiResponse(false, 'No customer information found.');
|
return new ApiResponse(false, 'No customer information found.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// get customer location from customer_metadata using customer id
|
|
||||||
$lng = $req->request->get('longitude');
|
|
||||||
$lat = $req->request->get('latitude');
|
|
||||||
|
|
||||||
if ((empty($lng)) || (empty($lat)))
|
|
||||||
{
|
|
||||||
// use customer metadata location as basis
|
|
||||||
$coordinates = $this->getCustomerMetadata($cust);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$coordinates = new Point($lng, $lat);
|
|
||||||
|
|
||||||
// make invoice criteria
|
// make invoice criteria
|
||||||
$icrit = new InvoiceCriteria();
|
$icrit = new InvoiceCriteria();
|
||||||
$icrit->setServiceType($req->request->get('service_type'));
|
$icrit->setServiceType($req->request->get('service_type'));
|
||||||
|
|
@ -120,8 +103,7 @@ class InvoiceController extends ApiController
|
||||||
if (!empty($trade_in_type) && !empty($trade_in_batt)) {
|
if (!empty($trade_in_type) && !empty($trade_in_batt)) {
|
||||||
$ti_batt_obj = $this->em->getRepository(Battery::class)->find($trade_in_batt);
|
$ti_batt_obj = $this->em->getRepository(Battery::class)->find($trade_in_batt);
|
||||||
if (!empty($ti_batt_obj)) {
|
if (!empty($ti_batt_obj)) {
|
||||||
$ti_batt_size_obj = $ti_batt_obj->getSize();
|
$icrit->addEntry($ti_batt_obj, $trade_in_type, 1);
|
||||||
$icrit->addTradeInEntry($ti_batt_size_obj, $trade_in_type, 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,18 +113,6 @@ class InvoiceController extends ApiController
|
||||||
// set JO source
|
// set JO source
|
||||||
$icrit->setSource(TransactionOrigin::MOBILE_APP);
|
$icrit->setSource(TransactionOrigin::MOBILE_APP);
|
||||||
|
|
||||||
// set price tier
|
|
||||||
$pt_id = 0;
|
|
||||||
if ($coordinates != null)
|
|
||||||
{
|
|
||||||
error_log('coordinates are not null');
|
|
||||||
$pt_id = $pt_manager->getPriceTier($coordinates);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
error_log('null?');
|
|
||||||
|
|
||||||
$icrit->setPriceTier($pt_id);
|
|
||||||
|
|
||||||
// send to invoice generator
|
// send to invoice generator
|
||||||
$invoice = $ic->generateInvoice($icrit);
|
$invoice = $ic->generateInvoice($icrit);
|
||||||
|
|
||||||
|
|
@ -178,28 +148,4 @@ class InvoiceController extends ApiController
|
||||||
// response
|
// response
|
||||||
return new ApiResponse(true, '', $data);
|
return new ApiResponse(true, '', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getCustomerMetadata(Customer $cust)
|
|
||||||
{
|
|
||||||
$coordinates = null;
|
|
||||||
|
|
||||||
// check if customer already has existing metadata
|
|
||||||
$c_meta = $this->em->getRepository(CustomerMetadata::class)->findOneBy(['customer' => $cust]);
|
|
||||||
if ($c_meta != null)
|
|
||||||
{
|
|
||||||
$meta_data = $c_meta->getAllMetaInfo();
|
|
||||||
foreach ($meta_data as $m_info)
|
|
||||||
{
|
|
||||||
if ((isset($m_info['longitude'])) && (isset($m_info['latitude'])))
|
|
||||||
{
|
|
||||||
$lng = $m_info['longitude'];
|
|
||||||
$lat = $m_info['latitude'];
|
|
||||||
|
|
||||||
$coordinates = new Point($lng, $lat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $coordinates;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ use App\Service\HubDistributor;
|
||||||
use App\Service\HubFilterLogger;
|
use App\Service\HubFilterLogger;
|
||||||
use App\Service\HubFilteringGeoChecker;
|
use App\Service\HubFilteringGeoChecker;
|
||||||
use App\Service\JobOrderManager;
|
use App\Service\JobOrderManager;
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
use App\Ramcar\ServiceType;
|
use App\Ramcar\ServiceType;
|
||||||
use App\Ramcar\APIRiderStatus;
|
use App\Ramcar\APIRiderStatus;
|
||||||
use App\Ramcar\InvoiceCriteria;
|
use App\Ramcar\InvoiceCriteria;
|
||||||
|
|
@ -35,7 +34,6 @@ use App\Ramcar\WarrantyClass;
|
||||||
use App\Ramcar\HubCriteria;
|
use App\Ramcar\HubCriteria;
|
||||||
use App\Ramcar\DeliveryStatus;
|
use App\Ramcar\DeliveryStatus;
|
||||||
use App\Entity\Battery;
|
use App\Entity\Battery;
|
||||||
use App\Entity\BatterySize;
|
|
||||||
use App\Entity\Hub;
|
use App\Entity\Hub;
|
||||||
use App\Entity\Promo;
|
use App\Entity\Promo;
|
||||||
use App\Entity\JOEvent;
|
use App\Entity\JOEvent;
|
||||||
|
|
@ -486,11 +484,8 @@ class JobOrderController extends ApiController
|
||||||
HubDistributor $hub_dist,
|
HubDistributor $hub_dist,
|
||||||
HubFilterLogger $hub_filter_logger,
|
HubFilterLogger $hub_filter_logger,
|
||||||
HubFilteringGeoChecker $hub_geofence,
|
HubFilteringGeoChecker $hub_geofence,
|
||||||
JobOrderManager $jo_manager,
|
JobOrderManager $jo_manager
|
||||||
PriceTierManager $pt_manager
|
|
||||||
) {
|
) {
|
||||||
//error_log("CREATING JOB ORDER WITH PARAMS " . print_r($req->request->all(), true));
|
|
||||||
|
|
||||||
// validate params
|
// validate params
|
||||||
$validity = $this->validateRequest($req, [
|
$validity = $this->validateRequest($req, [
|
||||||
'service_type',
|
'service_type',
|
||||||
|
|
@ -578,8 +573,6 @@ class JobOrderController extends ApiController
|
||||||
$flag_advance_order = true;
|
$flag_advance_order = true;
|
||||||
// $flag_advance_order = $advance_order ? true : false;
|
// $flag_advance_order = $advance_order ? true : false;
|
||||||
|
|
||||||
//error_log("RUNNING QUERY NEXT");
|
|
||||||
|
|
||||||
$jo = new JobOrder();
|
$jo = new JobOrder();
|
||||||
$jo->setSource(TransactionOrigin::MOBILE_APP)
|
$jo->setSource(TransactionOrigin::MOBILE_APP)
|
||||||
->setStatus(JOStatus::PENDING)
|
->setStatus(JOStatus::PENDING)
|
||||||
|
|
@ -648,8 +641,6 @@ class JobOrderController extends ApiController
|
||||||
$icrit->addPromo($promo);
|
$icrit->addPromo($promo);
|
||||||
}
|
}
|
||||||
|
|
||||||
//error_log("CONTINUING QUERY BUILDING");
|
|
||||||
|
|
||||||
// check customer vehicle
|
// check customer vehicle
|
||||||
$cv = $this->em->getRepository(CustomerVehicle::class)->find($req->request->get('cv_id'));
|
$cv = $this->em->getRepository(CustomerVehicle::class)->find($req->request->get('cv_id'));
|
||||||
if ($cv == null) {
|
if ($cv == null) {
|
||||||
|
|
@ -697,8 +688,7 @@ class JobOrderController extends ApiController
|
||||||
if (!empty($trade_in_type) && !empty($trade_in_batt)) {
|
if (!empty($trade_in_type) && !empty($trade_in_batt)) {
|
||||||
$ti_batt_obj = $this->em->getRepository(Battery::class)->find($trade_in_batt);
|
$ti_batt_obj = $this->em->getRepository(Battery::class)->find($trade_in_batt);
|
||||||
if (!empty($ti_batt_obj)) {
|
if (!empty($ti_batt_obj)) {
|
||||||
$ti_batt_size_obj = $ti_batt_obj->getSize();
|
$icrit->addEntry($ti_batt_obj, $trade_in_type, 1);
|
||||||
$icrit->addTradeInEntry($ti_batt_size_obj, $trade_in_type, 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -708,38 +698,17 @@ class JobOrderController extends ApiController
|
||||||
// set JO source
|
// set JO source
|
||||||
$icrit->setSource(TransactionOrigin::MOBILE_APP);
|
$icrit->setSource(TransactionOrigin::MOBILE_APP);
|
||||||
|
|
||||||
// set price tier
|
|
||||||
$pt_id = $pt_manager->getPriceTier($jo->getCoordinates());
|
|
||||||
$icrit->setPriceTier($pt_id);
|
|
||||||
|
|
||||||
// send to invoice generator
|
// send to invoice generator
|
||||||
$invoice = $ic->generateInvoice($icrit);
|
$invoice = $ic->generateInvoice($icrit);
|
||||||
$jo->setInvoice($invoice);
|
$jo->setInvoice($invoice);
|
||||||
|
|
||||||
//error_log("GENERATED INVOICE");
|
|
||||||
|
|
||||||
// save here first so we have a JO ID which is required for the hub selector
|
|
||||||
$this->em->persist($invoice);
|
|
||||||
$this->em->persist($jo);
|
|
||||||
$this->em->flush();
|
|
||||||
|
|
||||||
// assign hub and rider
|
// assign hub and rider
|
||||||
// check if hub is null
|
// check if hub is null
|
||||||
if ($hub == null) {
|
if ($hub == null) {
|
||||||
//error_log("NO HUB");
|
|
||||||
|
|
||||||
// TODO: need to factor out the setting of HubCriteria fields
|
// TODO: need to factor out the setting of HubCriteria fields
|
||||||
$hub_criteria = new HubCriteria();
|
$hub_criteria = new HubCriteria();
|
||||||
$hub_criteria->setPoint($jo->getCoordinates());
|
$hub_criteria->setPoint($jo->getCoordinates());
|
||||||
|
|
||||||
// set job order info
|
|
||||||
$hub_criteria->setJobOrderId($jo->getID())
|
|
||||||
->setJoType($jo->getServiceType())
|
|
||||||
->setJoOrigin($jo->getSource())
|
|
||||||
->setCustomerClass($cust->getCustomerClassification())
|
|
||||||
->setOrderDate($jo->getDateCreate())
|
|
||||||
->setServiceType($jo->getServiceType());
|
|
||||||
|
|
||||||
// get distance limit for mobile from env
|
// get distance limit for mobile from env
|
||||||
// get value of hub_filter_enable from env
|
// get value of hub_filter_enable from env
|
||||||
$limit_distance = $_ENV['CUST_DISTANCE_LIMIT'];
|
$limit_distance = $_ENV['CUST_DISTANCE_LIMIT'];
|
||||||
|
|
@ -777,10 +746,6 @@ class JobOrderController extends ApiController
|
||||||
|
|
||||||
$hub_criteria->setCustomerId($customer_id);
|
$hub_criteria->setCustomerId($customer_id);
|
||||||
|
|
||||||
// set filter flags for inventory and available riders
|
|
||||||
$hub_criteria->setInventoryCheck();
|
|
||||||
$hub_criteria->setRidersCheck();
|
|
||||||
|
|
||||||
// find nearest hubs
|
// find nearest hubs
|
||||||
$nearest_hubs = $hub_select->find($hub_criteria);
|
$nearest_hubs = $hub_select->find($hub_criteria);
|
||||||
|
|
||||||
|
|
@ -859,8 +824,6 @@ class JobOrderController extends ApiController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//error_log("HAS HUB: " . $hub->getID());
|
|
||||||
|
|
||||||
$jo->setHub($hub);
|
$jo->setHub($hub);
|
||||||
$jo->setStatus(JOStatus::RIDER_ASSIGN);
|
$jo->setStatus(JOStatus::RIDER_ASSIGN);
|
||||||
$jo->setStatusAutoAssign(AutoAssignStatus::HUB_ASSIGNED);
|
$jo->setStatusAutoAssign(AutoAssignStatus::HUB_ASSIGNED);
|
||||||
|
|
@ -872,10 +835,8 @@ class JobOrderController extends ApiController
|
||||||
$hub_dist->incrementJoCountForHub($hub);
|
$hub_dist->incrementJoCountForHub($hub);
|
||||||
}
|
}
|
||||||
|
|
||||||
//error_log("DONE SELECTING HUB");
|
|
||||||
|
|
||||||
// save additional hub related changes
|
|
||||||
$this->em->persist($jo);
|
$this->em->persist($jo);
|
||||||
|
$this->em->persist($invoice);
|
||||||
|
|
||||||
// add event log for JO
|
// add event log for JO
|
||||||
$event = new JOEvent();
|
$event = new JOEvent();
|
||||||
|
|
@ -986,8 +947,6 @@ class JobOrderController extends ApiController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//error_log("DONE CREATING JOB ORDER " . $jo->getID());
|
|
||||||
|
|
||||||
// response
|
// response
|
||||||
return new ApiResponse(true, '', [
|
return new ApiResponse(true, '', [
|
||||||
'jo_id' => $jo->getID(),
|
'jo_id' => $jo->getID(),
|
||||||
|
|
@ -1011,8 +970,7 @@ class JobOrderController extends ApiController
|
||||||
HubDistributor $hub_dist,
|
HubDistributor $hub_dist,
|
||||||
HubFilterLogger $hub_filter_logger,
|
HubFilterLogger $hub_filter_logger,
|
||||||
HubFilteringGeoChecker $hub_geofence,
|
HubFilteringGeoChecker $hub_geofence,
|
||||||
JobOrderManager $jo_manager,
|
JobOrderManager $jo_manager
|
||||||
PriceTierManager $pt_manager
|
|
||||||
) {
|
) {
|
||||||
// validate params
|
// validate params
|
||||||
$validity = $this->validateRequest($req, [
|
$validity = $this->validateRequest($req, [
|
||||||
|
|
@ -1159,8 +1117,7 @@ class JobOrderController extends ApiController
|
||||||
if (!empty($trade_in_type) && !empty($trade_in_batt)) {
|
if (!empty($trade_in_type) && !empty($trade_in_batt)) {
|
||||||
$ti_batt_obj = $this->em->getRepository(Battery::class)->find($trade_in_batt);
|
$ti_batt_obj = $this->em->getRepository(Battery::class)->find($trade_in_batt);
|
||||||
if (!empty($ti_batt_obj)) {
|
if (!empty($ti_batt_obj)) {
|
||||||
$battery_size = $ti_batt_obj->getSize();
|
$icrit->addEntry($ti_batt_obj, $trade_in_type, 1);
|
||||||
$icrit->addTradeInEntry($battery_size, $trade_in_type, 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1170,10 +1127,6 @@ class JobOrderController extends ApiController
|
||||||
// set JO source
|
// set JO source
|
||||||
$icrit->setSource(TransactionOrigin::MOBILE_APP);
|
$icrit->setSource(TransactionOrigin::MOBILE_APP);
|
||||||
|
|
||||||
// set price tier
|
|
||||||
$pt_id = $pt_manager->getPriceTier($jo->getCoordinates());
|
|
||||||
$icrit->setPriceTier($pt_id);
|
|
||||||
|
|
||||||
// send to invoice generator
|
// send to invoice generator
|
||||||
$invoice = $ic->generateInvoice($icrit);
|
$invoice = $ic->generateInvoice($icrit);
|
||||||
$jo->setInvoice($invoice);
|
$jo->setInvoice($invoice);
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,16 @@ namespace App\Controller\CustomerAppAPI;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Catalyst\ApiBundle\Component\Response as ApiResponse;
|
use Catalyst\ApiBundle\Component\Response as ApiResponse;
|
||||||
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
|
||||||
|
|
||||||
use App\Entity\CustomerVehicle;
|
use App\Entity\CustomerVehicle;
|
||||||
use App\Entity\JobOrder;
|
use App\Entity\JobOrder;
|
||||||
use App\Entity\VehicleManufacturer;
|
use App\Entity\VehicleManufacturer;
|
||||||
use App\Entity\Vehicle;
|
use App\Entity\Vehicle;
|
||||||
use App\Entity\ItemType;
|
|
||||||
use App\Ramcar\JOStatus;
|
use App\Ramcar\JOStatus;
|
||||||
use App\Ramcar\ServiceType;
|
use App\Ramcar\ServiceType;
|
||||||
use App\Ramcar\TradeInType;
|
use App\Ramcar\TradeInType;
|
||||||
use App\Ramcar\InsuranceApplicationStatus;
|
use App\Ramcar\InsuranceApplicationStatus;
|
||||||
use App\Service\PayMongoConnector;
|
use App\Service\PayMongoConnector;
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
|
||||||
class VehicleController extends ApiController
|
class VehicleController extends ApiController
|
||||||
|
|
@ -240,7 +237,7 @@ class VehicleController extends ApiController
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCompatibleBatteries(Request $req, $vid, PriceTierManager $pt_manager)
|
public function getCompatibleBatteries(Request $req, $vid)
|
||||||
{
|
{
|
||||||
// validate params
|
// validate params
|
||||||
$validity = $this->validateRequest($req);
|
$validity = $this->validateRequest($req);
|
||||||
|
|
@ -255,43 +252,11 @@ class VehicleController extends ApiController
|
||||||
return new ApiResponse(false, 'Invalid vehicle.');
|
return new ApiResponse(false, 'Invalid vehicle.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// get location from request
|
|
||||||
$lng = $req->query->get('longitude', '');
|
|
||||||
$lat = $req->query->get('latitude', '');
|
|
||||||
|
|
||||||
$batts = $vehicle->getActiveBatteries();
|
|
||||||
$pt_id = 0;
|
|
||||||
if ((!(empty($lng))) && (!(empty($lat))))
|
|
||||||
{
|
|
||||||
// get the price tier
|
|
||||||
$coordinates = new Point($lng, $lat);
|
|
||||||
|
|
||||||
$pt_id = $pt_manager->getPriceTier($coordinates);
|
|
||||||
}
|
|
||||||
|
|
||||||
// batteries
|
// batteries
|
||||||
$batt_list = [];
|
$batt_list = [];
|
||||||
|
$batts = $vehicle->getActiveBatteries();
|
||||||
foreach ($batts as $batt) {
|
foreach ($batts as $batt) {
|
||||||
// TODO: Add warranty_tnv to battery information
|
// TODO: Add warranty_tnv to battery information
|
||||||
// check if customer location is in a price tier location
|
|
||||||
if ($pt_id == 0)
|
|
||||||
$price = $batt->getSellingPrice();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// get item type for battery
|
|
||||||
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'battery']);
|
|
||||||
if ($item_type == null)
|
|
||||||
$price = $batt->getSellingPrice();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$batt_id = $batt->getID();
|
|
||||||
|
|
||||||
// find the item price given price tier id and battery id
|
|
||||||
$price = $pt_manager->getItemPrice($pt_id, $item_type_id, $batt_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$batt_list[] = [
|
$batt_list[] = [
|
||||||
'id' => $batt->getID(),
|
'id' => $batt->getID(),
|
||||||
'mfg_id' => $batt->getManufacturer()->getID(),
|
'mfg_id' => $batt->getManufacturer()->getID(),
|
||||||
|
|
@ -300,7 +265,7 @@ class VehicleController extends ApiController
|
||||||
'model_name' => $batt->getModel()->getName(),
|
'model_name' => $batt->getModel()->getName(),
|
||||||
'size_id' => $batt->getSize()->getID(),
|
'size_id' => $batt->getSize()->getID(),
|
||||||
'size_name' => $batt->getSize()->getName(),
|
'size_name' => $batt->getSize()->getName(),
|
||||||
'price' => $price,
|
'price' => $batt->getSellingPrice(),
|
||||||
'wty_private' => $batt->getWarrantyPrivate(),
|
'wty_private' => $batt->getWarrantyPrivate(),
|
||||||
'wty_commercial' => $batt->getWarrantyCommercial(),
|
'wty_commercial' => $batt->getWarrantyCommercial(),
|
||||||
'image_url' => $this->getBatteryImageURL($req, $batt),
|
'image_url' => $this->getBatteryImageURL($req, $batt),
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ namespace App\Controller;
|
||||||
|
|
||||||
use App\Ramcar\InsuranceApplicationStatus;
|
use App\Ramcar\InsuranceApplicationStatus;
|
||||||
use App\Service\FCMSender;
|
use App\Service\FCMSender;
|
||||||
use App\Service\InsuranceConnector;
|
|
||||||
use App\Entity\InsuranceApplication;
|
use App\Entity\InsuranceApplication;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
|
|
@ -16,13 +15,11 @@ use DateTime;
|
||||||
|
|
||||||
class InsuranceController extends Controller
|
class InsuranceController extends Controller
|
||||||
{
|
{
|
||||||
protected $ic;
|
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $fcmclient;
|
protected $fcmclient;
|
||||||
|
|
||||||
public function __construct(InsuranceConnector $ic, EntityManagerInterface $em, FCMSender $fcmclient)
|
public function __construct(EntityManagerInterface $em, FCMSender $fcmclient)
|
||||||
{
|
{
|
||||||
$this->ic = $ic;
|
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->fcmclient = $fcmclient;
|
$this->fcmclient = $fcmclient;
|
||||||
}
|
}
|
||||||
|
|
@ -31,8 +28,17 @@ class InsuranceController extends Controller
|
||||||
{
|
{
|
||||||
$payload = $req->request->all();
|
$payload = $req->request->all();
|
||||||
|
|
||||||
// log this callback
|
// DEBUG
|
||||||
$this->ic->log('CALLBACK', "[]", json_encode($payload), 'callback');
|
@file_put_contents(__DIR__ . '/../../var/log/insurance.log', print_r($payload, true) . "\r\n----------------------------------------\r\n\r\n", FILE_APPEND);
|
||||||
|
error_log(print_r($payload, true));
|
||||||
|
|
||||||
|
/*
|
||||||
|
return $this->json([
|
||||||
|
'success' => true,
|
||||||
|
]);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// END DEBUG
|
||||||
|
|
||||||
// if no transaction code given, silently fail
|
// if no transaction code given, silently fail
|
||||||
if (empty($payload['transaction_code'])) {
|
if (empty($payload['transaction_code'])) {
|
||||||
|
|
|
||||||
|
|
@ -1,269 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller;
|
|
||||||
|
|
||||||
use Doctrine\ORM\Query;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
||||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
|
||||||
|
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
|
|
||||||
|
|
||||||
use Catalyst\MenuBundle\Annotation\Menu;
|
|
||||||
|
|
||||||
use App\Entity\PriceTier;
|
|
||||||
use App\Entity\Battery;
|
|
||||||
use App\Entity\ServiceOffering;
|
|
||||||
use App\Entity\ItemType;
|
|
||||||
use App\Entity\ItemPrice;
|
|
||||||
|
|
||||||
class ItemPricingController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @Menu(selected="item_pricing")
|
|
||||||
* @IsGranted("item_pricing.update")
|
|
||||||
*/
|
|
||||||
public function index (EntityManagerInterface $em)
|
|
||||||
{
|
|
||||||
// get all the price tiers
|
|
||||||
$price_tiers = $em->getRepository(PriceTier::class)->findAll();
|
|
||||||
|
|
||||||
// get all item types
|
|
||||||
$item_types = $em->getRepository(ItemType::class)->findBy([], ['name' => 'asc']);
|
|
||||||
|
|
||||||
// get all the items/batteries
|
|
||||||
// load only batteries upon initial loading
|
|
||||||
$items = $this->getBatteries($em);
|
|
||||||
|
|
||||||
// set the default item type to battery
|
|
||||||
$default_it = $em->getRepository(ItemType::class)->findOneBy(['code' => 'battery']);
|
|
||||||
|
|
||||||
$params = [
|
|
||||||
'sets' => [
|
|
||||||
'price_tiers' => $price_tiers,
|
|
||||||
'item_types' => $item_types,
|
|
||||||
],
|
|
||||||
'items' => $items,
|
|
||||||
'default_item_type_id' => $default_it->getID(),
|
|
||||||
];
|
|
||||||
|
|
||||||
return $this->render('item-pricing/form.html.twig', $params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Menu(selected="item_pricing")
|
|
||||||
* @IsGranted("item_pricing.update")
|
|
||||||
*/
|
|
||||||
public function formSubmit(Request $req, EntityManagerInterface $em)
|
|
||||||
{
|
|
||||||
$pt_id = $req->request->get('price_tier_id');
|
|
||||||
$it_id = $req->request->get('item_type_id');
|
|
||||||
$prices = $req->request->get('price');
|
|
||||||
|
|
||||||
// get the item type
|
|
||||||
$item_type = $em->getRepository(ItemType::class)->find($it_id);
|
|
||||||
|
|
||||||
if ($item_type->getCode() == 'battery')
|
|
||||||
{
|
|
||||||
// get batteries
|
|
||||||
$items = $em->getRepository(Battery::class)->findBy(['flag_active' => true], ['id' => 'asc']);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// get service offerings
|
|
||||||
$items = $em->getRepository(ServiceOffering::class)->findBy([], ['id' => 'asc']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// on default price tier
|
|
||||||
if ($pt_id == 0)
|
|
||||||
{
|
|
||||||
// default price tier, update battery or service offering, depending on item type
|
|
||||||
// NOTE: battery and service offering prices or fees are stored as decimal.
|
|
||||||
foreach ($items as $item)
|
|
||||||
{
|
|
||||||
$item_id = $item->getID();
|
|
||||||
if (isset($prices[$item_id]))
|
|
||||||
{
|
|
||||||
// check item type
|
|
||||||
if ($item_type->getCode() == 'battery')
|
|
||||||
$item->setSellingPrice($prices[$item_id]);
|
|
||||||
else
|
|
||||||
$item->setFee($prices[$item_id]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// get the price tier
|
|
||||||
$price_tier = $em->getRepository(PriceTier::class)->find($pt_id);
|
|
||||||
|
|
||||||
$item_prices = $price_tier->getItemPrices();
|
|
||||||
|
|
||||||
// clear the tier's item prices for the specific item type
|
|
||||||
foreach ($item_prices as $ip)
|
|
||||||
{
|
|
||||||
if ($ip->getItemType() == $item_type)
|
|
||||||
$em->remove($ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the tier's item prices
|
|
||||||
foreach ($items as $item)
|
|
||||||
{
|
|
||||||
$item_id = $item->getID();
|
|
||||||
|
|
||||||
$item_price = new ItemPrice();
|
|
||||||
|
|
||||||
$item_price->setItemType($item_type)
|
|
||||||
->setPriceTier($price_tier)
|
|
||||||
->setItemID($item_id);
|
|
||||||
|
|
||||||
if (isset($prices[$item_id]))
|
|
||||||
{
|
|
||||||
$item_price->setPrice($prices[$item_id] * 100);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$item_price->setPrice($item->getPrice() * 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// save
|
|
||||||
$em->persist($item_price);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$em->flush();
|
|
||||||
|
|
||||||
return $this->redirectToRoute('item_pricing');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @IsGranted("item_pricing.update")
|
|
||||||
*/
|
|
||||||
public function itemPrices(EntityManagerInterface $em, $pt_id, $it_id)
|
|
||||||
{
|
|
||||||
$pt_prices = [];
|
|
||||||
|
|
||||||
// get the item type
|
|
||||||
$it = $em->getRepository(ItemType::class)->find($it_id);
|
|
||||||
|
|
||||||
// check if default prices are needed
|
|
||||||
if ($pt_id != 0)
|
|
||||||
{
|
|
||||||
// get the price tier
|
|
||||||
$pt = $em->getRepository(PriceTier::class)->find($pt_id);
|
|
||||||
|
|
||||||
// get the items under the price tier
|
|
||||||
$pt_items = $pt->getItemPrices();
|
|
||||||
|
|
||||||
foreach ($pt_items as $pt_item)
|
|
||||||
{
|
|
||||||
// make item price hash
|
|
||||||
$pt_prices[$pt_item->getItemID()] = $pt_item->getPrice();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the prices from battery or service offering, depending on item type
|
|
||||||
if ($it->getCode() == 'battery')
|
|
||||||
{
|
|
||||||
// get batteries
|
|
||||||
$items = $em->getRepository(Battery::class)->findBy(['flag_active' => true], ['id' => 'asc']);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// get service offerings
|
|
||||||
$items = $em->getRepository(ServiceOffering::class)->findBy([], ['id' => 'asc']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data_items = [];
|
|
||||||
foreach ($items as $item)
|
|
||||||
{
|
|
||||||
$item_id = $item->getID();
|
|
||||||
|
|
||||||
// get default price
|
|
||||||
if ($it->getCode() == 'battery')
|
|
||||||
{
|
|
||||||
$price = $item->getSellingPrice();
|
|
||||||
$name = $item->getModel()->getName() . ' ' . $item->getSize()->getName();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$price = $item->getFee();
|
|
||||||
$name = $item->getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if tier has price for item
|
|
||||||
if (isset($pt_prices[$item_id]))
|
|
||||||
{
|
|
||||||
$pt_price = $pt_prices[$item_id];
|
|
||||||
|
|
||||||
// actual price
|
|
||||||
$price = number_format($pt_price / 100, 2, '.', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
$actual_price = $price;
|
|
||||||
|
|
||||||
$data_items[] = [
|
|
||||||
'id' => $item_id,
|
|
||||||
'name' => $name,
|
|
||||||
'item_type_id' => $it->getID(),
|
|
||||||
'item_type' => $it->getName(),
|
|
||||||
'price' => $actual_price,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// response
|
|
||||||
return new JsonResponse([
|
|
||||||
'items' => $data_items,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getBatteries(EntityManagerInterface $em)
|
|
||||||
{
|
|
||||||
// get the item type for battery
|
|
||||||
$batt_item_type = $em->getRepository(ItemType::class)->findOneBy(['code' => 'battery']);
|
|
||||||
|
|
||||||
// get all active batteries
|
|
||||||
$batts = $em->getRepository(Battery::class)->findBy(['flag_active' => true], ['id' => 'asc']);
|
|
||||||
foreach ($batts as $batt)
|
|
||||||
{
|
|
||||||
$batt_set[$batt->getID()] = [
|
|
||||||
'name' => $batt->getModel()->getName() . ' ' . $batt->getSize()->getName(),
|
|
||||||
'item_type_id' => $batt_item_type->getID(),
|
|
||||||
'item_type' => $batt_item_type->getName(),
|
|
||||||
'price' => $batt->getSellingPrice(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'items' => $batt_set,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getServiceOfferings(EntityeManagerInterface $em)
|
|
||||||
{
|
|
||||||
// get the item type for service offering
|
|
||||||
$service_item_type = $em->getRepository(ItemType::class)->findOneBy(['code' => 'service_offering']);
|
|
||||||
|
|
||||||
// get all service offerings
|
|
||||||
$services = $em->getRepository(ServiceOffering::class)->findBy([], ['id' => 'asc']);
|
|
||||||
$service_set = [];
|
|
||||||
foreach ($services as $service)
|
|
||||||
{
|
|
||||||
$service_set[$service->getID()] = [
|
|
||||||
'name' => $service->getName(),
|
|
||||||
'item_type_id' => $service_item_type->getID(),
|
|
||||||
'item_type' => $service_item_type->getName(),
|
|
||||||
'price' => $service->getFee(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'items' => $service_set,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,251 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller;
|
|
||||||
|
|
||||||
use Doctrine\ORM\Query;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
|
||||||
|
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
|
|
||||||
|
|
||||||
use App\Entity\ItemType;
|
|
||||||
|
|
||||||
use Catalyst\MenuBundle\Annotation\Menu;
|
|
||||||
|
|
||||||
class ItemTypeController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @Menu(selected="item_type_list")
|
|
||||||
* @IsGranted("item_type.list")
|
|
||||||
*/
|
|
||||||
public function index ()
|
|
||||||
{
|
|
||||||
return $this->render('item-type/list.html.twig');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @IsGranted("item_type.list")
|
|
||||||
*/
|
|
||||||
public function datatableRows(Request $req)
|
|
||||||
{
|
|
||||||
// get query builder
|
|
||||||
$qb = $this->getDoctrine()
|
|
||||||
->getRepository(ItemType::class)
|
|
||||||
->createQueryBuilder('q');
|
|
||||||
|
|
||||||
// get datatable params
|
|
||||||
$datatable = $req->request->get('datatable');
|
|
||||||
|
|
||||||
// count total records
|
|
||||||
$tquery = $qb->select('COUNT(q)');
|
|
||||||
$this->setQueryFilters($datatable, $tquery);
|
|
||||||
$total = $tquery->getQuery()
|
|
||||||
->getSingleScalarResult();
|
|
||||||
|
|
||||||
// get current page number
|
|
||||||
$page = $datatable['pagination']['page'] ?? 1;
|
|
||||||
|
|
||||||
$perpage = $datatable['pagination']['perpage'];
|
|
||||||
$offset = ($page - 1) * $perpage;
|
|
||||||
|
|
||||||
// add metadata
|
|
||||||
$meta = [
|
|
||||||
'page' => $page,
|
|
||||||
'perpage' => $perpage,
|
|
||||||
'pages' => ceil($total / $perpage),
|
|
||||||
'total' => $total,
|
|
||||||
'sort' => 'asc',
|
|
||||||
'field' => 'id'
|
|
||||||
];
|
|
||||||
|
|
||||||
// build query
|
|
||||||
$query = $qb->select('q');
|
|
||||||
$this->setQueryFilters($datatable, $query);
|
|
||||||
|
|
||||||
// check if sorting is present, otherwise use default
|
|
||||||
if (isset($datatable['sort']['field']) && !empty($datatable['sort']['field'])) {
|
|
||||||
$order = $datatable['sort']['sort'] ?? 'asc';
|
|
||||||
$query->orderBy('q.' . $datatable['sort']['field'], $order);
|
|
||||||
} else {
|
|
||||||
$query->orderBy('q.id', 'asc');
|
|
||||||
}
|
|
||||||
|
|
||||||
// get rows for this page
|
|
||||||
$obj_rows = $query->setFirstResult($offset)
|
|
||||||
->setMaxResults($perpage)
|
|
||||||
->getQuery()
|
|
||||||
->getResult();
|
|
||||||
|
|
||||||
// process rows
|
|
||||||
$rows = [];
|
|
||||||
foreach ($obj_rows as $orow) {
|
|
||||||
// add row data
|
|
||||||
$row['id'] = $orow->getID();
|
|
||||||
$row['name'] = $orow->getName();
|
|
||||||
|
|
||||||
// add row metadata
|
|
||||||
$row['meta'] = [
|
|
||||||
'update_url' => '',
|
|
||||||
'delete_url' => ''
|
|
||||||
];
|
|
||||||
|
|
||||||
// add crud urls
|
|
||||||
if ($this->isGranted('item_type.update'))
|
|
||||||
$row['meta']['update_url'] = $this->generateUrl('item_type_update_form', ['id' => $row['id']]);
|
|
||||||
if ($this->isGranted('item_type.delete'))
|
|
||||||
$row['meta']['delete_url'] = $this->generateUrl('item_type_delete', ['id' => $row['id']]);
|
|
||||||
|
|
||||||
$rows[] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
// response
|
|
||||||
return $this->json([
|
|
||||||
'meta' => $meta,
|
|
||||||
'data' => $rows
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Menu(selected="item_type.list")
|
|
||||||
* @IsGranted("item_type.add")
|
|
||||||
*/
|
|
||||||
public function addForm()
|
|
||||||
{
|
|
||||||
$item_type = new ItemType();
|
|
||||||
$params = [
|
|
||||||
'obj' => $item_type,
|
|
||||||
'mode' => 'create',
|
|
||||||
];
|
|
||||||
|
|
||||||
// response
|
|
||||||
return $this->render('item-type/form.html.twig', $params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @IsGranted("item_type.add")
|
|
||||||
*/
|
|
||||||
public function addSubmit(Request $req, EntityManagerInterface $em, ValidatorInterface $validator)
|
|
||||||
{
|
|
||||||
$item_type = new ItemType();
|
|
||||||
|
|
||||||
$this->setObject($item_type, $req);
|
|
||||||
|
|
||||||
// validate
|
|
||||||
$errors = $validator->validate($item_type);
|
|
||||||
|
|
||||||
// initialize error list
|
|
||||||
$error_array = [];
|
|
||||||
|
|
||||||
// add errors to list
|
|
||||||
foreach ($errors as $error) {
|
|
||||||
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if any errors were found
|
|
||||||
if (!empty($error_array)) {
|
|
||||||
// return validation failure response
|
|
||||||
return $this->json([
|
|
||||||
'success' => false,
|
|
||||||
'errors' => $error_array
|
|
||||||
], 422);
|
|
||||||
}
|
|
||||||
|
|
||||||
// validated! save the entity
|
|
||||||
$em->persist($item_type);
|
|
||||||
$em->flush();
|
|
||||||
|
|
||||||
// return successful response
|
|
||||||
return $this->json([
|
|
||||||
'success' => 'Changes have been saved!'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Menu(selected="item_type_list")
|
|
||||||
* @ParamConverter("item_type", class="App\Entity\ItemType")
|
|
||||||
* @IsGranted("item_type.update")
|
|
||||||
*/
|
|
||||||
public function updateForm($id, EntityManagerInterface $em, ItemType $item_type)
|
|
||||||
{
|
|
||||||
$params = [];
|
|
||||||
$params['obj'] = $item_type;
|
|
||||||
$params['mode'] = 'update';
|
|
||||||
|
|
||||||
// response
|
|
||||||
return $this->render('item-type/form.html.twig', $params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ParamConverter("item_type", class="App\Entity\ItemType")
|
|
||||||
* @IsGranted("item_type.update")
|
|
||||||
*/
|
|
||||||
public function updateSubmit(Request $req, EntityManagerInterface $em, ValidatorInterface $validator, ItemType $item_type)
|
|
||||||
{
|
|
||||||
$this->setObject($item_type, $req);
|
|
||||||
|
|
||||||
// validate
|
|
||||||
$errors = $validator->validate($item_type);
|
|
||||||
|
|
||||||
// initialize error list
|
|
||||||
$error_array = [];
|
|
||||||
|
|
||||||
// add errors to list
|
|
||||||
foreach ($errors as $error) {
|
|
||||||
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if any errors were found
|
|
||||||
if (!empty($error_array)) {
|
|
||||||
// return validation failure response
|
|
||||||
return $this->json([
|
|
||||||
'success' => false,
|
|
||||||
'errors' => $error_array
|
|
||||||
], 422);
|
|
||||||
}
|
|
||||||
|
|
||||||
// validated! save the entity
|
|
||||||
$em->flush();
|
|
||||||
|
|
||||||
// return successful response
|
|
||||||
return $this->json([
|
|
||||||
'success' => 'Changes have been saved!'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ParamConverter("item_type", class="App\Entity\ItemType")
|
|
||||||
* @IsGranted("item_type.delete")
|
|
||||||
*/
|
|
||||||
public function deleteSubmit(EntityManagerInterface $em, ItemType $item_type)
|
|
||||||
{
|
|
||||||
// delete this object
|
|
||||||
$em->remove($item_type);
|
|
||||||
$em->flush();
|
|
||||||
|
|
||||||
// response
|
|
||||||
$response = new Response();
|
|
||||||
$response->setStatusCode(Response::HTTP_OK);
|
|
||||||
$response->send();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected function setObject(ItemType $obj, Request $req)
|
|
||||||
{
|
|
||||||
// set and save values
|
|
||||||
$obj->setName($req->request->get('name'))
|
|
||||||
->setCode($req->request->get('code'));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function setQueryFilters($datatable, QueryBuilder $query)
|
|
||||||
{
|
|
||||||
if (isset($datatable['query']['data-rows-search']) && !empty($datatable['query']['data-rows-search'])) {
|
|
||||||
$query->where('q.name LIKE :filter')
|
|
||||||
->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -30,7 +30,6 @@ use App\Service\HubSelector;
|
||||||
|
|
||||||
use App\Service\RiderTracker;
|
use App\Service\RiderTracker;
|
||||||
use App\Service\MotivConnector;
|
use App\Service\MotivConnector;
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
use App\Service\GeofenceTracker;
|
use App\Service\GeofenceTracker;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
@ -43,8 +42,6 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
use Catalyst\MenuBundle\Annotation\Menu;
|
use Catalyst\MenuBundle\Annotation\Menu;
|
||||||
|
|
||||||
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
|
||||||
|
|
||||||
class JobOrderController extends Controller
|
class JobOrderController extends Controller
|
||||||
{
|
{
|
||||||
public function getJobOrders(Request $req, JobOrderHandlerInterface $jo_handler)
|
public function getJobOrders(Request $req, JobOrderHandlerInterface $jo_handler)
|
||||||
|
|
@ -744,7 +741,7 @@ class JobOrderController extends Controller
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateInvoice(Request $req, InvoiceGeneratorInterface $ic, PriceTierManager $pt_manager)
|
public function generateInvoice(Request $req, InvoiceGeneratorInterface $ic)
|
||||||
{
|
{
|
||||||
// error_log('generating invoice...');
|
// error_log('generating invoice...');
|
||||||
$error = false;
|
$error = false;
|
||||||
|
|
@ -754,21 +751,6 @@ class JobOrderController extends Controller
|
||||||
$promo_id = $req->request->get('promo');
|
$promo_id = $req->request->get('promo');
|
||||||
$cvid = $req->request->get('cvid');
|
$cvid = $req->request->get('cvid');
|
||||||
$service_charges = $req->request->get('service_charges', []);
|
$service_charges = $req->request->get('service_charges', []);
|
||||||
$flag_coolant = $req->request->get('flag_coolant', false);
|
|
||||||
$flag_sealant = $req->request->get('flag_sealant', false);
|
|
||||||
|
|
||||||
// coordinates
|
|
||||||
// need to check if lng and lat are set
|
|
||||||
$lng = $req->request->get('coord_lng', 0);
|
|
||||||
$lat = $req->request->get('coord_lat', 0);
|
|
||||||
|
|
||||||
$price_tier = 0;
|
|
||||||
if (!empty($lng) && !empty($lat))
|
|
||||||
{
|
|
||||||
$coordinates = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat'));
|
|
||||||
$price_tier = $pt_manager->getPriceTier($coordinates);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
|
|
@ -785,10 +767,8 @@ class JobOrderController extends Controller
|
||||||
$criteria->setServiceType($stype)
|
$criteria->setServiceType($stype)
|
||||||
->setCustomerVehicle($cv)
|
->setCustomerVehicle($cv)
|
||||||
->setIsTaxable()
|
->setIsTaxable()
|
||||||
->setSource(TransactionOrigin::CALL)
|
->setSource(TransactionOrigin::CALL);
|
||||||
->setPriceTier($price_tier)
|
|
||||||
->setHasCoolant($flag_coolant)
|
|
||||||
->setHasSealant($flag_sealant);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// if it's a jumpstart or troubleshoot only, we know what to charge already
|
// if it's a jumpstart or troubleshoot only, we know what to charge already
|
||||||
|
|
|
||||||
|
|
@ -4,23 +4,18 @@ namespace App\Controller;
|
||||||
|
|
||||||
use App\Entity\GatewayTransaction;
|
use App\Entity\GatewayTransaction;
|
||||||
use App\Ramcar\TransactionStatus;
|
use App\Ramcar\TransactionStatus;
|
||||||
use App\Service\PayMongoConnector;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
|
|
||||||
use DateTime;
|
|
||||||
|
|
||||||
class PayMongoController extends Controller
|
class PayMongoController extends Controller
|
||||||
{
|
{
|
||||||
protected $pm;
|
|
||||||
protected $em;
|
protected $em;
|
||||||
|
|
||||||
public function __construct(PayMongoConnector $pm, EntityManagerInterface $em)
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->pm = $pm;
|
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,8 +23,16 @@ class PayMongoController extends Controller
|
||||||
{
|
{
|
||||||
$payload = json_decode($req->getContent(), true);
|
$payload = json_decode($req->getContent(), true);
|
||||||
|
|
||||||
// log this callback
|
// DEBUG
|
||||||
$this->pm->log('CALLBACK', "[]", $req->getContent(), 'callback');
|
@file_put_contents(__DIR__ . '/../../var/log/paymongo.log', print_r($payload, true) . "\r\n----------------------------------------\r\n\r\n", FILE_APPEND);
|
||||||
|
|
||||||
|
/*
|
||||||
|
return $this->json([
|
||||||
|
'success' => true,
|
||||||
|
]);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// END DEBUG
|
||||||
|
|
||||||
// if no event type given, silently fail
|
// if no event type given, silently fail
|
||||||
if (empty($payload['data'])) {
|
if (empty($payload['data'])) {
|
||||||
|
|
@ -47,8 +50,10 @@ class PayMongoController extends Controller
|
||||||
switch ($event_name) {
|
switch ($event_name) {
|
||||||
case "payment.paid":
|
case "payment.paid":
|
||||||
return $this->handlePaymentPaid($event);
|
return $this->handlePaymentPaid($event);
|
||||||
|
break;
|
||||||
case "payment.failed":
|
case "payment.failed":
|
||||||
return $this->handlePaymentFailed($event);
|
return $this->handlePaymentPaid($event);
|
||||||
|
break;
|
||||||
case "payment.refunded": // TODO: handle refunds
|
case "payment.refunded": // TODO: handle refunds
|
||||||
case "payment.refund.updated":
|
case "payment.refund.updated":
|
||||||
case "checkout_session.payment.paid":
|
case "checkout_session.payment.paid":
|
||||||
|
|
@ -69,7 +74,6 @@ class PayMongoController extends Controller
|
||||||
if (!empty($obj)) {
|
if (!empty($obj)) {
|
||||||
// mark as paid
|
// mark as paid
|
||||||
$obj->setStatus(TransactionStatus::PAID);
|
$obj->setStatus(TransactionStatus::PAID);
|
||||||
$obj->setDatePay(new DateTime());
|
|
||||||
$this->em->flush();
|
$this->em->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +82,7 @@ class PayMongoController extends Controller
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function handlePaymentFailed($event)
|
protected function handlePaymentFailed(Request $req)
|
||||||
{
|
{
|
||||||
// TODO: do something about failed payments?
|
// TODO: do something about failed payments?
|
||||||
return $this->json([
|
return $this->json([
|
||||||
|
|
|
||||||
|
|
@ -1,355 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller;
|
|
||||||
|
|
||||||
use Doctrine\ORM\Query;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
|
||||||
|
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
|
|
||||||
|
|
||||||
use Catalyst\MenuBundle\Annotation\Menu;
|
|
||||||
|
|
||||||
use App\Entity\PriceTier;
|
|
||||||
use App\Entity\SupportedArea;
|
|
||||||
|
|
||||||
class PriceTierController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @Menu(selected="price_tier_list")
|
|
||||||
* @IsGranted("price_tier.list")
|
|
||||||
*/
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
return $this->render('price-tier/list.html.twig');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @IsGranted("price_tier.list")
|
|
||||||
*/
|
|
||||||
public function datatableRows(Request $req)
|
|
||||||
{
|
|
||||||
// get query builder
|
|
||||||
$qb = $this->getDoctrine()
|
|
||||||
->getRepository(PriceTier::class)
|
|
||||||
->createQueryBuilder('q');
|
|
||||||
|
|
||||||
// get datatable params
|
|
||||||
$datatable = $req->request->get('datatable');
|
|
||||||
|
|
||||||
// count total records
|
|
||||||
$tquery = $qb->select('COUNT(q)');
|
|
||||||
$this->setQueryFilters($datatable, $tquery);
|
|
||||||
$total = $tquery->getQuery()
|
|
||||||
->getSingleScalarResult();
|
|
||||||
|
|
||||||
// get current page number
|
|
||||||
$page = $datatable['pagination']['page'] ?? 1;
|
|
||||||
|
|
||||||
$perpage = $datatable['pagination']['perpage'];
|
|
||||||
$offset = ($page - 1) * $perpage;
|
|
||||||
|
|
||||||
// add metadata
|
|
||||||
$meta = [
|
|
||||||
'page' => $page,
|
|
||||||
'perpage' => $perpage,
|
|
||||||
'pages' => ceil($total / $perpage),
|
|
||||||
'total' => $total,
|
|
||||||
'sort' => 'asc',
|
|
||||||
'field' => 'id'
|
|
||||||
];
|
|
||||||
|
|
||||||
// build query
|
|
||||||
$query = $qb->select('q');
|
|
||||||
$this->setQueryFilters($datatable, $query);
|
|
||||||
|
|
||||||
// check if sorting is present, otherwise use default
|
|
||||||
if (isset($datatable['sort']['field']) && !empty($datatable['sort']['field'])) {
|
|
||||||
$order = $datatable['sort']['sort'] ?? 'asc';
|
|
||||||
$query->orderBy('q.' . $datatable['sort']['field'], $order);
|
|
||||||
} else {
|
|
||||||
$query->orderBy('q.id', 'asc');
|
|
||||||
}
|
|
||||||
|
|
||||||
// get rows for this page
|
|
||||||
$obj_rows = $query->setFirstResult($offset)
|
|
||||||
->setMaxResults($perpage)
|
|
||||||
->getQuery()
|
|
||||||
->getResult();
|
|
||||||
|
|
||||||
// process rows
|
|
||||||
$rows = [];
|
|
||||||
foreach ($obj_rows as $orow) {
|
|
||||||
// add row data
|
|
||||||
$row['id'] = $orow->getID();
|
|
||||||
$row['name'] = $orow->getName();
|
|
||||||
|
|
||||||
// add row metadata
|
|
||||||
$row['meta'] = [
|
|
||||||
'update_url' => '',
|
|
||||||
'delete_url' => ''
|
|
||||||
];
|
|
||||||
|
|
||||||
// add crud urls
|
|
||||||
if ($this->isGranted('price_tier.update'))
|
|
||||||
$row['meta']['update_url'] = $this->generateUrl('price_tier_update_form', ['id' => $row['id']]);
|
|
||||||
if ($this->isGranted('service_offering.delete'))
|
|
||||||
$row['meta']['delete_url'] = $this->generateUrl('price_tier_delete', ['id' => $row['id']]);
|
|
||||||
|
|
||||||
$rows[] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
// response
|
|
||||||
return $this->json([
|
|
||||||
'meta' => $meta,
|
|
||||||
'data' => $rows
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Menu(selected="price_tier.list")
|
|
||||||
* @IsGranted("price_tier.add")
|
|
||||||
*/
|
|
||||||
public function addForm(EntityManagerInterface $em)
|
|
||||||
{
|
|
||||||
$pt = new PriceTier();
|
|
||||||
|
|
||||||
// get the supported areas
|
|
||||||
$sets = $this->generateFormSets($em);
|
|
||||||
|
|
||||||
$params = [
|
|
||||||
'obj' => $pt,
|
|
||||||
'sets' => $sets,
|
|
||||||
'mode' => 'create',
|
|
||||||
];
|
|
||||||
|
|
||||||
// response
|
|
||||||
return $this->render('price-tier/form.html.twig', $params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @IsGranted("price_tier.add")
|
|
||||||
*/
|
|
||||||
public function addSubmit(Request $req, EntityManagerInterface $em, ValidatorInterface $validator)
|
|
||||||
{
|
|
||||||
// initialize error list
|
|
||||||
$error_array = [];
|
|
||||||
|
|
||||||
$pt = new PriceTier();
|
|
||||||
|
|
||||||
$error_array = $this->validateRequest($em, $req);
|
|
||||||
|
|
||||||
$this->setObject($pt, $req);
|
|
||||||
|
|
||||||
// validate
|
|
||||||
$errors = $validator->validate($pt);
|
|
||||||
|
|
||||||
// add errors to list
|
|
||||||
foreach ($errors as $error) {
|
|
||||||
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if any errors were found
|
|
||||||
if (!empty($error_array)) {
|
|
||||||
// return validation failure response
|
|
||||||
return $this->json([
|
|
||||||
'success' => false,
|
|
||||||
'errors' => $error_array
|
|
||||||
], 422);
|
|
||||||
}
|
|
||||||
|
|
||||||
// validated! save the entity
|
|
||||||
$em->persist($pt);
|
|
||||||
|
|
||||||
// set the price tier id for the selected supported areas
|
|
||||||
$this->updateSupportedAreas($em, $pt, $req);
|
|
||||||
|
|
||||||
$em->flush();
|
|
||||||
|
|
||||||
// return successful response
|
|
||||||
return $this->json([
|
|
||||||
'success' => 'Changes have been saved!'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Menu(selected="price_tier_list")
|
|
||||||
* @ParamConverter("pt", class="App\Entity\PriceTier")
|
|
||||||
* @IsGranted("price_tier.update")
|
|
||||||
*/
|
|
||||||
public function updateForm($id, EntityManagerInterface $em, PriceTier $pt)
|
|
||||||
{
|
|
||||||
// get the supported areas
|
|
||||||
$sets = $this->generateFormSets($em, $pt);
|
|
||||||
|
|
||||||
$params = [
|
|
||||||
'obj' => $pt,
|
|
||||||
'sets' => $sets,
|
|
||||||
'mode' => 'update',
|
|
||||||
];
|
|
||||||
|
|
||||||
// response
|
|
||||||
return $this->render('price-tier/form.html.twig', $params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ParamConverter("pt", class="App\Entity\PriceTier")
|
|
||||||
* @IsGranted("price_tier.update")
|
|
||||||
*/
|
|
||||||
public function updateSubmit(Request $req, EntityManagerInterface $em, ValidatorInterface $validator, PriceTier $pt)
|
|
||||||
{
|
|
||||||
// initialize error list
|
|
||||||
$error_array = [];
|
|
||||||
|
|
||||||
// clear supported areas of price tier
|
|
||||||
$this->clearPriceTierSupportedAreas($em, $pt);
|
|
||||||
|
|
||||||
$error_array = $this->validateRequest($em, $req);
|
|
||||||
$this->setObject($pt, $req);
|
|
||||||
|
|
||||||
// validate
|
|
||||||
$errors = $validator->validate($pt);
|
|
||||||
|
|
||||||
// add errors to list
|
|
||||||
foreach ($errors as $error) {
|
|
||||||
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if any errors were found
|
|
||||||
if (!empty($error_array)) {
|
|
||||||
// return validation failure response
|
|
||||||
return $this->json([
|
|
||||||
'success' => false,
|
|
||||||
'errors' => $error_array
|
|
||||||
], 422);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the price tier id for the selected supported areas
|
|
||||||
$this->updateSupportedAreas($em, $pt, $req);
|
|
||||||
|
|
||||||
// validated! save the entity
|
|
||||||
$em->flush();
|
|
||||||
|
|
||||||
// return successful response
|
|
||||||
return $this->json([
|
|
||||||
'success' => 'Changes have been saved!'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ParamConverter("pt", class="App\Entity\PriceTier")
|
|
||||||
* @IsGranted("price_tier.delete")
|
|
||||||
*/
|
|
||||||
public function deleteSubmit(EntityManagerInterface $em, PriceTier $pt)
|
|
||||||
{
|
|
||||||
// clear supported areas of price tier
|
|
||||||
$this->clearPriceTierSupportedAreas($em, $pt);
|
|
||||||
|
|
||||||
// delete this object
|
|
||||||
$em->remove($pt);
|
|
||||||
$em->flush();
|
|
||||||
|
|
||||||
// response
|
|
||||||
$response = new Response();
|
|
||||||
$response->setStatusCode(Response::HTTP_OK);
|
|
||||||
$response->send();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function validateRequest(EntityManagerInterface $em, Request $req)
|
|
||||||
{
|
|
||||||
// get areas
|
|
||||||
$areas = $req->request->get('areas');
|
|
||||||
|
|
||||||
// check if no areas selected aka empty
|
|
||||||
if (!empty($areas))
|
|
||||||
{
|
|
||||||
foreach ($areas as $area_id)
|
|
||||||
{
|
|
||||||
$supported_area = $em->getRepository(SupportedArea::class)->find($area_id);
|
|
||||||
|
|
||||||
if ($supported_area == null)
|
|
||||||
return ['areas' => 'Invalid area'];
|
|
||||||
|
|
||||||
// check if supported area already belongs to a price tier
|
|
||||||
if ($supported_area->getPriceTier() != null)
|
|
||||||
return ['areas' => 'Area already belongs to a price tier.'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function setObject(PriceTier $obj, Request $req)
|
|
||||||
{
|
|
||||||
// clear supported areas first
|
|
||||||
$obj->clearSupportedAreas();
|
|
||||||
|
|
||||||
$obj->setName($req->request->get('name'));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function clearPriceTierSupportedAreas(EntityManagerInterface $em, PriceTier $obj)
|
|
||||||
{
|
|
||||||
// find the supported areas set with the price tier
|
|
||||||
$areas = $em->getRepository(SupportedArea::class)->findBy(['price_tier' => $obj]);
|
|
||||||
|
|
||||||
if (!empty($areas))
|
|
||||||
{
|
|
||||||
// set the price tier id for the supported areas to null
|
|
||||||
foreach ($areas as $area)
|
|
||||||
{
|
|
||||||
$area->setPriceTier(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
$em->flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function updateSupportedAreas(EntityManagerInterface $em, PriceTier $obj, Request $req)
|
|
||||||
{
|
|
||||||
// get the selected areas
|
|
||||||
$areas = $req->request->get('areas');
|
|
||||||
|
|
||||||
// check if no areas selected aka empty
|
|
||||||
if (!empty($areas))
|
|
||||||
{
|
|
||||||
foreach ($areas as $area_id)
|
|
||||||
{
|
|
||||||
// get supported area
|
|
||||||
$supported_area = $em->getRepository(SupportedArea::class)->find($area_id);
|
|
||||||
|
|
||||||
if ($supported_area != null)
|
|
||||||
$supported_area->setPriceTier($obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function generateFormSets(EntityManagerInterface $em, PriceTier $pt = null)
|
|
||||||
{
|
|
||||||
// get the supported areas with no price tier id or price tier id is set to the one that is being updated
|
|
||||||
$areas = $em->getRepository(SupportedArea::class)->findBy(['price_tier' => array(null, $pt)]);
|
|
||||||
$areas_set = [];
|
|
||||||
foreach ($areas as $area)
|
|
||||||
{
|
|
||||||
$areas_set[$area->getID()] = $area->getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'areas' => $areas_set
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function setQueryFilters($datatable, QueryBuilder $query)
|
|
||||||
{
|
|
||||||
if (isset($datatable['query']['data-rows-search']) && !empty($datatable['query']['data-rows-search'])) {
|
|
||||||
$query->where('q.name LIKE :filter')
|
|
||||||
->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -236,10 +236,6 @@ class ReportController extends Controller
|
||||||
|
|
||||||
$reason = $jor->getReason();
|
$reason = $jor->getReason();
|
||||||
|
|
||||||
$dispatched_by = 'system';
|
|
||||||
if ($jor->getUser() != null)
|
|
||||||
$dispatched_by = $jor->getUser()->getFullName();
|
|
||||||
|
|
||||||
$res[] = [
|
$res[] = [
|
||||||
$jo->getID(),
|
$jo->getID(),
|
||||||
$jo->getDateSchedule()->format('m/d/Y H:i'),
|
$jo->getDateSchedule()->format('m/d/Y H:i'),
|
||||||
|
|
@ -248,7 +244,7 @@ class ReportController extends Controller
|
||||||
JORejectionReason::getName($jor->getReason()),
|
JORejectionReason::getName($jor->getReason()),
|
||||||
$jor->getContactPerson(),
|
$jor->getContactPerson(),
|
||||||
$jor->getRemarks(),
|
$jor->getRemarks(),
|
||||||
!empty($jor->getUser()) ? $jor->getUser()->getFullName() : "",
|
$jor->getUser()->getFullName(),
|
||||||
ServiceType::getName($jo->getServiceType()),
|
ServiceType::getName($jo->getServiceType()),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ use App\Ramcar\JOStatus;
|
||||||
use App\Ramcar\ServiceType;
|
use App\Ramcar\ServiceType;
|
||||||
use App\Ramcar\WillingToWaitContent;
|
use App\Ramcar\WillingToWaitContent;
|
||||||
use App\Ramcar\CustomerClassification;
|
use App\Ramcar\CustomerClassification;
|
||||||
use App\Ramcar\CustomerNotWaitReason;
|
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,6 @@ use Catalyst\ApiBundle\Component\Response as APIResponse;
|
||||||
use App\Ramcar\APIResult;
|
use App\Ramcar\APIResult;
|
||||||
|
|
||||||
use App\Entity\Vehicle;
|
use App\Entity\Vehicle;
|
||||||
use App\Entity\ItemType;
|
|
||||||
|
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
|
||||||
|
|
||||||
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
|
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
|
||||||
|
|
||||||
|
|
@ -30,7 +25,7 @@ class BatteryController extends ApiController
|
||||||
$this->acl_gen = $acl_gen;
|
$this->acl_gen = $acl_gen;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCompatibleBatteries(Request $req, $vid, EntityManagerInterface $em, PriceTierManager $pt_manager)
|
public function getCompatibleBatteries(Request $req, $vid, EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('tapi_battery_compatible.list', null, 'No access.');
|
$this->denyAccessUnlessGranted('tapi_battery_compatible.list', null, 'No access.');
|
||||||
|
|
||||||
|
|
@ -48,44 +43,13 @@ class BatteryController extends ApiController
|
||||||
return new APIResponse(false, $message);
|
return new APIResponse(false, $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get location from request
|
|
||||||
$lng = $req->request->get('longitude', '');
|
|
||||||
$lat = $req->request->get('latitude', '');
|
|
||||||
|
|
||||||
$batts = $vehicle->getActiveBatteries();
|
|
||||||
$pt_id = 0;
|
|
||||||
if ((!(empty($lng))) && (!(empty($lat))))
|
|
||||||
{
|
|
||||||
// get the price tier
|
|
||||||
$coordinates = new Point($lng, $lat);
|
|
||||||
|
|
||||||
$pt_id = $pt_manager->getPriceTier($coordinates);
|
|
||||||
}
|
|
||||||
|
|
||||||
// batteries
|
// batteries
|
||||||
$batt_list = [];
|
$batt_list = [];
|
||||||
|
// $batts = $vehicle->getBatteries();
|
||||||
|
$batts = $vehicle->getActiveBatteries();
|
||||||
foreach ($batts as $batt)
|
foreach ($batts as $batt)
|
||||||
{
|
{
|
||||||
// TODO: Add warranty_tnv to battery information
|
// TODO: Add warranty_tnv to battery information
|
||||||
// check if customer location is in a price tier location
|
|
||||||
if ($pt_id == 0)
|
|
||||||
$price = $batt->getSellingPrice();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// get item type for battery
|
|
||||||
$item_type = $em->getRepository(ItemType::class)->findOneBy(['code' => 'battery']);
|
|
||||||
if ($item_type == null)
|
|
||||||
$price = $batt->getSellingPrice();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$batt_id = $batt->getID();
|
|
||||||
|
|
||||||
// find the item price given price tier id and battery id
|
|
||||||
$price = $pt_manager->getItemPrice($pt_id, $item_type_id, $batt_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$batt_list[] = [
|
$batt_list[] = [
|
||||||
'id' => $batt->getID(),
|
'id' => $batt->getID(),
|
||||||
'mfg_id' => $batt->getManufacturer()->getID(),
|
'mfg_id' => $batt->getManufacturer()->getID(),
|
||||||
|
|
@ -94,7 +58,7 @@ class BatteryController extends ApiController
|
||||||
'model_name' => $batt->getModel()->getName(),
|
'model_name' => $batt->getModel()->getName(),
|
||||||
'size_id' => $batt->getSize()->getID(),
|
'size_id' => $batt->getSize()->getID(),
|
||||||
'size_name' => $batt->getSize()->getName(),
|
'size_name' => $batt->getSize()->getName(),
|
||||||
'price' => $price,
|
'price' => $batt->getSellingPrice(),
|
||||||
'wty_private' => $batt->getWarrantyPrivate(),
|
'wty_private' => $batt->getWarrantyPrivate(),
|
||||||
'wty_commercial' => $batt->getWarrantyCommercial(),
|
'wty_commercial' => $batt->getWarrantyCommercial(),
|
||||||
'image_url' => $this->getBatteryImageURL($req, $batt),
|
'image_url' => $this->getBatteryImageURL($req, $batt),
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ use App\Service\RiderTracker;
|
||||||
use App\Service\PromoLogger;
|
use App\Service\PromoLogger;
|
||||||
use App\Service\MapTools;
|
use App\Service\MapTools;
|
||||||
use App\Service\JobOrderManager;
|
use App\Service\JobOrderManager;
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
use App\Entity\JobOrder;
|
use App\Entity\JobOrder;
|
||||||
use App\Entity\CustomerVehicle;
|
use App\Entity\CustomerVehicle;
|
||||||
|
|
@ -80,8 +79,7 @@ class JobOrderController extends ApiController
|
||||||
FCMSender $fcmclient,
|
FCMSender $fcmclient,
|
||||||
RiderAssignmentHandlerInterface $rah, PromoLogger $promo_logger,
|
RiderAssignmentHandlerInterface $rah, PromoLogger $promo_logger,
|
||||||
HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger,
|
HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger,
|
||||||
HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em, JobOrderManager $jo_manager,
|
HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em, JobOrderManager $jo_manager)
|
||||||
PriceTierManager $pt_manager)
|
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('tapi_jo.request', null, 'No access.');
|
$this->denyAccessUnlessGranted('tapi_jo.request', null, 'No access.');
|
||||||
|
|
||||||
|
|
@ -167,17 +165,7 @@ class JobOrderController extends ApiController
|
||||||
// set JO source
|
// set JO source
|
||||||
$icrit->setSource(TransactionOrigin::THIRD_PARTY);
|
$icrit->setSource(TransactionOrigin::THIRD_PARTY);
|
||||||
|
|
||||||
// set price tier
|
$icrit->addEntry($data['batt'], $data['trade_in_type'], 1);
|
||||||
$pt_id = $pt_manager->getPriceTier($jo->getCoordinates());
|
|
||||||
$icrit->setPriceTier($pt_id);
|
|
||||||
|
|
||||||
// add the actual battery item first
|
|
||||||
$icrit->addEntry($data['batt'], null, 1);
|
|
||||||
|
|
||||||
// if we have a trade in, add it as well, assuming trade in battery == battery purchased
|
|
||||||
if (!empty($data['trade_in_type'])) {
|
|
||||||
$icrit->addEntry($data['batt'], $data['trade_in_type'], 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// send to invoice generator
|
// send to invoice generator
|
||||||
$invoice = $ic->generateInvoice($icrit);
|
$invoice = $ic->generateInvoice($icrit);
|
||||||
|
|
@ -239,10 +227,6 @@ class JobOrderController extends ApiController
|
||||||
// find nearest hubs
|
// find nearest hubs
|
||||||
$nearest_hubs = $hub_select->find($hub_criteria);
|
$nearest_hubs = $hub_select->find($hub_criteria);
|
||||||
|
|
||||||
// set filter flags for inventory and available riders
|
|
||||||
$hub_criteria->setInventoryCheck();
|
|
||||||
$hub_criteria->setRidersCheck();
|
|
||||||
|
|
||||||
if (!empty($nearest_hubs))
|
if (!empty($nearest_hubs))
|
||||||
{
|
{
|
||||||
// go through the hub list, find the nearest hub
|
// go through the hub list, find the nearest hub
|
||||||
|
|
|
||||||
|
|
@ -114,9 +114,7 @@ class Hub
|
||||||
public function getAvailableRiders()
|
public function getAvailableRiders()
|
||||||
{
|
{
|
||||||
$crit = Criteria::create();
|
$crit = Criteria::create();
|
||||||
$crit->where(Criteria::expr()->eq('flag_available', true))
|
$crit->where(Criteria::expr()->eq('flag_available', true));
|
||||||
->where(Criteria::expr()->eq('flag_active', true))
|
|
||||||
->where(Criteria::expr()->eq('current_job_order', null));
|
|
||||||
|
|
||||||
return $this->riders->matching($crit);
|
return $this->riders->matching($crit);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,24 +50,10 @@ class InvoiceItem
|
||||||
*/
|
*/
|
||||||
protected $battery;
|
protected $battery;
|
||||||
|
|
||||||
// battery size for trade in items
|
|
||||||
/**
|
|
||||||
* @ORM\ManyToOne(targetEntity="BatterySize")
|
|
||||||
* @ORM\JoinColumn(name="battery_size_id", referencedColumnName="id")
|
|
||||||
*/
|
|
||||||
protected $battery_size;
|
|
||||||
|
|
||||||
// trade in type
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=20)
|
|
||||||
*/
|
|
||||||
protected $trade_in_type;
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->title = '';
|
$this->title = '';
|
||||||
$this->price = 0.0;
|
$this->price = 0.0;
|
||||||
$this->trade_in_type = '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -129,26 +115,4 @@ class InvoiceItem
|
||||||
{
|
{
|
||||||
return $this->battery;
|
return $this->battery;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setBatterySize(BatterySize $battery_size)
|
|
||||||
{
|
|
||||||
$this->battery_size = $battery_size;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBatterySize()
|
|
||||||
{
|
|
||||||
return $this->battery_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTradeInType(string $trade_in_type)
|
|
||||||
{
|
|
||||||
$this->trade_in_type = $trade_in_type;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTradeInType()
|
|
||||||
{
|
|
||||||
return $this->trade_in_type;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Entity;
|
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Entity
|
|
||||||
* @ORM\Table(name="item_price")
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ItemPrice
|
|
||||||
{
|
|
||||||
// unique id
|
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
* @ORM\GeneratedValue(strategy="AUTO")
|
|
||||||
*/
|
|
||||||
protected $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\ManyToOne(targetEntity="PriceTier", inversedBy="item_prices")
|
|
||||||
* @ORM\JoinColumn(name="price_tier_id", referencedColumnName="id")
|
|
||||||
*/
|
|
||||||
protected $price_tier;
|
|
||||||
|
|
||||||
// item type
|
|
||||||
/**
|
|
||||||
* @ORM\ManyToOne(targetEntity="ItemType", inversedBy="items")
|
|
||||||
* @ORM\JoinColumn(name="item_type_id", referencedColumnName="id")
|
|
||||||
*/
|
|
||||||
protected $item_type;
|
|
||||||
|
|
||||||
// could be battery id or service offering id, loosely coupled
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
protected $item_id;
|
|
||||||
|
|
||||||
// current price
|
|
||||||
// NOTE: we need to move the decimal point two places to the left to get actual value
|
|
||||||
// we want to avoid floating point problems
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
protected $price;
|
|
||||||
|
|
||||||
public function getID()
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setPriceTier(PriceTier $price_tier)
|
|
||||||
{
|
|
||||||
$this->price_tier = $price_tier;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPriceTier()
|
|
||||||
{
|
|
||||||
return $this->price_tier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setItemType(ItemType $item_type)
|
|
||||||
{
|
|
||||||
$this->item_type = $item_type;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getItemType()
|
|
||||||
{
|
|
||||||
return $this->item_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setItemID($item_id)
|
|
||||||
{
|
|
||||||
$this->item_id = $item_id;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getItemID()
|
|
||||||
{
|
|
||||||
return $this->item_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setPrice($price)
|
|
||||||
{
|
|
||||||
$this->price = $price;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPrice()
|
|
||||||
{
|
|
||||||
return $this->price;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Entity;
|
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
|
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Entity
|
|
||||||
* @ORM\Table(name="item_type", indexes={
|
|
||||||
* @ORM\Index(name="item_type_idx", columns={"code"})
|
|
||||||
* })
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ItemType
|
|
||||||
{
|
|
||||||
// unique id
|
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
* @ORM\GeneratedValue(strategy="AUTO")
|
|
||||||
*/
|
|
||||||
protected $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=80)
|
|
||||||
* @Assert\NotBlank()
|
|
||||||
*/
|
|
||||||
protected $name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=80)
|
|
||||||
* @Assert\NotBlank()
|
|
||||||
*/
|
|
||||||
protected $code;
|
|
||||||
|
|
||||||
// items under an item type
|
|
||||||
/**
|
|
||||||
* @ORM\OneToMany(targetEntity="ItemPrice", mappedBy="item_type")
|
|
||||||
*/
|
|
||||||
protected $items;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->code = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getID()
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setName($name)
|
|
||||||
{
|
|
||||||
$this->name = $name;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName()
|
|
||||||
{
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCode($code)
|
|
||||||
{
|
|
||||||
$this->code = $code;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCode()
|
|
||||||
{
|
|
||||||
return $this->code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getItems()
|
|
||||||
{
|
|
||||||
return $this->items;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -441,12 +441,6 @@ class JobOrder
|
||||||
*/
|
*/
|
||||||
protected $flag_cust_new;
|
protected $flag_cust_new;
|
||||||
|
|
||||||
// only for tire service, if it requires sealant or not
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="boolean")
|
|
||||||
*/
|
|
||||||
protected $flag_sealant;
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->date_create = new DateTime();
|
$this->date_create = new DateTime();
|
||||||
|
|
@ -464,7 +458,6 @@ class JobOrder
|
||||||
$this->trade_in_type = null;
|
$this->trade_in_type = null;
|
||||||
$this->flag_rider_rating = false;
|
$this->flag_rider_rating = false;
|
||||||
$this->flag_coolant = false;
|
$this->flag_coolant = false;
|
||||||
$this->flag_sealant = false;
|
|
||||||
|
|
||||||
$this->priority = 0;
|
$this->priority = 0;
|
||||||
$this->meta = [];
|
$this->meta = [];
|
||||||
|
|
@ -1263,15 +1256,4 @@ class JobOrder
|
||||||
return $this->flag_cust_new;
|
return $this->flag_cust_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setHasSealant($flag = true)
|
|
||||||
{
|
|
||||||
$this->flag_sealant = $flag;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function hasSealant()
|
|
||||||
{
|
|
||||||
return $this->flag_sealant;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Entity;
|
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Entity
|
|
||||||
* @ORM\Table(name="price_tier")
|
|
||||||
*/
|
|
||||||
|
|
||||||
class PriceTier
|
|
||||||
{
|
|
||||||
// unique id
|
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
* @ORM\GeneratedValue(strategy="AUTO")
|
|
||||||
*/
|
|
||||||
protected $id;
|
|
||||||
|
|
||||||
// name of price tier
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=80)
|
|
||||||
*/
|
|
||||||
protected $name;
|
|
||||||
|
|
||||||
// supported areas under price tier
|
|
||||||
/**
|
|
||||||
* @ORM\OneToMany(targetEntity="SupportedArea", mappedBy="price_tier");
|
|
||||||
*/
|
|
||||||
protected $supported_areas;
|
|
||||||
|
|
||||||
// items under a price tier
|
|
||||||
/**
|
|
||||||
* @ORM\OneToMany(targetEntity="ItemPrice", mappedBy="price_tier")
|
|
||||||
*/
|
|
||||||
protected $item_prices;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->supported_areas = new ArrayCollection();
|
|
||||||
$this->items = new ArrayCollection();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getID()
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setName($name)
|
|
||||||
{
|
|
||||||
$this->name = $name;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName()
|
|
||||||
{
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSupportedAreaObjects()
|
|
||||||
{
|
|
||||||
return $this->supported_areas;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSupportedAreas()
|
|
||||||
{
|
|
||||||
$str_supported_areas = [];
|
|
||||||
foreach ($this->supported_areas as $supported_area)
|
|
||||||
$str_supported_areas[] = $supported_area->getID();
|
|
||||||
|
|
||||||
return $str_supported_areas;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function clearSupportedAreas()
|
|
||||||
{
|
|
||||||
$this->supported_areas->clear();
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getItemPrices()
|
|
||||||
{
|
|
||||||
return $this->item_prices;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,6 @@ use Catalyst\AuthBundle\Entity\Role as BaseRole;
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
|
||||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -17,19 +16,6 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
*/
|
*/
|
||||||
class Role extends BaseRole
|
class Role extends BaseRole
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\Column(type="string", length=80)
|
|
||||||
* @Assert\NotBlank()
|
|
||||||
*/
|
|
||||||
protected $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=80)
|
|
||||||
* @Assert\NotBlank()
|
|
||||||
*/
|
|
||||||
protected $name;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToMany(targetEntity="User", mappedBy="roles", fetch="EXTRA_LAZY")
|
* @ORM\ManyToMany(targetEntity="User", mappedBy="roles", fetch="EXTRA_LAZY")
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -39,24 +39,9 @@ class SupportedArea
|
||||||
*/
|
*/
|
||||||
protected $coverage_area;
|
protected $coverage_area;
|
||||||
|
|
||||||
// prevent certain hub filters from being used
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="json", nullable=true)
|
|
||||||
*/
|
|
||||||
protected $hub_filter_exceptions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\ManyToOne(targetEntity="PriceTier", inversedBy="supported_areas")
|
|
||||||
* @ORM\JoinColumn(name="price_tier_id", referencedColumnName="id", nullable=true)
|
|
||||||
*/
|
|
||||||
protected $price_tier;
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->date_create = new DateTime();
|
$this->date_create = new DateTime();
|
||||||
|
|
||||||
$this->price_tier = null;
|
|
||||||
$this->hub_filter_exceptions = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -72,7 +57,7 @@ class SupportedArea
|
||||||
|
|
||||||
public function getDateCreate()
|
public function getDateCreate()
|
||||||
{
|
{
|
||||||
return $this->date_create;
|
return $this->date_Create;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setName($name)
|
public function setName($name)
|
||||||
|
|
@ -97,27 +82,5 @@ class SupportedArea
|
||||||
{
|
{
|
||||||
return $this->coverage_area;
|
return $this->coverage_area;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPriceTier(PriceTier $price_tier = null)
|
|
||||||
{
|
|
||||||
$this->price_tier = $price_tier;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPriceTier()
|
|
||||||
{
|
|
||||||
return $this->price_tier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setHubFilterExceptions($exceptions)
|
|
||||||
{
|
|
||||||
$this->hub_filter_exceptions = $exceptions;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHubFilterExceptions()
|
|
||||||
{
|
|
||||||
return $this->hub_filter_exceptions;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,20 +58,17 @@ class GatewayTransactionListener
|
||||||
'gateway_transaction' => $gt_obj,
|
'gateway_transaction' => $gt_obj,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// make sure the object exists and has not been processed yet
|
if (!empty($obj)) {
|
||||||
if (!empty($obj) && $obj->getStatus() === InsuranceApplicationStatus::CREATED) {
|
|
||||||
// mark as paid
|
// mark as paid
|
||||||
$obj->setDatePay(new DateTime());
|
$obj->setDatePay(new DateTime());
|
||||||
$obj->setStatus(InsuranceApplicationStatus::PAID);
|
$obj->setStatus(InsuranceApplicationStatus::PAID);
|
||||||
$this->em->flush();
|
$this->em->flush();
|
||||||
|
}
|
||||||
|
|
||||||
// flag on api as paid
|
// flag on api as paid
|
||||||
$result = $this->ic->tagApplicationPaid($obj->getExtTransactionId());
|
$result = $this->ic->tagApplicationPaid($obj->getID());
|
||||||
|
if (!$result['success'] || $result['response']['transaction_code'] !== 'GR004') {
|
||||||
// something went wrong with insurance api
|
error_log("INSURANCE MARK AS PAID FAILED FOR " . $obj->getID() . ": " . $result['error']['message']);
|
||||||
if (!$result['success'] || $result['response']['transaction_code'] !== 'GR004') {
|
|
||||||
error_log("INSURANCE MARK AS PAID FAILED FOR " . $obj->getID() . ": " . $result['error']['message']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,19 +11,14 @@ use App\Ramcar\TradeInType;
|
||||||
|
|
||||||
use App\Entity\Battery;
|
use App\Entity\Battery;
|
||||||
use App\Entity\ServiceOffering;
|
use App\Entity\ServiceOffering;
|
||||||
use App\Entity\ItemType;
|
|
||||||
|
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
class BatteryReplacementWarranty implements InvoiceRuleInterface
|
class BatteryReplacementWarranty implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $pt_manager;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, PriceTierManager $pt_manager)
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->pt_manager = $pt_manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -34,7 +29,6 @@ class BatteryReplacementWarranty implements InvoiceRuleInterface
|
||||||
public function compute($criteria, &$total)
|
public function compute($criteria, &$total)
|
||||||
{
|
{
|
||||||
$stype = $criteria->getServiceType();
|
$stype = $criteria->getServiceType();
|
||||||
$pt_id = $criteria->getPriceTier();
|
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
if ($stype == $this->getID())
|
if ($stype == $this->getID())
|
||||||
|
|
@ -46,14 +40,7 @@ class BatteryReplacementWarranty implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
$batt = $entry['battery'];
|
$batt = $entry['battery'];
|
||||||
$qty = 1;
|
$qty = 1;
|
||||||
|
$price = $this->getServiceTypeFee();
|
||||||
// check if price tier has item price
|
|
||||||
$pt_price = $this->getPriceTierItemPrice($pt_id);
|
|
||||||
|
|
||||||
if ($pt_price == null)
|
|
||||||
$price = $this->getServiceTypeFee();
|
|
||||||
else
|
|
||||||
$price = $pt_price;
|
|
||||||
|
|
||||||
$items[] = [
|
$items[] = [
|
||||||
'service_type' => $this->getID(),
|
'service_type' => $this->getID(),
|
||||||
|
|
@ -116,46 +103,20 @@ class BatteryReplacementWarranty implements InvoiceRuleInterface
|
||||||
$qty = $item['quantity'];
|
$qty = $item['quantity'];
|
||||||
if ($qty < 1)
|
if ($qty < 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (empty($item['trade_in']))
|
// if this is a trade in, add trade in
|
||||||
{
|
if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in']))
|
||||||
|
$trade_in = $item['trade_in'];
|
||||||
|
else
|
||||||
$trade_in = null;
|
$trade_in = null;
|
||||||
$criteria->addEntry($battery, $trade_in, $qty);
|
|
||||||
}
|
$criteria->addEntry($battery, $trade_in, $qty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPriceTierItemPrice($pt_id)
|
|
||||||
{
|
|
||||||
// price_tier is default
|
|
||||||
if ($pt_id == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the item type for service offering
|
|
||||||
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'service_offering']);
|
|
||||||
if ($item_type == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the service offering
|
|
||||||
$code = 'battery_replacement_warranty_fee';
|
|
||||||
$service = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
|
||||||
|
|
||||||
// check if service is null. If null, return null
|
|
||||||
if ($service == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$item_id = $service->getID();
|
|
||||||
|
|
||||||
$price = $this->pt_manager->getItemPrice($pt_id, $item_type_id, $item_id);
|
|
||||||
|
|
||||||
return $price;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected function getTitle($battery)
|
protected function getTitle($battery)
|
||||||
{
|
{
|
||||||
$title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName() . ' - Service Unit';
|
$title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName() . ' - Service Unit';
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,14 @@ use App\Ramcar\TradeInType;
|
||||||
use App\Ramcar\ServiceType;
|
use App\Ramcar\ServiceType;
|
||||||
|
|
||||||
use App\Entity\Battery;
|
use App\Entity\Battery;
|
||||||
use App\Entity\ItemType;
|
|
||||||
|
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
class BatterySales implements InvoiceRuleInterface
|
class BatterySales implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $pt_manager;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, PriceTierManager $pt_manager)
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->pt_manager = $pt_manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -33,7 +28,6 @@ class BatterySales implements InvoiceRuleInterface
|
||||||
public function compute($criteria, &$total)
|
public function compute($criteria, &$total)
|
||||||
{
|
{
|
||||||
$stype = $criteria->getServiceType();
|
$stype = $criteria->getServiceType();
|
||||||
$pt = $criteria->getPriceTier();
|
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
if ($stype == $this->getID())
|
if ($stype == $this->getID())
|
||||||
|
|
@ -42,28 +36,19 @@ class BatterySales implements InvoiceRuleInterface
|
||||||
$entries = $criteria->getEntries();
|
$entries = $criteria->getEntries();
|
||||||
foreach($entries as $entry)
|
foreach($entries as $entry)
|
||||||
{
|
{
|
||||||
|
$batt = $entry['battery'];
|
||||||
$qty = $entry['qty'];
|
$qty = $entry['qty'];
|
||||||
$trade_in = null;
|
$trade_in = null;
|
||||||
|
|
||||||
// check if entry is for trade in
|
|
||||||
if (isset($entry['trade_in']))
|
if (isset($entry['trade_in']))
|
||||||
$trade_in = $entry['trade_in'];
|
$trade_in = $entry['trade_in'];
|
||||||
|
|
||||||
// entry is a battery purchase
|
$size = $batt->getSize();
|
||||||
|
|
||||||
if ($trade_in == null)
|
if ($trade_in == null)
|
||||||
{
|
{
|
||||||
// safe to get entry with battery key since CRM and apps
|
// battery purchase
|
||||||
// will set this for a battery purchase and trade_in will
|
$price = $batt->getSellingPrice();
|
||||||
// will not be set
|
|
||||||
$batt = $entry['battery'];
|
|
||||||
|
|
||||||
// check if price tier has item price for battery
|
|
||||||
$pt_price = $this->getPriceTierItemPrice($pt, $batt);
|
|
||||||
|
|
||||||
if ($pt_price == null)
|
|
||||||
$price = $batt->getSellingPrice();
|
|
||||||
else
|
|
||||||
$price = $pt_price;
|
|
||||||
|
|
||||||
$items[] = [
|
$items[] = [
|
||||||
'service_type' => $this->getID(),
|
'service_type' => $this->getID(),
|
||||||
|
|
@ -103,49 +88,32 @@ class BatterySales implements InvoiceRuleInterface
|
||||||
// check if this is a valid battery
|
// check if this is a valid battery
|
||||||
foreach ($invoice_items as $item)
|
foreach ($invoice_items as $item)
|
||||||
{
|
{
|
||||||
if (isset($item['battery']))
|
$battery = $this->em->getRepository(Battery::class)->find($item['battery']);
|
||||||
|
|
||||||
|
if (empty($battery))
|
||||||
{
|
{
|
||||||
$battery = $this->em->getRepository(Battery::class)->find($item['battery']);
|
$error = 'Invalid battery specified.';
|
||||||
|
return $error;
|
||||||
if (empty($battery))
|
|
||||||
{
|
|
||||||
$error = 'Invalid battery specified.';
|
|
||||||
return $error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// quantity
|
|
||||||
$qty = $item['quantity'];
|
|
||||||
if ($qty < 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$trade_in = null;
|
|
||||||
$criteria->addEntry($battery, $trade_in, $qty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// quantity
|
||||||
|
$qty = $item['quantity'];
|
||||||
|
if ($qty < 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// if this is a trade in, add trade in
|
||||||
|
if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in']))
|
||||||
|
$trade_in = $item['trade_in'];
|
||||||
|
else
|
||||||
|
$trade_in = null;
|
||||||
|
|
||||||
|
$criteria->addEntry($battery, $trade_in, $qty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPriceTierItemPrice($pt_id, $batt)
|
|
||||||
{
|
|
||||||
// price tier is default
|
|
||||||
if ($pt_id == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the item type battery
|
|
||||||
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'battery']);
|
|
||||||
if ($item_type == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$item_id = $batt->getID();
|
|
||||||
|
|
||||||
$price = $this->pt_manager->getItemPrice($pt_id, $item_type_id, $item_id);
|
|
||||||
|
|
||||||
return $price;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getTitle($battery)
|
protected function getTitle($battery)
|
||||||
{
|
{
|
||||||
$title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName();
|
$title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName();
|
||||||
|
|
|
||||||
|
|
@ -11,19 +11,14 @@ use App\Ramcar\ServiceType;
|
||||||
|
|
||||||
use App\Entity\ServiceOffering;
|
use App\Entity\ServiceOffering;
|
||||||
use App\Entity\CustomerVehicle;
|
use App\Entity\CustomerVehicle;
|
||||||
use App\Entity\ItemType;
|
|
||||||
|
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
class Fuel implements InvoiceRuleInterface
|
class Fuel implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $pt_manager;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, PriceTierManager $pt_manager)
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->pt_manager = $pt_manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -34,7 +29,6 @@ class Fuel implements InvoiceRuleInterface
|
||||||
public function compute($criteria, &$total)
|
public function compute($criteria, &$total)
|
||||||
{
|
{
|
||||||
$stype = $criteria->getServiceType();
|
$stype = $criteria->getServiceType();
|
||||||
$pt_id = $criteria->getPriceTier();
|
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
|
|
||||||
|
|
@ -42,13 +36,7 @@ class Fuel implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
$cv = $criteria->getCustomerVehicle();
|
$cv = $criteria->getCustomerVehicle();
|
||||||
|
|
||||||
// check if price tier has item price
|
$fee = $this->getServiceTypeFee($cv);
|
||||||
$pt_price = $this->getPriceTierItemPrice($pt_id, $cv);
|
|
||||||
|
|
||||||
if ($pt_price == null)
|
|
||||||
$service_price = $this->getServiceTypeFee($cv);
|
|
||||||
else
|
|
||||||
$service_price = $pt_price;
|
|
||||||
|
|
||||||
$ftype = $cv->getFuelType();
|
$ftype = $cv->getFuelType();
|
||||||
|
|
||||||
|
|
@ -58,10 +46,10 @@ class Fuel implements InvoiceRuleInterface
|
||||||
'service_type' => $this->getID(),
|
'service_type' => $this->getID(),
|
||||||
'qty' => $qty,
|
'qty' => $qty,
|
||||||
'title' => $this->getServiceTitle($ftype),
|
'title' => $this->getServiceTitle($ftype),
|
||||||
'price' => $service_price,
|
'price' => $fee,
|
||||||
];
|
];
|
||||||
|
|
||||||
$qty_fee = bcmul($qty, $service_price, 2);
|
$qty_fee = bcmul($qty, $fee, 2);
|
||||||
$total_price = $qty_fee;
|
$total_price = $qty_fee;
|
||||||
|
|
||||||
switch ($ftype)
|
switch ($ftype)
|
||||||
|
|
@ -69,15 +57,7 @@ class Fuel implements InvoiceRuleInterface
|
||||||
case FuelType::GAS:
|
case FuelType::GAS:
|
||||||
case FuelType::DIESEL:
|
case FuelType::DIESEL:
|
||||||
$qty = 1;
|
$qty = 1;
|
||||||
|
$price = $this->getFuelFee($ftype);
|
||||||
// check if price tier has item price for fuel type
|
|
||||||
$pt_price = $this->getPriceTierFuelItemPrice($pt_id, $ftype);
|
|
||||||
|
|
||||||
if ($pt_price == null)
|
|
||||||
$price = $this->getFuelFee($ftype);
|
|
||||||
else
|
|
||||||
$price = $pt_price;
|
|
||||||
|
|
||||||
$items[] = [
|
$items[] = [
|
||||||
'service_type' => $this->getID(),
|
'service_type' => $this->getID(),
|
||||||
'qty' => $qty,
|
'qty' => $qty,
|
||||||
|
|
@ -158,70 +138,6 @@ class Fuel implements InvoiceRuleInterface
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPriceTierItemPrice($pt_id, CustomerVehicle $cv)
|
|
||||||
{
|
|
||||||
// price_tier is default
|
|
||||||
if ($pt_id == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the item type for service offering
|
|
||||||
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'service_offering']);
|
|
||||||
if ($item_type == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the service offering
|
|
||||||
// check if customer vehicle has a motolite battery
|
|
||||||
// if yes, set the code to the motolite user service fee
|
|
||||||
if ($cv->hasMotoliteBattery())
|
|
||||||
$code = 'motolite_user_service_fee';
|
|
||||||
else
|
|
||||||
$code = 'fuel_service_fee';
|
|
||||||
|
|
||||||
$service = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
|
||||||
|
|
||||||
// check if service is null. If null, return null
|
|
||||||
if ($service == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$item_id = $service->getID();
|
|
||||||
|
|
||||||
$price = $this->pt_manager->getItemPrice($pt_id, $item_type_id, $item_id);
|
|
||||||
|
|
||||||
return $price;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getPriceTierFuelItemPrice($pt_id, $fuel_type)
|
|
||||||
{
|
|
||||||
// price_tier is default
|
|
||||||
if ($pt_id == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the item type for service offering
|
|
||||||
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'service_offering']);
|
|
||||||
if ($item_type == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the service offering
|
|
||||||
$code = '';
|
|
||||||
if ($fuel_type == FuelType::GAS)
|
|
||||||
$code = 'fuel_gas_fee';
|
|
||||||
if ($fuel_type == FuelType::DIESEL)
|
|
||||||
$code = 'fuel_diesel_fee';
|
|
||||||
$service = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
|
||||||
|
|
||||||
// check if service is null. If null, return null
|
|
||||||
if ($service == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$item_id = $service->getID();
|
|
||||||
|
|
||||||
$price = $this->pt_manager->getItemPrice($pt_id, $item_type_id, $item_id);
|
|
||||||
|
|
||||||
return $price;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getTitle($fuel_type)
|
protected function getTitle($fuel_type)
|
||||||
{
|
{
|
||||||
$title = '4L - ' . ucfirst($fuel_type);
|
$title = '4L - ' . ucfirst($fuel_type);
|
||||||
|
|
|
||||||
|
|
@ -8,21 +8,16 @@ use App\InvoiceRuleInterface;
|
||||||
|
|
||||||
use App\Entity\ServiceOffering;
|
use App\Entity\ServiceOffering;
|
||||||
use App\Entity\CustomerVehicle;
|
use App\Entity\CustomerVehicle;
|
||||||
use App\Entity\ItemType;
|
|
||||||
|
|
||||||
use App\Ramcar\TransactionOrigin;
|
use App\Ramcar\TransactionOrigin;
|
||||||
|
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
class Jumpstart implements InvoiceRuleInterface
|
class Jumpstart implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $pt_manager;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, PriceTierManager $pt_manager)
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->pt_manager = $pt_manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -34,21 +29,13 @@ class Jumpstart implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
$stype = $criteria->getServiceType();
|
$stype = $criteria->getServiceType();
|
||||||
$source = $criteria->getSource();
|
$source = $criteria->getSource();
|
||||||
$pt_id = $criteria->getPriceTier();
|
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
|
|
||||||
if ($stype == $this->getID())
|
if ($stype == $this->getID())
|
||||||
{
|
{
|
||||||
$cv = $criteria->getCustomerVehicle();
|
$cv = $criteria->getCustomerVehicle();
|
||||||
|
$fee = $this->getServiceTypeFee($source, $cv);
|
||||||
// check if price tier has item price
|
|
||||||
$pt_price = $this->getPriceTierItemPrice($pt_id, $source, $cv);
|
|
||||||
|
|
||||||
if ($pt_price == null)
|
|
||||||
$price = $this->getServiceTypeFee($source, $cv);
|
|
||||||
else
|
|
||||||
$price = $pt_price;
|
|
||||||
|
|
||||||
// add the service fee to items
|
// add the service fee to items
|
||||||
$qty = 1;
|
$qty = 1;
|
||||||
|
|
@ -56,10 +43,10 @@ class Jumpstart implements InvoiceRuleInterface
|
||||||
'service_type' => $this->getID(),
|
'service_type' => $this->getID(),
|
||||||
'qty' => $qty,
|
'qty' => $qty,
|
||||||
'title' => $this->getServiceTitle(),
|
'title' => $this->getServiceTitle(),
|
||||||
'price' => $price,
|
'price' => $fee,
|
||||||
];
|
];
|
||||||
|
|
||||||
$qty_price = bcmul($price, $qty, 2);
|
$qty_price = bcmul($fee, $qty, 2);
|
||||||
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
|
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,8 +55,18 @@ class Jumpstart implements InvoiceRuleInterface
|
||||||
|
|
||||||
public function getServiceTypeFee($source, CustomerVehicle $cv)
|
public function getServiceTypeFee($source, CustomerVehicle $cv)
|
||||||
{
|
{
|
||||||
// get the service fee code, depending on the JO source and if customer vehicle has a motolite battery
|
// check the source of JO
|
||||||
$code = $this->getServiceFeeCode($cv, $source);
|
// (1) if from app, service fee is 0 if motolite user. jumpstart fee for app if non-motolite user.
|
||||||
|
// (2) any other source, jumpstart fees are charged whether motolite user or not
|
||||||
|
if ($source == TransactionOrigin::MOBILE_APP)
|
||||||
|
{
|
||||||
|
if ($cv->hasMotoliteBattery())
|
||||||
|
$code = 'motolite_user_service_fee';
|
||||||
|
else
|
||||||
|
$code = 'jumpstart_fee_mobile_app';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$code = 'jumpstart_fee';
|
||||||
|
|
||||||
$fee = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
$fee = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
||||||
|
|
||||||
|
|
@ -89,68 +86,10 @@ class Jumpstart implements InvoiceRuleInterface
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPriceTierItemPrice($pt_id, $source, $cv)
|
|
||||||
{
|
|
||||||
// price_tier is default
|
|
||||||
if ($pt_id == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the item type for service offering
|
|
||||||
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'service_offering']);
|
|
||||||
if ($item_type == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// get the service fee code, depending on the JO source and if customer vehicle has a motolite battery
|
|
||||||
$code = $this->getServiceFeeCode($cv, $source);
|
|
||||||
|
|
||||||
// find the service offering
|
|
||||||
$service = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
|
||||||
|
|
||||||
// check if service is null. If null, return null
|
|
||||||
if ($service == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$item_id = $service->getID();
|
|
||||||
|
|
||||||
$price = $this->pt_manager->getItemPrice($pt_id, $item_type_id, $item_id);
|
|
||||||
|
|
||||||
return $price;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getServiceTitle()
|
protected function getServiceTitle()
|
||||||
{
|
{
|
||||||
$title = 'Service - Troubleshooting fee';
|
$title = 'Service - Troubleshooting fee';
|
||||||
|
|
||||||
return $title;
|
return $title;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getServiceFeeCode(CustomerVehicle $cv, $source)
|
|
||||||
{
|
|
||||||
// check the source of JO
|
|
||||||
// (1) if from app, service fee is 0 if motolite user. jumpstart fee for app if non-motolite user.
|
|
||||||
// (2) any other source, jumpstart fees are charged whether motolite user or not. Service fees for non-motolite
|
|
||||||
// and motolite users are now different (used to be the same)
|
|
||||||
if ($source == TransactionOrigin::MOBILE_APP)
|
|
||||||
{
|
|
||||||
if ($cv->hasMotoliteBattery())
|
|
||||||
$code = 'motolite_user_service_fee';
|
|
||||||
else
|
|
||||||
$code = 'jumpstart_fee_mobile_app';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
error_log('hotline');
|
|
||||||
if ($cv->hasMotoliteBattery())
|
|
||||||
{
|
|
||||||
error_log('has motolite battery');
|
|
||||||
$code = 'motolite_user_jumpstart_fee';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$code = 'jumpstart_fee';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $code;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,14 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||||
use App\InvoiceRuleInterface;
|
use App\InvoiceRuleInterface;
|
||||||
|
|
||||||
use App\Entity\ServiceOffering;
|
use App\Entity\ServiceOffering;
|
||||||
use App\Entity\ItemType;
|
|
||||||
use App\Entity\CustomerVehicle;
|
|
||||||
|
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
class JumpstartWarranty implements InvoiceRuleInterface
|
class JumpstartWarranty implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $pt_manager;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, PriceTierManager $pt_manager)
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->pt_manager = $pt_manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -31,21 +25,12 @@ class JumpstartWarranty implements InvoiceRuleInterface
|
||||||
public function compute($criteria, &$total)
|
public function compute($criteria, &$total)
|
||||||
{
|
{
|
||||||
$stype = $criteria->getServiceType();
|
$stype = $criteria->getServiceType();
|
||||||
$pt_id = $criteria->getPriceTier();
|
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
|
|
||||||
if ($stype == $this->getID())
|
if ($stype == $this->getID())
|
||||||
{
|
{
|
||||||
$cv = $criteria->getCustomerVehicle();
|
$fee = $this->getServiceTypeFee();
|
||||||
|
|
||||||
// check if price tier has item price
|
|
||||||
$pt_price = $this->getPriceTierItemPrice($pt_id, $cv);
|
|
||||||
|
|
||||||
if ($pt_price == null)
|
|
||||||
$price = $this->getServiceTypeFee($cv);
|
|
||||||
else
|
|
||||||
$price = $pt_price;
|
|
||||||
|
|
||||||
// add the service fee to items
|
// add the service fee to items
|
||||||
$qty = 1;
|
$qty = 1;
|
||||||
|
|
@ -53,24 +38,19 @@ class JumpstartWarranty implements InvoiceRuleInterface
|
||||||
'service_type' => $this->getID(),
|
'service_type' => $this->getID(),
|
||||||
'qty' => $qty,
|
'qty' => $qty,
|
||||||
'title' => $this->getServiceTitle(),
|
'title' => $this->getServiceTitle(),
|
||||||
'price' => $price,
|
'price' => $fee,
|
||||||
];
|
];
|
||||||
|
|
||||||
$qty_price = bcmul($price, $qty, 2);
|
$qty_price = bcmul($fee, $qty, 2);
|
||||||
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
|
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getServiceTypeFee(CustomerVehicle $cv)
|
public function getServiceTypeFee()
|
||||||
{
|
{
|
||||||
// check if user has motolite battery.
|
$code = 'jumpstart_warranty_fee';
|
||||||
// Motolite users now have a service fee for jumpstart warranty
|
|
||||||
if ($cv->hasMotoliteBattery())
|
|
||||||
$code = 'motolite_user_jumpstart_warranty_fee';
|
|
||||||
else
|
|
||||||
$code = 'jumpstart_warranty_fee';
|
|
||||||
|
|
||||||
// find the service fee using the code
|
// find the service fee using the code
|
||||||
// if we can't find the fee, return 0
|
// if we can't find the fee, return 0
|
||||||
|
|
@ -92,39 +72,6 @@ class JumpstartWarranty implements InvoiceRuleInterface
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPriceTierItemPrice($pt_id, CustomerVehicle $cv)
|
|
||||||
{
|
|
||||||
// price_tier is default
|
|
||||||
if ($pt_id == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the item type for service offering
|
|
||||||
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'service_offering']);
|
|
||||||
if ($item_type == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the service offering
|
|
||||||
// check if user has motolite battery.
|
|
||||||
// Motolite users now have a service fee for jumpstart warranty
|
|
||||||
if ($cv->hasMotoliteBattery())
|
|
||||||
$code = 'motolite_user_jumpstart_warranty_fee';
|
|
||||||
else
|
|
||||||
$code = 'jumpstart_warranty_fee';
|
|
||||||
|
|
||||||
$service = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
|
||||||
|
|
||||||
// check if service is null. If null, return null
|
|
||||||
if ($service == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$item_id = $service->getID();
|
|
||||||
|
|
||||||
$price = $this->pt_manager->getItemPrice($pt_id, $item_type_id, $item_id);
|
|
||||||
|
|
||||||
return $price;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getServiceTitle()
|
protected function getServiceTitle()
|
||||||
{
|
{
|
||||||
$title = 'Service - Troubleshooting fee';
|
$title = 'Service - Troubleshooting fee';
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,14 @@ use App\Ramcar\ServiceType;
|
||||||
|
|
||||||
use App\Entity\ServiceOffering;
|
use App\Entity\ServiceOffering;
|
||||||
use App\Entity\CustomerVehicle;
|
use App\Entity\CustomerVehicle;
|
||||||
use App\Entity\ItemType;
|
|
||||||
|
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
class Overheat implements InvoiceRuleInterface
|
class Overheat implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $pt_manager;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, PriceTierManager $pt_manager)
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->pt_manager = $pt_manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -34,22 +29,13 @@ class Overheat implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
$stype = $criteria->getServiceType();
|
$stype = $criteria->getServiceType();
|
||||||
$has_coolant = $criteria->hasCoolant();
|
$has_coolant = $criteria->hasCoolant();
|
||||||
$pt_id = $criteria->getPriceTier();
|
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
|
|
||||||
if ($stype == $this->getID())
|
if ($stype == $this->getID())
|
||||||
{
|
{
|
||||||
$cv = $criteria->getCustomerVehicle();
|
$cv = $criteria->getCustomerVehicle();
|
||||||
|
$fee = $this->getServiceTypeFee($cv);
|
||||||
// check if price tier has item price
|
|
||||||
$pt_price = $this->getPriceTierItemPrice($pt_id, $cv);
|
|
||||||
|
|
||||||
if ($pt_price == null)
|
|
||||||
$price = $this->getServiceTypeFee($cv);
|
|
||||||
else
|
|
||||||
|
|
||||||
$price = $pt_price;
|
|
||||||
|
|
||||||
// add the service fee to items
|
// add the service fee to items
|
||||||
$qty = 1;
|
$qty = 1;
|
||||||
|
|
@ -57,10 +43,10 @@ class Overheat implements InvoiceRuleInterface
|
||||||
'service_type' => $this->getID(),
|
'service_type' => $this->getID(),
|
||||||
'qty' => $qty,
|
'qty' => $qty,
|
||||||
'title' => $this->getServiceTitle(),
|
'title' => $this->getServiceTitle(),
|
||||||
'price' => $price,
|
'price' => $fee,
|
||||||
];
|
];
|
||||||
|
|
||||||
$qty_fee = bcmul($qty, $price, 2);
|
$qty_fee = bcmul($qty, $fee, 2);
|
||||||
$total_price = $qty_fee;
|
$total_price = $qty_fee;
|
||||||
|
|
||||||
if ($has_coolant)
|
if ($has_coolant)
|
||||||
|
|
@ -108,7 +94,7 @@ class Overheat implements InvoiceRuleInterface
|
||||||
|
|
||||||
// find the service fee using the code
|
// find the service fee using the code
|
||||||
// if we can't find the fee, return 0
|
// if we can't find the fee, return 0
|
||||||
$fee = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
$fee = $this->em->getRepository(ServiceOffering::class)->findOneBy($code);
|
||||||
|
|
||||||
if ($fee == null)
|
if ($fee == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -126,39 +112,6 @@ class Overheat implements InvoiceRuleInterface
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPriceTierItemPrice($pt_id, CustomerVehicle $cv)
|
|
||||||
{
|
|
||||||
// price_tier is default
|
|
||||||
if ($pt_id == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the item type for service offering
|
|
||||||
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'service_offering']);
|
|
||||||
if ($item_type == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the service offering
|
|
||||||
$code = 'overheat_fee';
|
|
||||||
|
|
||||||
// check if customer vehicle has a motolite battery
|
|
||||||
// if yes, set the code to the motolite user service fee
|
|
||||||
if ($cv->hasMotoliteBattery())
|
|
||||||
$code = 'motolite_user_service_fee';
|
|
||||||
|
|
||||||
$service = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
|
||||||
|
|
||||||
// check if service is null. If null, return null
|
|
||||||
if ($service == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$item_id = $service->getID();
|
|
||||||
|
|
||||||
$price = $this->pt_manager->getItemPrice($pt_id, $item_type_id, $item_id);
|
|
||||||
|
|
||||||
return $price;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getServiceTitle()
|
protected function getServiceTitle()
|
||||||
{
|
{
|
||||||
$title = 'Service - ' . ServiceType::getName(ServiceType::OVERHEAT_ASSISTANCE);
|
$title = 'Service - ' . ServiceType::getName(ServiceType::OVERHEAT_ASSISTANCE);
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,14 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||||
use App\InvoiceRuleInterface;
|
use App\InvoiceRuleInterface;
|
||||||
|
|
||||||
use App\Entity\ServiceOffering;
|
use App\Entity\ServiceOffering;
|
||||||
use App\Entity\ItemType;
|
|
||||||
|
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
class PostRecharged implements InvoiceRuleInterface
|
class PostRecharged implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $pt_manager;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, PriceTierManager $pt_manager)
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->pt_manager = $pt_manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -30,29 +25,22 @@ class PostRecharged implements InvoiceRuleInterface
|
||||||
public function compute($criteria, &$total)
|
public function compute($criteria, &$total)
|
||||||
{
|
{
|
||||||
$stype = $criteria->getServiceType();
|
$stype = $criteria->getServiceType();
|
||||||
$pt_id = $criteria->getPriceTier();
|
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
|
|
||||||
if ($stype == $this->getID())
|
if ($stype == $this->getID())
|
||||||
{
|
{
|
||||||
// check if price tier has item price
|
$fee = $this->getServiceTypeFee();
|
||||||
$pt_price = $this->getPriceTierItemPrice($pt_id);
|
|
||||||
|
|
||||||
if ($pt_price == null)
|
|
||||||
$price = $this->getServiceTypeFee();
|
|
||||||
else
|
|
||||||
$price = $pt_price;
|
|
||||||
|
|
||||||
$qty = 1;
|
$qty = 1;
|
||||||
$items[] = [
|
$items[] = [
|
||||||
'service_type' => $this->getID(),
|
'service_type' => $this->getID(),
|
||||||
'qty' => $qty,
|
'qty' => $qty,
|
||||||
'title' => $this->getServiceTitle(),
|
'title' => $this->getServiceTitle(),
|
||||||
'price' => $price,
|
'price' => $fee,
|
||||||
];
|
];
|
||||||
|
|
||||||
$qty_price = bcmul($price, $qty, 2);
|
$qty_price = bcmul($fee, $qty, 2);
|
||||||
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
|
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -84,33 +72,6 @@ class PostRecharged implements InvoiceRuleInterface
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPriceTierItemPrice($pt_id)
|
|
||||||
{
|
|
||||||
// price_tier is default
|
|
||||||
if ($pt_id == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the item type for service offering
|
|
||||||
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'service_offering']);
|
|
||||||
if ($item_type == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the service offering
|
|
||||||
$code = 'post_recharged_fee';
|
|
||||||
$service = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
|
||||||
|
|
||||||
// check if service is null. If null, return null
|
|
||||||
if ($service == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$item_id = $service->getID();
|
|
||||||
|
|
||||||
$price = $this->pt_manager->getItemPrice($pt_id, $item_type_id, $item_id);
|
|
||||||
|
|
||||||
return $price;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getServiceTitle()
|
protected function getServiceTitle()
|
||||||
{
|
{
|
||||||
$title = 'Recharge fee';
|
$title = 'Recharge fee';
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,14 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||||
use App\InvoiceRuleInterface;
|
use App\InvoiceRuleInterface;
|
||||||
|
|
||||||
use App\Entity\ServiceOffering;
|
use App\Entity\ServiceOffering;
|
||||||
use App\Entity\ItemType;
|
|
||||||
|
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
class PostReplacement implements InvoiceRuleInterface
|
class PostReplacement implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $pt_manager;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, PriceTierManager $pt_manager)
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->pt_manager = $pt_manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -30,29 +25,22 @@ class PostReplacement implements InvoiceRuleInterface
|
||||||
public function compute($criteria, &$total)
|
public function compute($criteria, &$total)
|
||||||
{
|
{
|
||||||
$stype = $criteria->getServiceType();
|
$stype = $criteria->getServiceType();
|
||||||
$pt_id = $criteria->getPriceTier();
|
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
|
|
||||||
if ($stype == $this->getID())
|
if ($stype == $this->getID())
|
||||||
{
|
{
|
||||||
// check if price tier has item price
|
$fee = $this->getServiceTypeFee();
|
||||||
$pt_price = $this->getPriceTierItemPrice($pt_id);
|
|
||||||
|
|
||||||
if ($pt_price == null)
|
|
||||||
$price = $this->getServiceTypeFee();
|
|
||||||
else
|
|
||||||
$price = $pt_price;
|
|
||||||
|
|
||||||
$qty = 1;
|
$qty = 1;
|
||||||
$items[] = [
|
$items[] = [
|
||||||
'service_type' => $this->getID(),
|
'service_type' => $this->getID(),
|
||||||
'qty' => $qty,
|
'qty' => $qty,
|
||||||
'title' => $this->getServiceTitle(),
|
'title' => $this->getServiceTitle(),
|
||||||
'price' => $price,
|
'price' => $fee,
|
||||||
];
|
];
|
||||||
|
|
||||||
$qty_price = bcmul($price, $qty, 2);
|
$qty_price = bcmul($fee, $qty, 2);
|
||||||
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
|
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,33 +71,6 @@ class PostReplacement implements InvoiceRuleInterface
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPriceTierItemPrice($pt_id)
|
|
||||||
{
|
|
||||||
// price_tier is default
|
|
||||||
if ($pt_id == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the item type for service offering
|
|
||||||
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'service_offering']);
|
|
||||||
if ($item_type == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the service offering
|
|
||||||
$code = 'post_replacement_fee';
|
|
||||||
$service = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
|
||||||
|
|
||||||
// check if service is null. If null, return null
|
|
||||||
if ($service == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$item_id = $service->getID();
|
|
||||||
|
|
||||||
$price = $this->pt_manager->getItemPrice($pt_id, $item_type_id, $item_id);
|
|
||||||
|
|
||||||
return $price;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getServiceTitle()
|
protected function getServiceTitle()
|
||||||
{
|
{
|
||||||
$title = 'Battery replacement';
|
$title = 'Battery replacement';
|
||||||
|
|
|
||||||
|
|
@ -9,19 +9,14 @@ use App\InvoiceRuleInterface;
|
||||||
use App\Ramcar\ServiceType;
|
use App\Ramcar\ServiceType;
|
||||||
|
|
||||||
use App\Entity\ServiceOffering;
|
use App\Entity\ServiceOffering;
|
||||||
use App\Entity\ItemType;
|
|
||||||
|
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
class Tax implements InvoiceRuleInterface
|
class Tax implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $pt_manager;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, PriceTierManager $pt_manager)
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->pt_manager = $pt_manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -45,7 +40,6 @@ class Tax implements InvoiceRuleInterface
|
||||||
|
|
||||||
// compute tax per item if service type is battery sales
|
// compute tax per item if service type is battery sales
|
||||||
$stype = $criteria->getServiceType();
|
$stype = $criteria->getServiceType();
|
||||||
$pt = $criteria->getPriceTier();
|
|
||||||
|
|
||||||
if ($stype == ServiceType::BATTERY_REPLACEMENT_NEW)
|
if ($stype == ServiceType::BATTERY_REPLACEMENT_NEW)
|
||||||
{
|
{
|
||||||
|
|
@ -64,13 +58,7 @@ class Tax implements InvoiceRuleInterface
|
||||||
$battery = $entry['battery'];
|
$battery = $entry['battery'];
|
||||||
$qty = $entry['qty'];
|
$qty = $entry['qty'];
|
||||||
|
|
||||||
// check if price tier has item price for battery
|
$price = $battery->getSellingPrice();
|
||||||
$pt_price = $this->getPriceTierItemPrice($pt, $battery);
|
|
||||||
|
|
||||||
if ($pt_price == null)
|
|
||||||
$price = $battery->getSellingPrice();
|
|
||||||
else
|
|
||||||
$price = $pt_price;
|
|
||||||
|
|
||||||
$vat = $this->getTaxAmount($price, $tax_rate);
|
$vat = $this->getTaxAmount($price, $tax_rate);
|
||||||
|
|
||||||
|
|
@ -108,25 +96,6 @@ class Tax implements InvoiceRuleInterface
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPriceTierItemPrice($pt_id, $batt)
|
|
||||||
{
|
|
||||||
// price tier is default
|
|
||||||
if ($pt_id == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the item type battery
|
|
||||||
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'battery']);
|
|
||||||
if ($item_type == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$item_id = $batt->getID();
|
|
||||||
|
|
||||||
$price = $this->pt_manager->getItemPrice($pt_id, $item_type_id, $item_id);
|
|
||||||
|
|
||||||
return $price;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getTaxAmount($price, $tax_rate)
|
protected function getTaxAmount($price, $tax_rate)
|
||||||
{
|
{
|
||||||
$vat_ex_price = $this->getTaxExclusivePrice($price, $tax_rate);
|
$vat_ex_price = $this->getTaxExclusivePrice($price, $tax_rate);
|
||||||
|
|
|
||||||
|
|
@ -8,19 +8,14 @@ use App\InvoiceRuleInterface;
|
||||||
|
|
||||||
use App\Entity\ServiceOffering;
|
use App\Entity\ServiceOffering;
|
||||||
use App\Entity\CustomerVehicle;
|
use App\Entity\CustomerVehicle;
|
||||||
use App\Entity\ItemType;
|
|
||||||
|
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
class TireRepair implements InvoiceRuleInterface
|
class TireRepair implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $pt_manager;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, PriceTierManager $pt_manager)
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->pt_manager = $pt_manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -31,22 +26,13 @@ class TireRepair implements InvoiceRuleInterface
|
||||||
public function compute($criteria, &$total)
|
public function compute($criteria, &$total)
|
||||||
{
|
{
|
||||||
$stype = $criteria->getServiceType();
|
$stype = $criteria->getServiceType();
|
||||||
$has_sealant = $criteria->hasSealant();
|
|
||||||
$pt_id = $criteria->getPriceTier();
|
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
|
|
||||||
if ($stype == $this->getID())
|
if ($stype == $this->getID())
|
||||||
{
|
{
|
||||||
$cv = $criteria->getCustomerVehicle();
|
$cv = $criteria->getCustomerVehicle();
|
||||||
|
$fee = $this->getServiceTypeFee($cv);
|
||||||
// check if price tier has item price
|
|
||||||
$pt_price = $this->getPriceTierItemPrice($pt_id, $cv);
|
|
||||||
|
|
||||||
if ($pt_price == null)
|
|
||||||
$price = $this->getServiceTypeFee($cv);
|
|
||||||
else
|
|
||||||
$price = $pt_price;
|
|
||||||
|
|
||||||
// add the service fee to items
|
// add the service fee to items
|
||||||
$qty = 1;
|
$qty = 1;
|
||||||
|
|
@ -54,31 +40,11 @@ class TireRepair implements InvoiceRuleInterface
|
||||||
'service_type' => $this->getID(),
|
'service_type' => $this->getID(),
|
||||||
'qty' => $qty,
|
'qty' => $qty,
|
||||||
'title' => $this->getServiceTitle(),
|
'title' => $this->getServiceTitle(),
|
||||||
'price' => $price,
|
'price' => $fee,
|
||||||
];
|
];
|
||||||
|
|
||||||
$qty_fee = bcmul($qty, $price, 2);
|
$qty_price = bcmul($fee, $qty, 2);
|
||||||
$total_price = $qty_fee;
|
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
|
||||||
|
|
||||||
if ($has_sealant)
|
|
||||||
{
|
|
||||||
$sealant_fee_data = $this->getSealantFeeData();
|
|
||||||
|
|
||||||
$sealant_fee = $sealant_fee_data['fee'];
|
|
||||||
$sealant_title = $sealant_fee_data['title'];
|
|
||||||
|
|
||||||
$items[] = [
|
|
||||||
'service_type' => $this->getID(),
|
|
||||||
'qty' => $qty,
|
|
||||||
'title' => $sealant_title,
|
|
||||||
'price' => $sealant_fee,
|
|
||||||
];
|
|
||||||
|
|
||||||
$qty_price = bcmul($sealant_fee, $qty, 2);
|
|
||||||
$total_price = bcadd($total_price, $qty_price, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
$total['total_price'] = bcadd($total['total_price'], $total_price, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $items;
|
return $items;
|
||||||
|
|
@ -113,67 +79,10 @@ class TireRepair implements InvoiceRuleInterface
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPriceTierItemPrice($pt_id, CustomerVehicle $cv)
|
|
||||||
{
|
|
||||||
// price_tier is default
|
|
||||||
if ($pt_id == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the item type for service offering
|
|
||||||
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'service_offering']);
|
|
||||||
if ($item_type == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the service offering
|
|
||||||
$code = 'tire_repair_fee';
|
|
||||||
|
|
||||||
// check if customer vehicle has a motolite battery
|
|
||||||
// if yes, set the code to the motolite user service fee
|
|
||||||
if ($cv->hasMotoliteBattery())
|
|
||||||
$code = 'motolite_user_service_fee';
|
|
||||||
|
|
||||||
$service = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
|
||||||
|
|
||||||
// check if service is null. If null, return null
|
|
||||||
if ($service == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$item_type_id = $item_type->getID();
|
|
||||||
$item_id = $service->getID();
|
|
||||||
|
|
||||||
$price = $this->pt_manager->getItemPrice($pt_id, $item_type_id, $item_id);
|
|
||||||
|
|
||||||
return $price;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getServiceTitle()
|
protected function getServiceTitle()
|
||||||
{
|
{
|
||||||
$title = 'Service - Flat Tire';
|
$title = 'Service - Flat Tire';
|
||||||
|
|
||||||
return $title;
|
return $title;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSealantFeeData()
|
|
||||||
{
|
|
||||||
$data = [
|
|
||||||
'fee' => 0.00,
|
|
||||||
'title' => '',
|
|
||||||
];
|
|
||||||
|
|
||||||
$code = 'tire_sealant_fee';
|
|
||||||
|
|
||||||
// find the service fee using the code
|
|
||||||
// if we can't find the fee, return 0
|
|
||||||
$fee = $this->em->getRepository(ServiceOffering::class)->findOneBy(['code' => $code]);
|
|
||||||
|
|
||||||
if ($fee != null)
|
|
||||||
{
|
|
||||||
$data = [
|
|
||||||
'fee' => $fee->getFee(),
|
|
||||||
'title' => $fee->getName(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,24 +2,12 @@
|
||||||
|
|
||||||
namespace App\InvoiceRule;
|
namespace App\InvoiceRule;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
|
|
||||||
use App\InvoiceRuleInterface;
|
use App\InvoiceRuleInterface;
|
||||||
|
|
||||||
use App\Ramcar\TradeInType;
|
use App\Ramcar\TradeInType;
|
||||||
use App\Ramcar\ServiceType;
|
|
||||||
|
|
||||||
use App\Entity\BatterySize;
|
|
||||||
|
|
||||||
class TradeIn implements InvoiceRuleInterface
|
class TradeIn implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
protected $em;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em)
|
|
||||||
{
|
|
||||||
$this->em = $em;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
{
|
{
|
||||||
return 'trade-in';
|
return 'trade-in';
|
||||||
|
|
@ -33,6 +21,7 @@ class TradeIn implements InvoiceRuleInterface
|
||||||
$entries = $criteria->getEntries();
|
$entries = $criteria->getEntries();
|
||||||
foreach($entries as $entry)
|
foreach($entries as $entry)
|
||||||
{
|
{
|
||||||
|
$batt = $entry['battery'];
|
||||||
$qty = $entry['qty'];
|
$qty = $entry['qty'];
|
||||||
$trade_in_type = null;
|
$trade_in_type = null;
|
||||||
|
|
||||||
|
|
@ -41,9 +30,7 @@ class TradeIn implements InvoiceRuleInterface
|
||||||
|
|
||||||
if ($trade_in_type != null)
|
if ($trade_in_type != null)
|
||||||
{
|
{
|
||||||
$batt_size = $entry['battery_size'];
|
$ti_rate = $this->getTradeInRate($batt, $trade_in_type);
|
||||||
|
|
||||||
$ti_rate = $this->getTradeInRate($batt_size, $trade_in_type);
|
|
||||||
|
|
||||||
$qty_ti = bcmul($ti_rate, $qty, 2);
|
$qty_ti = bcmul($ti_rate, $qty, 2);
|
||||||
|
|
||||||
|
|
@ -53,10 +40,8 @@ class TradeIn implements InvoiceRuleInterface
|
||||||
$price = bcmul($ti_rate, -1, 2);
|
$price = bcmul($ti_rate, -1, 2);
|
||||||
|
|
||||||
$items[] = [
|
$items[] = [
|
||||||
'battery_size' => $batt_size,
|
|
||||||
'trade_in_type' => $trade_in_type,
|
|
||||||
'qty' => $qty,
|
'qty' => $qty,
|
||||||
'title' => $this->getTitle($batt_size, $trade_in_type),
|
'title' => $this->getTitle($batt, $trade_in_type),
|
||||||
'price' => $price,
|
'price' => $price,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
@ -72,47 +57,13 @@ class TradeIn implements InvoiceRuleInterface
|
||||||
|
|
||||||
public function validateInvoiceItems($criteria, $invoice_items)
|
public function validateInvoiceItems($criteria, $invoice_items)
|
||||||
{
|
{
|
||||||
// check service type. Only battery sales and battery warranty should have invoice items.
|
|
||||||
$stype = $criteria->getServiceType();
|
|
||||||
if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// return error if there's a problem, false otherwise
|
|
||||||
if (!empty($invoice_items))
|
|
||||||
{
|
|
||||||
// check if this is a valid battery
|
|
||||||
foreach ($invoice_items as $item)
|
|
||||||
{
|
|
||||||
if (isset($item['battery_size']))
|
|
||||||
{
|
|
||||||
$battery_size = $this->em->getRepository(BatterySize::class)->find($item['battery_size']);
|
|
||||||
|
|
||||||
if (empty($battery_size))
|
|
||||||
{
|
|
||||||
$error = 'Invalid battery size specified.';
|
|
||||||
return $error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// quantity
|
|
||||||
$qty = $item['quantity'];
|
|
||||||
if ($qty < 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// check if trade in is set and if trade in type if valid
|
|
||||||
if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in']))
|
|
||||||
{
|
|
||||||
$trade_in = $item['trade_in'];
|
|
||||||
$criteria->addTradeInEntry($battery_size, $trade_in, $qty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getTradeInRate($size, $trade_in_type)
|
protected function getTradeInRate($battery, $trade_in_type)
|
||||||
{
|
{
|
||||||
|
$size = $battery->getSize();
|
||||||
|
|
||||||
switch ($trade_in_type)
|
switch ($trade_in_type)
|
||||||
{
|
{
|
||||||
case TradeInType::MOTOLITE:
|
case TradeInType::MOTOLITE:
|
||||||
|
|
@ -126,9 +77,9 @@ class TradeIn implements InvoiceRuleInterface
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getTitle($battery_size, $trade_in_type)
|
protected function getTitle($battery, $trade_in_type)
|
||||||
{
|
{
|
||||||
$title = 'Trade-in ' . TradeInType::getName($trade_in_type) . ' ' . $battery_size->getName() . ' battery';
|
$title = 'Trade-in ' . TradeInType::getName($trade_in_type) . ' ' . $battery->getSize()->getName() . ' battery';
|
||||||
|
|
||||||
return $title;
|
return $title;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ class DeliveryStatus extends NameValue
|
||||||
const COLLECTION = [
|
const COLLECTION = [
|
||||||
'rider_assign' => 'Assigned Rider',
|
'rider_assign' => 'Assigned Rider',
|
||||||
'requeue' => 'Requeue',
|
'requeue' => 'Requeue',
|
||||||
'rider_accept' => 'Rider Accept',
|
'accept' => 'Rider Accept',
|
||||||
'rider_arrive' => 'Rider Arrive',
|
'arrive' => 'Rider Arrive',
|
||||||
'rider_edit' => 'Rider Edit',
|
'rider_edit' => 'Rider Edit',
|
||||||
'rider_depart_hub' => 'Rider Depart Hub',
|
'rider_depart_hub' => 'Rider Depart Hub',
|
||||||
'rider_arrive_hub_pre_jo' => 'Rider Arrive Hub Pre JO',
|
'rider_arrive_hub_pre_jo' => 'Rider Arrive Hub Pre JO',
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ class HubCriteria
|
||||||
protected $limit_results; // number of results to return
|
protected $limit_results; // number of results to return
|
||||||
protected $limit_distance; // distance limit for search in km
|
protected $limit_distance; // distance limit for search in km
|
||||||
protected $flag_inventory_check; // flag if we need to check for inventory
|
protected $flag_inventory_check; // flag if we need to check for inventory
|
||||||
protected $flag_riders_check; // flag if we need to check for riders available
|
|
||||||
protected $jo_type; // jo service needed
|
protected $jo_type; // jo service needed
|
||||||
protected $date_time; // date and time to check if hub is open or not
|
protected $date_time; // date and time to check if hub is open or not
|
||||||
protected $items; // array of items: items[sku] = quantity to check for
|
protected $items; // array of items: items[sku] = quantity to check for
|
||||||
|
|
@ -21,10 +20,6 @@ class HubCriteria
|
||||||
protected $flag_round_robin; // flag if we use round robin or not
|
protected $flag_round_robin; // flag if we use round robin or not
|
||||||
protected $jo_id; // JO id. This is null if called from mobile API
|
protected $jo_id; // JO id. This is null if called from mobile API
|
||||||
protected $customer_id; // customer id
|
protected $customer_id; // customer id
|
||||||
protected $customer_class; // customer class
|
|
||||||
protected $order_date; // date JO was created
|
|
||||||
protected $service_type; // service type of JO
|
|
||||||
protected $jo_origin; // origin of JO
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
|
@ -34,17 +29,12 @@ class HubCriteria
|
||||||
$this->jo_type = '';
|
$this->jo_type = '';
|
||||||
$this->date_time = new DateTime();
|
$this->date_time = new DateTime();
|
||||||
$this->flag_inventory_check = false;
|
$this->flag_inventory_check = false;
|
||||||
$this->flag_riders_check = false;
|
|
||||||
$this->items = [];
|
$this->items = [];
|
||||||
$this->payment_method = '';
|
$this->payment_method = '';
|
||||||
$this->flag_emergency = false;
|
$flag_emergency = false;
|
||||||
$this->flag_round_robin = false;
|
$flag_round_robin = false;
|
||||||
$this->jo_id = null;
|
$jo_id = null;
|
||||||
$this->customer_id = null;
|
$customer_id = null;
|
||||||
$this->customer_class = null;
|
|
||||||
$this->order_date = new DateTime();
|
|
||||||
$this->service_type = null;
|
|
||||||
$this->jo_origin = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPoint(Point $point)
|
public function setPoint(Point $point)
|
||||||
|
|
@ -91,17 +81,6 @@ class HubCriteria
|
||||||
return $this->flag_inventory_check;
|
return $this->flag_inventory_check;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setRidersCheck($flag_riders_check = true)
|
|
||||||
{
|
|
||||||
$this->flag_riders_check = $flag_riders_check;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function hasRidersCheck()
|
|
||||||
{
|
|
||||||
return $this->flag_riders_check;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setJoType($jo_type)
|
public function setJoType($jo_type)
|
||||||
{
|
{
|
||||||
// TODO: validate the jo type
|
// TODO: validate the jo type
|
||||||
|
|
@ -192,48 +171,5 @@ class HubCriteria
|
||||||
return $this->customer_id;
|
return $this->customer_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setCustomerClass($customer_class)
|
|
||||||
{
|
|
||||||
$this->customer_class = $customer_class;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCustomerClass()
|
|
||||||
{
|
|
||||||
return $this->customer_class;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setOrderDate($order_date)
|
|
||||||
{
|
|
||||||
$this->order_date = $order_date;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getOrderDate()
|
|
||||||
{
|
|
||||||
return $this->order_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setServiceType($service_type)
|
|
||||||
{
|
|
||||||
$this->service_type = $service_type;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getServiceType()
|
|
||||||
{
|
|
||||||
return $this->service_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setJoOrigin($jo_origin)
|
|
||||||
{
|
|
||||||
$this->jo_origin = $jo_origin;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getJoOrigin()
|
|
||||||
{
|
|
||||||
return $this->jo_origin;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Ramcar;
|
|
||||||
|
|
||||||
class InsuranceBodyType extends NameValue
|
|
||||||
{
|
|
||||||
const SEDAN = 'sedan';
|
|
||||||
const SUV = 'suv';
|
|
||||||
const TRUCK = 'truck';
|
|
||||||
const MOTORCYCLE = 'motorcycle';
|
|
||||||
|
|
||||||
const COLLECTION = [
|
|
||||||
'SEDAN' => 'Sedan',
|
|
||||||
'SUV' => 'SUV',
|
|
||||||
'TRUCK' => 'Truck',
|
|
||||||
'MOTORCYCLE' => 'Motorcycle',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -17,8 +17,6 @@ class InvoiceCriteria
|
||||||
protected $service_charges;
|
protected $service_charges;
|
||||||
protected $flag_taxable;
|
protected $flag_taxable;
|
||||||
protected $source; // use Ramcar's TransactionOrigin
|
protected $source; // use Ramcar's TransactionOrigin
|
||||||
protected $price_tier;
|
|
||||||
protected $flag_sealant;
|
|
||||||
|
|
||||||
// entries are battery and trade-in combos
|
// entries are battery and trade-in combos
|
||||||
protected $entries;
|
protected $entries;
|
||||||
|
|
@ -34,8 +32,6 @@ class InvoiceCriteria
|
||||||
$this->service_charges = [];
|
$this->service_charges = [];
|
||||||
$this->flag_taxable = false;
|
$this->flag_taxable = false;
|
||||||
$this->source = '';
|
$this->source = '';
|
||||||
$this->price_tier = 0; // set to default
|
|
||||||
$this->flag_sealant = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setServiceType($stype)
|
public function setServiceType($stype)
|
||||||
|
|
@ -112,17 +108,6 @@ class InvoiceCriteria
|
||||||
$this->entries[] = $entry;
|
$this->entries[] = $entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addTradeInEntry($battery_size, $trade_in, $qty)
|
|
||||||
{
|
|
||||||
$entry = [
|
|
||||||
'battery_size' => $battery_size,
|
|
||||||
'trade_in' => $trade_in,
|
|
||||||
'qty' => $qty
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->entries[] = $entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEntries()
|
public function getEntries()
|
||||||
{
|
{
|
||||||
return $this->entries;
|
return $this->entries;
|
||||||
|
|
@ -194,25 +179,4 @@ class InvoiceCriteria
|
||||||
return $this->source;
|
return $this->source;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPriceTier($price_tier)
|
|
||||||
{
|
|
||||||
$this->price_tier = $price_tier;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPriceTier()
|
|
||||||
{
|
|
||||||
return $this->price_tier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setHasSealant($flag = true)
|
|
||||||
{
|
|
||||||
$this->flag_sealant = $flag;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function hasSealant()
|
|
||||||
{
|
|
||||||
return $this->flag_sealant;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,24 +4,17 @@ namespace App\Ramcar;
|
||||||
|
|
||||||
class JORejectionReason extends NameValue
|
class JORejectionReason extends NameValue
|
||||||
{
|
{
|
||||||
const ADMINISTRATIVE = 'administrative';
|
const ADMINISTRATIVE = 'administrative';
|
||||||
const NO_STOCK_SALES = 'no_stock_sales';
|
const NO_STOCK_SALES = 'no_stock_sales';
|
||||||
const NO_STOCK_SERVICE = 'no_stock_service';
|
const NO_STOCK_SERVICE = 'no_stock_service';
|
||||||
const LINE_NO_ANSWER = 'line_no_answer';
|
const LINE_NO_ANSWER = 'line_no_answer';
|
||||||
const LINE_BUSY = 'line_busy';
|
const LINE_BUSY = 'line_busy';
|
||||||
const NO_RIDER_AVAILABLE = 'no_rider_available';
|
const NO_RIDER_AVAILABLE = 'no_rider_available';
|
||||||
const NO_RIDER_IN_TRANSIT = 'no_rider_in_transit';
|
const NO_RIDER_IN_TRANSIT = 'no_rider_in_transit';
|
||||||
const REFUSAL = 'refusal';
|
const REFUSAL = 'refusal';
|
||||||
const STORE_CLOSED = 'store_closed';
|
const STORE_CLOSED = 'store_closed';
|
||||||
const NO_CREDIT_CARD = 'no_credit_card';
|
const NO_CREDIT_CARD = 'no_credit_card';
|
||||||
const DISCOUNT = 'discount';
|
const DISCOUNT = 'discount';
|
||||||
const STORE_CLOSED_SCHEDULED = 'store_closed_scheduled';
|
|
||||||
const STORE_CLOSED_HALF_DAY = 'store_closed_half_day';
|
|
||||||
const STORE_CLOSED_NO_ADVISE = 'store_closed_no_advise';
|
|
||||||
const PRIORITY_HUB_WTY_CLAIM = 'priority_hub_wty_claim';
|
|
||||||
const PRIORITY_HUB_JUMPSTART = 'priority_hub_jumpstart';
|
|
||||||
const PRIORITY_HUB_RESQ_REQUEST = 'priority_hub_resq_req';
|
|
||||||
const CUSTOMER_REQUEST = 'customer_request';
|
|
||||||
|
|
||||||
const COLLECTION = [
|
const COLLECTION = [
|
||||||
'administrative' => 'ADMINISTRATIVE',
|
'administrative' => 'ADMINISTRATIVE',
|
||||||
|
|
@ -35,16 +28,5 @@ class JORejectionReason extends NameValue
|
||||||
'store_closed' => 'STORE CLOSED',
|
'store_closed' => 'STORE CLOSED',
|
||||||
'no_credit_card' => 'NO CREDIT CARD PAYMENT / NO TERMINAL',
|
'no_credit_card' => 'NO CREDIT CARD PAYMENT / NO TERMINAL',
|
||||||
'discount' => 'DISCOUNT',
|
'discount' => 'DISCOUNT',
|
||||||
'store_closed_scheduled' => 'STORE CLOSED (ON SCHEDULE)',
|
|
||||||
'store_closed_half_day' => 'STORE CLOSED (HALF DAY)',
|
|
||||||
'store_closed_no_advise' => 'STORE CLOSED (NO ADVISE)',
|
|
||||||
'priority_hub_wty_claim' => 'PRIORITY HUB OUTLET FOR WARRANTY CLAIM',
|
|
||||||
'priority_hub_jumpstart' => 'PRIORITY HUB OUTLET FOR JUMPSTART',
|
|
||||||
'priority_hub_resq_req' => 'PRIORITY HUB OUTLET FOR RESQ-Q REQUEST',
|
|
||||||
'customer_request' => 'CUSTOMER REQUEST',
|
|
||||||
];
|
|
||||||
|
|
||||||
const BLACKLIST = [
|
|
||||||
self::ADMINISTRATIVE => true,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,21 +4,9 @@ namespace App\Ramcar;
|
||||||
|
|
||||||
class NameValue
|
class NameValue
|
||||||
{
|
{
|
||||||
const BLACKLIST = [];
|
|
||||||
|
|
||||||
static public function getCollection()
|
static public function getCollection()
|
||||||
{
|
{
|
||||||
$result = [];
|
return static::COLLECTION;
|
||||||
$blacklist = static::getBlacklist();
|
|
||||||
|
|
||||||
// filter from blacklist
|
|
||||||
foreach(static::COLLECTION as $key => $row) {
|
|
||||||
if (!isset($blacklist[$key])) {
|
|
||||||
$result[$key] = $row;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function validate($value)
|
static public function validate($value)
|
||||||
|
|
@ -36,9 +24,4 @@ class NameValue
|
||||||
|
|
||||||
return 'Unknown';
|
return 'Unknown';
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getBlacklist()
|
|
||||||
{
|
|
||||||
return static::BLACKLIST ?? [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,17 +17,13 @@ class TransactionOrigin extends NameValue
|
||||||
const YOKOHAMA_TWITTER = 'yokohama_twitter';
|
const YOKOHAMA_TWITTER = 'yokohama_twitter';
|
||||||
const YOKOHAMA_INSTAGRAM = 'yokohama_instagram';
|
const YOKOHAMA_INSTAGRAM = 'yokohama_instagram';
|
||||||
const YOKOHAMA_CAROUSELL = 'yokohama_carousell';
|
const YOKOHAMA_CAROUSELL = 'yokohama_carousell';
|
||||||
const HOTLINE_CEBU = 'hotline_cebu';
|
|
||||||
const FACEBOOK_CEBU = 'facebook_cebu';
|
|
||||||
|
|
||||||
// TODO: for now, resq also gets the walk-in option
|
// TODO: for now, resq also gets the walk-in option
|
||||||
// resq also gets new YOKOHAMA options
|
// resq also gets new YOKOHAMA options
|
||||||
const COLLECTION = [
|
const COLLECTION = [
|
||||||
'call' => 'Hotline Manila',
|
'call' => 'Hotline',
|
||||||
'hotline_cebu' => 'Hotline Cebu',
|
|
||||||
'online' => 'Online',
|
'online' => 'Online',
|
||||||
'facebook' => 'Facebook Manila',
|
'facebook' => 'Facebook',
|
||||||
'facebook_cebu' => 'Facebook Cebu',
|
|
||||||
'vip' => 'VIP',
|
'vip' => 'VIP',
|
||||||
'mobile_app' => 'Mobile App',
|
'mobile_app' => 'Mobile App',
|
||||||
'walk_in' => 'Walk-in',
|
'walk_in' => 'Walk-in',
|
||||||
|
|
@ -37,6 +33,6 @@ class TransactionOrigin extends NameValue
|
||||||
'yokohama_op_facebook' => 'Yokohama OP Facebook',
|
'yokohama_op_facebook' => 'Yokohama OP Facebook',
|
||||||
'yokohama_twitter' => 'Yokohama Twitter',
|
'yokohama_twitter' => 'Yokohama Twitter',
|
||||||
'yokohama_instagram' => 'Yokohama Instagram',
|
'yokohama_instagram' => 'Yokohama Instagram',
|
||||||
'yokohama_carousell' => 'Yokohama Carousell'
|
'yokohama_carousell' => 'Yokohama Carousell',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,6 @@ class HubDistributor
|
||||||
'distance' => $hub_data['distance'],
|
'distance' => $hub_data['distance'],
|
||||||
'duration' => $hub_data['duration'],
|
'duration' => $hub_data['duration'],
|
||||||
'jo_count' => $hub_jo_count,
|
'jo_count' => $hub_jo_count,
|
||||||
'inventory' => $hub_data['inventory'] ?? 0,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -92,7 +91,6 @@ class HubDistributor
|
||||||
'distance' => $hub_data['distance'],
|
'distance' => $hub_data['distance'],
|
||||||
'duration' => $hub_data['duration'],
|
'duration' => $hub_data['duration'],
|
||||||
'jo_count' => 0,
|
'jo_count' => 0,
|
||||||
'inventory' => $hub_data['inventory'] ?? 0,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,144 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Service\HubFilter;
|
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
|
||||||
|
|
||||||
use App\Service\HubFilterLogger;
|
|
||||||
use App\Entity\Hub;
|
|
||||||
use App\Entity\JobOrder;
|
|
||||||
use App\Entity\JORejection;
|
|
||||||
use App\Ramcar\ServiceType;
|
|
||||||
use App\Ramcar\JORejectionReason;
|
|
||||||
use App\Service\RisingTideGateway;
|
|
||||||
|
|
||||||
use DateTime;
|
|
||||||
|
|
||||||
class BaseHubFilter
|
|
||||||
{
|
|
||||||
protected $id;
|
|
||||||
protected $jo_id;
|
|
||||||
protected $customer_id;
|
|
||||||
protected $hub_filter_logger;
|
|
||||||
protected $em;
|
|
||||||
protected $rt;
|
|
||||||
protected $trans;
|
|
||||||
|
|
||||||
public function __construct(HubFilterLogger $hub_filter_logger, EntityManagerInterface $em, RisingTideGateway $rt, TranslatorInterface $trans)
|
|
||||||
{
|
|
||||||
$this->hub_filter_logger = $hub_filter_logger;
|
|
||||||
$this->em = $em;
|
|
||||||
$this->rt = $rt;
|
|
||||||
$this->trans = $trans;
|
|
||||||
|
|
||||||
error_log("-------------------");
|
|
||||||
error_log("HUB FILTER RUNNING: " . $this->getID());
|
|
||||||
error_log("-------------------");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getID(): string
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setJOID(int $jo_id)
|
|
||||||
{
|
|
||||||
$this->jo_id = $jo_id;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getJOID(): int
|
|
||||||
{
|
|
||||||
return $this->jo_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCustomerID(int $customer_id)
|
|
||||||
{
|
|
||||||
$this->customer_id = $customer_id;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCustomerID(): int
|
|
||||||
{
|
|
||||||
return $this->customer_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function log(Hub $hub): void
|
|
||||||
{
|
|
||||||
$this->hub_filter_logger->logFilteredHub($hub, $this->getID(), $this->getJOID(), $this->getCustomerID());
|
|
||||||
|
|
||||||
// log to file
|
|
||||||
$filename = '/../../../var/log/hub_rejection.log';
|
|
||||||
$date = date("Y-m-d H:i:s");
|
|
||||||
|
|
||||||
// build log entry
|
|
||||||
$entry = implode("", [
|
|
||||||
"[JO: " . $this->getJOID() . "]",
|
|
||||||
"[" . $date . "]",
|
|
||||||
"[" . $this->getID() . "]",
|
|
||||||
" " . $hub->getName() . " (ID: " . $hub->getID() . ")",
|
|
||||||
"\r\n",
|
|
||||||
]);
|
|
||||||
|
|
||||||
@file_put_contents(__DIR__ . $filename, $entry, FILE_APPEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function createRejectionEntry($hub, $reason, $remarks = ""): JORejection
|
|
||||||
{
|
|
||||||
$jo = $this->em->getRepository(JobOrder::class)->find($this->getJOID());
|
|
||||||
|
|
||||||
$robj = new JORejection();
|
|
||||||
$robj->setDateCreate(new DateTime())
|
|
||||||
->setHub($hub)
|
|
||||||
->setJobOrder($jo)
|
|
||||||
->setReason($reason)
|
|
||||||
->setRemarks(implode(" ", ["Automatically filtered by hub selector.", $remarks]));
|
|
||||||
|
|
||||||
$this->em->persist($robj);
|
|
||||||
$this->em->flush();
|
|
||||||
|
|
||||||
return $robj;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function sendSMSMessage($hub, $order_date, $service_type, $rejection, $reason = "", $remarks = ""): void
|
|
||||||
{
|
|
||||||
$jo_id = $this->getJOID();
|
|
||||||
|
|
||||||
// check if we already have a rejection record for this hub and JO. this also means an SMS was already sent
|
|
||||||
$rejection_count = $this->em->createQueryBuilder()
|
|
||||||
->select('count(r)')
|
|
||||||
->from(JORejection::class, 'r')
|
|
||||||
->where('r.job_order = :jo_id')
|
|
||||||
->andWhere('r.hub = :hub_id')
|
|
||||||
->andWhere('r.id != :rejection_id')
|
|
||||||
->setParameter('jo_id', $jo_id)
|
|
||||||
->setParameter('hub_id', $hub->getID())
|
|
||||||
->setParameter('rejection_id', $rejection->getID())
|
|
||||||
->getQuery()
|
|
||||||
->getSingleScalarResult();
|
|
||||||
|
|
||||||
// if we already have a rejection record for this hub and JO, do not send another SMS
|
|
||||||
if ($rejection_count >= 1) {
|
|
||||||
error_log("ALREADY SENT REJECTION SMS TO HUB " . $hub->getID() . " FOR JO " . $jo_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$message = 'Job Order #: ' . $jo_id . "\n" .
|
|
||||||
'Order Date and Time: ' . $order_date->format('d M Y g:i A') . "\n" .
|
|
||||||
'Date and Time Rejected: ' . $rejection->getDateCreate()->format('d M Y g:i A') . "\n" .
|
|
||||||
'Enrollee Name: ' . implode(" - ", [$hub->getName(), $hub->getBranch()]) . "\n" .
|
|
||||||
'Reason of Rejection: ' . $reason . "\n" .
|
|
||||||
'Remarks: ' . $remarks . "\n" .
|
|
||||||
'Type of Service: ' . ServiceType::getName($service_type);
|
|
||||||
|
|
||||||
error_log("SENDING SMS MESSAGE:\r\n" . $message);
|
|
||||||
|
|
||||||
// send SMS message to hub
|
|
||||||
$this->rt->sendSMS(
|
|
||||||
$hub->getNotifNumber(),
|
|
||||||
$this->trans->trans('message.battery_brand_allcaps'),
|
|
||||||
$message
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Service\HubFilter\Filters;
|
|
||||||
|
|
||||||
use App\Service\HubFilter\BaseHubFilter;
|
|
||||||
use App\Service\HubFilter\HubFilterInterface;
|
|
||||||
|
|
||||||
class DateAndTimeHubFilter extends BaseHubFilter implements HubFilterInterface
|
|
||||||
{
|
|
||||||
protected $id = 'date_and_time';
|
|
||||||
|
|
||||||
public function getRequestedParams() : array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'date_time',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function filter(array $hubs, array $params = []) : array
|
|
||||||
{
|
|
||||||
if ($params['date_time'] == null)
|
|
||||||
return $hubs;
|
|
||||||
|
|
||||||
$results = [];
|
|
||||||
|
|
||||||
foreach ($hubs as $hub_data)
|
|
||||||
{
|
|
||||||
// go through each hub's opening times to check if hub is open
|
|
||||||
// for the specified time
|
|
||||||
// get hub opening and closing times
|
|
||||||
// TODO: maybe in the future, might also have to check if hub
|
|
||||||
// is open/available on date/day
|
|
||||||
$hub = $hub_data['hub'];
|
|
||||||
|
|
||||||
$time_open = $hub->getTimeOpen()->format("H:i:s");
|
|
||||||
$time_close = $hub->getTimeClose()->format("H:i:s");
|
|
||||||
|
|
||||||
$filter_time = $params['date_time']->format("H:i:s");
|
|
||||||
|
|
||||||
if (($filter_time >= $time_open) &&
|
|
||||||
($filter_time <= $time_close))
|
|
||||||
{
|
|
||||||
$results[] = [
|
|
||||||
'hub' => $hub,
|
|
||||||
'db_distance' => $hub_data['db_distance'],
|
|
||||||
'distance' => $hub_data['distance'],
|
|
||||||
'duration' => $hub_data['duration'],
|
|
||||||
'jo_count' => 0,
|
|
||||||
'inventory' => $hub_data['inventory'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$this->log($hub);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,164 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Service\HubFilter\Filters;
|
|
||||||
|
|
||||||
use App\Service\HubFilter\BaseHubFilter;
|
|
||||||
use App\Service\HubFilter\HubFilterInterface;
|
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
|
||||||
|
|
||||||
use App\Ramcar\JORejectionReason;
|
|
||||||
use App\Ramcar\ServiceType;
|
|
||||||
use App\Ramcar\CustomerClassification;
|
|
||||||
use App\Service\InventoryManager;
|
|
||||||
use App\Service\HubFilterLogger;
|
|
||||||
use App\Service\RisingTideGateway;
|
|
||||||
use App\Entity\Battery;
|
|
||||||
use App\Ramcar\TransactionOrigin;
|
|
||||||
|
|
||||||
class InventoryHubFilter extends BaseHubFilter implements HubFilterInterface
|
|
||||||
{
|
|
||||||
protected $id = 'no_inventory';
|
|
||||||
protected $im;
|
|
||||||
|
|
||||||
public function __construct(HubFilterLogger $hub_filter_logger, EntityManagerInterface $em, RisingTideGateway $rt, TranslatorInterface $trans, InventoryManager $im)
|
|
||||||
{
|
|
||||||
parent::__construct($hub_filter_logger, $em, $rt, $trans);
|
|
||||||
$this->im = $im;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRequestedParams() : array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'flag_inventory_check',
|
|
||||||
'customer_class',
|
|
||||||
'jo_type',
|
|
||||||
'jo_origin',
|
|
||||||
'order_date',
|
|
||||||
'service_type',
|
|
||||||
'items',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function filter(array $hubs, array $params = []) : array
|
|
||||||
{
|
|
||||||
// check if this is enabled
|
|
||||||
if (!$params['flag_inventory_check']) {
|
|
||||||
error_log("INVENTORY CHECK " . $this->getJOID() . ": DISABLED");
|
|
||||||
return $hubs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check customer class
|
|
||||||
if ((!empty($params['customer_class']) && $params['customer_class'] == CustomerClassification::VIP) ||
|
|
||||||
$params['jo_origin'] === TransactionOrigin::VIP) {
|
|
||||||
error_log("INVENTORY CHECK " . $this->getJOID() . ": VIP CLASS");
|
|
||||||
return $hubs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check item list is not empty
|
|
||||||
if (empty($params['items'])) {
|
|
||||||
error_log("INVENTORY CHECK " . $this->getJOID() . ": NO ITEMS");
|
|
||||||
return $hubs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check this is a battery item related JO
|
|
||||||
if ($params['jo_type'] != ServiceType::BATTERY_REPLACEMENT_NEW &&
|
|
||||||
$params['jo_type'] != ServiceType::BATTERY_REPLACEMENT_WARRANTY
|
|
||||||
) {
|
|
||||||
error_log("INVENTORY CHECK " . $this->getJOID() . ": INVALID SERVICE TYPE: " . $params['jo_type']);
|
|
||||||
return $hubs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get a list of all hubs with branch codes
|
|
||||||
$branch_codes = [];
|
|
||||||
foreach ($hubs as $hub_data) {
|
|
||||||
$branch_code = $hub_data['hub']->getBranchCode();
|
|
||||||
if (!empty($branch_code)) {
|
|
||||||
$branch_codes[] = $branch_code;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$hubs_to_filter = [];
|
|
||||||
$results = [];
|
|
||||||
$qtys = [];
|
|
||||||
|
|
||||||
// call inventory manager for all hubs for selected SKUs
|
|
||||||
$skus = array_keys($params['items']);
|
|
||||||
|
|
||||||
error_log("CHECKING INVENTORY FOR " . count($skus) . " ITEM(S) ON HUBS " . count($branch_codes) . "...");
|
|
||||||
|
|
||||||
$branches = $this->im->getBranchesInventory($branch_codes, $skus);
|
|
||||||
|
|
||||||
error_log("REQUEST COMPLETE, RESULT COUNT: " . count($branches));
|
|
||||||
|
|
||||||
// check each result to see if sufficient quantity exists to meet request
|
|
||||||
foreach ($branches as $branch) {
|
|
||||||
if (isset($branch['BranchCode'])) {
|
|
||||||
// filter out branch if it does not have sufficient inventory
|
|
||||||
if (!isset($params['items'][$branch['SapCode']]) || $branch['Quantity'] < $params['items'][$branch['SapCode']] &&
|
|
||||||
!isset($hubs_to_filter[$branch['BranchCode']])
|
|
||||||
) {
|
|
||||||
error_log("FILTERING BRANCH WITH NO INVENTORY: " . $branch['BranchCode']);
|
|
||||||
$hubs_to_filter[$branch['BranchCode']] = true;
|
|
||||||
} else {
|
|
||||||
// save inventory count so we don't have to recheck later
|
|
||||||
$qtys[$branch['BranchCode']] = $branch['Quantity'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get battery models for each requested SKU
|
|
||||||
$batteries = [];
|
|
||||||
foreach ($skus as $sku) {
|
|
||||||
$bobj = $this->em->getRepository(Battery::class)->findOneBy(['sap_code' => $sku]);
|
|
||||||
$batteries[] = implode(" ", [$bobj->getModel()->getName(), $bobj->getSize()->getName()]);
|
|
||||||
}
|
|
||||||
$battery_string = implode(", ", $batteries);
|
|
||||||
|
|
||||||
// remove filtered hubs from list
|
|
||||||
foreach ($hubs as $hub_data) {
|
|
||||||
$hub = $hub_data['hub'];
|
|
||||||
$branch_code = $hub_data['hub']->getBranchCode();
|
|
||||||
|
|
||||||
// check if we are filtering this hub
|
|
||||||
if (isset($hubs_to_filter[$branch_code]) || empty($branch_code) || !isset($qtys[$branch_code])) {
|
|
||||||
// if we have a JO, create rejection record and notify
|
|
||||||
$jo_id = $this->getJOID();
|
|
||||||
|
|
||||||
if (!empty($jo_id)) {
|
|
||||||
// create rejection report entry
|
|
||||||
$robj = $this->createRejectionEntry(
|
|
||||||
$hub,
|
|
||||||
JORejectionReason::NO_STOCK_SALES,
|
|
||||||
"SKU(s): " . $battery_string,
|
|
||||||
);
|
|
||||||
|
|
||||||
// build SMS message
|
|
||||||
$this->sendSMSMessage(
|
|
||||||
$hub,
|
|
||||||
$params['order_date'],
|
|
||||||
$params['service_type'],
|
|
||||||
$robj,
|
|
||||||
JORejectionReason::getName(JORejectionReason::NO_STOCK_SALES),
|
|
||||||
"Requested SKU(s) - " . $battery_string
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// log this filter
|
|
||||||
$this->log($hub);
|
|
||||||
|
|
||||||
error_log("FILTERED HUB " . $hub->getID() . " (no_inventory)");
|
|
||||||
} else {
|
|
||||||
// include inventory in hub data
|
|
||||||
$hub_data['inventory'] = $qtys[$branch_code];
|
|
||||||
|
|
||||||
// we only include branches with branch codes and quantities
|
|
||||||
$results[] = $hub_data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return filtered hubs
|
|
||||||
return $results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Service\HubFilter\Filters;
|
|
||||||
|
|
||||||
use App\Service\HubFilter\BaseHubFilter;
|
|
||||||
use App\Service\HubFilter\HubFilterInterface;
|
|
||||||
|
|
||||||
class JoTypeHubFilter extends BaseHubFilter implements HubFilterInterface
|
|
||||||
{
|
|
||||||
protected $id = 'job_order_type';
|
|
||||||
|
|
||||||
public function getRequestedParams() : array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'flag_emergency',
|
|
||||||
'jo_type',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function filter(array $hubs, array $params = []) : array
|
|
||||||
{
|
|
||||||
if ($params['flag_emergency'])
|
|
||||||
return $hubs;
|
|
||||||
|
|
||||||
if (empty($params['jo_type']))
|
|
||||||
return $hubs;
|
|
||||||
|
|
||||||
$results = [];
|
|
||||||
foreach ($hubs as $hub_data)
|
|
||||||
{
|
|
||||||
$hub = $hub_data['hub'];
|
|
||||||
|
|
||||||
// TODO: for now, have this return true
|
|
||||||
$has_jo_type = true;
|
|
||||||
// check if hub offers the jo_type
|
|
||||||
// TODO: add service to hub
|
|
||||||
if ($has_jo_type)
|
|
||||||
$results[] = [
|
|
||||||
'hub' => $hub,
|
|
||||||
'db_distance' => $hub_data['db_distance'],
|
|
||||||
'distance' => $hub_data['distance'],
|
|
||||||
'duration' => $hub_data['duration'],
|
|
||||||
'jo_count' => 0,
|
|
||||||
'inventory' => $hub_data['inventory'],
|
|
||||||
];
|
|
||||||
else
|
|
||||||
$this->log($hub);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Service\HubFilter\Filters;
|
|
||||||
|
|
||||||
use App\Service\HubFilter\BaseHubFilter;
|
|
||||||
use App\Service\HubFilter\HubFilterInterface;
|
|
||||||
|
|
||||||
class MaxResultsHubFilter extends BaseHubFilter implements HubFilterInterface
|
|
||||||
{
|
|
||||||
protected $id = 'max_results';
|
|
||||||
|
|
||||||
public function getRequestedParams() : array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'limit_results',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function filter(array $hubs, array $params = []) : array
|
|
||||||
{
|
|
||||||
if (empty($params['limit_results']))
|
|
||||||
return $hubs;
|
|
||||||
|
|
||||||
$results = [];
|
|
||||||
for ($i = 0; $i < count($hubs); $i++)
|
|
||||||
{
|
|
||||||
if ($i < $params['limit_results'])
|
|
||||||
$results[] = $hubs[$i];
|
|
||||||
else
|
|
||||||
$this->log($hubs[$i]['hub']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Service\HubFilter\Filters;
|
|
||||||
|
|
||||||
use App\Service\HubFilter\BaseHubFilter;
|
|
||||||
use App\Service\HubFilter\HubFilterInterface;
|
|
||||||
|
|
||||||
class PaymentMethodHubFilter extends BaseHubFilter implements HubFilterInterface
|
|
||||||
{
|
|
||||||
protected $id = 'no_payment_method';
|
|
||||||
|
|
||||||
public function getRequestedParams() : array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'flag_emergency',
|
|
||||||
'payment_method',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function filter(array $hubs, array $params = []) : array
|
|
||||||
{
|
|
||||||
if ($params['flag_emergency'])
|
|
||||||
return $hubs;
|
|
||||||
|
|
||||||
if (empty($params['payment_method']))
|
|
||||||
return $hubs;
|
|
||||||
|
|
||||||
$results = [];
|
|
||||||
foreach ($hubs as $hub_data)
|
|
||||||
{
|
|
||||||
$hub = $hub_data['hub'];
|
|
||||||
|
|
||||||
// name of payment method is what is saved
|
|
||||||
$payment_methods = $hub->getPaymentMethods();
|
|
||||||
if ($payment_methods != null)
|
|
||||||
{
|
|
||||||
$flag_found_pmethod = false;
|
|
||||||
foreach ($payment_methods as $pmethod)
|
|
||||||
{
|
|
||||||
if ($pmethod == $params['payment_method'])
|
|
||||||
{
|
|
||||||
$results[] = [
|
|
||||||
'hub' => $hub,
|
|
||||||
'db_distance' => $hub_data['db_distance'],
|
|
||||||
'distance' => $hub_data['distance'],
|
|
||||||
'duration' => $hub_data['duration'],
|
|
||||||
'jo_count' => 0,
|
|
||||||
'inventory' => $hub_data['inventory'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
$flag_found_pmethod = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$flag_found_pmethod)
|
|
||||||
$this->log($hub);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$this->log($hub);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Service\HubFilter\Filters;
|
|
||||||
|
|
||||||
use App\Service\HubFilter\BaseHubFilter;
|
|
||||||
use App\Service\HubFilter\HubFilterInterface;
|
|
||||||
|
|
||||||
use App\Ramcar\JORejectionReason;
|
|
||||||
use App\Ramcar\CustomerClassification;
|
|
||||||
|
|
||||||
class RiderAvailabilityHubFilter extends BaseHubFilter implements HubFilterInterface
|
|
||||||
{
|
|
||||||
protected $id = 'no_available_rider';
|
|
||||||
|
|
||||||
public function getRequestedParams() : array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'flag_riders_check',
|
|
||||||
'customer_class',
|
|
||||||
'order_date',
|
|
||||||
'service_type',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function filter(array $hubs, array $params = []) : array
|
|
||||||
{
|
|
||||||
// check if this is enabled
|
|
||||||
if (!$params['flag_riders_check']) {
|
|
||||||
return $hubs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check customer class
|
|
||||||
if (!empty($params['customer_class']) && $params['customer_class'] == CustomerClassification::VIP) {
|
|
||||||
error_log("RIDER CHECK " . $this->getJOID() . ": VIP CLASS");
|
|
||||||
return $hubs;
|
|
||||||
}
|
|
||||||
|
|
||||||
$results = [];
|
|
||||||
|
|
||||||
foreach ($hubs as $hub_data) {
|
|
||||||
$hub = $hub_data['hub'];
|
|
||||||
|
|
||||||
$available_riders = count($hub->getAvailableRiders());
|
|
||||||
// check we have available riders
|
|
||||||
error_log("TOTAL RIDERS: " . $available_riders);
|
|
||||||
if ($available_riders === 0) {
|
|
||||||
// if we have a JO, create rejection record and notify
|
|
||||||
$jo_id = $this->getJOID();
|
|
||||||
|
|
||||||
if (!empty($jo_id)) {
|
|
||||||
// create rejection report entry
|
|
||||||
$robj = $this->createRejectionEntry($hub, JORejectionReason::NO_RIDER_AVAILABLE);
|
|
||||||
|
|
||||||
// build SMS message
|
|
||||||
$this->sendSMSMessage(
|
|
||||||
$hub,
|
|
||||||
$params['order_date'],
|
|
||||||
$params['service_type'],
|
|
||||||
$robj,
|
|
||||||
JORejectionReason::getName(JORejectionReason::NO_RIDER_AVAILABLE),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// log this filter
|
|
||||||
$this->log($hub);
|
|
||||||
|
|
||||||
error_log("FILTERED HUB " . $hub->getID() . " (no_available_rider)");
|
|
||||||
} else {
|
|
||||||
$results[] = $hub_data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Service\HubFilter\Filters;
|
|
||||||
|
|
||||||
use App\Service\HubFilter\BaseHubFilter;
|
|
||||||
use App\Service\HubFilter\HubFilterInterface;
|
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
|
||||||
|
|
||||||
use App\Service\HubDistributor;
|
|
||||||
use App\Service\HubFilterLogger;
|
|
||||||
use App\Service\RisingTideGateway;
|
|
||||||
|
|
||||||
class RoundRobinHubFilter extends BaseHubFilter implements HubFilterInterface
|
|
||||||
{
|
|
||||||
protected $id = 'round_robin';
|
|
||||||
protected $hub_distributor;
|
|
||||||
|
|
||||||
public function __construct(HubFilterLogger $hub_filter_logger, EntityManagerInterface $em, RisingTideGateway $rt, TranslatorInterface $trans, HubDistributor $hub_distributor)
|
|
||||||
{
|
|
||||||
parent::__construct($hub_filter_logger, $em, $rt, $trans);
|
|
||||||
$this->hub_distributor = $hub_distributor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRequestedParams() : array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'flag_round_robin',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function filter(array $hubs, array $params = []) : array
|
|
||||||
{
|
|
||||||
if (!$params['flag_round_robin'])
|
|
||||||
return $hubs;
|
|
||||||
|
|
||||||
$results = [];
|
|
||||||
|
|
||||||
// call hub distributor service
|
|
||||||
$arranged_hubs = $this->hub_distributor->arrangeHubs($hubs);
|
|
||||||
$results = $arranged_hubs;
|
|
||||||
|
|
||||||
return $results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Service\HubFilter;
|
|
||||||
|
|
||||||
interface HubFilterInterface
|
|
||||||
{
|
|
||||||
public function getID() : string;
|
|
||||||
|
|
||||||
public function filter(array $hubs, array $params = []) : array;
|
|
||||||
|
|
||||||
public function setJOID(int $jo_id);
|
|
||||||
|
|
||||||
public function getJOID() : int;
|
|
||||||
|
|
||||||
public function setCustomerID(int $customer_id);
|
|
||||||
|
|
||||||
public function getCustomerID() : int;
|
|
||||||
|
|
||||||
public function getRequestedParams() : array;
|
|
||||||
}
|
|
||||||
|
|
@ -5,20 +5,21 @@ namespace App\Service;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
|
||||||
|
|
||||||
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
||||||
|
|
||||||
|
use App\Entity\Hub;
|
||||||
|
|
||||||
use App\Service\HubDistributor;
|
use App\Service\HubDistributor;
|
||||||
use App\Service\InventoryManager;
|
use App\Service\InventoryManager;
|
||||||
use App\Service\HubFilterLogger;
|
use App\Service\HubFilterLogger;
|
||||||
use App\Service\RisingTideGateway;
|
use App\Service\RisingTideGateway;
|
||||||
|
|
||||||
use App\Ramcar\HubCriteria;
|
use App\Ramcar\HubCriteria;
|
||||||
|
use App\Ramcar\ServiceType;
|
||||||
|
|
||||||
class HubSelector
|
class HubSelector
|
||||||
{
|
{
|
||||||
protected $container;
|
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $im;
|
protected $im;
|
||||||
protected $hub_distributor;
|
protected $hub_distributor;
|
||||||
|
|
@ -26,11 +27,10 @@ class HubSelector
|
||||||
protected $trans;
|
protected $trans;
|
||||||
protected $rt;
|
protected $rt;
|
||||||
|
|
||||||
public function __construct(ContainerInterface $container, EntityManagerInterface $em, InventoryManager $im,
|
public function __construct(EntityManagerInterface $em, InventoryManager $im,
|
||||||
HubDistributor $hub_distributor, HubFilterLogger $hub_filter_logger,
|
HubDistributor $hub_distributor, HubFilterLogger $hub_filter_logger,
|
||||||
TranslatorInterface $trans, RisingTideGateway $rt)
|
TranslatorInterface $trans, RisingTideGateway $rt)
|
||||||
{
|
{
|
||||||
$this->container = $container;
|
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->im = $im;
|
$this->im = $im;
|
||||||
$this->hub_distributor = $hub_distributor;
|
$this->hub_distributor = $hub_distributor;
|
||||||
|
|
@ -39,18 +39,6 @@ class HubSelector
|
||||||
$this->rt = $rt;
|
$this->rt = $rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getActiveFilters(): array
|
|
||||||
{
|
|
||||||
$fnames = explode(",", $this->container->getParameter('enabled_hub_filters'));
|
|
||||||
$enabled_filters = [];
|
|
||||||
|
|
||||||
foreach ($fnames as $filter) {
|
|
||||||
$enabled_filters[] = 'App\\Service\\HubFilter\\Filters\\' . $filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $enabled_filters;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function find(HubCriteria $criteria)
|
public function find(HubCriteria $criteria)
|
||||||
{
|
{
|
||||||
$point = $criteria->getPoint();
|
$point = $criteria->getPoint();
|
||||||
|
|
@ -58,20 +46,15 @@ class HubSelector
|
||||||
$limit_distance = $criteria->getLimitDistance();
|
$limit_distance = $criteria->getLimitDistance();
|
||||||
$jo_type = $criteria->getJoType();
|
$jo_type = $criteria->getJoType();
|
||||||
$flag_inventory_check = $criteria->hasInventoryCheck();
|
$flag_inventory_check = $criteria->hasInventoryCheck();
|
||||||
$flag_riders_check = $criteria->hasRidersCheck();
|
|
||||||
$items = $criteria->getItems();
|
$items = $criteria->getItems();
|
||||||
$date_time = $criteria->getDateTime();
|
$date_time = $criteria->getDateTime();
|
||||||
$payment_method = $criteria->getPaymentMethod();
|
$payment_method = $criteria->getPaymentMethod();
|
||||||
$flag_emergency = $criteria->isEmergency();
|
$flag_emergency = $criteria->isEmergency();
|
||||||
$flag_round_robin = $criteria->isRoundRobin();
|
$flag_round_robin = $criteria->isRoundRobin();
|
||||||
$jo_id = $criteria->getJobOrderId();
|
$jo_id = $criteria->getJobOrderId();
|
||||||
$jo_origin = $criteria->getJoOrigin();
|
|
||||||
$customer_id = $criteria->getCustomerId();
|
$customer_id = $criteria->getCustomerId();
|
||||||
$customer_class = $criteria->getCustomerClass();
|
|
||||||
|
|
||||||
// needed for JORejection records and SMS notifs
|
$results = [];
|
||||||
$order_date = $criteria->getOrderDate();
|
|
||||||
$service_type = $criteria->getServiceType();
|
|
||||||
|
|
||||||
// error_log('payment methods ' . $payment_method);
|
// error_log('payment methods ' . $payment_method);
|
||||||
// error_log('distance limit ' . $limit_distance);
|
// error_log('distance limit ' . $limit_distance);
|
||||||
|
|
@ -80,52 +63,278 @@ class HubSelector
|
||||||
// get all the hubs within distance
|
// get all the hubs within distance
|
||||||
$filtered_hubs = $this->getClosestHubs($point, $limit_distance, $jo_id, $customer_id);
|
$filtered_hubs = $this->getClosestHubs($point, $limit_distance, $jo_id, $customer_id);
|
||||||
|
|
||||||
// build param list
|
// error_log('closest hubs ' . json_encode($filtered_hubs));
|
||||||
$params = [
|
|
||||||
'date_time' => $date_time,
|
|
||||||
'flag_inventory_check' => $flag_inventory_check,
|
|
||||||
'customer_class' => $customer_class,
|
|
||||||
'jo_type' => $jo_type,
|
|
||||||
'jo_origin' => $jo_origin,
|
|
||||||
'order_date' => $order_date,
|
|
||||||
'service_type' => $service_type,
|
|
||||||
'items' => $items,
|
|
||||||
'flag_emergency' => $flag_emergency,
|
|
||||||
'limit_results' => $limit_results,
|
|
||||||
'payment_method' => $payment_method,
|
|
||||||
'flag_riders_check' => $flag_riders_check,
|
|
||||||
'flag_round_robin' => $flag_round_robin,
|
|
||||||
];
|
|
||||||
|
|
||||||
// loop through all enabled filters
|
// filter the first hub results for date and opening times
|
||||||
foreach ($this->getActiveFilters() as $hub_filter) {
|
$hubs_date_time = $this->filterHubsByDateAndTime($filtered_hubs, $date_time, $jo_id, $customer_id);
|
||||||
// no hubs left to filter
|
$filtered_hubs = $hubs_date_time;
|
||||||
if (empty($filtered_hubs)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$f = $this->container->get($hub_filter);
|
// error_log('date_time hubs ' . json_encode($filtered_hubs));
|
||||||
|
|
||||||
// check if supported area is exempted from this filter
|
if (!$flag_emergency)
|
||||||
if ($this->isExemptedByArea($f->getID(), $point)) {
|
{
|
||||||
continue;
|
// filter jo types
|
||||||
}
|
$hubs_jo_type = $this->filterHubsByJoType($filtered_hubs, $jo_type, $jo_id, $customer_id);
|
||||||
|
$filtered_hubs = $hubs_jo_type;
|
||||||
|
|
||||||
$f->setJOID($jo_id);
|
//error_log('jo_type hubs ' . json_encode($filtered_hubs));
|
||||||
$f->setCustomerID($customer_id);
|
|
||||||
|
|
||||||
// get requested params only
|
// filter hubs by payment methods
|
||||||
$req_params = array_intersect_key($params, array_flip($f->getRequestedParams()));
|
$hubs_payment_method = $this->filterHubsByPaymentMethod($filtered_hubs, $payment_method, $jo_id, $customer_id);
|
||||||
|
$filtered_hubs = $hubs_payment_method;
|
||||||
|
|
||||||
// filter hub list
|
//error_log('payment hubs ' . json_encode($filtered_hubs));
|
||||||
$filtered_hubs = $f->filter($filtered_hubs, $req_params);
|
|
||||||
|
|
||||||
// error_log($f->getID() . ' hubs ' . json_encode($filtered_hubs));
|
// inventory filter
|
||||||
|
$hubs_inventory = $this->filterHubsByInventory($filtered_hubs, $flag_inventory_check,
|
||||||
|
$jo_type, $items, $jo_id, $customer_id);
|
||||||
|
$filtered_hubs = $hubs_inventory;
|
||||||
|
|
||||||
|
//error_log('inventory hubs ' . json_encode($filtered_hubs));
|
||||||
|
|
||||||
|
// round robin filter
|
||||||
|
$hubs_round_robin = $this->filterHubsByRoundRobin($filtered_hubs, $flag_round_robin);
|
||||||
|
$filtered_hubs = $hubs_round_robin;
|
||||||
|
|
||||||
|
// error_log('round robin hubs ' . json_encode($filtered_hubs));
|
||||||
|
|
||||||
|
// max results filter
|
||||||
|
$hubs_max_result = $this->filterHubsByMaxResults($filtered_hubs, $limit_results, $jo_id, $customer_id);
|
||||||
|
$filtered_hubs = $hubs_max_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// error_log('final hub list ' . json_encode($filtered_hubs));
|
$results = $filtered_hubs;
|
||||||
|
|
||||||
return $filtered_hubs;
|
// error_log(json_encode($results));
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function filterHubsByRoundRobin($hubs, $flag_round_robin)
|
||||||
|
{
|
||||||
|
if (empty($hubs))
|
||||||
|
return $hubs;
|
||||||
|
if (!$flag_round_robin)
|
||||||
|
return $hubs;
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
// call hub distributor service
|
||||||
|
$arranged_hubs = $this->hub_distributor->arrangeHubs($hubs);
|
||||||
|
$results = $arranged_hubs;
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function filterHubsByMaxResults($hubs, $limit_result, $jo_id, $customer_id)
|
||||||
|
{
|
||||||
|
if (empty($hubs))
|
||||||
|
return $hubs;
|
||||||
|
if (empty($limit_result))
|
||||||
|
return $hubs;
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
for ($i = 0; $i < count($hubs); $i++)
|
||||||
|
{
|
||||||
|
if ($i < $limit_result)
|
||||||
|
$results[] = $hubs[$i];
|
||||||
|
else
|
||||||
|
$this->hub_filter_logger->logFilteredHub($hubs[$i]['hub'], 'max_results', $jo_id, $customer_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function filterHubsByJoType($hubs, $jo_type, $jo_id, $customer_id)
|
||||||
|
{
|
||||||
|
if (empty($hubs))
|
||||||
|
return $hubs;
|
||||||
|
if (empty($jo_type))
|
||||||
|
return $hubs;
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
foreach ($hubs as $hub_data)
|
||||||
|
{
|
||||||
|
$hub = $hub_data['hub'];
|
||||||
|
|
||||||
|
// TODO: for now, have this return true
|
||||||
|
$has_jo_type = true;
|
||||||
|
// check if hub offers the jo_type
|
||||||
|
// TODO: add service to hub
|
||||||
|
if ($has_jo_type)
|
||||||
|
$results[] = [
|
||||||
|
'hub' => $hub,
|
||||||
|
'db_distance' => $hub_data['db_distance'],
|
||||||
|
'distance' => $hub_data['distance'],
|
||||||
|
'duration' => $hub_data['duration'],
|
||||||
|
'jo_count' => 0,
|
||||||
|
];
|
||||||
|
else
|
||||||
|
$this->hub_filter_logger->logFilteredHub($hub, 'job_order_type', $jo_id, $customer_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function filterHubsByPaymentMethod($hubs, $payment_method, $jo_id, $customer_id)
|
||||||
|
{
|
||||||
|
if (empty($hubs))
|
||||||
|
return $hubs;
|
||||||
|
if (empty($payment_method))
|
||||||
|
return $hubs;
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
foreach ($hubs as $hub_data)
|
||||||
|
{
|
||||||
|
$hub = $hub_data['hub'];
|
||||||
|
|
||||||
|
// name of payment method is what is saved
|
||||||
|
$payment_methods = $hub->getPaymentMethods();
|
||||||
|
if ($payment_methods != null)
|
||||||
|
{
|
||||||
|
$flag_found_pmethod = false;
|
||||||
|
foreach ($payment_methods as $pmethod)
|
||||||
|
{
|
||||||
|
if ($pmethod == $payment_method)
|
||||||
|
{
|
||||||
|
$results[] = [
|
||||||
|
'hub' => $hub,
|
||||||
|
'db_distance' => $hub_data['db_distance'],
|
||||||
|
'distance' => $hub_data['distance'],
|
||||||
|
'duration' => $hub_data['duration'],
|
||||||
|
'jo_count' => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$flag_found_pmethod = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$flag_found_pmethod)
|
||||||
|
$this->hub_filter_logger->logFilteredHub($hub, 'no_payment_method', $jo_id, $customer_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$this->hub_filter_logger->logFilteredHub($hub, 'no_payment_method', $jo_id, $customer_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function filterHubsByDateAndTime($hubs, $date_time, $jo_id, $customer_id)
|
||||||
|
{
|
||||||
|
if (empty($hubs))
|
||||||
|
return $hubs;
|
||||||
|
|
||||||
|
if ($date_time == null)
|
||||||
|
return $hubs;
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
|
||||||
|
foreach ($hubs as $hub_data)
|
||||||
|
{
|
||||||
|
// go through each hub's opening times to check if hub is open
|
||||||
|
// for the specified time
|
||||||
|
// get hub opening and closing times
|
||||||
|
// TODO: maybe in the future, might also have to check if hub
|
||||||
|
// is open/available on date/day
|
||||||
|
$hub = $hub_data['hub'];
|
||||||
|
|
||||||
|
$time_open = $hub->getTimeOpen()->format("H:i:s");
|
||||||
|
$time_close = $hub->getTimeClose()->format("H:i:s");
|
||||||
|
|
||||||
|
$filter_time = $date_time->format("H:i:s");
|
||||||
|
|
||||||
|
if (($filter_time >= $time_open) &&
|
||||||
|
($filter_time <= $time_close))
|
||||||
|
{
|
||||||
|
$results[] = [
|
||||||
|
'hub' => $hub,
|
||||||
|
'db_distance' => $hub_data['db_distance'],
|
||||||
|
'distance' => $hub_data['distance'],
|
||||||
|
'duration' => $hub_data['duration'],
|
||||||
|
'jo_count' => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$this->hub_filter_logger->logFilteredHub($hub, 'date_and_time', $jo_id, $customer_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function filterHubsByInventory($hubs, $flag_inventory_check, $jo_type, $items, $jo_id, $customer_id)
|
||||||
|
{
|
||||||
|
if (empty($hubs))
|
||||||
|
return $hubs;
|
||||||
|
|
||||||
|
if (!$flag_inventory_check)
|
||||||
|
return $hubs;
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
if ($flag_inventory_check)
|
||||||
|
{
|
||||||
|
foreach ($hubs as $hub_data)
|
||||||
|
{
|
||||||
|
$hub = $hub_data['hub'];
|
||||||
|
|
||||||
|
if ($jo_type == ServiceType::BATTERY_REPLACEMENT_NEW)
|
||||||
|
{
|
||||||
|
// call inventory
|
||||||
|
$has_items = $this->checkInventory($items, $hub);
|
||||||
|
if ($has_items)
|
||||||
|
$results[] = [
|
||||||
|
'hub' => $hub,
|
||||||
|
'db_distance' => $hub_data['db_distance'],
|
||||||
|
'distance' => $hub_data['distance'],
|
||||||
|
'duration' => $hub_data['duration'],
|
||||||
|
'jo_count' => 0,
|
||||||
|
];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// get the skus for the message
|
||||||
|
$sku_text = '';
|
||||||
|
foreach ($items as $key => $value)
|
||||||
|
{
|
||||||
|
$sku_text .= ' ' . $key;
|
||||||
|
}
|
||||||
|
// send SMS to hub
|
||||||
|
$message = str_replace('item_display', trim($sku_text), $this->trans->trans('no_inventory_message'));
|
||||||
|
// error_log($message);
|
||||||
|
$this->sendSMSMessage($hub, $items);
|
||||||
|
|
||||||
|
$this->hub_filter_logger->logFilteredHub($hub, 'no_inventory', $jo_id, $customer_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($jo_type == ServiceType::BATTERY_REPLACEMENT_WARRANTY)
|
||||||
|
{
|
||||||
|
// call inventory
|
||||||
|
$has_items = $this->checkInventory($items, $hub);
|
||||||
|
if ($has_items)
|
||||||
|
$results[] = [
|
||||||
|
'hub' => $hub,
|
||||||
|
'db_distance' => $hub_data['db_distance'],
|
||||||
|
'distance' => $hub_data['distance'],
|
||||||
|
'duration' => $hub_data['duration'],
|
||||||
|
'jo_count' => 0,
|
||||||
|
];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// get the skus for the message
|
||||||
|
$sku_text = '';
|
||||||
|
foreach ($items as $key => $value)
|
||||||
|
{
|
||||||
|
$sku_text .= ' ' . $key;
|
||||||
|
}
|
||||||
|
// send SMS to hub
|
||||||
|
$message = str_replace('item_display', trim($sku_text), $this->trans->trans('no_inventory_message'));
|
||||||
|
// error_log($message);
|
||||||
|
$this->sendSMSMessage($hub, $items);
|
||||||
|
|
||||||
|
$this->hub_filter_logger->logFilteredHub($hub, 'no_inventory', $jo_id, $customer_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getClosestHubs(Point $point, $limit_distance, $jo_id, $customer_id)
|
protected function getClosestHubs(Point $point, $limit_distance, $jo_id, $customer_id)
|
||||||
|
|
@ -166,11 +375,7 @@ class HubSelector
|
||||||
'distance' => $dist,
|
'distance' => $dist,
|
||||||
'duration' => 0,
|
'duration' => 0,
|
||||||
'jo_count' => 0,
|
'jo_count' => 0,
|
||||||
'inventory' => 0,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// log to file
|
|
||||||
$this->logClosestHubResult($jo_id, $row[0], $dist, $limit_distance);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -181,6 +386,45 @@ class HubSelector
|
||||||
return $hubs_data;
|
return $hubs_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function checkInventory($items, $hub)
|
||||||
|
{
|
||||||
|
// check if hub has all items
|
||||||
|
$skus = [];
|
||||||
|
$branch_codes[] = $hub->getBranchCode();
|
||||||
|
$result = false;
|
||||||
|
|
||||||
|
foreach ($items as $key=> $value)
|
||||||
|
{
|
||||||
|
// add sap code of item/battery into array since
|
||||||
|
// getBranchesInventory takes in an array of hubs/branches
|
||||||
|
// and an array of skus
|
||||||
|
// $items as format: $items[sku] = quantity
|
||||||
|
$skus[] = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
// call InventoryManager's getBranchesInventory to check if hub has all items
|
||||||
|
$branches_with_items = $this->im->getBranchesInventory($branch_codes, $skus);
|
||||||
|
|
||||||
|
if (!empty($branches_with_items))
|
||||||
|
{
|
||||||
|
// check if branch has enough quantity for item
|
||||||
|
foreach ($branches_with_items as $branch)
|
||||||
|
{
|
||||||
|
// get quantity from call
|
||||||
|
$qty_available = $branch['Quantity'];
|
||||||
|
|
||||||
|
// get the quantity request
|
||||||
|
$sku_requested = $branch['SapCode'];
|
||||||
|
$qty_requested = $items[$sku_requested];
|
||||||
|
if ($qty_available >= $qty_requested)
|
||||||
|
$result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return true or false
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
// convert db distance to kilometers
|
// convert db distance to kilometers
|
||||||
protected function distance($lat1, $lon1, $lat2, $lon2)
|
protected function distance($lat1, $lon1, $lat2, $lon2)
|
||||||
{
|
{
|
||||||
|
|
@ -196,50 +440,26 @@ class HubSelector
|
||||||
return round(($miles * 1.609344), 1);
|
return round(($miles * 1.609344), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function isExemptedByArea(string $filter_id, Point $coordinates): bool
|
protected function sendSMSMessage($hub, $items)
|
||||||
{
|
{
|
||||||
$long = $coordinates->getLongitude();
|
// compose message
|
||||||
$lat = $coordinates->getLatitude();
|
// get the skus for the message
|
||||||
|
$sku_text = '';
|
||||||
// get supported area given a set of coordinates
|
foreach ($items as $key => $value)
|
||||||
$query = $this->em->createQuery('SELECT s from App\Entity\SupportedArea s where st_contains(s.coverage_area, point(:long, :lat)) = true');
|
{
|
||||||
$area = $query->setParameter('long', $long)
|
$sku_text .= ' ' . $key;
|
||||||
->setParameter('lat', $lat)
|
|
||||||
->setMaxResults(1)
|
|
||||||
->getOneOrNullResult();
|
|
||||||
|
|
||||||
if ($area !== null) {
|
|
||||||
// get all exceptions
|
|
||||||
$exceptions = $area->getHubFilterExceptions();
|
|
||||||
|
|
||||||
if (isset($exceptions[$filter_id])) {
|
|
||||||
error_log("FILTER " . $filter_id . " DISABLED FOR AREA: " . $area->getName());
|
|
||||||
|
|
||||||
// disable this filter for this area
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
$message = str_replace('item_display', trim($sku_text), $this->trans->trans('no_inventory_message'));
|
||||||
|
|
||||||
// filter is in place
|
// get hub notification number
|
||||||
return false;
|
$mobile_number = $hub->getNotifNumber();
|
||||||
}
|
|
||||||
|
|
||||||
protected function logClosestHubResult($jo_id, $hub, $distance, $limit_distance)
|
if (!empty($mobile_number))
|
||||||
{
|
{
|
||||||
// log to file
|
// send SMS message
|
||||||
$filename = '/../../var/log/closest_hubs_selected.log';
|
// error_log('sending sms to - ' . $mobile_number);
|
||||||
$date = date("Y-m-d H:i:s");
|
$this->rt->sendSMS($mobile_number, $this->trans->trans('message.battery_brand_allcaps'), $message);
|
||||||
|
}
|
||||||
// build log entry
|
|
||||||
$entry = implode("", [
|
|
||||||
"[JO: " . $jo_id . "]",
|
|
||||||
"[" . $date . "]",
|
|
||||||
"[Distance: " . $distance . " vs " . $limit_distance . "]",
|
|
||||||
" " . $hub->getName() . " (ID: " . $hub->getID() . ")",
|
|
||||||
"\r\n",
|
|
||||||
]);
|
|
||||||
|
|
||||||
@file_put_contents(__DIR__ . $filename, $entry, FILE_APPEND);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ class InsuranceConnector
|
||||||
return base64_encode($this->username . ":" . $this->password);
|
return base64_encode($this->username . ":" . $this->password);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function doRequest($url, $method, $request_body = [])
|
protected function doRequest($url, $method, $body = [])
|
||||||
{
|
{
|
||||||
$client = new Client();
|
$client = new Client();
|
||||||
$headers = [
|
$headers = [
|
||||||
|
|
@ -102,7 +102,7 @@ class InsuranceConnector
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$response = $client->request($method, $this->base_url . '/' . $url, [
|
$response = $client->request($method, $this->base_url . '/' . $url, [
|
||||||
'json' => $request_body,
|
'json' => $body,
|
||||||
'headers' => $headers,
|
'headers' => $headers,
|
||||||
]);
|
]);
|
||||||
} catch (RequestException $e) {
|
} catch (RequestException $e) {
|
||||||
|
|
@ -111,11 +111,6 @@ class InsuranceConnector
|
||||||
error_log("Insurance API Error: " . $error['message']);
|
error_log("Insurance API Error: " . $error['message']);
|
||||||
error_log(Psr7\Message::toString($e->getRequest()));
|
error_log(Psr7\Message::toString($e->getRequest()));
|
||||||
error_log($e->getResponse()->getBody()->getContents());
|
error_log($e->getResponse()->getBody()->getContents());
|
||||||
error_log("Insurance Creds: " . $this->username . ", " . $this->password);
|
|
||||||
error_log("Insurance Hash: " . $this->generateHash());
|
|
||||||
|
|
||||||
// log this error
|
|
||||||
$this->log($url, Psr7\Message::toString($e->getRequest()), Psr7\Message::toString($e->getResponse()), 'error');
|
|
||||||
|
|
||||||
if ($e->hasResponse()) {
|
if ($e->hasResponse()) {
|
||||||
$error['response'] = Psr7\Message::toString($e->getResponse());
|
$error['response'] = Psr7\Message::toString($e->getResponse());
|
||||||
|
|
@ -127,32 +122,11 @@ class InsuranceConnector
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$result_body = $response->getBody();
|
error_log(print_r(json_decode($response->getBody(), true), true));
|
||||||
|
|
||||||
// log response
|
|
||||||
$this->log($url, json_encode($request_body), $result_body);
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'success' => true,
|
'success' => true,
|
||||||
'response' => json_decode($result_body, true),
|
'response' => json_decode($response->getBody(), true)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make this more elegant
|
|
||||||
public function log($title, $request_body = "[]", $result_body = "[]", $type = 'api')
|
|
||||||
{
|
|
||||||
$filename = '/../../var/log/insurance_' . $type . '.log';
|
|
||||||
$date = date("Y-m-d H:i:s");
|
|
||||||
|
|
||||||
// build log entry
|
|
||||||
$entry = implode("\r\n", [
|
|
||||||
$date,
|
|
||||||
$title,
|
|
||||||
"REQUEST:\r\n" . $request_body,
|
|
||||||
"RESPONSE:\r\n" . $result_body,
|
|
||||||
"\r\n----------------------------------------\r\n\r\n",
|
|
||||||
]);
|
|
||||||
|
|
||||||
@file_put_contents(__DIR__ . $filename, $entry, FILE_APPEND);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate invoice criteria
|
// generate invoice criteria
|
||||||
public function generateInvoiceCriteria($jo, $discount, $invoice_items, $price_tier = null, $source = null, &$error_array)
|
public function generateInvoiceCriteria($jo, $discount, $invoice_items, $source = null, &$error_array)
|
||||||
{
|
{
|
||||||
$em = $this->em;
|
$em = $this->em;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ class ResqInvoiceGenerator implements InvoiceGeneratorInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate invoice criteria
|
// generate invoice criteria
|
||||||
public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, $price_tier = null, $source = null, &$error_array)
|
public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, $source = null, &$error_array)
|
||||||
{
|
{
|
||||||
$em = $this->em;
|
$em = $this->em;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ namespace App\Service;
|
||||||
|
|
||||||
use App\Entity\Invoice;
|
use App\Entity\Invoice;
|
||||||
use App\Entity\JobOrder;
|
use App\Entity\JobOrder;
|
||||||
use App\Entity\PriceTier;
|
|
||||||
|
|
||||||
use App\Ramcar\InvoiceCriteria;
|
use App\Ramcar\InvoiceCriteria;
|
||||||
|
|
||||||
|
|
@ -14,7 +13,7 @@ interface InvoiceGeneratorInterface
|
||||||
public function generateInvoice(InvoiceCriteria $criteria);
|
public function generateInvoice(InvoiceCriteria $criteria);
|
||||||
|
|
||||||
// generate invoice criteria
|
// generate invoice criteria
|
||||||
public function generateInvoiceCriteria(JobOrder $jo, int $promo_id, array $invoice_items, $source, PriceTier $price_tier, array &$error_array);
|
public function generateInvoiceCriteria(JobOrder $jo, int $promo_id, array $invoice_items, $source, array &$error_array);
|
||||||
|
|
||||||
// prepare draft for invoice
|
// prepare draft for invoice
|
||||||
public function generateDraftInvoice(InvoiceCriteria $criteria, int $promo_id, array $service_charges, array $items);
|
public function generateDraftInvoice(InvoiceCriteria $criteria, int $promo_id, array $service_charges, array $items);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||||
use App\InvoiceRule;
|
use App\InvoiceRule;
|
||||||
|
|
||||||
use App\Service\InvoiceGeneratorInterface;
|
use App\Service\InvoiceGeneratorInterface;
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
use App\Ramcar\InvoiceCriteria;
|
use App\Ramcar\InvoiceCriteria;
|
||||||
use App\Ramcar\InvoiceStatus;
|
use App\Ramcar\InvoiceStatus;
|
||||||
|
|
@ -29,14 +28,12 @@ class InvoiceManager implements InvoiceGeneratorInterface
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $validator;
|
protected $validator;
|
||||||
protected $available_rules;
|
protected $available_rules;
|
||||||
protected $pt_manager;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, Security $security, ValidatorInterface $validator, PriceTierManager $pt_manager)
|
public function __construct(EntityManagerInterface $em, Security $security, ValidatorInterface $validator)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->security = $security;
|
$this->security = $security;
|
||||||
$this->validator = $validator;
|
$this->validator = $validator;
|
||||||
$this->pt_manager = $pt_manager;
|
|
||||||
|
|
||||||
$this->available_rules = $this->getAvailableRules();
|
$this->available_rules = $this->getAvailableRules();
|
||||||
}
|
}
|
||||||
|
|
@ -45,37 +42,28 @@ class InvoiceManager implements InvoiceGeneratorInterface
|
||||||
{
|
{
|
||||||
// TODO: get list of invoice rules from .env or a json file?
|
// TODO: get list of invoice rules from .env or a json file?
|
||||||
return [
|
return [
|
||||||
new InvoiceRule\BatterySales($this->em, $this->pt_manager),
|
new InvoiceRule\BatterySales($this->em),
|
||||||
new InvoiceRule\BatteryReplacementWarranty($this->em, $this->pt_manager),
|
new InvoiceRule\BatteryReplacementWarranty($this->em),
|
||||||
new InvoiceRule\Jumpstart($this->em, $this->pt_manager),
|
new InvoiceRule\Jumpstart($this->em),
|
||||||
new InvoiceRule\JumpstartWarranty($this->em, $this->pt_manager),
|
new InvoiceRule\JumpstartWarranty($this->em),
|
||||||
new InvoiceRule\PostRecharged($this->em, $this->pt_manager),
|
new InvoiceRule\PostRecharged($this->em),
|
||||||
new InvoiceRule\PostReplacement($this->em, $this->pt_manager),
|
new InvoiceRule\PostReplacement($this->em),
|
||||||
new InvoiceRule\Overheat($this->em, $this->pt_manager),
|
new InvoiceRule\Overheat($this->em),
|
||||||
new InvoiceRule\Fuel($this->em, $this->pt_manager),
|
new InvoiceRule\Fuel($this->em),
|
||||||
new InvoiceRule\TireRepair($this->em, $this->pt_manager),
|
new InvoiceRule\TireRepair($this->em),
|
||||||
new InvoiceRule\DiscountType($this->em),
|
new InvoiceRule\DiscountType($this->em),
|
||||||
new InvoiceRule\TradeIn($this->em),
|
new InvoiceRule\TradeIn(),
|
||||||
new InvoiceRule\Tax($this->em, $this->pt_manager),
|
new InvoiceRule\Tax($this->em),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is called when JO is submitted
|
// this is called when JO is submitted
|
||||||
public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, $source, $price_tier, &$error_array)
|
public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, $source, &$error_array)
|
||||||
{
|
{
|
||||||
// instantiate the invoice criteria
|
// instantiate the invoice criteria
|
||||||
$criteria = new InvoiceCriteria();
|
$criteria = new InvoiceCriteria();
|
||||||
$criteria->setServiceType($jo->getServiceType())
|
$criteria->setServiceType($jo->getServiceType())
|
||||||
->setCustomerVehicle($jo->getCustomerVehicle())
|
->setCustomerVehicle($jo->getCustomerVehicle());
|
||||||
->setPriceTier($price_tier);
|
|
||||||
|
|
||||||
if (($jo->getServiceType() == ServiceType::OVERHEAT_ASSISTANCE) &&
|
|
||||||
($jo->hasCoolant()))
|
|
||||||
$criteria->setHasCoolant(true);
|
|
||||||
|
|
||||||
if (($jo->getServiceType() == ServiceType::TIRE_REPAIR) &&
|
|
||||||
($jo->hasSealant()))
|
|
||||||
$criteria->setHasSealant(true);
|
|
||||||
|
|
||||||
// set if taxable
|
// set if taxable
|
||||||
// NOTE: ideally, this should be a parameter when calling generateInvoiceCriteria. But that
|
// NOTE: ideally, this should be a parameter when calling generateInvoiceCriteria. But that
|
||||||
|
|
@ -174,7 +162,6 @@ class InvoiceManager implements InvoiceGeneratorInterface
|
||||||
// (3) generateInvoiceCriteria
|
// (3) generateInvoiceCriteria
|
||||||
// (4) RiderAPIHandler's changeService
|
// (4) RiderAPIHandler's changeService
|
||||||
// (5) TAPI's JobOrderController
|
// (5) TAPI's JobOrderController
|
||||||
// (6) CAPI's RiderAppController
|
|
||||||
public function generateInvoice($criteria)
|
public function generateInvoice($criteria)
|
||||||
{
|
{
|
||||||
// no need to validate since generateDraftInvoice was called before this was called
|
// no need to validate since generateDraftInvoice was called before this was called
|
||||||
|
|
@ -223,27 +210,17 @@ class InvoiceManager implements InvoiceGeneratorInterface
|
||||||
$price = $item['price'];
|
$price = $item['price'];
|
||||||
|
|
||||||
$battery = null;
|
$battery = null;
|
||||||
$battery_size = null;
|
|
||||||
$trade_in_type = '';
|
|
||||||
if (isset($item['battery']))
|
if (isset($item['battery']))
|
||||||
$battery = $item['battery'];
|
$battery = $item['battery'];
|
||||||
|
|
||||||
if (isset($item['promo']))
|
if (isset($item['promo']))
|
||||||
$promo = $item['promo'];
|
$promo = $item['promo'];
|
||||||
|
|
||||||
if (isset($item['battery_size']))
|
|
||||||
$battery_size = $item['battery_size'];
|
|
||||||
|
|
||||||
if (isset($item['trade_in_type']))
|
|
||||||
$trade_in_type = $item['trade_in_type'];
|
|
||||||
|
|
||||||
$invoice_items[] = [
|
$invoice_items[] = [
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'quantity' => $quantity,
|
'quantity' => $quantity,
|
||||||
'price' => $price,
|
'price' => $price,
|
||||||
'battery' => $battery,
|
'battery' => $battery,
|
||||||
'battery_size' => $battery_size,
|
|
||||||
'trade_in_type' => $trade_in_type,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -292,15 +269,11 @@ class InvoiceManager implements InvoiceGeneratorInterface
|
||||||
$invoice_item->setInvoice($invoice)
|
$invoice_item->setInvoice($invoice)
|
||||||
->setTitle($item['title'])
|
->setTitle($item['title'])
|
||||||
->setQuantity($item['quantity'])
|
->setQuantity($item['quantity'])
|
||||||
->setPrice((float)$item['price'])
|
->setPrice((float)$item['price']);
|
||||||
->setTradeInType($item['trade_in_type']);
|
|
||||||
|
|
||||||
if ($item['battery'] != null)
|
if ($item['battery'] != null)
|
||||||
$invoice_item->setBattery($item['battery']);
|
$invoice_item->setBattery($item['battery']);
|
||||||
|
|
||||||
if ($item['battery_size'] != null)
|
|
||||||
$invoice_item->setBatterySize($item['battery_size']);
|
|
||||||
|
|
||||||
$invoice->addItem($invoice_item);
|
$invoice->addItem($invoice_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ use App\Entity\EmergencyType;
|
||||||
use App\Entity\OwnershipType;
|
use App\Entity\OwnershipType;
|
||||||
use App\Entity\CustomerLocation;
|
use App\Entity\CustomerLocation;
|
||||||
use App\Entity\Battery;
|
use App\Entity\Battery;
|
||||||
use App\Entity\BatterySize;
|
|
||||||
|
|
||||||
use App\Ramcar\ServiceType;
|
use App\Ramcar\ServiceType;
|
||||||
use App\Ramcar\TradeInType;
|
use App\Ramcar\TradeInType;
|
||||||
|
|
@ -70,7 +69,6 @@ use App\Service\HubSelector;
|
||||||
use App\Service\HubDistributor;
|
use App\Service\HubDistributor;
|
||||||
use App\Service\HubFilteringGeoChecker;
|
use App\Service\HubFilteringGeoChecker;
|
||||||
use App\Service\JobOrderManager;
|
use App\Service\JobOrderManager;
|
||||||
use App\Service\PriceTierManager;
|
|
||||||
|
|
||||||
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
||||||
|
|
||||||
|
|
@ -96,9 +94,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
protected $hub_dist;
|
protected $hub_dist;
|
||||||
protected $hub_geofence;
|
protected $hub_geofence;
|
||||||
protected $cust_distance_limit;
|
protected $cust_distance_limit;
|
||||||
protected $hub_filter_enabled;
|
protected $hub_filter_enable;
|
||||||
protected $jo_manager;
|
protected $jo_manager;
|
||||||
protected $pt_manager;
|
|
||||||
|
|
||||||
protected $template_hash;
|
protected $template_hash;
|
||||||
|
|
||||||
|
|
@ -107,7 +104,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah,
|
TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah,
|
||||||
string $country_code, WarrantyHandler $wh, RisingTideGateway $rt,
|
string $country_code, WarrantyHandler $wh, RisingTideGateway $rt,
|
||||||
PromoLogger $promo_logger, HubDistributor $hub_dist, HubFilteringGeoChecker $hub_geofence,
|
PromoLogger $promo_logger, HubDistributor $hub_dist, HubFilteringGeoChecker $hub_geofence,
|
||||||
string $cust_distance_limit, string $hub_filter_enabled, JobOrderManager $jo_manager, PriceTierManager $pt_manager)
|
string $cust_distance_limit, string $hub_filter_enabled, JobOrderManager $jo_manager)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->ic = $ic;
|
$this->ic = $ic;
|
||||||
|
|
@ -124,7 +121,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
$this->cust_distance_limit = $cust_distance_limit;
|
$this->cust_distance_limit = $cust_distance_limit;
|
||||||
$this->hub_filter_enabled = $hub_filter_enabled;
|
$this->hub_filter_enabled = $hub_filter_enabled;
|
||||||
$this->jo_manager = $jo_manager;
|
$this->jo_manager = $jo_manager;
|
||||||
$this->pt_manager = $pt_manager;
|
|
||||||
|
|
||||||
$this->loadTemplates();
|
$this->loadTemplates();
|
||||||
}
|
}
|
||||||
|
|
@ -589,9 +585,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
{
|
{
|
||||||
$source = $jo->getSource();
|
$source = $jo->getSource();
|
||||||
|
|
||||||
// get the price tier according to location.
|
$this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $source, $error_array);
|
||||||
$price_tier = $this->pt_manager->getPriceTier($jo->getCoordinates());
|
|
||||||
$this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $source, $price_tier, $error_array);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
|
|
@ -823,9 +817,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
{
|
{
|
||||||
$source = $obj->getSource();
|
$source = $obj->getSource();
|
||||||
|
|
||||||
// get the price tier according to location.
|
$this->ic->generateInvoiceCriteria($obj, $promo_id, $invoice_items, $source, $error_array);
|
||||||
$price_tier = $this->pt_manager->getPriceTier($obj->getCoordinates());
|
|
||||||
$this->ic->generateInvoiceCriteria($obj, $promo_id, $invoice_items, $source, $price_tier, $error_array);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
|
|
@ -1612,26 +1604,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
$error_array['cust_location'] = 'Invalid customer location';
|
$error_array['cust_location'] = 'Invalid customer location';
|
||||||
}
|
}
|
||||||
|
|
||||||
// check facilitated type
|
|
||||||
$fac_type = $req->request->get('facilitated_type');
|
|
||||||
if (!empty($fac_type))
|
|
||||||
{
|
|
||||||
if (!FacilitatedType::validate($fac_type))
|
|
||||||
$fac_type = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$fac_type = null;
|
|
||||||
|
|
||||||
// check facilitated by
|
|
||||||
$fac_by_id = $req->request->get('facilitated_by');
|
|
||||||
$fac_by = null;
|
|
||||||
if (!empty($fac_by_id))
|
|
||||||
{
|
|
||||||
$fac_by = $em->getRepository(Hub::class)->find($fac_by_id);
|
|
||||||
if (empty($fac_by))
|
|
||||||
$fac_by = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get previously assigned hub, if any
|
// get previously assigned hub, if any
|
||||||
$old_hub = $obj->getHub();
|
$old_hub = $obj->getHub();
|
||||||
|
|
||||||
|
|
@ -1692,8 +1664,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
->setOwnershipType($owner_type)
|
->setOwnershipType($owner_type)
|
||||||
->setCustomerLocation($cust_location)
|
->setCustomerLocation($cust_location)
|
||||||
->setInventoryCount($req->request->get('hub_inv_count', 0))
|
->setInventoryCount($req->request->get('hub_inv_count', 0))
|
||||||
->setFacilitatedType($fac_type)
|
|
||||||
->setFacilitatedBy($fac_by)
|
|
||||||
->clearRider();
|
->clearRider();
|
||||||
|
|
||||||
if ($user != null)
|
if ($user != null)
|
||||||
|
|
@ -2044,7 +2014,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
|
|
||||||
// NOTE: for resq2 app
|
// NOTE: for resq2 app
|
||||||
$mclientv2->sendEvent($obj, $payload);
|
$mclientv2->sendEvent($obj, $payload);
|
||||||
$mclientv2->sendRiderEvent($obj, $payload);
|
|
||||||
$fcmclient->sendJoEvent($obj, "jo_fcm_title_driver_assigned", "jo_fcm_body_driver_assigned");
|
$fcmclient->sendJoEvent($obj, "jo_fcm_title_driver_assigned", "jo_fcm_body_driver_assigned");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2196,9 +2165,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
// NOTE: this is CMB code but for compilation purposes we need to add this
|
// NOTE: this is CMB code but for compilation purposes we need to add this
|
||||||
$source = $jo->getSource();
|
$source = $jo->getSource();
|
||||||
|
|
||||||
// get the price tier according to location.
|
$this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $source, $error_array);
|
||||||
$price_tier = $this->pt_manager->getPriceTier($jo->getCoordinates());
|
|
||||||
$this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $source, $price_tier, $error_array);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
|
|
@ -2335,13 +2302,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
$em = $this->em;
|
$em = $this->em;
|
||||||
$jo = $em->getRepository(JobOrder::class)->find($id);
|
$jo = $em->getRepository(JobOrder::class)->find($id);
|
||||||
|
|
||||||
// get the job order's invoice items
|
|
||||||
$invoice = $jo->getInvoice();
|
|
||||||
$invoice_items = [];
|
|
||||||
if ($invoice != null)
|
|
||||||
$invoice_items = $invoice->getItems();
|
|
||||||
|
|
||||||
$params['invoice_items'] = $invoice_items;
|
|
||||||
$params['obj'] = $jo;
|
$params['obj'] = $jo;
|
||||||
$params['mode'] = 'open_edit';
|
$params['mode'] = 'open_edit';
|
||||||
$params['cvid'] = $jo->getCustomerVehicle()->getID();
|
$params['cvid'] = $jo->getCustomerVehicle()->getID();
|
||||||
|
|
@ -2581,20 +2541,10 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
->setDateTime($obj->getDateSchedule())
|
->setDateTime($obj->getDateSchedule())
|
||||||
->setLimitResults(50);
|
->setLimitResults(50);
|
||||||
|
|
||||||
// NOTE: set JO type regardless, for now
|
|
||||||
$hub_criteria->setJoType($obj->getServiceType())
|
|
||||||
->setOrderDate($obj->getDateCreate())
|
|
||||||
->setServiceType($obj->getServiceType());
|
|
||||||
|
|
||||||
// set customer class
|
|
||||||
$cust = $obj->getCustomer();
|
|
||||||
$hub_criteria->setCustomerClass($cust->getCustomerClassification());
|
|
||||||
|
|
||||||
// check if hub filter is enabled. If not, use default values
|
// check if hub filter is enabled. If not, use default values
|
||||||
// for the rest of the HubCriteria fields
|
// for the rest of the HubCriteria fields
|
||||||
if ($this->hub_filter_enabled == 'true')
|
if ($this->hub_filter_enabled == 'true')
|
||||||
{
|
{
|
||||||
// TODO: allow this to be disabled via env or CRM. commenting out for now
|
|
||||||
// error_log('hub filter is enabled');
|
// error_log('hub filter is enabled');
|
||||||
if ($this->hub_geofence->isCovered($long, $lat))
|
if ($this->hub_geofence->isCovered($long, $lat))
|
||||||
{
|
{
|
||||||
|
|
@ -2602,6 +2552,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
// error_log('Area is covered by hub filtering');
|
// error_log('Area is covered by hub filtering');
|
||||||
$hub_criteria->setLimitDistance($this->cust_distance_limit)
|
$hub_criteria->setLimitDistance($this->cust_distance_limit)
|
||||||
->setPaymentMethod($obj->getModeOfPayment())
|
->setPaymentMethod($obj->getModeOfPayment())
|
||||||
|
->setJoType($obj->getServiceType())
|
||||||
->setRoundRobin(true);
|
->setRoundRobin(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2612,22 +2563,15 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
{
|
{
|
||||||
// reset distance limit if emergency
|
// reset distance limit if emergency
|
||||||
//TODO: move to .env the emergency distance limit
|
//TODO: move to .env the emergency distance limit
|
||||||
$hub_criteria->setLimitDistance(500)
|
$hub_criteria->setLimitDistance(500);
|
||||||
->setEmergency(true)
|
$hub_criteria->setEmergency(true);
|
||||||
->setPaymentMethod(null)
|
|
||||||
->setRoundRobin(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set filter flags for inventory and available riders
|
|
||||||
$hub_criteria->setInventoryCheck();
|
|
||||||
$hub_criteria->setRidersCheck();
|
|
||||||
|
|
||||||
// get JO and customer id for logging purposes
|
// get JO and customer id for logging purposes
|
||||||
$jo_id = $obj->getID();
|
$jo_id = $obj->getID();
|
||||||
$customer_id = $obj->getCustomer()->getID();
|
$customer_id = $obj->getCustomer()->getID();
|
||||||
|
|
||||||
$hub_criteria->setJobOrderId($jo_id)
|
$hub_criteria->setJobOrderId($jo_id)
|
||||||
->setJoOrigin($obj->getSource())
|
|
||||||
->setCustomerId($customer_id);
|
->setCustomerId($customer_id);
|
||||||
|
|
||||||
$hubs = $hub_selector->find($hub_criteria);
|
$hubs = $hub_selector->find($hub_criteria);
|
||||||
|
|
@ -2692,7 +2636,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
|
|
||||||
// handle inventory data
|
// handle inventory data
|
||||||
$bcode = $hub['hub']->getBranchCode();
|
$bcode = $hub['hub']->getBranchCode();
|
||||||
//$hub['inventory'] = 0;
|
$hub['inventory'] = 0;
|
||||||
if ($bcode != '')
|
if ($bcode != '')
|
||||||
{
|
{
|
||||||
$branch_codes[] = $bcode;
|
$branch_codes[] = $bcode;
|
||||||
|
|
@ -2706,65 +2650,43 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
$params['hubs'][$hub_id] = $hub;
|
$params['hubs'][$hub_id] = $hub;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get all enabled filters
|
|
||||||
$enabled_filter_str = $_ENV['ENABLED_HUB_FILTERS'];
|
|
||||||
$enabled_filters = explode(",", $enabled_filter_str);
|
|
||||||
|
|
||||||
// if inventory filter is disabled, fetch inventory here
|
|
||||||
if (!in_array('InventoryHubFilter', $enabled_filters) || $this->skipInventoryCheck($obj->getCoordinates())) {
|
|
||||||
error_log("NO INVENTORY CHECKS, GETTING INVENTORY FOR JO " . $obj->getID());
|
|
||||||
|
|
||||||
// get battery (if any)
|
|
||||||
$skus = [];
|
|
||||||
$invoice = $obj->getInvoice();
|
|
||||||
$inv_items = $invoice->getItems();
|
|
||||||
foreach ($inv_items as $inv_item)
|
|
||||||
{
|
|
||||||
$batt = $inv_item->getBattery();
|
|
||||||
if ($batt == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$skus[] = $batt->getSapCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get inventory
|
|
||||||
$mres = $motiv->getInventory($branch_codes, $skus);
|
|
||||||
$x = 0;
|
|
||||||
|
|
||||||
error_log("TOTAL RESULTS FROM MOTIV: " . count($mres) . " OUT OF " . count($branch_codes) . " BRANCH CODES AND " . count($skus) . " SKUS");
|
|
||||||
|
|
||||||
foreach ($mres as $mres_item)
|
|
||||||
{
|
|
||||||
// check if we have a valid response from motiv, ignore otherwise
|
|
||||||
if (isset($mres_item['BranchCode']))
|
|
||||||
{
|
|
||||||
$bcode = $mres_item['BranchCode'];
|
|
||||||
$inv_count = $mres_item['Quantity'];
|
|
||||||
if (isset($inv_data[$bcode]))
|
|
||||||
{
|
|
||||||
$hub_id = $inv_data[$bcode]['hub_id'];
|
|
||||||
|
|
||||||
$params['hubs'][$hub_id]['inventory'] = $inv_count;
|
|
||||||
|
|
||||||
error_log("SETTING HUB " . $hub_id . " INVENTORY TO " . $inv_count);
|
|
||||||
$x++;
|
|
||||||
} else {
|
|
||||||
error_log("CANNOT FIND BCODE FOR " . $bcode);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
error_log("CANNOT FIND BCODE FOR RESULT: " . print_r($mres_item, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
error_log("SET QUANTITY OF " . $x . " HUBS TO NON ZERO");
|
|
||||||
|
|
||||||
// error_log(print_r($mres, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
$params['obj'] = $obj;
|
$params['obj'] = $obj;
|
||||||
// get template to display
|
// get template to display
|
||||||
$params['template'] = $this->getTwigTemplate('jo_processing_form');
|
$params['template'] = $this->getTwigTemplate('jo_processing_form');
|
||||||
|
|
||||||
|
// get battery (if any)
|
||||||
|
$skus = [];
|
||||||
|
$invoice = $obj->getInvoice();
|
||||||
|
$inv_items = $invoice->getItems();
|
||||||
|
foreach ($inv_items as $inv_item)
|
||||||
|
{
|
||||||
|
$batt = $inv_item->getBattery();
|
||||||
|
if ($batt == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$skus[] = $batt->getSapCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get inventory
|
||||||
|
$mres = $motiv->getInventory($branch_codes, $skus);
|
||||||
|
foreach ($mres as $mres_item)
|
||||||
|
{
|
||||||
|
// check if we have a valid response from motiv, ignore otherwise
|
||||||
|
if (isset($mres_item['BranchCode']))
|
||||||
|
{
|
||||||
|
$bcode = $mres_item['BranchCode'];
|
||||||
|
$inv_count = $mres_item['Quantity'];
|
||||||
|
if (isset($inv_data[$bcode]))
|
||||||
|
{
|
||||||
|
$hub_id = $inv_data[$bcode]['hub_id'];
|
||||||
|
|
||||||
|
$params['hubs'][$hub_id]['inventory'] = $inv_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// error_log(print_r($mres, true));
|
||||||
|
|
||||||
return $params;
|
return $params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2957,22 +2879,13 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
->setDateTime($obj->getDateSchedule())
|
->setDateTime($obj->getDateSchedule())
|
||||||
->setLimitResults(50);
|
->setLimitResults(50);
|
||||||
|
|
||||||
// NOTE: set JO type regardless, for now
|
|
||||||
$hub_criteria->setJoType($obj->getServiceType())
|
|
||||||
->setOrderDate($obj->getDateCreate())
|
|
||||||
->setServiceType($obj->getServiceType());
|
|
||||||
|
|
||||||
// set customer class
|
|
||||||
$cust = $obj->getCustomer();
|
|
||||||
$hub_criteria->setCustomerClass($cust->getCustomerClassification());
|
|
||||||
|
|
||||||
// TODO: allow this to be disabled via env or CRM. commenting out for now
|
|
||||||
if ($this->hub_geofence->isCovered($long, $lat))
|
if ($this->hub_geofence->isCovered($long, $lat))
|
||||||
{
|
{
|
||||||
// if true, set other values for HubCriteria
|
// if true, set other values for HubCriteria
|
||||||
// error_log('Area is covered by hub');
|
// error_log('Area is covered by hub');
|
||||||
$hub_criteria->setLimitDistance($this->cust_distance_limit)
|
$hub_criteria->setLimitDistance($this->cust_distance_limit)
|
||||||
->setPaymentMethod($obj->getModeOfPayment())
|
->setPaymentMethod($obj->getModeOfPayment())
|
||||||
|
->setJoType($obj->getServiceType())
|
||||||
->setRoundRobin(true);
|
->setRoundRobin(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2981,22 +2894,15 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
if ($willing_to_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT)
|
if ($willing_to_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT)
|
||||||
{
|
{
|
||||||
//TODO: move to .env the emergency distance limit
|
//TODO: move to .env the emergency distance limit
|
||||||
$hub_criteria->setLimitDistance(500)
|
$hub_criteria->setLimitDistance(500);
|
||||||
->setEmergency(true)
|
$hub_criteria->setEmergency(true);
|
||||||
->setPaymentMethod(null)
|
|
||||||
->setRoundRobin(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set filter flags for inventory and available riders
|
|
||||||
$hub_criteria->setInventoryCheck();
|
|
||||||
$hub_criteria->setRidersCheck();
|
|
||||||
|
|
||||||
// get JO and customer id for logging purposes
|
// get JO and customer id for logging purposes
|
||||||
$jo_id = $obj->getID();
|
$jo_id = $obj->getID();
|
||||||
$customer_id = $cust->getID();
|
$customer_id = $obj->getCustomer()->getID();
|
||||||
|
|
||||||
$hub_criteria->setJobOrderId($jo_id)
|
$hub_criteria->setJobOrderId($jo_id)
|
||||||
->setJoOrigin($obj->getSource())
|
|
||||||
->setCustomerId($customer_id);
|
->setCustomerId($customer_id);
|
||||||
|
|
||||||
$hubs = $hub_selector->find($hub_criteria);
|
$hubs = $hub_selector->find($hub_criteria);
|
||||||
|
|
@ -3004,9 +2910,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
$params['status_cancelled'] = JOStatus::CANCELLED;
|
$params['status_cancelled'] = JOStatus::CANCELLED;
|
||||||
$params['hubs'] = [];
|
$params['hubs'] = [];
|
||||||
|
|
||||||
$branch_codes = [];
|
|
||||||
$inv_data = [];
|
|
||||||
|
|
||||||
// format duration and distance into friendly time
|
// format duration and distance into friendly time
|
||||||
foreach ($hubs as $hub) {
|
foreach ($hubs as $hub) {
|
||||||
// duration
|
// duration
|
||||||
|
|
@ -3062,7 +2965,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
|
|
||||||
// handle inventory data
|
// handle inventory data
|
||||||
$bcode = $hub['hub']->getBranchCode();
|
$bcode = $hub['hub']->getBranchCode();
|
||||||
//$hub['inventory'] = 0;
|
$hub['inventory'] = 0;
|
||||||
if ($bcode != '')
|
if ($bcode != '')
|
||||||
{
|
{
|
||||||
$branch_codes[] = $bcode;
|
$branch_codes[] = $bcode;
|
||||||
|
|
@ -3075,62 +2978,40 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
|
|
||||||
$params['hubs'][$hub_id] = $hub;
|
$params['hubs'][$hub_id] = $hub;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get all enabled filters
|
|
||||||
$enabled_filter_str = $_ENV['ENABLED_HUB_FILTERS'];
|
|
||||||
$enabled_filters = explode(",", $enabled_filter_str);
|
|
||||||
|
|
||||||
// if inventory filter is disabled, fetch inventory here
|
// get battery (if any)
|
||||||
if (!in_array('InventoryHubFilter', $enabled_filters) || $this->skipInventoryCheck($obj->getCoordinates())) {
|
$skus = [];
|
||||||
error_log("NO INVENTORY CHECKS, GETTING INVENTORY FOR JO " . $obj->getID());
|
$invoice = $obj->getInvoice();
|
||||||
|
$inv_items = $invoice->getItems();
|
||||||
|
foreach ($inv_items as $inv_item)
|
||||||
|
{
|
||||||
|
$batt = $inv_item->getBattery();
|
||||||
|
if ($batt == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
// get battery (if any)
|
$skus[] = $batt->getSapCode();
|
||||||
$skus = [];
|
}
|
||||||
$invoice = $obj->getInvoice();
|
|
||||||
$inv_items = $invoice->getItems();
|
// get inventory
|
||||||
foreach ($inv_items as $inv_item)
|
$mres = $motiv->getInventory($branch_codes, $skus);
|
||||||
|
foreach ($mres as $mres_item)
|
||||||
|
{
|
||||||
|
// check if we have a valid response from motiv, ignore otherwise
|
||||||
|
if (isset($mres_item['BranchCode']))
|
||||||
{
|
{
|
||||||
$batt = $inv_item->getBattery();
|
$bcode = $mres_item['BranchCode'];
|
||||||
if ($batt == null)
|
$inv_count = $mres_item['Quantity'];
|
||||||
continue;
|
if (isset($inv_data[$bcode]))
|
||||||
|
|
||||||
$skus[] = $batt->getSapCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get inventory
|
|
||||||
$mres = $motiv->getInventory($branch_codes, $skus);
|
|
||||||
$x = 0;
|
|
||||||
|
|
||||||
error_log("TOTAL RESULTS FROM MOTIV: " . count($mres) . " OUT OF " . count($branch_codes) . " BRANCH CODES AND " . count($skus) . " SKUS");
|
|
||||||
|
|
||||||
foreach ($mres as $mres_item)
|
|
||||||
{
|
|
||||||
// check if we have a valid response from motiv, ignore otherwise
|
|
||||||
if (isset($mres_item['BranchCode']))
|
|
||||||
{
|
{
|
||||||
$bcode = $mres_item['BranchCode'];
|
$hub_id = $inv_data[$bcode]['hub_id'];
|
||||||
$inv_count = $mres_item['Quantity'];
|
|
||||||
if (isset($inv_data[$bcode]))
|
|
||||||
{
|
|
||||||
$hub_id = $inv_data[$bcode]['hub_id'];
|
|
||||||
|
|
||||||
$params['hubs'][$hub_id]['inventory'] = $inv_count;
|
$params['hubs'][$hub_id]['inventory'] = $inv_count;
|
||||||
|
|
||||||
error_log("SETTING HUB " . $hub_id . " INVENTORY TO " . $inv_count);
|
|
||||||
$x++;
|
|
||||||
} else {
|
|
||||||
error_log("CANNOT FIND BCODE FOR " . $bcode);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
error_log("CANNOT FIND BCODE FOR RESULT: " . print_r($mres_item, true));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error_log("SET QUANTITY OF " . $x . " HUBS TO NON ZERO");
|
|
||||||
|
|
||||||
// error_log(print_r($mres, true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// error_log(print_r($mres, true));
|
||||||
|
|
||||||
$params['obj'] = $obj;
|
$params['obj'] = $obj;
|
||||||
// get template to display
|
// get template to display
|
||||||
$params['template'] = $this->getTwigTemplate('jo_open_hub_form');
|
$params['template'] = $this->getTwigTemplate('jo_open_hub_form');
|
||||||
|
|
@ -3661,15 +3542,15 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
$params['trade_in_bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll();
|
$params['trade_in_bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll();
|
||||||
$params['promos'] = $em->getRepository(Promo::class)->findAll();
|
$params['promos'] = $em->getRepository(Promo::class)->findAll();
|
||||||
|
|
||||||
// list of battery sizes for trade-in
|
// list of batteries for trade-in
|
||||||
$ti_batt_sizes = $em->getRepository(BatterySize::class)->findAll();
|
$ti_batteries = $em->getRepository(Battery::class)->findAll();
|
||||||
$trade_in_batt_sizes = [];
|
$trade_in_batteries = [];
|
||||||
foreach ($ti_batt_sizes as $ti_batt_size)
|
foreach ($ti_batteries as $ti_battery)
|
||||||
{
|
{
|
||||||
$batt_size_name = $ti_batt_size->getName();
|
$battery_name = $ti_battery->getModel()->getName() . ' ' . $ti_battery->getSize()->getName();
|
||||||
$trade_in_batt_sizes[$ti_batt_size->getID()] = $batt_size_name;
|
$trade_in_batteries[$ti_battery->getID()] = $battery_name;
|
||||||
}
|
}
|
||||||
$params['trade_in_batt_sizes'] = $trade_in_batt_sizes;
|
$params['trade_in_batteries'] = $trade_in_batteries;
|
||||||
|
|
||||||
// list of emergency types
|
// list of emergency types
|
||||||
$e_types = $em->getRepository(EmergencyType::class)->findBy([], ['name' => 'ASC']);
|
$e_types = $em->getRepository(EmergencyType::class)->findBy([], ['name' => 'ASC']);
|
||||||
|
|
@ -4367,10 +4248,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
|
|
||||||
$phone_number = $this->country_code . $notif_number;
|
$phone_number = $this->country_code . $notif_number;
|
||||||
|
|
||||||
// check if reason is in the list of rejection reason
|
// check if reason is administrative
|
||||||
$flag_send_sms = $this->checkRejectionReason($rejection->getReason());
|
if ($rejection->getReason() == JORejectionReason::ADMINISTRATIVE)
|
||||||
|
|
||||||
if (!$flag_send_sms)
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// sms content
|
// sms content
|
||||||
|
|
@ -4404,65 +4283,4 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
$this->rt->sendSMS($phone_number, $this->translator->trans('message.battery_brand_allcaps'), $msg);
|
$this->rt->sendSMS($phone_number, $this->translator->trans('message.battery_brand_allcaps'), $msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function checkRejectionReason($reason): bool
|
|
||||||
{
|
|
||||||
// reason is administrative
|
|
||||||
if ($reason == JORejectionReason::ADMINISTRATIVE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// reason is discount
|
|
||||||
if ($reason == JORejectionReason::DISCOUNT)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// reason is store closed on schedule
|
|
||||||
if ($reason == JORejectionReason::STORE_CLOSED_SCHEDULED)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// store closed half day
|
|
||||||
if ($reason == JORejectionReason::STORE_CLOSED_HALF_DAY)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// prio hub for warranty claim
|
|
||||||
if ($reason == JORejectionReason::PRIORITY_HUB_WTY_CLAIM)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// prio hub for jumpstart
|
|
||||||
if ($reason == JORejectionReason::PRIORITY_HUB_JUMPSTART)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// prio hub for RES-Q request
|
|
||||||
if ($reason == JORejectionReason::PRIORITY_HUB_RESQ_REQUEST)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// customer request
|
|
||||||
if ($reason == JORejectionReason::CUSTOMER_REQUEST)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function skipInventoryCheck(Point $coordinates): bool
|
|
||||||
{
|
|
||||||
$long = $coordinates->getLongitude();
|
|
||||||
$lat = $coordinates->getLatitude();
|
|
||||||
|
|
||||||
// get supported area given a set of coordinates
|
|
||||||
$query = $this->em->createQuery('SELECT s from App\Entity\SupportedArea s where st_contains(s.coverage_area, point(:long, :lat)) = true');
|
|
||||||
$area = $query->setParameter('long', $long)
|
|
||||||
->setParameter('lat', $lat)
|
|
||||||
->setMaxResults(1)
|
|
||||||
->getOneOrNullResult();
|
|
||||||
|
|
||||||
if ($area !== null) {
|
|
||||||
// get all exceptions
|
|
||||||
$exceptions = $area->getHubFilterExceptions();
|
|
||||||
|
|
||||||
if (isset($exceptions['no_inventory'])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter is in place
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,31 +68,4 @@ class MQTTClientApiv2
|
||||||
// error_log('sent to ' . $channel);
|
// error_log('sent to ' . $channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sendRiderEvent(JobOrder $job_order, $payload)
|
|
||||||
{
|
|
||||||
// check if a rider is available
|
|
||||||
$rider = $job_order->getRider();
|
|
||||||
if ($rider == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
// NOTE: this is for the old rider app
|
|
||||||
// check if rider has sessions
|
|
||||||
$sessions = $rider->getSessions();
|
|
||||||
if (count($sessions) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// send to every rider session
|
|
||||||
foreach ($sessions as $sess)
|
|
||||||
{
|
|
||||||
$sess_id = $sess->getID();
|
|
||||||
$channel = self::RIDER_PREFIX . $sess_id;
|
|
||||||
$this->publish($channel, json_encode($payload));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// NOTE: this is for the new rider app
|
|
||||||
$this->publish('rider/' . $rider->getID() . '/delivery', json_encode($payload));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,22 +74,12 @@ class PayMongoConnector
|
||||||
return $this->doRequest('/v1/checkout_sessions/' . $checkout_id, 'GET');
|
return $this->doRequest('/v1/checkout_sessions/' . $checkout_id, 'GET');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getWebhook($id)
|
|
||||||
{
|
|
||||||
return $this->doRequest('/v1/webhooks/'. $id, 'GET');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function enableWebhook($id)
|
|
||||||
{
|
|
||||||
return $this->doRequest('/v1/webhooks/' . $id . '/enable', 'POST');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function generateHash()
|
protected function generateHash()
|
||||||
{
|
{
|
||||||
return base64_encode($this->secret_key);
|
return base64_encode($this->secret_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function doRequest($url, $method, $request_body = [])
|
protected function doRequest($url, $method, $body = [])
|
||||||
{
|
{
|
||||||
$client = new Client();
|
$client = new Client();
|
||||||
$headers = [
|
$headers = [
|
||||||
|
|
@ -100,14 +90,14 @@ class PayMongoConnector
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$response = $client->request($method, $this->base_url . '/' . $url, [
|
$response = $client->request($method, $this->base_url . '/' . $url, [
|
||||||
'json' => $request_body,
|
'json' => $body,
|
||||||
'headers' => $headers,
|
'headers' => $headers,
|
||||||
]);
|
]);
|
||||||
} catch (RequestException $e) {
|
} catch (RequestException $e) {
|
||||||
$error = ['message' => $e->getMessage()];
|
$error = ['message' => $e->getMessage()];
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
//var_dump($request_body);
|
var_dump($body);
|
||||||
$varres = ob_get_clean();
|
$varres = ob_get_clean();
|
||||||
error_log($varres);
|
error_log($varres);
|
||||||
|
|
||||||
|
|
@ -117,9 +107,6 @@ class PayMongoConnector
|
||||||
error_log("PayMongo API Error: " . $error['message']);
|
error_log("PayMongo API Error: " . $error['message']);
|
||||||
error_log(Psr7\Message::toString($e->getRequest()));
|
error_log(Psr7\Message::toString($e->getRequest()));
|
||||||
|
|
||||||
// log this error
|
|
||||||
$this->log($url, Psr7\Message::toString($e->getRequest()), Psr7\Message::toString($e->getResponse()), 'error');
|
|
||||||
|
|
||||||
if ($e->hasResponse()) {
|
if ($e->hasResponse()) {
|
||||||
$error['response'] = Psr7\Message::toString($e->getResponse());
|
$error['response'] = Psr7\Message::toString($e->getResponse());
|
||||||
}
|
}
|
||||||
|
|
@ -130,32 +117,9 @@ class PayMongoConnector
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$result_body = $response->getBody();
|
|
||||||
|
|
||||||
// log response
|
|
||||||
$this->log($url, json_encode($request_body), $result_body);
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'success' => true,
|
'success' => true,
|
||||||
'response' => json_decode($response->getBody(), true)
|
'response' => json_decode($response->getBody(), true)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make this more elegant
|
|
||||||
public function log($title, $request_body = "[]", $result_body = "[]", $type = 'api')
|
|
||||||
{
|
|
||||||
$filename = '/../../var/log/paymongo_' . $type . '.log';
|
|
||||||
$date = date("Y-m-d H:i:s");
|
|
||||||
|
|
||||||
// build log entry
|
|
||||||
$entry = implode("\r\n", [
|
|
||||||
$date,
|
|
||||||
$title,
|
|
||||||
"REQUEST:\r\n" . $request_body,
|
|
||||||
"RESPONSE:\r\n" . $result_body,
|
|
||||||
"\r\n----------------------------------------\r\n\r\n",
|
|
||||||
]);
|
|
||||||
|
|
||||||
@file_put_contents(__DIR__ . $filename, $entry, FILE_APPEND);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Service;
|
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
|
|
||||||
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
|
||||||
|
|
||||||
use App\Entity\PriceTier;
|
|
||||||
|
|
||||||
class PriceTierManager
|
|
||||||
{
|
|
||||||
protected $em;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em)
|
|
||||||
{
|
|
||||||
$this->em = $em;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getItemPrice($pt_id, $item_type_id, $item_id)
|
|
||||||
{
|
|
||||||
// find the item price, given the price tier, battery id, and item type (battery)
|
|
||||||
$db_conn = $this->em->getConnection();
|
|
||||||
|
|
||||||
$ip_sql = 'SELECT ip.price AS price
|
|
||||||
FROM item_price ip
|
|
||||||
WHERE ip.price_tier_id = :pt_id
|
|
||||||
AND ip.item_type_id = :it_id
|
|
||||||
AND ip.item_id = :item_id';
|
|
||||||
|
|
||||||
$ip_stmt = $db_conn->prepare($ip_sql);
|
|
||||||
$ip_stmt->bindValue('pt_id', $pt_id);
|
|
||||||
$ip_stmt->bindValue('it_id', $item_type_id);
|
|
||||||
$ip_stmt->bindValue('item_id', $item_id);
|
|
||||||
|
|
||||||
$ip_result = $ip_stmt->executeQuery();
|
|
||||||
|
|
||||||
// results found
|
|
||||||
$actual_price = null;
|
|
||||||
|
|
||||||
// go through rows
|
|
||||||
while ($row = $ip_result->fetchAssociative())
|
|
||||||
{
|
|
||||||
// get the price
|
|
||||||
$price = $row['price'];
|
|
||||||
|
|
||||||
// actual price
|
|
||||||
$actual_price = number_format($price / 100, 2, '.', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $actual_price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPriceTier(Point $coordinates)
|
|
||||||
{
|
|
||||||
$price_tier_id = 0;
|
|
||||||
|
|
||||||
if ($coordinates != null)
|
|
||||||
{
|
|
||||||
$long = $coordinates->getLongitude();
|
|
||||||
$lat = $coordinates->getLatitude();
|
|
||||||
|
|
||||||
// get location's price tier, given a set of coordinates
|
|
||||||
$query = $this->em->createQuery('SELECT s from App\Entity\SupportedArea s where st_contains(s.coverage_area, point(:long, :lat)) = true');
|
|
||||||
$area = $query->setParameter('long', $long)
|
|
||||||
->setParameter('lat', $lat)
|
|
||||||
->setMaxResults(1)
|
|
||||||
->getOneOrNullResult();
|
|
||||||
|
|
||||||
if ($area != null)
|
|
||||||
{
|
|
||||||
$price_tier = $area->getPriceTier();
|
|
||||||
if ($price_tier != null)
|
|
||||||
$price_tier_id = $price_tier->getID();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $price_tier_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -8,11 +8,11 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-3">
|
<div class="col-lg-3">
|
||||||
<label for="invoice-trade-in-battery-size">Battery Size For Trade In</label>
|
<label for="invoice-trade-in-battery">Battery For Trade In</label>
|
||||||
<select class="form-control m-input" id="invoice-trade-in-battery-size" data-value="">
|
<select class="form-control m-input" id="invoice-trade-in-battery" data-value="">
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
{% for id, batt_size_name in trade_in_batt_sizes %}
|
{% for id, battery_name in trade_in_batteries %}
|
||||||
<option value="{{ id }}">{{ batt_size_name }}</option>
|
<option value="{{ id }}">{{ battery_name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
// add trade in battery to invoice
|
// add trade in battery to invoice
|
||||||
$('#btn-add-trade-in-to-invoice').click(function() {
|
$('#btn-add-trade-in-to-invoice').click(function() {
|
||||||
var bmfg = $("#invoice-trade-in-bmfg").val();
|
var bmfg = $("#invoice-trade-in-bmfg").val();
|
||||||
var battery_size = $("#invoice-trade-in-battery-size").val();
|
var battery = $("#invoice-trade-in-battery").val();
|
||||||
var tradeIn = $("#invoice-trade-in-type").val();
|
var tradeIn = $("#invoice-trade-in-type").val();
|
||||||
var qty = $("#invoice-trade-in-quantity").val();
|
var qty = $("#invoice-trade-in-quantity").val();
|
||||||
|
|
||||||
// add to invoice array
|
// add to invoice array
|
||||||
invoiceItems.push({
|
invoiceItems.push({
|
||||||
battery_size: battery_size,
|
battery: battery,
|
||||||
quantity: qty,
|
quantity: qty,
|
||||||
trade_in: tradeIn,
|
trade_in: tradeIn,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,164 +0,0 @@
|
||||||
{% 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">Item Pricing</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- END: Subheader -->
|
|
||||||
<div class="m-content">
|
|
||||||
<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-2">
|
|
||||||
<label>Item Prices for </label>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<div class="m-input-icon m-input-icon--left">
|
|
||||||
<div class="input-group">
|
|
||||||
<select class="form-control m-input" id="price-tier-select" name="price_tier_list">
|
|
||||||
<option value="0">Default Price Tier</option>
|
|
||||||
{% for price_tier in sets.price_tiers %}
|
|
||||||
<option value="{{ price_tier.getID }}">{{ price_tier.getName }} </option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<div class="m-input-icon m-input-icon--left">
|
|
||||||
<div class="input-group">
|
|
||||||
<select class="form-control m-input" id="item-type-select" name="item_type_list">
|
|
||||||
{% for item_type in sets.item_types %}
|
|
||||||
<option value="{{ item_type.getID }}">{{ item_type.getName }} </option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form id="row-form" class="m-form m-form--fit m-form--label-align-right" method="post" action="{{ url('item_pricing_update') }}">
|
|
||||||
<input id="price-tier-id" type="hidden" name="price_tier_id" value="0">
|
|
||||||
<input id="item-type-id" type="hidden" name="item_type_id" value="{{ default_item_type_id }}">
|
|
||||||
<div style="padding-left: 25px; padding-right: 25px;">
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th style="width: 100px">ID</th>
|
|
||||||
<th>Name</th>
|
|
||||||
<th hidden> Item Type ID </th>
|
|
||||||
<th>Item Type</th>
|
|
||||||
<th style="width: 180px">Price</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="table-body">
|
|
||||||
{% for id, item in items.items %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ id }}</td>
|
|
||||||
<td>{{ item.name }} </td>
|
|
||||||
<td hidden> {{ item.item_type_id }} </td>
|
|
||||||
<td>{{ item.item_type }} </td>
|
|
||||||
<td class="py-1">
|
|
||||||
<input name="price[{{ id }}]" class="form-control ca-filter" type="number" value="{{ item.price }}" step="0.01">
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div class="">
|
|
||||||
<input type="submit" class="btn btn-primary" value="Update Price">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
<script>
|
|
||||||
|
|
||||||
initialize();
|
|
||||||
|
|
||||||
function initialize() {
|
|
||||||
init_price_tier_dropdown();
|
|
||||||
init_item_type_dropdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
function init_price_tier_dropdown() {
|
|
||||||
var pt_dropdown = document.getElementById('price-tier-select');
|
|
||||||
var it_dropdown = document.getElementById('item-type-select');
|
|
||||||
pt_dropdown.addEventListener('change', function(e) {
|
|
||||||
var it_type = it_dropdown.value;
|
|
||||||
load_prices(e.target.value, it_type);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function init_item_type_dropdown() {
|
|
||||||
var it_dropdown = document.getElementById('item-type-select');
|
|
||||||
var pt_dropdown = document.getElementById('price-tier-select');
|
|
||||||
it_dropdown.addEventListener('change', function(e) {
|
|
||||||
var pt_type = pt_dropdown.value;
|
|
||||||
load_prices(pt_type, e.target.value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function load_prices(price_tier_id, item_type_id) {
|
|
||||||
var req = new XMLHttpRequest();
|
|
||||||
req.onreadystatechange = function() {
|
|
||||||
// process response
|
|
||||||
if (this.readyState == 4 && this.status == 200) {
|
|
||||||
// update form
|
|
||||||
update_table(JSON.parse(req.responseText));
|
|
||||||
var pt_field = document.getElementById('price-tier-id');
|
|
||||||
pt_field.value = price_tier_id;
|
|
||||||
var it_field = document.getElementById('item-type-id');
|
|
||||||
it_field.value = item_type_id;
|
|
||||||
} else {
|
|
||||||
// console.log('could not load tier prices');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var url_pattern = '{{ url('item_pricing_prices', {'pt_id': '--id--', 'it_id': '--it-id--'}) }}';
|
|
||||||
var url = url_pattern.replace('--id--', price_tier_id).replace('--it-id--', item_type_id);
|
|
||||||
console.log(url);
|
|
||||||
req.open('GET', url, true);
|
|
||||||
req.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_table(data) {
|
|
||||||
console.log(data);
|
|
||||||
var item_html = '';
|
|
||||||
for (var i in data.items) {
|
|
||||||
var item = data.items[i];
|
|
||||||
// console.log(item);
|
|
||||||
item_html += '<tr>';
|
|
||||||
item_html += '<td>' + item.id + '</td>';
|
|
||||||
item_html += '<td>' + item.name + '</td>';
|
|
||||||
item_html += '<td hidden>' + item.item_type_id + '</td>';
|
|
||||||
item_html += '<td>' + item.item_type + '</td>';
|
|
||||||
item_html += '<td class="py-1">';
|
|
||||||
item_html += '<input name="price[' + item.id + ']" class="form-control ca-filter" type="number" value="' + item.price + '" step="0.01">';
|
|
||||||
item_html += '</td>';
|
|
||||||
item_html += '</tr>';
|
|
||||||
}
|
|
||||||
|
|
||||||
var table_body = document.getElementById('table-body');
|
|
||||||
table_body.innerHTML = item_html;
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -1,142 +0,0 @@
|
||||||
{% 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">Item Types</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- END: Subheader -->
|
|
||||||
<div class="m-content">
|
|
||||||
<!--Begin::Section-->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-6">
|
|
||||||
<div class="m-portlet m-portlet--mobile">
|
|
||||||
<div class="m-portlet__head">
|
|
||||||
<div class="m-portlet__head-caption">
|
|
||||||
<div class="m-portlet__head-title">
|
|
||||||
<span class="m-portlet__head-icon">
|
|
||||||
<i class="la la-industry"></i>
|
|
||||||
</span>
|
|
||||||
<h3 class="m-portlet__head-text">
|
|
||||||
{% if mode == 'update' %}
|
|
||||||
Edit Item Type
|
|
||||||
<small>{{ obj.getName() }}</small>
|
|
||||||
{% else %}
|
|
||||||
New Item Type
|
|
||||||
{% endif %}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form id="row-form" class="m-form m-form--fit m-form--label-align-right m-form--group-seperator-dashed" method="post" action="{{ mode == 'update' ? url('item_type_update_submit', {'id': obj.getId()}) : url('item_type_add_submit') }}">
|
|
||||||
<div class="m-portlet__body">
|
|
||||||
<div class="form-group m-form__group row no-border">
|
|
||||||
<label class="col-lg-3 col-form-label" data-field="name">
|
|
||||||
Name:
|
|
||||||
</label>
|
|
||||||
<div class="col-lg-9">
|
|
||||||
<input type="text" name="name" class="form-control m-input" value="{{ obj.getName() }}">
|
|
||||||
<div class="form-control-feedback hide" data-field="name"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group m-form__group row no-border">
|
|
||||||
<label class="col-lg-3 col-form-label" data-field="code">
|
|
||||||
Code:
|
|
||||||
</label>
|
|
||||||
<div class="col-lg-9">
|
|
||||||
<input type="text" name="code" class="form-control m-input" value="{{ obj.getCode() }}">
|
|
||||||
<div class="form-control-feedback hide" data-field="code"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="m-portlet__foot m-portlet__foot--fit">
|
|
||||||
<div class="m-form__actions m-form__actions--solid m-form__actions--right">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12">
|
|
||||||
<button type="submit" class="btn btn-success">Submit</button>
|
|
||||||
<a href="{{ url('item_type_list') }}" class="btn btn-secondary">Back</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
<script>
|
|
||||||
$(function() {
|
|
||||||
$("#row-form").submit(function(e) {
|
|
||||||
var form = $(this);
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
method: "POST",
|
|
||||||
url: form.prop('action'),
|
|
||||||
data: form.serialize()
|
|
||||||
}).done(function(response) {
|
|
||||||
// remove all error classes
|
|
||||||
removeErrors();
|
|
||||||
swal({
|
|
||||||
title: 'Done!',
|
|
||||||
text: 'Your changes have been saved!',
|
|
||||||
type: 'success',
|
|
||||||
onClose: function() {
|
|
||||||
window.location.href = "{{ url('item_type_list') }}";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).fail(function(response) {
|
|
||||||
if (response.status == 422) {
|
|
||||||
var errors = response.responseJSON.errors;
|
|
||||||
var firstfield = false;
|
|
||||||
|
|
||||||
// remove all error classes first
|
|
||||||
removeErrors();
|
|
||||||
|
|
||||||
// display errors contextually
|
|
||||||
$.each(errors, function(field, msg) {
|
|
||||||
var formfield = $("[name='" + field + "']");
|
|
||||||
var label = $("label[data-field='" + field + "']");
|
|
||||||
var msgbox = $(".form-control-feedback[data-field='" + field + "']");
|
|
||||||
|
|
||||||
// add error classes to bad fields
|
|
||||||
formfield.addClass('form-control-danger');
|
|
||||||
label.addClass('has-danger');
|
|
||||||
msgbox.html(msg).addClass('has-danger').removeClass('hide');
|
|
||||||
|
|
||||||
// check if this field comes first in DOM
|
|
||||||
var domfield = formfield.get(0);
|
|
||||||
|
|
||||||
if (!firstfield || (firstfield && firstfield.compareDocumentPosition(domfield) === 2)) {
|
|
||||||
firstfield = domfield;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// focus on first bad field
|
|
||||||
firstfield.focus();
|
|
||||||
|
|
||||||
// scroll to above that field to make it visible
|
|
||||||
$('html, body').animate({
|
|
||||||
scrollTop: $(firstfield).offset().top - 200
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// remove all error classes
|
|
||||||
function removeErrors() {
|
|
||||||
$(".form-control-danger").removeClass('form-control-danger');
|
|
||||||
$("[data-field]").removeClass('has-danger');
|
|
||||||
$(".form-control-feedback[data-field]").addClass('hide');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
||||||
{% 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">
|
|
||||||
Item Types
|
|
||||||
</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-8 order-2 order-xl-1">
|
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
<div class="col-xl-4 order-1 order-xl-2 m--align-right">
|
|
||||||
<a href="{{ url('item_type_add_form') }}" class="btn btn-focus m-btn m-btn--custom m-btn--icon m-btn--air m-btn--pill">
|
|
||||||
<span>
|
|
||||||
<i class="la la-industry"></i>
|
|
||||||
<span>New Item Type</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
<div class="m-separator m-separator--dashed d-xl-none"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--begin: Datatable -->
|
|
||||||
<div id="data-rows"></div>
|
|
||||||
<!--end: Datatable -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
<script>
|
|
||||||
$(function() {
|
|
||||||
var options = {
|
|
||||||
data: {
|
|
||||||
type: 'remote',
|
|
||||||
source: {
|
|
||||||
read: {
|
|
||||||
url: '{{ url("item_type_rows") }}',
|
|
||||||
method: 'POST'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
saveState: {
|
|
||||||
cookie: false,
|
|
||||||
webstorage: false
|
|
||||||
},
|
|
||||||
pageSize: 10,
|
|
||||||
serverPaging: true,
|
|
||||||
serverFiltering: true,
|
|
||||||
serverSorting: true
|
|
||||||
},
|
|
||||||
layout: {
|
|
||||||
scroll: true
|
|
||||||
},
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
field: 'id',
|
|
||||||
title: 'ID',
|
|
||||||
width: 30
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'name',
|
|
||||||
title: 'Name'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'Actions',
|
|
||||||
width: 110,
|
|
||||||
title: 'Actions',
|
|
||||||
sortable: false,
|
|
||||||
overflow: 'visible',
|
|
||||||
template: function (row, index, datatable) {
|
|
||||||
var actions = '';
|
|
||||||
|
|
||||||
if (row.meta.update_url != '') {
|
|
||||||
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" data-id="' + row.name + '" title="Edit"><i class="la la-edit"></i></a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row.meta.delete_url != '') {
|
|
||||||
actions += '<a href="' + row.meta.delete_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete" data-id="' + row.name + '" title="Delete"><i class="la la-trash"></i></a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
return actions;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
],
|
|
||||||
search: {
|
|
||||||
onEnter: false,
|
|
||||||
input: $('#data-rows-search'),
|
|
||||||
delay: 400
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var table = $("#data-rows").mDatatable(options);
|
|
||||||
|
|
||||||
$(document).on('click', '.btn-delete', function(e) {
|
|
||||||
var url = $(this).prop('href');
|
|
||||||
var id = $(this).data('id');
|
|
||||||
var btn = $(this);
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
swal({
|
|
||||||
title: 'Confirmation',
|
|
||||||
html: 'Are you sure you want to delete <strong>' + id + '</strong>?',
|
|
||||||
type: 'warning',
|
|
||||||
showCancelButton: true
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.value) {
|
|
||||||
$.ajax({
|
|
||||||
method: "DELETE",
|
|
||||||
url: url
|
|
||||||
}).done(function(response) {
|
|
||||||
table.row(btn.parents('tr')).remove();
|
|
||||||
table.reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -1,177 +0,0 @@
|
||||||
{% 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">Items</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- END: Subheader -->
|
|
||||||
<div class="m-content">
|
|
||||||
<!--Begin::Section-->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-6">
|
|
||||||
<div class="m-portlet m-portlet--mobile">
|
|
||||||
<div class="m-portlet__head">
|
|
||||||
<div class="m-portlet__head-caption">
|
|
||||||
<div class="m-portlet__head-title">
|
|
||||||
<span class="m-portlet__head-icon">
|
|
||||||
<i class="la la-industry"></i>
|
|
||||||
</span>
|
|
||||||
<h3 class="m-portlet__head-text">
|
|
||||||
{% if mode == 'update' %}
|
|
||||||
Edit Item
|
|
||||||
<small>{{ obj.getName() }}</small>
|
|
||||||
{% else %}
|
|
||||||
New Item
|
|
||||||
{% endif %}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form id="row-form" class="m-form m-form--fit m-form--label-align-right m-form--group-seperator-dashed" method="post" action="{{ mode == 'update' ? url('item_type_update_submit', {'id': obj.getId()}) : url('item_add_submit') }}">
|
|
||||||
<div class="m-portlet__body">
|
|
||||||
<div class="form-group m-form__group row no-border">
|
|
||||||
<label class="col-lg-3 col-form-label" data-field="item_type">
|
|
||||||
Item Type:
|
|
||||||
</label>
|
|
||||||
<div class="col-lg-9">
|
|
||||||
<select class="form-control m-input" id="item-type" name="item_type">
|
|
||||||
{% for id, label in sets.item_types %}
|
|
||||||
{% if obj.getItemType %}
|
|
||||||
<option value="{{ id }}"{{ obj.getItemType.getID == id ? ' selected' }}>{{ label }}</option>
|
|
||||||
{% else %}
|
|
||||||
<option value="{{ id }}">{{ label }}</option>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
<div class="form-control-feedback hide" data-field="item_type"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group m-form__group row no-border
|
|
||||||
{% if obj.getItemType %}
|
|
||||||
{% if obj.getItemType.getCode is not same as ('battery') %}
|
|
||||||
hide
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
hide
|
|
||||||
{% endif %}
|
|
||||||
" id="battery-row">
|
|
||||||
<label class="col-lg-3 col-form-label" data-field="battery">
|
|
||||||
Battery:
|
|
||||||
</label>
|
|
||||||
<div class="col-lg-9">
|
|
||||||
<select class="form-control m-input" id="item-type" name="battery">
|
|
||||||
{% for id, label in sets.batteries %}
|
|
||||||
<option value="{{ id }}"{{ obj.getItemID == id ? ' selected' }}>{{ label }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
<div class="form-control-feedback hide" data-field="battery"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="m-portlet__foot m-portlet__foot--fit">
|
|
||||||
<div class="m-form__actions m-form__actions--solid m-form__actions--right">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12">
|
|
||||||
<button type="submit" class="btn btn-success">Submit</button>
|
|
||||||
<a href="{{ url('item_list') }}" class="btn btn-secondary">Back</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
<script>
|
|
||||||
$(function() {
|
|
||||||
$("#row-form").submit(function(e) {
|
|
||||||
var form = $(this);
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
method: "POST",
|
|
||||||
url: form.prop('action'),
|
|
||||||
data: form.serialize()
|
|
||||||
}).done(function(response) {
|
|
||||||
// remove all error classes
|
|
||||||
removeErrors();
|
|
||||||
swal({
|
|
||||||
title: 'Done!',
|
|
||||||
text: 'Your changes have been saved!',
|
|
||||||
type: 'success',
|
|
||||||
onClose: function() {
|
|
||||||
window.location.href = "{{ url('item_list') }}";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).fail(function(response) {
|
|
||||||
if (response.status == 422) {
|
|
||||||
var errors = response.responseJSON.errors;
|
|
||||||
var firstfield = false;
|
|
||||||
|
|
||||||
// remove all error classes first
|
|
||||||
removeErrors();
|
|
||||||
|
|
||||||
// display errors contextually
|
|
||||||
$.each(errors, function(field, msg) {
|
|
||||||
var formfield = $("[name='" + field + "']");
|
|
||||||
var label = $("label[data-field='" + field + "']");
|
|
||||||
var msgbox = $(".form-control-feedback[data-field='" + field + "']");
|
|
||||||
|
|
||||||
// add error classes to bad fields
|
|
||||||
formfield.addClass('form-control-danger');
|
|
||||||
label.addClass('has-danger');
|
|
||||||
msgbox.html(msg).addClass('has-danger').removeClass('hide');
|
|
||||||
|
|
||||||
// check if this field comes first in DOM
|
|
||||||
var domfield = formfield.get(0);
|
|
||||||
|
|
||||||
if (!firstfield || (firstfield && firstfield.compareDocumentPosition(domfield) === 2)) {
|
|
||||||
firstfield = domfield;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// focus on first bad field
|
|
||||||
firstfield.focus();
|
|
||||||
|
|
||||||
// scroll to above that field to make it visible
|
|
||||||
$('html, body').animate({
|
|
||||||
scrollTop: $(firstfield).offset().top - 200
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// remove all error classes
|
|
||||||
function removeErrors() {
|
|
||||||
$(".form-control-danger").removeClass('form-control-danger');
|
|
||||||
$("[data-field]").removeClass('has-danger');
|
|
||||||
$(".form-control-feedback[data-field]").addClass('hide');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#item-type').change(function(e) {
|
|
||||||
console.log('item type change ' + e.target.value);
|
|
||||||
if (e.target.value === '1') {
|
|
||||||
// display battery row
|
|
||||||
$('#battery-row').removeClass("hide");
|
|
||||||
|
|
||||||
// hide service offering rows
|
|
||||||
} else {
|
|
||||||
// display service offering row
|
|
||||||
|
|
||||||
// hide battery row
|
|
||||||
$('#battery-row').addClass("hide");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
||||||
{% 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">
|
|
||||||
Items
|
|
||||||
</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-8 order-2 order-xl-1">
|
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
<div class="col-xl-4 order-1 order-xl-2 m--align-right">
|
|
||||||
<a href="{{ url('item_add_form') }}" class="btn btn-focus m-btn m-btn--custom m-btn--icon m-btn--air m-btn--pill">
|
|
||||||
<span>
|
|
||||||
<i class="la la-industry"></i>
|
|
||||||
<span>New Item</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
<div class="m-separator m-separator--dashed d-xl-none"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--begin: Datatable -->
|
|
||||||
<div id="data-rows"></div>
|
|
||||||
<!--end: Datatable -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
<script>
|
|
||||||
$(function() {
|
|
||||||
var options = {
|
|
||||||
data: {
|
|
||||||
type: 'remote',
|
|
||||||
source: {
|
|
||||||
read: {
|
|
||||||
url: '{{ url("item_rows") }}',
|
|
||||||
method: 'POST'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
saveState: {
|
|
||||||
cookie: false,
|
|
||||||
webstorage: false
|
|
||||||
},
|
|
||||||
pageSize: 10,
|
|
||||||
serverPaging: true,
|
|
||||||
serverFiltering: true,
|
|
||||||
serverSorting: true
|
|
||||||
},
|
|
||||||
layout: {
|
|
||||||
scroll: true
|
|
||||||
},
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
field: 'id',
|
|
||||||
title: 'ID',
|
|
||||||
width: 30
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'name',
|
|
||||||
title: 'Name'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'Actions',
|
|
||||||
width: 110,
|
|
||||||
title: 'Actions',
|
|
||||||
sortable: false,
|
|
||||||
overflow: 'visible',
|
|
||||||
template: function (row, index, datatable) {
|
|
||||||
var actions = '';
|
|
||||||
|
|
||||||
if (row.meta.update_url != '') {
|
|
||||||
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" data-id="' + row.name + '" title="Edit"><i class="la la-edit"></i></a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row.meta.delete_url != '') {
|
|
||||||
actions += '<a href="' + row.meta.delete_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete" data-id="' + row.name + '" title="Delete"><i class="la la-trash"></i></a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
return actions;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
],
|
|
||||||
search: {
|
|
||||||
onEnter: false,
|
|
||||||
input: $('#data-rows-search'),
|
|
||||||
delay: 400
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var table = $("#data-rows").mDatatable(options);
|
|
||||||
|
|
||||||
$(document).on('click', '.btn-delete', function(e) {
|
|
||||||
var url = $(this).prop('href');
|
|
||||||
var id = $(this).data('id');
|
|
||||||
var btn = $(this);
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
swal({
|
|
||||||
title: 'Confirmation',
|
|
||||||
html: 'Are you sure you want to delete <strong>' + id + '</strong>?',
|
|
||||||
type: 'warning',
|
|
||||||
showCancelButton: true
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.value) {
|
|
||||||
$.ajax({
|
|
||||||
method: "DELETE",
|
|
||||||
url: url
|
|
||||||
}).done(function(response) {
|
|
||||||
table.row(btn.parents('tr')).remove();
|
|
||||||
table.reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -630,24 +630,20 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group m-form__group row">
|
<div class="form-group m-form__group row">
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
<label>Discount Type</label>
|
<label>Discount Type</label>
|
||||||
{% if ftags.invoice_edit %}
|
{% if ftags.invoice_edit %}
|
||||||
<select class="form-control m-input" id="invoice-promo" name="invoice_promo">
|
<select class="form-control m-input" id="invoice-promo" name="invoice_promo">
|
||||||
<option value="">None</option>
|
<option value="">None</option>
|
||||||
{% for promo in promos %}
|
{% for promo in promos %}
|
||||||
{% if obj.getInvoice and obj.getInvoice.getPromo %}
|
<option value="{{ promo.getID() }}">{{ promo.getName() ~ ' (' ~ promo.getDiscountRate * 100 ~ '% applied to ' ~ discount_apply[promo.getDiscountApply] ~ ')' }}</option>
|
||||||
<option value="{{ promo.getID() }}" {{ obj.getInvoice.getPromo.getID == promo.getID ? ' selected'}}>{{ promo.getName() ~ ' (' ~ promo.getDiscountRate * 100 ~ '% applied to ' ~ discount_apply[promo.getDiscountApply] ~ ')' }}</option>
|
{% endfor %}
|
||||||
{% else %}
|
</select>
|
||||||
<option value="{{ promo.getID() }}">{{ promo.getName() ~ ' (' ~ promo.getDiscountRate * 100 ~ '% applied to ' ~ discount_apply[promo.getDiscountApply] ~ ')' }}</option>
|
<div class="form-control-feedback hide" data-field="invoice_promo"></div>
|
||||||
{% endif %}
|
{% else %}
|
||||||
{% endfor %}
|
<input type="text" id="invoice-promo" class="form-control m-input" value="{{ obj.getInvoice.getPromo.getName|default('None') }}" disabled>
|
||||||
</select>
|
{% endif %}
|
||||||
<div class="form-control-feedback hide" data-field="invoice_promo"></div>
|
</div>
|
||||||
{% else %}
|
|
||||||
<input type="text" id="invoice-promo" class="form-control m-input" value="{{ obj.getInvoice.getPromo.getName|default('None') }}" disabled>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-3">
|
<div class="col-lg-3">
|
||||||
<label>Promo Discount</label>
|
<label>Promo Discount</label>
|
||||||
<input type="text" id="invoice-promo-discount" class="form-control m-input text-right" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount|number_format(2) : '0.00' }}" disabled>
|
<input type="text" id="invoice-promo-discount" class="form-control m-input text-right" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount|number_format(2) : '0.00' }}" disabled>
|
||||||
|
|
@ -831,28 +827,20 @@
|
||||||
<div class="m-form__section">
|
<div class="m-form__section">
|
||||||
<div class="form-group m-form__group row">
|
<div class="form-group m-form__group row">
|
||||||
<div class="col-lg-2">
|
<div class="col-lg-2">
|
||||||
<label for="facilitated-type">Battery Facilitated By</label>
|
<label for="faciliateted-type">Battery Facilitated By</label>
|
||||||
<select name="facilitated_type" class="form-control m-input" id="facilitated-type">
|
<select name="facilitated_type" class="form-control m-input" id="facilitated-type">
|
||||||
<option value="">None</option>
|
<option value="">None</option>
|
||||||
{% for key, type in facilitated_types %}
|
{% for key, type in facilitated_types %}
|
||||||
{% if obj.getFacilitatedType %}
|
<option value="{{ key }}">{{ type }}</option>
|
||||||
<option value="{{ key }}"{{ obj.getFacilitatedType == key ? ' selected' }}>{{ type }}</option>
|
|
||||||
{% else %}
|
|
||||||
<option value="{{ key }}">{{ type }}</option>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-8">
|
<div class="col-lg-8">
|
||||||
<label for="facilitated-by"> </label>
|
<label for="faciliateted-by"> </label>
|
||||||
<select name="facilitated_by" class="form-control m-input" id="facilitated-by">
|
<select name="facilitated_by" class="form-control m-input" id="facilitated-by">
|
||||||
<option value="">None</option>
|
<option value="">None</option>
|
||||||
{% for key, name in facilitated_hubs %}
|
{% for key, name in facilitated_hubs %}
|
||||||
{% if obj.getFacilitatedBy %}
|
<option value="{{ key }}">{{ name }}</option>
|
||||||
<option value="{{ key }}"{{ obj.getFacilitatedBy.getID == key ? ' selected' }}>{{ name }}</option>
|
|
||||||
{% else %}
|
|
||||||
<option value="{{ key }}">{{ name }}</option>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1206,10 +1194,6 @@
|
||||||
<script src="/assets/vendors/custom/gmaps/gmaps.js" type="text/javascript"></script>
|
<script src="/assets/vendors/custom/gmaps/gmaps.js" type="text/javascript"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var invoiceItems = [];
|
|
||||||
var hasCoolant = 0;
|
|
||||||
var hasSealant = 0;
|
|
||||||
|
|
||||||
// location search autocomplete
|
// location search autocomplete
|
||||||
var input = document.getElementById('m_gmap_address');
|
var input = document.getElementById('m_gmap_address');
|
||||||
|
|
||||||
|
|
@ -1234,7 +1218,6 @@ autocomplete.addListener('place_changed', function() {
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
var form_in_process = false;
|
var form_in_process = false;
|
||||||
var invoiceItems = [];
|
|
||||||
|
|
||||||
// openstreet maps stuff
|
// openstreet maps stuff
|
||||||
// TODO: move this to a service
|
// TODO: move this to a service
|
||||||
|
|
@ -1245,54 +1228,9 @@ $(function() {
|
||||||
|
|
||||||
var markerLayerGroup = L.layerGroup().addTo(osm_map);
|
var markerLayerGroup = L.layerGroup().addTo(osm_map);
|
||||||
|
|
||||||
function populateInvoiceItems()
|
|
||||||
{
|
|
||||||
{% if invoice_items is defined %}
|
|
||||||
{% for item in invoice_items %}
|
|
||||||
var qty = {{ item.getQuantity }};
|
|
||||||
{% if item.getBattery is not null %}
|
|
||||||
var battery_id = {{ item.getBattery.getID }};
|
|
||||||
|
|
||||||
invoiceItems.push({
|
|
||||||
battery: battery_id,
|
|
||||||
quantity: qty,
|
|
||||||
trade_in: '',
|
|
||||||
});
|
|
||||||
{% else %}
|
|
||||||
{% if item.getBatterySize is not null %}
|
|
||||||
var battery_size = {{ item.getBatterySize.GetID }};
|
|
||||||
var trade_in_type = '{{ item.getTradeInType }}';
|
|
||||||
|
|
||||||
// add to invoice array
|
|
||||||
invoiceItems.push({
|
|
||||||
battery_size: battery_size,
|
|
||||||
quantity: qty,
|
|
||||||
trade_in: trade_in_type,
|
|
||||||
});
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
// need to check if jo has coolant or sealant
|
|
||||||
{% if obj.getServiceType == 'overheat' %}
|
|
||||||
{% if obj.hasCoolant == 1 %}
|
|
||||||
hasCoolant = 1;
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if obj.getServiceType == 'tire' %}
|
|
||||||
{% if obj.hasSealant == 1 %}
|
|
||||||
hasSealant = 1;
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
}
|
|
||||||
|
|
||||||
function selectPoint(lat, lng)
|
function selectPoint(lat, lng)
|
||||||
{
|
{
|
||||||
// check if point is in coverage area
|
// check if point is in coverage area
|
||||||
// commenting out the geofence call for CRM
|
|
||||||
/*
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "GET",
|
method: "GET",
|
||||||
url: "{{ url('jo_geofence') }}",
|
url: "{{ url('jo_geofence') }}",
|
||||||
|
|
@ -1310,7 +1248,7 @@ $(function() {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}); */
|
});
|
||||||
|
|
||||||
// clear markers
|
// clear markers
|
||||||
markerLayerGroup.clearLayers();
|
markerLayerGroup.clearLayers();
|
||||||
|
|
@ -1326,9 +1264,6 @@ $(function() {
|
||||||
$('#map_lat').val(lat);
|
$('#map_lat').val(lat);
|
||||||
$('#map_lng').val(lng);
|
$('#map_lng').val(lng);
|
||||||
|
|
||||||
// regenerate invoice
|
|
||||||
generateInvoice();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
osm_map.on('click', function(e) {
|
osm_map.on('click', function(e) {
|
||||||
|
|
@ -1372,11 +1307,6 @@ $(function() {
|
||||||
// OSM code
|
// OSM code
|
||||||
var lat = {{ obj.getCoordinates.getLatitude }};
|
var lat = {{ obj.getCoordinates.getLatitude }};
|
||||||
var lng = {{ obj.getCoordinates.getLongitude }};
|
var lng = {{ obj.getCoordinates.getLongitude }};
|
||||||
|
|
||||||
var promo = $("#invoice-promo").val();
|
|
||||||
|
|
||||||
populateInvoiceItems();
|
|
||||||
|
|
||||||
selectPoint(lat, lng);
|
selectPoint(lat, lng);
|
||||||
|
|
||||||
// remove placeholder text
|
// remove placeholder text
|
||||||
|
|
@ -1760,6 +1690,8 @@ $(function() {
|
||||||
placeholder: ""
|
placeholder: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var invoiceItems = [];
|
||||||
|
|
||||||
{% include 'invoice/trade_in.js.twig' %}
|
{% include 'invoice/trade_in.js.twig' %}
|
||||||
|
|
||||||
// add to invoice
|
// add to invoice
|
||||||
|
|
@ -1829,8 +1761,6 @@ $(function() {
|
||||||
var table = $("#invoice-table tbody");
|
var table = $("#invoice-table tbody");
|
||||||
var stype = $("#service_type").val();
|
var stype = $("#service_type").val();
|
||||||
var cvid = $("#customer-vehicle").val();
|
var cvid = $("#customer-vehicle").val();
|
||||||
var lng = $("#map_lng").val();
|
|
||||||
var lat = $("#map_lat").val();
|
|
||||||
|
|
||||||
console.log(JSON.stringify(invoiceItems));
|
console.log(JSON.stringify(invoiceItems));
|
||||||
|
|
||||||
|
|
@ -1842,11 +1772,7 @@ $(function() {
|
||||||
'stype': stype,
|
'stype': stype,
|
||||||
'items': invoiceItems,
|
'items': invoiceItems,
|
||||||
'promo': promo,
|
'promo': promo,
|
||||||
'cvid': cvid,
|
'cvid': cvid
|
||||||
'coord_lng': lng,
|
|
||||||
'coord_lat': lat,
|
|
||||||
'flag_coolant': hasCoolant,
|
|
||||||
'flag_sealant': hasSealant,
|
|
||||||
}
|
}
|
||||||
}).done(function(response) {
|
}).done(function(response) {
|
||||||
// mark as invoice changed
|
// mark as invoice changed
|
||||||
|
|
|
||||||
|
|
@ -635,8 +635,6 @@ $(function() {
|
||||||
function selectPoint(lat, lng)
|
function selectPoint(lat, lng)
|
||||||
{
|
{
|
||||||
// check if point is in coverage area
|
// check if point is in coverage area
|
||||||
// commenting out the geofence call for CRM
|
|
||||||
/*
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "GET",
|
method: "GET",
|
||||||
url: "{{ url('jo_geofence') }}",
|
url: "{{ url('jo_geofence') }}",
|
||||||
|
|
@ -654,7 +652,7 @@ $(function() {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}); */
|
});
|
||||||
|
|
||||||
// clear markers
|
// clear markers
|
||||||
markerLayerGroup.clearLayers();
|
markerLayerGroup.clearLayers();
|
||||||
|
|
|
||||||
|
|
@ -1,154 +0,0 @@
|
||||||
{% 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">Price Tiers</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- END: Subheader -->
|
|
||||||
<div class="m-content">
|
|
||||||
<!--Begin::Section-->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-6">
|
|
||||||
<div class="m-portlet m-portlet--mobile">
|
|
||||||
<div class="m-portlet__head">
|
|
||||||
<div class="m-portlet__head-caption">
|
|
||||||
<div class="m-portlet__head-title">
|
|
||||||
<span class="m-portlet__head-icon">
|
|
||||||
<i class="la la-industry"></i>
|
|
||||||
</span>
|
|
||||||
<h3 class="m-portlet__head-text">
|
|
||||||
{% if mode == 'update' %}
|
|
||||||
Edit Price Tier
|
|
||||||
<small>{{ obj.getName() }}</small>
|
|
||||||
{% else %}
|
|
||||||
New Price Tier
|
|
||||||
{% endif %}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form id="row-form" class="m-form m-form--fit m-form--label-align-right m-form--group-seperator-dashed" method="post" action="{{ mode == 'update' ? url('price_tier_update_submit', {'id': obj.getId()}) : url('price_tier_add_submit') }}">
|
|
||||||
<div class="m-portlet__body">
|
|
||||||
<div class="form-group m-form__group row no-border">
|
|
||||||
<label class="col-lg-3 col-form-label" data-field="name">
|
|
||||||
Name:
|
|
||||||
</label>
|
|
||||||
<div class="col-lg-9">
|
|
||||||
<input type="text" name="name" class="form-control m-input" value="{{ obj.getName() }}">
|
|
||||||
<div class="form-control-feedback hide" data-field="name"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group m-form__group row no-border">
|
|
||||||
<label class="col-lg-3 col-form-label" data-field="areas">
|
|
||||||
Coverage Area:
|
|
||||||
</label>
|
|
||||||
<div class="col-lg-9">
|
|
||||||
{% if sets.areas is empty %}
|
|
||||||
No available supported areas.
|
|
||||||
{% else %}
|
|
||||||
<div class="m-checkbox-list">
|
|
||||||
{% for id, label in sets.areas %}
|
|
||||||
<label class="m-checkbox">
|
|
||||||
<input type="checkbox" name="areas[]" value="{{ id }}"{{ id in obj.getSupportedAreas() ? ' checked' : '' }}>
|
|
||||||
{{ label }}
|
|
||||||
<span></span>
|
|
||||||
</label>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="form-control-feedback hide" data-field="areas"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="m-portlet__foot m-portlet__foot--fit">
|
|
||||||
<div class="m-form__actions m-form__actions--solid m-form__actions--right">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12">
|
|
||||||
<button type="submit" class="btn btn-success">Submit</button>
|
|
||||||
<a href="{{ url('price_tier_list') }}" class="btn btn-secondary">Back</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
<script>
|
|
||||||
$(function() {
|
|
||||||
$("#row-form").submit(function(e) {
|
|
||||||
var form = $(this);
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
method: "POST",
|
|
||||||
url: form.prop('action'),
|
|
||||||
data: form.serialize()
|
|
||||||
}).done(function(response) {
|
|
||||||
// remove all error classes
|
|
||||||
removeErrors();
|
|
||||||
swal({
|
|
||||||
title: 'Done!',
|
|
||||||
text: 'Your changes have been saved!',
|
|
||||||
type: 'success',
|
|
||||||
onClose: function() {
|
|
||||||
window.location.href = "{{ url('price_tier_list') }}";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).fail(function(response) {
|
|
||||||
if (response.status == 422) {
|
|
||||||
var errors = response.responseJSON.errors;
|
|
||||||
var firstfield = false;
|
|
||||||
|
|
||||||
// remove all error classes first
|
|
||||||
removeErrors();
|
|
||||||
|
|
||||||
// display errors contextually
|
|
||||||
$.each(errors, function(field, msg) {
|
|
||||||
var formfield = $("[name='" + field + "']");
|
|
||||||
var label = $("label[data-field='" + field + "']");
|
|
||||||
var msgbox = $(".form-control-feedback[data-field='" + field + "']");
|
|
||||||
|
|
||||||
// add error classes to bad fields
|
|
||||||
formfield.addClass('form-control-danger');
|
|
||||||
label.addClass('has-danger');
|
|
||||||
msgbox.html(msg).addClass('has-danger').removeClass('hide');
|
|
||||||
|
|
||||||
// check if this field comes first in DOM
|
|
||||||
var domfield = formfield.get(0);
|
|
||||||
|
|
||||||
if (!firstfield || (firstfield && firstfield.compareDocumentPosition(domfield) === 2)) {
|
|
||||||
firstfield = domfield;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// focus on first bad field
|
|
||||||
firstfield.focus();
|
|
||||||
|
|
||||||
// scroll to above that field to make it visible
|
|
||||||
$('html, body').animate({
|
|
||||||
scrollTop: $(firstfield).offset().top - 200
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// remove all error classes
|
|
||||||
function removeErrors() {
|
|
||||||
$(".form-control-danger").removeClass('form-control-danger');
|
|
||||||
$("[data-field]").removeClass('has-danger');
|
|
||||||
$(".form-control-feedback[data-field]").addClass('hide');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
||||||
{% 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">
|
|
||||||
Price Tiers
|
|
||||||
</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-8 order-2 order-xl-1">
|
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
<div class="col-xl-4 order-1 order-xl-2 m--align-right">
|
|
||||||
<a href="{{ url('price_tier_add_form') }}" class="btn btn-focus m-btn m-btn--custom m-btn--icon m-btn--air m-btn--pill">
|
|
||||||
<span>
|
|
||||||
<i class="la la-industry"></i>
|
|
||||||
<span>New Price Tier</span>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
<div class="m-separator m-separator--dashed d-xl-none"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--begin: Datatable -->
|
|
||||||
<div id="data-rows"></div>
|
|
||||||
<!--end: Datatable -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
<script>
|
|
||||||
$(function() {
|
|
||||||
var options = {
|
|
||||||
data: {
|
|
||||||
type: 'remote',
|
|
||||||
source: {
|
|
||||||
read: {
|
|
||||||
url: '{{ url("price_tier_rows") }}',
|
|
||||||
method: 'POST'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
saveState: {
|
|
||||||
cookie: false,
|
|
||||||
webstorage: false
|
|
||||||
},
|
|
||||||
pageSize: 10,
|
|
||||||
serverPaging: true,
|
|
||||||
serverFiltering: true,
|
|
||||||
serverSorting: true
|
|
||||||
},
|
|
||||||
layout: {
|
|
||||||
scroll: true
|
|
||||||
},
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
field: 'id',
|
|
||||||
title: 'ID',
|
|
||||||
width: 30
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'name',
|
|
||||||
title: 'Name'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'Actions',
|
|
||||||
width: 110,
|
|
||||||
title: 'Actions',
|
|
||||||
sortable: false,
|
|
||||||
overflow: 'visible',
|
|
||||||
template: function (row, index, datatable) {
|
|
||||||
var actions = '';
|
|
||||||
|
|
||||||
if (row.meta.update_url != '') {
|
|
||||||
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" data-id="' + row.name + '" title="Edit"><i class="la la-edit"></i></a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row.meta.delete_url != '') {
|
|
||||||
actions += '<a href="' + row.meta.delete_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete" data-id="' + row.name + '" title="Delete"><i class="la la-trash"></i></a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
return actions;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
],
|
|
||||||
search: {
|
|
||||||
onEnter: false,
|
|
||||||
input: $('#data-rows-search'),
|
|
||||||
delay: 400
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var table = $("#data-rows").mDatatable(options);
|
|
||||||
|
|
||||||
$(document).on('click', '.btn-delete', function(e) {
|
|
||||||
var url = $(this).prop('href');
|
|
||||||
var id = $(this).data('id');
|
|
||||||
var btn = $(this);
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
swal({
|
|
||||||
title: 'Confirmation',
|
|
||||||
html: 'Are you sure you want to delete <strong>' + id + '</strong>?',
|
|
||||||
type: 'warning',
|
|
||||||
showCancelButton: true
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.value) {
|
|
||||||
$.ajax({
|
|
||||||
method: "DELETE",
|
|
||||||
url: url
|
|
||||||
}).done(function(response) {
|
|
||||||
table.row(btn.parents('tr')).remove();
|
|
||||||
table.reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -13,8 +13,7 @@ add_cust_vehicle_battery_info: This vehicle is using a Motolite battery
|
||||||
jo_title_pdf: Motolite Res-Q Job Order
|
jo_title_pdf: Motolite Res-Q Job Order
|
||||||
country_code_prefix: '+63'
|
country_code_prefix: '+63'
|
||||||
delivery_instructions_label: Delivery Instructions
|
delivery_instructions_label: Delivery Instructions
|
||||||
no_inventory_message: 'A Job Order was created but there is insufficient stock for the following SKU(s) on this branch: [item_display]'
|
no_inventory_message: No stock for [item_display]
|
||||||
no_riders_message: A Job Order was created but there are no riders available for this branch.
|
|
||||||
|
|
||||||
# images
|
# images
|
||||||
image_logo_login: /assets/images/logo-resq.png
|
image_logo_login: /assets/images/logo-resq.png
|
||||||
|
|
@ -160,7 +159,6 @@ menu.database.subtickettypes: 'Sub Ticket Types'
|
||||||
menu.database.emergencytypes: 'Emergency Types'
|
menu.database.emergencytypes: 'Emergency Types'
|
||||||
menu.database.ownershiptypes: 'Ownership Types'
|
menu.database.ownershiptypes: 'Ownership Types'
|
||||||
menu.database.serviceofferings: 'Service Offerings'
|
menu.database.serviceofferings: 'Service Offerings'
|
||||||
menu.database.itemtypes: 'Item Types'
|
|
||||||
|
|
||||||
# fcm jo status updates
|
# fcm jo status updates
|
||||||
jo_fcm_title_outlet_assign: 'Looking for riders'
|
jo_fcm_title_outlet_assign: 'Looking for riders'
|
||||||
|
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
update supported_area set hub_filter_exceptions = '{"no_inventory":true,"no_available_rider":true}' where id = 34;
|
|
||||||
update supported_area set hub_filter_exceptions = '{"no_inventory":true,"no_available_rider":true}' where id = 35;
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
-- MySQL dump 10.19 Distrib 10.3.39-MariaDB, for Linux (x86_64)
|
|
||||||
--
|
|
||||||
-- Host: localhost Database: resq
|
|
||||||
-- ------------------------------------------------------
|
|
||||||
-- Server version 10.3.39-MariaDB
|
|
||||||
|
|
||||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
|
||||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
|
||||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
|
||||||
/*!40101 SET NAMES utf8mb4 */;
|
|
||||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
|
||||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
|
||||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
|
||||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
|
||||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
|
||||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Table structure for table `item_type`
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `item_type`;
|
|
||||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
|
||||||
/*!40101 SET character_set_client = utf8 */;
|
|
||||||
CREATE TABLE `item_type` (
|
|
||||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
`name` varchar(80) NOT NULL,
|
|
||||||
`code` varchar(80) NOT NULL,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
KEY `item_type_idx` (`code`)
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Dumping data for table `item_type`
|
|
||||||
--
|
|
||||||
|
|
||||||
LOCK TABLES `item_type` WRITE;
|
|
||||||
/*!40000 ALTER TABLE `item_type` DISABLE KEYS */;
|
|
||||||
INSERT INTO `item_type` VALUES (1,'Battery','battery'),(2,'Service Offering','service_offering');
|
|
||||||
/*!40000 ALTER TABLE `item_type` ENABLE KEYS */;
|
|
||||||
UNLOCK TABLES;
|
|
||||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
|
||||||
|
|
||||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
|
||||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
|
||||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
|
||||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
|
||||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
|
||||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
|
||||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
|
||||||
|
|
||||||
-- Dump completed on 2024-01-28 20:59:44
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
INSERT INTO service_offering (name, code, fee) VALUES ('Motolite User Jumpstart Warranty Fee', 'motolite_user_jumpstart_warranty_fee', 200.00);
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
INSERT INTO service_offering (name, code, fee) VALUES ('Tire Sealant Fee', 'tire_sealant_fee', '200.00');
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
-- MySQL dump 10.19 Distrib 10.3.39-MariaDB, for Linux (x86_64)
|
|
||||||
--
|
|
||||||
-- Host: localhost Database: resq
|
|
||||||
-- ------------------------------------------------------
|
|
||||||
-- Server version 10.3.39-MariaDB
|
|
||||||
|
|
||||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
|
||||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
|
||||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
|
||||||
/*!40101 SET NAMES utf8mb4 */;
|
|
||||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
|
||||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
|
||||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
|
||||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
|
||||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
|
||||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Table structure for table `service_offering`
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `service_offering`;
|
|
||||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
|
||||||
/*!40101 SET character_set_client = utf8 */;
|
|
||||||
CREATE TABLE `service_offering` (
|
|
||||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
||||||
`name` varchar(80) NOT NULL,
|
|
||||||
`code` varchar(80) NOT NULL,
|
|
||||||
`fee` decimal(9,2) NOT NULL,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
KEY `service_offering_idx` (`code`)
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Dumping data for table `service_offering`
|
|
||||||
--
|
|
||||||
|
|
||||||
LOCK TABLES `service_offering` WRITE;
|
|
||||||
/*!40000 ALTER TABLE `service_offering` DISABLE KEYS */;
|
|
||||||
INSERT INTO `service_offering` VALUES (1,'Tax','tax',0.12),(2,'Motolite User Service Fee','motolite_user_service_fee',0.00),(3,'Battery Replacement Warranty Fee','battery_replacement_warranty_fee',0.00),(4,'Fuel Service Fee','fuel_service_fee',300.00),(5,'Fuel Gas Fee','fuel_gas_fee',340.00),(6,'Fuel Diesel Fee','fuel_diesel_fee',320.00),(7,'Jumpstart Fee','jumpstart_fee',300.00),(8,'Jumpstart Fee Mobile App','jumpstart_fee_mobile_app',300.00),(9,'Jumpstart Warranty Fee','jumpstart_warranty_fee',300.00),(10,'Overheat Fee','overheat_fee',300.00),(11,'Coolant Fee','coolant_fee',1600.00),(12,'Post Recharged Fee','post_recharged_fee',300.00),(13,'Post Replacement Fee','post_replacement_fee',0.00),(14,'Tire Repair Fee','tire_repair_fee',300.00),(17,'Motolite User Jumpstart Warranty Fee','motolite_user_jumpstart_warranty_fee',200.00),(18,'Motolite User Jumpstart Fee','motolite_user_jumpstart_fee',200.00);
|
|
||||||
/*!40000 ALTER TABLE `service_offering` ENABLE KEYS */;
|
|
||||||
UNLOCK TABLES;
|
|
||||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
|
||||||
|
|
||||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
|
||||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
|
||||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
|
||||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
|
||||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
|
||||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
|
||||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
|
||||||
|
|
||||||
-- Dump completed on 2024-04-02 1:17:40
|
|
||||||
Loading…
Reference in a new issue