diff --git a/.env.dist b/.env.dist
index 4e10dffc..a9fe4b6a 100644
--- a/.env.dist
+++ b/.env.dist
@@ -42,3 +42,14 @@ POLICY_MOBILE=insertmobilepolicyidhere
# OTP
OTP_MODE=settotestorrandom
+
+# geofence
+GEOFENCE_ENABLE=settotrueorfalse
+
+# unknown manufacturer and vehicle ids
+CVU_MFG_ID=insertmfgidforunknownvehicles
+CVU_BRAND_ID=insertbrandidforunknownvehicles
+
+# country code prefix
+COUNTRY_CODE=+insertcountrycodehere
+
diff --git a/catalyst/api-bundle/Command/TestAPICommand.php b/catalyst/api-bundle/Command/TestAPICommand.php
index bf35ce1e..7e959808 100644
--- a/catalyst/api-bundle/Command/TestAPICommand.php
+++ b/catalyst/api-bundle/Command/TestAPICommand.php
@@ -41,7 +41,6 @@ class TestAPICommand extends Command
// TODO: shift this out of the bundle, since it's project specific
-
// warranty register
$serial = 'AJ34LJADR12134LKJL5';
$plate_num = 'XEN918';
@@ -54,16 +53,22 @@ class TestAPICommand extends Command
'date_expire' => '20191001',
'first_name' => 'First',
'last_name' => 'Last',
- 'mobile_number' => '12345678910',
+ 'mobile_number' => '09231234567',
];
- $api->post('/capi/warranties', $params);
+ //$api->post('/capi/warranties', $params);
// get all warranties
- $api->get('/capi/warranties');
+ $params = [
+ 'order' => 'DESC',
+ 'limit' => '5',
+ 'start' => '1',
+ ];
+
+ $api->get('/capi/warranties', $params);
// warranty find
- $api->get('/capi/warranties/' . $serial);
+ //$api->get('/capi/warranties/' . $serial);
// warranty update
$id = 86811;
@@ -78,7 +83,7 @@ class TestAPICommand extends Command
'last_name' => 'Last',
'mobile_number' => '123456789111',
];
- $api->post('/capi/warranties/'. $id, $params);
+ //$api->post('/capi/warranties/'. $id, $params);
// warranty set privacy policy
$id = 86811;
@@ -86,7 +91,7 @@ class TestAPICommand extends Command
$params = [
'privacy_policy_id' => $policy_id,
];
- $api->post('/capi/warranties/' . $id .'/privacypolicy', $params);
+ //$api->post('/capi/warranties/' . $id .'/privacypolicy', $params);
// warranty claim
$id = 86811;
@@ -94,30 +99,44 @@ class TestAPICommand extends Command
$params = [
'serial' => $serial,
];
- $api->post('/capi/warranties/' . $id . '/claim', $params);
+ //$api->post('/capi/warranties/' . $id . '/claim', $params);
// warranty cancel
$id = 86811;
- $api->get('/capi/warranties/' . $id . '/cancel');
+ //$api->get('/capi/warranties/' . $id . '/cancel');
// plate warranty
- $api->get('/capi/plates/' . $plate_num . '/warranties');
+ //$api->get('/capi/plates/' . $plate_num . '/warranties');
// warranty delete
$id = 86811;
- $api->post('/capi/warranties/' . $id . '/delete');
+ //$api->post('/capi/warranties/' . $id . '/delete');
// battery
- $api->get('/capi/battery_brands');
- $api->get('/capi/battery_sizes');
- $api->get('/capi/batteries');
+ //$api->get('/capi/battery_brands');
+ //$api->get('/capi/battery_sizes');
+ //$api->get('/capi/batteries');
// vehicle
- $api->get('/capi/vehicle_manufacturers');
- $api->get('/capi/vehicles');
+ //$api->get('/capi/vehicle_manufacturers');
+ //$api->get('/capi/vehicles');
// privacy policy
$privacy_policy_id = 2;
$api->get('/capi/privacy_policy/' . $privacy_policy_id );
+
+ // register new customer
+ $params = [
+ 'first_name' => 'Krispups',
+ 'last_name' =>'Porzindog',
+ 'mobile_number' => '9221111111',
+ 'v_make_id' => '22241',
+ 'v_model_year' => '2018',
+ 'v_plate_number' => 'KPP1234',
+ 'v_color' => 'White',
+ 'v_condition' => 'new',
+ 'v_fuel_type' => 'gas',
+ ];
+ $api->post('/capi/quick_registration', $params);
}
}
diff --git a/composer.json b/composer.json
index 6c67a564..e118abfc 100644
--- a/composer.json
+++ b/composer.json
@@ -12,6 +12,7 @@
"catalyst/menu-bundle": "dev-master",
"creof/doctrine2-spatial": "^1.2",
"data-dog/audit-bundle": "^0.1.10",
+ "edwinhoksberg/php-fcm": "^1.0",
"guzzlehttp/guzzle": "^6.3",
"predis/predis": "^1.1",
"sensio/framework-extra-bundle": "^5.1",
diff --git a/composer.lock b/composer.lock
index 54f7abba..b3630199 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,10 +1,10 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "content-hash": "ef9a215401e1fec51336e1d6a9df52d9",
+ "content-hash": "4873ae3fd18db755bc9bf395bbbfb141",
"packages": [
{
"name": "catalyst/auth-bundle",
@@ -1564,6 +1564,55 @@
],
"time": "2018-06-14T14:45:07+00:00"
},
+ {
+ "name": "edwinhoksberg/php-fcm",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/EdwinHoksberg/php-fcm.git",
+ "reference": "7be637139fe54ec23f37c8dba519bafa7543e336"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/EdwinHoksberg/php-fcm/zipball/7be637139fe54ec23f37c8dba519bafa7543e336",
+ "reference": "7be637139fe54ec23f37c8dba519bafa7543e336",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/guzzle": "^6.3",
+ "php": ">= 7.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Fcm\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Edwin Hoksberg",
+ "email": "mail@edwinhoksberg.nl"
+ }
+ ],
+ "description": "A library for sending Firebase cloud messages and managing user topic subscriptions, device groups and devices.",
+ "homepage": "https://github.com/EdwinHoksberg/php-fcm",
+ "keywords": [
+ "FCM",
+ "Firebase Cloud Messaging",
+ "firebase",
+ "google",
+ "notifications"
+ ],
+ "time": "2018-04-09T19:32:41+00:00"
+ },
{
"name": "guzzlehttp/guzzle",
"version": "6.3.3",
diff --git a/config/acl.yaml b/config/acl.yaml
index e7f42308..90b2f06d 100644
--- a/config/acl.yaml
+++ b/config/acl.yaml
@@ -256,6 +256,8 @@ access_keys:
label: Search
- id: warranty.search
label: Customer Battery Search
+ - id: warranty.upload
+ label: Warranty Upload
- id: ticket
label: Ticket Access
@@ -298,6 +300,12 @@ access_keys:
label: Popapp Comparison Report
- id: report.meh.customer
label: RESQ MEH Customer Report
+ - id: report.warranty.class
+ label: Warranty Class Report
+ - id: report.vehicle.battery.compatibility
+ label: Vehicle Battery Compatibility Report
+ - id: report.warranty.details
+ label: Warranty Details Report
- id: service
label: Other Services
@@ -364,3 +372,17 @@ access_keys:
label: Add
- id: warranty.update
label: Update
+
+ - id: staticcontent
+ label: Static Content
+ acls:
+ - id: static_content.menu
+ label: Menu
+ - id: static_content.list
+ label: List
+ - id: static_content.add
+ label: Add
+ - id: static_content.update
+ label: Update
+ - id: static_content.delete
+ label: Delete
diff --git a/config/api_acl.yaml b/config/api_acl.yaml
index 39557cf6..2ff18704 100644
--- a/config/api_acl.yaml
+++ b/config/api_acl.yaml
@@ -50,3 +50,8 @@ access_keys:
acls:
- id: privacypolicy.find
label: Find Privacy Policy
+ - id: customer
+ label: Customer
+ acls:
+ - id: customer.register
+ label: Register Customer
diff --git a/config/menu.yaml b/config/menu.yaml
index cd3f40b9..a64dd8b4 100644
--- a/config/menu.yaml
+++ b/config/menu.yaml
@@ -155,6 +155,14 @@ main_menu:
acl: warranty.list
label: Warranty
parent: support
+ - id: warranty_upload
+ acl: warranty.upload
+ label: Warranty Upload
+ parent: support
+ - id: static_content_list
+ acl: static_content.list
+ label: Static Content
+ parent: support
- id: service
acl: service.menu
diff --git a/config/routes/capi.yaml b/config/routes/capi.yaml
index cf533814..ee3c8668 100644
--- a/config/routes/capi.yaml
+++ b/config/routes/capi.yaml
@@ -135,3 +135,11 @@ capi_privacy_policy:
path: /capi/privacy_policy/{id}
controller: App\Controller\CAPI\PrivacyPolicyController::getPrivacyPolicy
methods: [GET]
+
+# customer
+
+# register customer and customer vehicle
+capi_customer_register:
+ path: /capi/quick_registration
+ controller: App\Controller\CAPI\CustomerController::register
+ methods: [POST]
diff --git a/config/routes/report.yaml b/config/routes/report.yaml
index 5d815490..85ad83ee 100644
--- a/config/routes/report.yaml
+++ b/config/routes/report.yaml
@@ -47,3 +47,33 @@ rep_resq_meh_export_csv:
path: /report/meh_customer_export
controller: App\Controller\ReportController::mehCustomerExportCSV
methods: [POST]
+
+rep_warranty_class_form:
+ path: /report/warranty_class_report
+ controller: App\Controller\ReportController::warrantyClassForm
+ methods: [GET]
+
+rep_warranty_class_export_csv:
+ path: /report/warranty_class_report
+ controller: App\Controller\ReportController::warrantyClassExportCSV
+ methods: [POST]
+
+rep_vehicle_battery_compatibility_form:
+ path: /report/vehicle_battery_compatibility_report
+ controller: App\Controller\ReportController::vehicleBatteryCompatibilityForm
+ methods: [GET]
+
+rep_vehicle_battery_compatibility_export_csv:
+ path: /report/vehicle_battery_compatibility_report
+ controller: App\Controller\ReportController::vehicleBatteryCompatibilityExportCSV
+ methods: [POST]
+
+rep_warranty_details_form:
+ path: /report/warranty_details_report
+ controller: App\Controller\ReportController::warrantyDetailsForm
+ methods: [GET]
+
+rep_warranty_details_export_csv:
+ path: /report/warranty_details_report
+ controller: App\Controller\ReportController::warrantyDetailsExportCSV
+ methods: [POST]
diff --git a/config/routes/static_content.yaml b/config/routes/static_content.yaml
new file mode 100644
index 00000000..88fe3cf4
--- /dev/null
+++ b/config/routes/static_content.yaml
@@ -0,0 +1,33 @@
+static_content_list:
+ path: /static_content
+ controller: App\Controller\StaticContentController::index
+
+static_content_rows:
+ path: /static_content/rows
+ controller: App\Controller\StaticContentController::rows
+ methods: [POST]
+
+static_content_create:
+ path: /static_content/create
+ controller: App\Controller\StaticContentController::addForm
+ methods: [GET]
+
+static_content_create_submit:
+ path: /static_content/create
+ controller: App\Controller\StaticContentController::addSubmit
+ methods: [POST]
+
+static_content_update:
+ path: /static_content/{id}
+ controller: App\Controller\StaticContentController::updateForm
+ methods: [GET]
+
+static_content_update_submit:
+ path: /static_content/{id}
+ controller: App\Controller\StaticContentController::updateSubmit
+ methods: [POST]
+
+static_content_delete:
+ path: /static_content/{id}
+ controller: App\Controller\StaticContentController::destroy
+ methods: [DELETE]
diff --git a/config/routes/warranty.yaml b/config/routes/warranty.yaml
index 86c3e9b9..3e049e54 100644
--- a/config/routes/warranty.yaml
+++ b/config/routes/warranty.yaml
@@ -28,3 +28,13 @@ warranty_update_submit:
path: /warranties/{id}
controller: App\Controller\WarrantyController::updateSubmit
methods: [POST]
+
+warranty_upload:
+ path: /warranty/upload
+ controller: App\Controller\WarrantyController::uploadForm
+ methods: [GET]
+
+warranty_upload_submit:
+ path: /warranty/upload
+ controller: App\Controller\WarrantyController::uploadSubmit
+ methods: [POST]
diff --git a/config/services.yaml b/config/services.yaml
index 353378b4..00c5c32f 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -10,6 +10,7 @@ parameters:
api_access_key: 'api_access_keys'
app_acl_file: 'acl.yaml'
app_access_key: 'access_keys'
+ cvu_brand_id: "%env(CVU_BRAND_ID)%"
services:
# default configuration for services in *this* file
@@ -87,6 +88,25 @@ services:
$password: "%env(REDIS_CLIENT_PASSWORD)%"
$env_flag: "dev"
+ App\Service\GeofenceTracker:
+ arguments:
+ $geofence_flag: "%env(GEOFENCE_ENABLE)%"
+
+ App\Service\WarrantyHandler:
+ arguments:
+ $em: "@doctrine.orm.entity_manager"
+
+ App\Command\SetCustomerPrivacyPolicyCommand:
+ arguments:
+ $policy_promo: "%env(POLICY_PROMO)%"
+ $policy_third_party: "%env(POLICY_THIRD_PARTY)%"
+ $policy_mobile: "%env(POLICY_MOBILE)%"
+
+ App\Command\CreateCustomerFromWarrantyCommand:
+ arguments:
+ $cvu_mfg_id: "%env(CVU_MFG_ID)%"
+ $cvu_brand_id: "%env(CVU_BRAND_ID)%"
+
# rider tracker service
App\Service\RiderTracker:
arguments:
@@ -144,14 +164,18 @@ services:
App\Service\InvoiceGeneratorInterface: "@App\\Service\\InvoiceGenerator\\ResqInvoiceGenerator"
# job order generator
- App\Service\JobOrderHandler\CMBJobOrderHandler: ~
+ App\Service\JobOrderHandler\ResqJobOrderHandler:
+ arguments:
+ $country_code: "%env(COUNTRY_CODE)%"
#job order generator interface
#App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\CMBJobOrderHandler"
App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\ResqJobOrderHandler"
# customer generator
- App\Service\CustomerHandler\CMBCustomerHandler: ~
+ App\Service\CustomerHandler\ResqCustomerHandler:
+ arguments:
+ $country_code: "%env(COUNTRY_CODE)%"
# customer generator interface
#App\Service\CustomerHandlerInterface: "@App\\Service\\CustomerHandler\\CMBCustomerHandler"
diff --git a/src/Command/ComputeWarrantyExpiryDateCommand.php b/src/Command/ComputeWarrantyExpiryDateCommand.php
new file mode 100644
index 00000000..383370f7
--- /dev/null
+++ b/src/Command/ComputeWarrantyExpiryDateCommand.php
@@ -0,0 +1,75 @@
+em = $em;
+ $this->wh = $wh;
+
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('warranty:computeexpirydate')
+ ->setDescription('Compute expiry date for existing warranties.')
+ ->setHelp('Compute expiry date for existing warranties.');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $warr_q = $this->em->createQuery('select w from App\Entity\Warranty w where w.date_expire is null');
+ $warranties = $warr_q->iterate();
+
+ foreach($warranties as $row)
+ {
+ $warr = $row[0];
+
+ error_log('Processing warranty for ' . $warr->getID());
+
+ $date_purchase = $warr->getDatePurchase();
+
+ $batteries = $this->wh->getBatteriesForWarranty($warr);
+ if (!empty($batteries))
+ {
+ $warranty_class = $warr->getWarrantyClass();
+
+ $warr_period = $this->wh->getWarrantyPeriod($batteries, $warranty_class);
+
+ if ($warr_period != null)
+ {
+ $expiry_date = $this->wh->computeDateExpire($date_purchase, $warr_period);
+ }
+ else
+ {
+ $expiry_date = $date_purchase;
+ }
+
+ // save expiry date
+ $warr->setDateExpire($expiry_date);
+
+ $this->em->persist($warr);
+ $this->em->flush();
+ }
+
+ $this->em->clear();
+ }
+ }
+}
diff --git a/src/Command/CreateCustomerFromWarrantyCommand.php b/src/Command/CreateCustomerFromWarrantyCommand.php
new file mode 100644
index 00000000..e644fc06
--- /dev/null
+++ b/src/Command/CreateCustomerFromWarrantyCommand.php
@@ -0,0 +1,458 @@
+em = $em;
+
+ $this->cvu_mfg_id = $cvu_mfg_id;
+ $this->cvu_brand_id = $cvu_brand_id;
+
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('customer:createfromwarranty')
+ ->setDescription('Create customers from existing warranties.')
+ ->setHelp('Creates customers from existing warranties.')
+ ->addArgument('file', InputArgument::REQUIRED, 'Path to the output CSV file with the warranties.');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $csv_file = $input->getArgument('file');
+
+ // attempt to open file
+ try
+ {
+ $fh = fopen($csv_file, "w");
+ }
+ catch (Exception $e)
+ {
+ throw new Exception('The file "' . $csv_file . '" could be opened.');
+ }
+
+ // counters for warranties, customers, customer vehicles
+ $total_warr = 0;
+ $total_inv_warr = 0;
+ $total_cust_added = 0;
+ $total_cv_added = 0;
+
+
+ /*
+ // load all customers
+ $output->writeln('Loading customer data...');
+ $this->loadCustomers($output);
+ */
+
+
+ // get all warranties
+ error_log('Getting warranties...');
+ $warr_q = $this->em->createQuery('select w from App\Entity\Warranty w where w.mobile_number is not null');
+ $warranties = $warr_q->iterate();
+ // $warranties = $warr_q->getResult();
+ // $warranties = $this->em->getRepository(Warranty::class)->findAll();
+
+ //$invalid_warranties = [];
+ // $warr_count = count($warranties);
+ $created_objs = [];
+ $output->writeln("Processing warranties... ");
+ foreach($warranties as $row)
+ {
+ $warr = $row[0];
+
+ $total_warr++;
+ // check if warranty mobile already exists in customer
+ $w_mobile = $warr->getMobileNumber();
+ if (empty($w_mobile))
+ {
+ // TODO: for now, if warranty mobile number is empty, add to list of invalid entries
+ //$invalid_warranties[] = $this->processInvalidEntries($warr);
+ continue;
+ }
+
+ // parse warranty mobile in case of multiple numbers
+ // check for spaces, slash, and forward slash
+ $w_mobile_array = [];
+ if (preg_match('/[\\\s\/]/', $w_mobile))
+ {
+ $w_mobile_array = preg_split('/[\\\s\/]/', $w_mobile);
+ }
+ else
+ {
+ // only one mobile number
+ $w_mobile_array[] = $w_mobile;
+ }
+
+ // set values for new customer vehicle
+ $w_plate_number = $this->cleanPlateNumber($warr->getPlateNumber());
+
+ $cust_found = false;
+ foreach ($w_mobile_array as $w_mobile_num)
+ {
+ $w_mobile_num = trim($w_mobile_num);
+
+ // empty mobile num
+ if (empty($w_mobile_num))
+ continue;
+
+ // does it fit our 09XXXXXXXXX pattern?
+ if (preg_match('/^09[0-9]{9}$/', $w_mobile_num))
+ {
+ // remove first '0'
+ $w_mobile_num = substr($w_mobile_num, 1);
+ error_log("CONVERTED TO $w_mobile_num");
+ }
+
+ // does it fit our 9XXXXXXXXX pattern?
+ if (!preg_match('/^9[0-9]{9}$/', $w_mobile_num))
+ continue;
+
+ /*
+ // min length 2
+ // TODO: we need to check proper phone number format
+ // format should be '9XXXXXXXXX'
+ // TODO: if format doesn't fit and there's a 0 or 63 prefix, we should be able to detect and convert
+ if (strlen($w_mobile_num <= 2))
+ continue;
+ */
+
+ error_log('');
+ error_log("($total_warr) processing $w_mobile_num from warranty...");
+
+ $customers = $this->findCustomerByNumber($w_mobile_num);
+
+ if (!empty($customers))
+ {
+ error_log('found customer for ' . $w_mobile_num);
+ foreach ($customers as $customer)
+ {
+ // get customer vehicles for customer
+ $c_vehicles = $customer->getVehicles();
+
+ $cv_found = false;
+ if (!empty($c_vehicles))
+ {
+ // check if plate number of customer vehicle matches warranty plate number
+ foreach ($c_vehicles as $c_vehicle)
+ {
+ $clean_cv_plate = $this->cleanPlateNumber($c_vehicle->getPlateNumber());
+
+ // check if it's already there
+ if ($clean_cv_plate == $w_plate_number)
+ {
+ // customer and customer vehicle already exists
+ $cv_found = true;
+ break;
+ }
+ }
+
+ }
+
+ // if there was a customer vehicle matched
+ if ($cv_found)
+ {
+ // vehicle found, do nothing.
+ error_log('vehicle found - ' . $w_plate_number);
+ $created_objs[] = $this->createReportData($warr, self::CV_FOUND);
+ }
+ else
+ {
+ // customer exists but not customer vehicle
+ // add customer vehicle to existing customer with unknown manufacturer and make
+ error_log('new vehicle - ' . $w_plate_number);
+ $this->createCustomerVehicle($customer, $this->getDefaultVehicle(), $w_plate_number);
+ $created_objs[] = $this->createReportData($warr, self::CV_NEW);
+ $total_cv_added++;
+ }
+ }
+ }
+ // customer not found
+ else
+ {
+ error_log('NEW customer and vehicle - ' . $w_plate_number);
+ // customer not found, add customer and customer vehicle
+ // get warranty first name, last name
+ $w_first_name = $warr->getFirstName();
+ $w_last_name = $warr->getLastName();
+
+ //$output->writeln($w_first_name);
+ //$output->writeln($w_last_name);
+ //$output->writeln($w_plate_number);
+
+ $new_cust = new Customer();
+ $new_cust->setFirstName($w_first_name)
+ ->setLastName($w_last_name)
+ ->setPhoneMobile($w_mobile_num);
+
+ $this->em->persist($new_cust);
+
+ $this->createCustomerVehicle($new_cust, $this->getDefaultVehicle(), $w_plate_number);
+
+ $created_objs[] = $this->createReportData($warr, self::CUST_NEW);
+
+ // add latest customer to hash
+ //$this->cust_index[$w_mobile_num][] = $new_cust;
+
+ $total_cust_added++;
+ $total_cv_added++;
+ }
+ }
+ $this->em->flush();
+ $this->em->clear();
+ }
+
+ /*
+ // process invalid warranties, if any
+ if (count($invalid_warranties) > 0)
+ {
+ fputcsv($fh, [
+ 'ID',
+ 'Serial',
+ 'Warranty Class',
+ 'Last Name',
+ 'First Name',
+ 'Mobile Number',
+ 'Plate Number',
+ 'Battery Model',
+ 'Battery Size',
+ 'SAP Battery',
+ 'Status',
+ 'Date Created',
+ 'Date Purchased',
+ 'Expiry Date',
+ 'Date Claimed',
+ 'Claimed From',
+ 'Privacy Policy',
+ ]);
+
+ foreach($invalid_warranties as $row)
+ {
+ $total_inv_warr++;
+ fputcsv($fh, $row);
+ }
+ }
+ */
+
+ // process the report data
+ if (count($created_objs) > 0)
+ {
+ fputcsv($fh, [
+ 'ID',
+ 'Mobile Number',
+ 'Plate Number',
+ 'Action Done',
+ ]);
+
+ foreach($created_objs as $row)
+ {
+ fputcsv($fh, $row);
+ }
+ }
+
+ fclose($fh);
+
+ $output->writeln('');
+ $output->writeln('Total warranties: ' . $total_warr);
+ //$output->writeln('Total warranties with no mobile number: ' . $total_inv_warr);
+ $output->writeln('Total customers added: ' . $total_cust_added);
+ $output->writeln('Total customer vehicles added: ' . $total_cv_added);
+ }
+
+ protected function getDefaultVehicle()
+ {
+ // get default vehicle
+ $default_vehicle = $this->em->getRepository(Vehicle::class)->find($this->cvu_brand_id);
+ if ($default_vehicle == null)
+ {
+ $output->writeln("Need to add vehicle with default values.");
+ return null;
+ }
+
+ return $default_vehicle;
+ }
+
+ protected function findCustomerByNumber($number)
+ {
+ $customers = $this->em->getRepository(Customer::class)->findBy(['phone_mobile' => $number]);
+ return $customers;
+ }
+
+ protected function loadCustomers()
+ {
+ error_log('starting query...');
+ // get all customers
+ $customers = $this->em->getRepository(Customer::class)->findAll();
+ $cust_q = $this->em->createQuery('select c from App\Entity\Customer c');
+ $cust_iter = $q->iterate();
+
+ error_log('looping through query...');
+ $this->cust_index = [];
+ foreach ($cust_iter as $customer)
+ {
+ error_log('here');
+ $mobile = trim($customer->getPhoneMobile());
+ if (!empty($mobile))
+ {
+ $mobile_array = [];
+ // need to check if multiple numbers in mobile
+ if (preg_match('/[\\\s\/]/', $mobile))
+ {
+ $mobile_array = preg_split('/[\\\s\/]/', $mobile);
+ }
+ else
+ {
+ // only one mobile number
+ $mobile_array[] = $mobile;
+ }
+
+ foreach($mobile_array as $number)
+ {
+ if (!(empty($number)))
+ {
+ if (!isset($this->cust_index[$number]))
+ $this->cust_index[$number] = [];
+ $this->cust_index[$number][] = $customer;
+ }
+ }
+ }
+ }
+ }
+
+ protected function createCustomerVehicle(Customer $cust, $vehicle, $plate_number)
+ {
+ $new_cv = new CustomerVehicle();
+
+ $new_cv->setCustomer($cust)
+ ->setPlateNumber($plate_number)
+ ->setStatusCondition(VehicleStatusCondition::BRAND_NEW)
+ ->setModelYear('')
+ ->setColor('')
+ ->setFuelType(FuelType::GAS)
+ ->setHasMotoliteBattery(true)
+ ->setVehicle($vehicle);
+
+ $this->em->persist($new_cv);
+ }
+
+ protected function createReportData($warr, $action)
+ {
+ $obj = [
+ 'id' => $warr->getID(),
+ 'mobile_number' => $warr->getMobileNumber(),
+ 'plate_number' => $warr->getPlateNumber(),
+ 'action_done' => $action,
+ ];
+
+ return $obj;
+
+ }
+
+ protected function processInvalidEntries($warr)
+ {
+ $batt_model = '';
+ $batt_size = '';
+ $sap_batt = '';
+ $policy = '';
+ $date_purchased = '';
+ $date_expire = '';
+ $date_claim = '';
+
+ $create_date = $warr->getDateCreate();
+ $date_create = $create_date->format('d/M/y');
+
+ if ($warr->getDatePurchase() != null)
+ {
+ $p_date = $warr->getDatePurchase();
+ $date_purchased = $p_date->format('d/M/y');
+ }
+ if ($warr->getDateClaim() != null)
+ {
+ $c_date = $warr->getDateClaim();
+ $date_claim = $c_date->format('d/M/y');
+ }
+ if ($warr->getDateExpire() != null)
+ {
+ $e_date = $warr->getDateExpire();
+ $date_expire = $e_date->format('d/M/y');
+ }
+
+ if ($warr->getBatteryModel() != null)
+ {
+ $batt_model = $warr->getBatteryModel()->getName();
+ }
+ if ($warr->getBatterySize() != null)
+ {
+ $batt_size = $warr->getBatterySize()->getName();
+ }
+ if ($warr->getSAPBattery() != null)
+ {
+ $sap_batt = $warr->getSAPBattery()->getBrand()->getName();
+ }
+ if ($warr->getPrivacyPolicy() != null)
+ {
+ $policy = $warr->getPrivacyPolicy()->getName();
+ }
+
+ $invalid_warranty = [
+ 'id' => $warr->getID(),
+ 'serial' => $warr->getSerial(),
+ 'warranty_class' => $warr->getWarrantyClass(),
+ 'last_name' => $warr->getLastName(),
+ 'first_name' => $warr->getFirstName(),
+ 'mobile_number' => $warr->getMobileNumber(),
+ 'plate_number' => $warr->getPlateNumber(),
+ 'battery_model' => $batt_model,
+ 'battery_size' => $batt_size,
+ 'sap_battery' => $sap_batt,
+ 'status' => $warr->getStatus(),
+ 'date_create' => $date_create,
+ 'date_purchase' => $date_purchased,
+ 'date_expire' => $date_expire,
+ 'date_claim' => $date_claim,
+ 'claimed_from' => $warr->getClaimedFrom(),
+ 'privacy_policy' => $policy,
+ ];
+
+ return $invalid_warranty;
+ }
+
+ protected function cleanPlateNumber($plate)
+ {
+ // remove spaces and make upper case
+ return strtoupper(str_replace(' ', '', $plate));
+ }
+}
diff --git a/src/Command/ImportPartnersCommand.php b/src/Command/ImportPartnersCommand.php
index 526fb282..74e02d5b 100644
--- a/src/Command/ImportPartnersCommand.php
+++ b/src/Command/ImportPartnersCommand.php
@@ -34,7 +34,7 @@ class ImportPartnersCommand extends Command
protected $em;
- public function __construct(Objectmanager $om)
+ public function __construct(ObjectManager $om)
{
$this->em = $om;
diff --git a/src/Command/SetCustomerPrivacyPolicyCommand.php b/src/Command/SetCustomerPrivacyPolicyCommand.php
index d4431175..4132fa91 100644
--- a/src/Command/SetCustomerPrivacyPolicyCommand.php
+++ b/src/Command/SetCustomerPrivacyPolicyCommand.php
@@ -7,7 +7,6 @@ use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Dotenv\Dotenv;
use Doctrine\Common\Persistence\ObjectManager;
@@ -19,10 +18,19 @@ class SetCustomerPrivacyPolicyCommand extends Command
{
private $em;
- public function __construct(ObjectManager $om)
+ private $policy_promo_id;
+ private $policy_third_party_id;
+ private $policy_mobile_id;
+
+ public function __construct(ObjectManager $om, $policy_promo,
+ $policy_third_party, $policy_mobile)
{
$this->em = $om;
+ $this->policy_promo_id = $policy_promo;
+ $this->policy_third_party_id = $policy_third_party;
+ $this->policy_mobile_id = $policy_mobile;
+
parent::__construct();
}
@@ -35,16 +43,8 @@ class SetCustomerPrivacyPolicyCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output)
{
- // get the policy ids from .env
- $dotenv = new Dotenv();
- $dotenv->loadEnv(__DIR__.'/../../.env');
-
- $policy_promo_id = $_ENV['POLICY_PROMO'];
- $policy_third_party_id = $_ENV['POLICY_THIRD_PARTY'];
- $policy_mobile_id = $_ENV['POLICY_MOBILE'];
-
// get third party policy
- $third_party_policy = $this->em->getRepository(PrivacyPolicy::class)->find($policy_third_party_id);
+ $third_party_policy = $this->em->getRepository(PrivacyPolicy::class)->find($this->policy_third_party_id);
// get customers on third party
$third_party_customers = $this->em->getRepository(Customer::class)->findBy(['priv_third_party' => true]);
@@ -54,7 +54,7 @@ class SetCustomerPrivacyPolicyCommand extends Command
}
// get promo policy
- $promo_policy = $this->em->getRepository(PrivacyPolicy::class)->find($policy_promo_id);
+ $promo_policy = $this->em->getRepository(PrivacyPolicy::class)->find($this->policy_promo_id);
// get customers on promo
$promo_customers = $this->em->getRepository(Customer::class)->findBy(['priv_promo' => true]);
@@ -66,7 +66,7 @@ class SetCustomerPrivacyPolicyCommand extends Command
$this->em->flush();
// get mobile policy
- $mobile_policy = $this->em->getRepository(PrivacyPolicy::class)->find($policy_mobile_id);
+ $mobile_policy = $this->em->getRepository(PrivacyPolicy::class)->find($this->policy_mobile_id);
// get mobile sessions
$mobile_sessions = $this->em->getRepository(MobileSession::class)->findAll();
diff --git a/src/Command/UpdateCustomerVehicleWarrantyCommand.php b/src/Command/UpdateCustomerVehicleWarrantyCommand.php
new file mode 100644
index 00000000..89b6e5e0
--- /dev/null
+++ b/src/Command/UpdateCustomerVehicleWarrantyCommand.php
@@ -0,0 +1,98 @@
+em = $em;
+ $this->wh = $wh;
+
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('customervehicle:updatewarrantyinfo')
+ ->setDescription('Update customer vehicle warranty.')
+ ->setHelp('Update customer vehicle warranty.');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ // get all warranties
+ // since it's possible that the same plate number will have multiple warranties, order them from earliest to latest
+ $warr_q = $this->em->createQuery('select w from App\Entity\Warranty w where w.plate_number is not null order by w.date_purchase asc');
+ $warranties = $warr_q->iterate();
+
+ foreach ($warranties as $row)
+ {
+ $warr = $row[0];
+
+ // clean plate number
+ $plate_number = $this->wh->cleanPlateNumber($warr->getPlateNumber());
+
+ // get other warranty information
+ $serial = $warr->getSerial();
+ $expiry_date = $warr->getDateExpire();
+
+ // TODO: check length of serial for now. Should not exceed 20.
+ // there is a warranty with 2 serial codes in live
+ // for now, ignore the warranty
+ if (strlen($serial) > 20)
+ {
+ continue;
+ }
+
+ // find battery
+ $batteries = $this->wh->getBatteriesForWarranty($warr);
+
+ // find customer vehicle using plate number
+ /*
+ error_log('Finding customer vehicle with plate number ' . $plate_number);
+ $cust_vehicles = $this->em->getRepository(CustomerVehicle::class)->findBy(['plate_number' => $plate_number]);
+
+ if (!empty($cust_vehicles))
+ {
+ if (!empty($batteries))
+ {
+ // set current battery to the first battery in list.
+ // there are cases where multiple batteries linked to an SAP code.
+ $battery = $batteries[0];
+ $battery_id = $battery->getID();
+ }
+ $q = $this->em->createQuery('update App\Entity\CustomerVehicle cv
+ set cv.curr_battery = :batt_id,
+ cv.warranty_code = :serial,
+ cv.warranty_expiration = :expiry_date
+ where cv.plate_number = :plate_number')
+ ->setParameters([
+ 'batt_id' => $battery_id,
+ 'serial' => $serial,
+ 'expiry_date' => $expiry_date,
+ 'plate_number' => $plate_number]);
+ $q->execute();
+
+ } */
+ $this->wh->updateCustomerVehicle($serial, $batteries, $plate_number, $expiry_date);
+
+ $this->em->detach($row[0]);
+ }
+ }
+}
diff --git a/src/Controller/APIController.php b/src/Controller/APIController.php
index 5642dad7..9765ad8f 100644
--- a/src/Controller/APIController.php
+++ b/src/Controller/APIController.php
@@ -341,6 +341,15 @@ class APIController extends Controller
$this->session->setCustomer($dupe_cust);
}
+ // TODO: check if mobile matches mobile of customer
+ $customer = $this->findCustomerByNumber($this->session->getPhoneNumber());
+ if ($customer != null)
+ {
+ // TODO: if there is a dupe_sess, do we need to check if
+ // dupe_cust is the same as the customer we found?
+ $this->session->setCustomer($customer);
+ }
+
$em->flush();
// response
@@ -839,18 +848,15 @@ class APIController extends Controller
$long = $req->request->get('long');
$lat = $req->request->get('lat');
- /*
// geofence
$is_covered = $geo->isCovered($long, $lat);
if (!$is_covered)
{
// TODO: put geofence error message in config file somewhere
$res->setError(true)
- ->setErrorMessage('Oops! Our service is limited to Metro Manila only. We will update you as soon as we are able to cover your area');
+ ->setErrorMessage('Oops! Our service is limited to some areas in Metro Manila, Laguna, and Baguio only. We will update you as soon as we are able to cover your area');
return $res->getReturnResponse();
}
- */
-
$jo = new JobOrder();
$jo->setSource(TransactionOrigin::MOBILE_APP)
@@ -2182,4 +2188,29 @@ class APIController extends Controller
return $res->getReturnResponse();
}
+
+ protected function findCustomerByNumber($number)
+ {
+ $em = $this->getDoctrine()->getManager();
+ $customers = $em->getRepository(Customer::class)->findBy(['phone_mobile' => $number]);
+
+ // find the customer with the most number of cars
+ $car_count = 0;
+ $cust = null;
+
+ foreach($customers as $customer)
+ {
+ $vehicles = $customer->getVehicles();
+ if (count($vehicles) > $car_count)
+ {
+ $car_count = count($vehicles);
+
+ // "save" customer object
+ $cust = $customer;
+ }
+ }
+
+ return $cust;
+ }
+
}
diff --git a/src/Controller/CAPI/CustomerController.php b/src/Controller/CAPI/CustomerController.php
new file mode 100644
index 00000000..55aae2bd
--- /dev/null
+++ b/src/Controller/CAPI/CustomerController.php
@@ -0,0 +1,204 @@
+acl_gen = $acl_gen;
+ }
+
+ public function register(Request $req, EntityManagerInterface $em)
+ {
+ $this->denyAccessUnlessGranted('customer.register', null, 'No access.');
+
+ // required parameters
+ $params = [
+ 'first_name',
+ 'last_name',
+ 'mobile_number',
+ 'v_make_id',
+ 'v_model_year',
+ 'v_plate_number',
+ 'v_color',
+ 'v_condition',
+ 'v_fuel_type',
+ ];
+
+ $msg = $this->checkRequiredParameters($req, $params);
+ error_log('msg - ' . $msg);
+ if ($msg)
+ return new APIResponse(false, $msg);
+
+ $first_name = $req->request->get('first_name');
+ $last_name = $req->request->get('last_name');
+ $mobile_number = $req->request->get('mobile_number');
+
+ $make_id = $req->request->get('v_make_id');
+ $model_year = $req->request->get('v_model_year');
+ $plate_number = $this->cleanPlateNumber($req->request->get('v_plate_number'));
+ $color = $req->request->get('v_color');
+ $condition = $req->request->get('v_condition');
+ $fuel_type = $req->request->get('v_fuel_type');
+
+ // check if vehicle exists
+ $vehicle = $em->getRepository(Vehicle::class)->find($make_id);
+ if ($vehicle == null)
+ return new APIResponse(false, 'Invalid vehicle make.');
+
+ // clean up mobile number
+ // does it fit our 09XXXXXXXXX pattern?
+ if (preg_match('/^09[0-9]{9}$/', $mobile_number))
+ {
+ // remove first '0'
+ $mobile_number = substr($mobile_number, 1);
+ error_log("CONVERTED TO $mobile_number");
+ }
+
+ // does it fit our 9XXXXXXXXX pattern?
+ if (!preg_match('/^9[0-9]{9}$/', $mobile_number))
+ return new APIResponse(false, 'Invalid mobile number.');
+
+ /*
+ // min length 2
+ // TODO: we need to check proper phone number format
+ // format should be '9XXXXXXXXX'
+ // TODO: if format doesn't fit and there's a 0 or 63 prefix, we should be able to detect and convert
+ if (strlen($mobile_number <= 2))
+ continue;
+ */
+
+
+ $data = [];
+ $message = '';
+ // check if customer already exists
+ $customers = $em->getRepository(Customer::class)->findBy(['phone_mobile' => $mobile_number]);
+ if (!empty($customers))
+ {
+ foreach($customers as $customer)
+ {
+ // get customer vehicles for customer
+ $c_vehicles = $customer->getVehicles();
+
+ $cv_found = false;
+ if (!empty($c_vehicles))
+ {
+ // check if plate number of customer vehicle matches plate number
+ foreach($c_vehicles as $c_vehicle)
+ {
+ $clean_cv_plate = $this->cleanPlateNumber($c_vehicle->getPlateNumber());
+
+ // check if it's already there
+ if ($clean_cv_plate == $plate_number)
+ {
+ // customer and customer vehicle already exists
+ $cv_found = true;
+ break;
+ }
+ }
+ }
+
+ // if there is a customer vehicle matched
+ if ($cv_found)
+ {
+ // vehicle found, do nothing
+ $message = 'Customer found.';
+ }
+ else
+ {
+ // customer already exists but not customer vehicle
+ // add customer vehicle
+ $new_cv = new CustomerVehicle();
+
+ $new_cv->setCustomer($customer)
+ ->setPlateNumber($plate_number)
+ ->setStatusCondition($condition)
+ ->setModelYear($model_year)
+ ->setColor($color)
+ ->setFuelType($fuel_type)
+ ->setHasMotoliteBattery(true)
+ ->setVehicle($vehicle);
+
+ $em->persist($new_cv);
+
+ $message = 'Vehicle added.';
+ $data[] = [
+ 'make_id' => $make_id,
+ 'model_year' => $model_year,
+ 'plate_number' => $plate_number,
+ 'color' => $color,
+ 'condition' => $condition,
+ 'fuel_type' => $fuel_type,
+ ];
+ }
+ }
+ }
+ else
+ {
+ // customer not found
+ $new_cust = new Customer();
+ $new_cust->setFirstName($first_name)
+ ->setLastName($last_name)
+ ->setPhoneMobile($mobile_number);
+
+ $em->persist($new_cust);
+
+ // add customer vehicle
+ $new_cv = new CustomerVehicle();
+
+ $new_cv->setCustomer($new_cust)
+ ->setPlateNumber($plate_number)
+ ->setStatusCondition($condition)
+ ->setModelYear($model_year)
+ ->setColor($color)
+ ->setFuelType($fuel_type)
+ ->setHasMotoliteBattery(true)
+ ->setVehicle($vehicle);
+
+ $em->persist($new_cv);
+
+ $message = 'Customer and vehicle added.';
+ $data[] = [
+ 'first_name' => $first_name,
+ 'last_name' => $last_name,
+ 'mobile_number' => $mobile_number,
+ 'make_id' => $make_id,
+ 'model_year' => $model_year,
+ 'plate_number' => $plate_number,
+ 'color' => $color,
+ 'condition' => $condition,
+ 'fuel_type' => $fuel_type,
+ ];
+ }
+
+ $em->flush();
+ $em->clear();
+
+ return new APIResponse(true, $message, $data);
+ }
+
+ protected function cleanPlateNumber($plate)
+ {
+ // remove spaces and make upper case
+ return strtoupper(str_replace(' ', '', $plate));
+ }
+
+}
diff --git a/src/Controller/CAPI/WarrantyController.php b/src/Controller/CAPI/WarrantyController.php
index d76afffc..83ecf74a 100644
--- a/src/Controller/CAPI/WarrantyController.php
+++ b/src/Controller/CAPI/WarrantyController.php
@@ -17,10 +17,16 @@ use App\Entity\SAPBattery;
use App\Entity\SAPBatterySize;
use App\Entity\SAPBatteryBrand;
use App\Entity\PrivacyPolicy;
+use App\Entity\Customer;
+use App\Entity\CustomerVehicle;
+use App\Entity\Vehicle;
use App\Ramcar\NameValue;
use App\Ramcar\WarrantyClass;
use App\Ramcar\WarrantyStatus;
+use App\Ramcar\FuelType;
+use App\Ramcar\VehicleStatusCondition;
+
use DateTime;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
@@ -226,6 +232,9 @@ class WarrantyController extends APIController
try
{
$em->persist($warr);
+
+ $this->getCustomerFromMobile($em, $warr);
+
$em->flush();
}
catch (UniqueConstraintViolationException $e)
@@ -488,9 +497,156 @@ class WarrantyController extends APIController
}
$em->persist($warr);
- $em->flush();
return new APIResponse(true, 'Privacy policy for warranty set successfully.');
}
+
+ protected function getCustomerFromMobile($em, $warranty)
+ {
+ $w_mobile = $warranty->getMobileNumber();
+ if (empty($w_mobile))
+ {
+ return null;
+ }
+
+ // set values for new customer vehicle
+ $w_plate_number = $this->cleanPlateNumber($warranty->getPlateNumber());
+
+ $cust_found = false;
+
+ $w_mobile_num = trim($w_mobile);
+
+ // does it fit our 09XXXXXXXXX pattern?
+ if (preg_match('/^09[0-9]{9}$/', $w_mobile_num))
+ {
+ // remove first '0'
+ $w_mobile_num = substr($w_mobile_num, 1);
+ error_log("CONVERTED TO $w_mobile_num");
+ }
+
+ // does it fit our 9XXXXXXXXX pattern?
+ if (!preg_match('/^9[0-9]{9}$/', $w_mobile_num))
+ return null;
+
+ /*
+ // min length 2
+ // TODO: we need to check proper phone number format
+ // format should be '9XXXXXXXXX'
+ // TODO: if format doesn't fit and there's a 0 or 63 prefix, we should be able to detect and convert
+ if (strlen($w_mobile_num <= 2))
+ continue;
+ */
+
+ $customers = $this->findCustomerByNumber($em, $w_mobile_num);
+
+ if (!empty($customers))
+ {
+ error_log('found customer for ' . $w_mobile_num);
+ foreach ($customers as $customer)
+ {
+ // get customer vehicles for customer
+ $c_vehicles = $customer->getVehicles();
+
+ $cv_found = false;
+ if (!empty($c_vehicles))
+ {
+ // check if plate number of customer vehicle matches warranty plate number
+ foreach ($c_vehicles as $c_vehicle)
+ {
+ $clean_cv_plate = $this->cleanPlateNumber($c_vehicle->getPlateNumber());
+
+ // check if it's already there
+ if ($clean_cv_plate == $w_plate_number)
+ {
+ // customer and customer vehicle already exists
+ $cv_found = true;
+ break;
+ }
+ }
+
+ }
+
+ // if there was a customer vehicle matched
+ if ($cv_found)
+ {
+ // vehicle found, do nothing.
+ error_log('vehicle found - ' . $w_plate_number);
+ }
+ else
+ {
+ // customer exists but not customer vehicle
+ // add customer vehicle to existing customer with unknown manufacturer and make
+ error_log('new vehicle - ' . $w_plate_number);
+ $this->createCustomerVehicle($em, $customer, $this->getDefaultVehicle($em), $w_plate_number);
+ }
+ }
+ }
+ // customer not found
+ else
+ {
+ error_log('NEW customer and vehicle - ' . $w_plate_number);
+ // customer not found, add customer and customer vehicle
+ // get warranty first name, last name
+ $w_first_name = $warranty->getFirstName();
+ $w_last_name = $warranty->getLastName();
+
+ $new_cust = new Customer();
+ $new_cust->setFirstName($w_first_name)
+ ->setLastName($w_last_name)
+ ->setPhoneMobile($w_mobile_num);
+
+ $em->persist($new_cust);
+
+ $this->createCustomerVehicle($em, $new_cust, $this->getDefaultVehicle($em), $w_plate_number);
+ }
+
+ $em->flush();
+ $em->clear();
+ }
+
+ protected function getDefaultVehicle($em)
+ {
+ // get default vehicle
+ $cvu_brand_id = $this->getParameter('cvu_brand_id');
+ $default_vehicle = $em->getRepository(Vehicle::class)->find($cvu_brand_id);
+ if ($default_vehicle == null)
+ {
+ $output->writeln("Need to add vehicle with default values.");
+ return null;
+ }
+
+ return $default_vehicle;
+ }
+
+
+ protected function cleanPlateNumber($plate)
+ {
+ // remove spaces and make upper case
+ return strtoupper(str_replace(' ', '', $plate));
+ }
+
+ protected function createCustomerVehicle($em, Customer $cust, $vehicle, $plate_number)
+ {
+ $new_cv = new CustomerVehicle();
+
+ $new_cv->setCustomer($cust)
+ ->setPlateNumber($plate_number)
+ ->setStatusCondition(VehicleStatusCondition::BRAND_NEW)
+ ->setModelYear('')
+ ->setColor('')
+ ->setFuelType(FuelType::GAS)
+ ->setHasMotoliteBattery(true)
+ ->setVehicle($vehicle);
+
+ $em->persist($new_cv);
+ }
+
+
+ protected function findCustomerByNumber($em, $number)
+ {
+ $customers = $em->getRepository(Customer::class)->findBy(['phone_mobile' => $number]);
+ return $customers;
+ }
+
}
diff --git a/src/Controller/ReportController.php b/src/Controller/ReportController.php
index e06d1711..2f72b3fa 100644
--- a/src/Controller/ReportController.php
+++ b/src/Controller/ReportController.php
@@ -14,6 +14,8 @@ use App\Entity\Warranty;
use App\Entity\CustomerVehicle;
use App\Entity\MobileSession;
use App\Entity\Customer;
+use App\Entity\BatteryModel;
+use App\Entity\BatterySize;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
@@ -27,7 +29,6 @@ use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
-use Symfony\Component\Dotenv\Dotenv;
use Catalyst\MenuBundle\Annotation\Menu;
@@ -36,6 +37,8 @@ use DateTime;
class ReportController extends Controller
{
+ const PREREGISTER_PREFIX = '9';
+
/**
* @Menu(selected="outlet_list")
*/
@@ -474,6 +477,7 @@ class ReportController extends Controller
'Plate Number',
'Warranty Create Date',
'Activation Status',
+ 'Warranty Class',
'Has Mobile App?',
'Date Mobile App Downloaded',
'Mobile Number Using Mobile App',
@@ -546,6 +550,181 @@ class ReportController extends Controller
return $resp;
}
+ /**
+ * @Menu(selected="outlet_list")
+ */
+ public function warrantyClassForm()
+ {
+ $this->denyAccessUnlessGranted('report.warranty.class', null, 'No access.');
+ $params['mode'] = 'form';
+
+ return $this->render('report/warranty-class/form.html.twig', $params);
+ }
+
+ /**
+ * @Menu(selected="outlet_list")
+ */
+ public function warrantyClassExportCSV(Request $req, EntityManagerInterface $em)
+ {
+ $data = $this->getWarrantyClassData($em);
+
+ $resp = new StreamedResponse();
+ $resp->setCallback(function() use ($data) {
+ // csv output
+ $csv_handle = fopen('php://output', 'w+');
+ fputcsv($csv_handle, [
+ 'Customer Last Name',
+ 'Customer First Name',
+ 'Vehicle Manufacturer',
+ 'Vehicle Make',
+ 'Model Year',
+ 'Vehicle Color',
+ 'Warranty Serial',
+ 'Warranty Class',
+ 'Plate Number',
+ 'Warranty Last Name',
+ 'Warranty First Name',
+ 'Warranty Mobile Number',
+ 'Warranty Battery Model',
+ 'Warranty Battery Size',
+ 'Warranty SAP Battery',
+ 'Warranty Status',
+ 'Warranty Created',
+ 'Warranty Purchased',
+ 'Warranty Expiry Date',
+ 'Warranty Claim Date',
+ 'Warranty Claimed From',
+ 'Warranty Privacy Policy',
+ 'Is Warranty Activated?',
+ ]);
+ foreach ($data as $row)
+ {
+ fputcsv($csv_handle, $row);
+ }
+
+ fclose($csv_handle);
+ });
+
+ $filename = 'warranty_class_report' . '.csv';
+
+ $resp->setStatusCode(200);
+ $resp->headers->set('Content-Type', 'text/csv; charset=utf-8');
+ $resp->headers->set('Content-Disposition', 'attachment; filename="' . $filename . '"');
+
+ return $resp;
+
+ }
+
+ /**
+ * @Menu(selected="outlet_list")
+ */
+ public function vehicleBatteryCompatibilityForm()
+ {
+ $this->denyAccessUnlessGranted('report.vehicle.battery.compatibility', null, 'No access.');
+ $params['mode'] = 'form';
+
+ return $this->render('report/vehicle-battery-compatibility/form.html.twig', $params);
+ }
+
+ /**
+ * @Menu(selected="outlet_list")
+ */
+ public function vehicleBatteryCompatibilityExportCSV(Request $req, EntityManagerInterface $em)
+ {
+ $data = $this->getVehicleBatteryCompatibilityData($em);
+
+ $resp = new StreamedResponse();
+ $resp->setCallback(function() use ($data) {
+ // csv output
+ $csv_handle = fopen('php://output', 'w+');
+ fputcsv($csv_handle, [
+ 'Vehicle Manufacturer',
+ 'Vehicle Make',
+ 'Vehicle Model Year From',
+ 'Vehicle Model Year To',
+ 'Battery Manufacturer',
+ 'Battery Model',
+ 'Battery Size',
+ 'Battery SAP Code',
+ ]);
+ foreach ($data as $row)
+ {
+ fputcsv($csv_handle, $row);
+ }
+
+ fclose($csv_handle);
+ });
+
+ $filename = 'vehicle_battery_compatibility_report' . '.csv';
+
+ $resp->setStatusCode(200);
+ $resp->headers->set('Content-Type', 'text/csv; charset=utf-8');
+ $resp->headers->set('Content-Disposition', 'attachment; filename="' . $filename . '"');
+
+ return $resp;
+ }
+
+ /**
+ * @Menu(selected="outlet_list")
+ */
+ public function warrantyDetailsForm()
+ {
+ $this->denyAccessUnlessGranted('report.warranty.details', null, 'No access.');
+ $params['mode'] = 'form';
+
+ return $this->render('report/warranty-details/form.html.twig', $params);
+ }
+
+ /**
+ * @Menu(selected="outlet_list")
+ */
+ public function warrantyDetailsExportCSV(Request $resq, EntityManagerInterface $em)
+ {
+ $data = $this->getWarrantyDetailsData($em);
+
+ $resp = new StreamedResponse();
+ $resp->setCallback(function() use ($data) {
+ // csv output
+ $csv_handle = fopen('php://output', 'w+');
+ fputcsv($csv_handle, [
+ 'Warranty ID',
+ 'Serial',
+ 'Battery Model',
+ 'Battery Size',
+ 'Warranty Class',
+ 'Plate Number',
+ 'Status',
+ 'Date Created',
+ 'Date Purchased',
+ 'Expiry Date',
+ 'Date Claimed',
+ 'SAP Battery ID',
+ 'Claim ID',
+ 'Last Name',
+ 'First Name',
+ 'Mobile Number',
+ 'Privacy Policy Number',
+ 'Activated?',
+
+ ]);
+ foreach ($data as $row)
+ {
+ fputcsv($csv_handle, $row);
+ }
+
+ fclose($csv_handle);
+ });
+
+ $filename = 'warranty_details_report' . '.csv';
+
+ $resp->setStatusCode(200);
+ $resp->headers->set('Content-Type', 'text/csv; charset=utf-8');
+ $resp->headers->set('Content-Disposition', 'attachment; filename="' . $filename . '"');
+
+ return $resp;
+
+ }
+
protected function processPopappFile(UploadedFile $csv_file, EntityManagerInterface $em)
{
// attempt to open file
@@ -588,6 +767,7 @@ class ReportController extends Controller
'plate_num' => '',
'warr_date_create' => '',
'warr_activation_status' => '',
+ 'warr_class' => '',
'has_mobile' => '',
'date_mobile' => '',
'mobile_number' => '',
@@ -605,66 +785,68 @@ class ReportController extends Controller
if (!empty($serial))
{
// get the warranty for serial
- $warr_qb = $this->getDoctrine()
- ->getRepository(Warranty::class)
- ->createQueryBuilder('q');
- $warranty_query = $warr_qb->select('q')
- ->where('q.serial = :serial')
- ->setParameter('serial', $serial);
- $warranty = $warranty_query->getQuery()->getOneOrNullResult();
+ $warranties = $em->getRepository(Warranty::class)->findBy(['serial' => $serial]);
- if ($warranty != null)
+ if (!empty($warranties))
{
- $isValid = InvalidPlateNumber::isInvalid($warranty->getPlateNumber());
- if ($isValid)
+ foreach ($warranties as $warranty)
{
- // get customer vehicles using plate number
- $customer_vehicles = $em->getRepository(CustomerVehicle::class)->findBy(['plate_number' => $warranty->getPlateNumber()]);
-
- // check if customer vehicle is empty
- if (count($customer_vehicles) != 0)
+ //error_log('found warranty for serial ' . $serial);
+ $plate_number = $warranty->getPlateNumber();
+ $isValid = InvalidPlateNumber::isInvalid($plate_number);
+ if ($isValid)
{
- $has_mobile = false;
- $mobile_date = '';
- $mobile_number = '';
-
- // get the first customer vehicle, store as best_cv until we find one with a mobile session
- $best_cv = current($customer_vehicles);
-
- foreach($customer_vehicles as $cv)
+ // get customer vehicles using plate number
+ $customer_vehicles = $em->getRepository(CustomerVehicle::class)->findBy(['plate_number' => $plate_number]);
+
+ // check if customer vehicle is empty
+ if (count($customer_vehicles) != 0)
{
- // get mobile session of customer
- //error_log($cv->getCustomer()->getLastName() . ' ' . $cv->getCustomer()->getFirstName());
- $mobile_session = $em->getRepository(MobileSession::class)
- ->findOneBy(['customer' => $cv->getCustomer()->getID()], ['date_generated' => 'ASC']);
- if ($mobile_session != null)
+ //error_log('found customer vehicle for plate number ' . $plate_number);
+ $has_mobile = false;
+ $mobile_date = '';
+ $mobile_number = '';
+
+ // get the first customer vehicle, store as best_cv until we find one with a mobile session
+ $best_cv = current($customer_vehicles);
+
+ foreach($customer_vehicles as $cv)
{
- // get mobile data
- $has_mobile = true;
- $mobile_date = $mobile_session->getDateGenerated()->format("d M Y");
- $mobile_number = $mobile_session->getPhoneNumber();
+ // get mobile session of customer
+ //error_log($cv->getCustomer()->getLastName() . ' ' . $cv->getCustomer()->getFirstName());
+ $cust_id = $cv->getCustomer()->getID();
+ $mobile_session = $em->getRepository(MobileSession::class)
+ ->findOneBy(['customer' => $cust_id], ['date_generated' => 'ASC']);
+ if ($mobile_session != null)
+ {
+ // get mobile data
+ //error_log('found mobile session for customer id ' . $cv->getCustomer()->getID());
+ $has_mobile = true;
+ $mobile_date = $mobile_session->getDateGenerated()->format("d M Y");
+ $mobile_number = $mobile_session->getPhoneNumber();
- // set best_cv to this customer vehicle with mobile session
- $best_cv = $cv;
+ // set best_cv to this customer vehicle with mobile session
+ $best_cv = $cv;
+ }
}
+ // set the customer data in results
+ $results[$key]['cust_id'] = $best_cv->getCustomer()->getID();
+ $results[$key]['cust_lastname'] = $best_cv->getCustomer()->getLastName();
+ $results[$key]['cust_firstname'] = $best_cv->getCustomer()->getFirstName();
+ $results[$key]['cust_mobile_number'] = $best_cv->getCustomer()->getPhoneMobile();
+ $results[$key]['plate_num'] = $best_cv->getPlateNumber();
+ $results[$key]['has_mobile'] = ($has_mobile ? 'Yes' : 'No');
+ $results[$key]['date_mobile'] = $mobile_date;
+ $results[$key]['mobile_number'] = $mobile_number;
}
-
- // set the customer data in results
- $results[$key]['cust_id'] = $best_cv->getCustomer()->getID();
- $results[$key]['cust_lastname'] = $best_cv->getCustomer()->getLastName();
- $results[$key]['cust_firstname'] = $best_cv->getCustomer()->getFirstName();
- $results[$key]['cust_mobile_number'] = $best_cv->getCustomer()->getPhoneMobile();
- $results[$key]['plate_num'] = $best_cv->getPlateNumber();
- $results[$key]['has_mobile'] = ($has_mobile ? 'Yes' : 'No');
- $results[$key]['date_mobile'] = $mobile_date;
- $results[$key]['mobile_number'] = $mobile_number;
}
+ // set the warranty data in results
+ $results[$key]['warr_lastname'] = $warranty->getLastName();
+ $results[$key]['warr_firstname'] = $warranty->getFirstName();
+ $results[$key]['warr_date_create'] = $warranty->getDateCreate()->format("d M Y");
+ $results[$key]['warr_activation_status'] = ($warranty->isActivated() ? 'Active' : 'Inactive');
+ $results[$key]['warr_class'] = $warranty->getWarrantyClass();
}
- // set the warranty data in results
- $results[$key]['warr_lastname'] = $warranty->getLastName();
- $results[$key]['warr_firstname'] = $warranty->getFirstName();
- $results[$key]['warr_date_create'] = $warranty->getDateCreate()->format("d M Y");
- $results[$key]['warr_activation_status'] = ($warranty->isActivated() ? 'Active' : 'Inactive');
}
}
}
@@ -719,6 +901,265 @@ class ReportController extends Controller
}
return $results;
+ }
+
+ protected function getWarrantyClassData(EntityManagerInterface $em)
+ {
+ $results = [];
+
+ // query preregistered ustomers using search term '%9'
+ $cust_query = $em->createQuery('select c from App\Entity\Customer c where c.phone_mobile like :search_mobile')
+ ->setParameter('search_mobile', "%" . self::PREREGISTER_PREFIX);
+ $customers = $cust_query->iterate();
+
+ foreach($customers as $crow)
+ {
+ $cust = $crow[0];
+ //error_log('Processing customer ' . $cust->getID());
+
+ // get list of customer vehicles
+ $c_vehicles = $cust->getVehicles();
+
+ foreach($c_vehicles as $cv)
+ {
+ if (!empty($c_vehicles))
+ {
+ // find warranty for plate number
+ $clean_cv_plate = $this->cleanPlateNumber($cv->getPlateNumber());
+
+ $warranties = $em->getRepository(Warranty::class)->findBy(['plate_number' => $clean_cv_plate]);
+
+ foreach ($warranties as $warr)
+ {
+ //error_log('Found warranty for plate number ' . $warr->getPlateNumber());
+
+ // form the result row
+ $results[] = $this->formWarrantyClassResult($cust, $cv, $warr);
+ }
+ }
+ }
+ $em->clear();
+
+ }
+
+ return $results;
+ }
+
+ protected function cleanPlateNumber($plate)
+ {
+ // remove spaces and make upper case
+ return strtoupper(str_replace(' ', '', $plate));
+ }
+
+ protected function formWarrantyClassResult($cust, $cv, $warr)
+ {
+ $batt_model = '';
+ $batt_size = '';
+ $sap_batt = '';
+ $policy = '';
+ $date_purchased = '';
+ $date_expire = '';
+ $date_claim = '';
+
+ $create_date = $warr->getDateCreate();
+ $date_create = $create_date->format('d/M/y');
+
+ if ($warr->getDatePurchase() != null)
+ {
+ $p_date = $warr->getDatePurchase();
+ $date_purchased = $p_date->format('d/M/y');
+ }
+ if ($warr->getDateClaim() != null)
+ {
+ $c_date = $warr->getDateClaim();
+ $date_claim = $c_date->format('d/M/y');
+ }
+ if ($warr->getDateExpire() != null)
+ {
+ $e_date = $warr->getDateExpire();
+ $date_expire = $e_date->format('d/M/y');
+ }
+
+ if ($warr->getBatteryModel() != null)
+ {
+ $batt_model = $warr->getBatteryModel()->getName();
+ }
+ if ($warr->getBatterySize() != null)
+ {
+ $batt_size = $warr->getBatterySize()->getName();
+ }
+ if ($warr->getSAPBattery() != null)
+ {
+ $sap_batt = $warr->getSAPBattery()->getBrand()->getName();
+ }
+ if ($warr->getPrivacyPolicy() != null)
+ {
+ $policy = $warr->getPrivacyPolicy()->getName();
+ }
+
+ $data = [
+ 'c_last_name' => $cust->getLastName(),
+ 'c_first_name' => $cust->getFirstName(),
+ 'manufacturer' => $cv->getVehicle()->getManufacturer()->getName(),
+ 'make' => $cv->getVehicle()->getMake(),
+ 'model_year' => $cv->getModelYear(),
+ 'color' => $cv->getColor(),
+ 'serial' => $warr->getSerial(),
+ 'class' => $warr->getWarrantyClass(),
+ 'plate_number' => $warr->getPlateNumber(),
+ 'w_last_name' => $warr->getLastName(),
+ 'w_first_name' => $warr->getFirstName(),
+ 'w_mobile_num' => $warr->getMobileNumber(),
+ 'w_batt_model' => $batt_model,
+ 'w_batt_size' => $batt_size,
+ 'w_sap_batt' => $sap_batt,
+ 'w_status' => $warr->getStatus(),
+ 'w_date_create' => $date_create,
+ 'w_date_purchase' => $date_purchased,
+ 'w_date_expire' => $date_expire,
+ 'w_date_claim' => $date_claim,
+ 'w_claimed_from' => $warr->getClaimedFrom(),
+ 'w_privacy_policy' => $policy,
+ 'w_activated' => ($warr->isActivated() ? 'Active' : 'Inactive'),
+ ];
+
+ return $data;
}
+
+ protected function getVehicleBatteryCompatibilityData(EntityManagerInterface $em)
+ {
+ $results = [];
+
+ $conn = $em->getConnection();
+ $sql = 'SELECT vm.name AS vm_name, v.make,
+ v.model_year_from, v.model_year_to,
+ bm.name AS bm_name, bmodel.name AS bmodel_name,
+ bsize.name AS bsize_name,
+ b.sap_code
+ FROM vehicle_manufacturer vm, vehicle v, battery_vehicle bv,
+ battery b, battery_manufacturer bm, battery_model bmodel,
+ battery_size bsize
+ WHERE vm.id = v.manufacturer_id
+ AND v.id = bv.vehicle_id
+ AND bv.battery_id = b.id
+ AND b.manufacturer_id = bm.id
+ AND b.model_id = bmodel.id
+ AND b.size_id = bsize.id
+ ORDER BY vm.name, v.make';
+
+ $stmt = $conn->prepare($sql);
+ $stmt->execute();
+
+ $query_results = $stmt->fetchAll();
+
+ foreach($query_results as $row)
+ {
+ $results[] = [
+ 'vehicle_manufacturer' => $row['vm_name'],
+ 'vehicle_make' => $row['make'],
+ 'vehicle_model_year_from' => $row['model_year_from'],
+ 'vehicle_model_year_to' => $row['model_year_to'],
+ 'battery_manufacturer' => $row['bm_name'],
+ 'battery_model' => $row['bmodel_name'],
+ 'battery_size' => $row['bsize_name'],
+ 'battery_sap_code' => $row['sap_code'],
+ ];
+ }
+
+ return $results;
+ }
+
+ protected function getWarrantyDetailsData(EntityManagerInterface $em)
+ {
+ $bm_hash = $this->loadBatteryModels($em);
+ $bs_hash = $this->loadBatterySizes($em);
+
+ $results = [];
+
+ $conn = $em->getConnection();
+ $sql = 'SELECT w.id, w.serial, w.warranty_class, w.plate_number,
+ w.status, w.date_create, w.date_purchase, w.date_expire,
+ w.date_claim, w.sap_bty_id, w.claim_id, w.first_name,
+ w.last_name, w.mobile_number, w.flag_activated,
+ w.warranty_privacy_policy, w.bty_model_id, w.bty_size_id
+ FROM warranty w';
+
+ $stmt = $conn->prepare($sql);
+ $stmt->execute();
+
+ $query_results = $stmt->fetchAll();
+
+ foreach ($query_results as $row)
+ {
+ // get battery model and size names
+ $bmodel_name = '';
+ $bm_id = $row['bty_model_id'];
+ if (!empty($bm_id))
+ {
+ if (isset($bm_hash[$bm_id]))
+ $bmodel_name = $bm_hash[$bm_id];
+ }
+
+ $bsize_name = '';
+ $bs_id = $row['bty_size_id'];
+ if (!empty($bs_id))
+ {
+ if (isset($bs_hash[$bs_id]))
+ $bsize_name = $bs_hash[$bs_id];
+ }
+
+ $results[] = [
+ 'id' => $row['id'],
+ 'serial' => $row['serial'],
+ 'battery_model' => $bmodel_name,
+ 'battery_size' => $bsize_name,
+ 'warranty_class' => $row['warranty_class'],
+ 'plate_number' => $row['plate_number'],
+ 'status' => $row['status'],
+ 'date_create' => $row['date_create'],
+ 'date_purchase' => $row['date_purchase'],
+ 'date_expire' => $row['date_expire'],
+ 'date_claim' => $row['date_claim'],
+ 'sap_bty_id' => $row['sap_bty_id'],
+ 'claim_id' => $row['claim_id'],
+ 'last_name' => $row['last_name'],
+ 'first_name' => $row['first_name'],
+ 'mobile_number' => $row['mobile_number'],
+ 'privacy_policy' => $row['warranty_privacy_policy'],
+ 'flag_activated' => (boolean) $row['flag_activated'],
+ ];
+ }
+
+ return $results;
+ }
+
+ protected function loadBatteryModels(EntityManagerInterface $em)
+ {
+ $bmodel_hash = [];
+
+ $models = $em->getRepository(BatteryModel::class)->findAll();
+ foreach ($models as $model)
+ {
+ $bmodel_id = $model->getID();
+ $bmodel_hash[$bmodel_id] = $model->getName();
+ }
+
+ return $bmodel_hash;
+ }
+
+ protected function loadBatterySizes(EntityManagerInterface $em)
+ {
+ $bsize_hash = [];
+
+ $sizes = $em->getRepository(BatterySize::class)->findAll();
+ foreach ($sizes as $size)
+ {
+ $bsize_id = $size->getID();
+ $bsize_hash[$bsize_id] = $size->getName();
+ }
+
+ return $bsize_hash;
+ }
+
}
diff --git a/src/Controller/StaticContentController.php b/src/Controller/StaticContentController.php
new file mode 100644
index 00000000..395736d4
--- /dev/null
+++ b/src/Controller/StaticContentController.php
@@ -0,0 +1,289 @@
+denyAccessUnlessGranted('static_content.list', null, 'No access.');
+
+ return $this->render('static-content/list.html.twig');
+ }
+
+ public function rows(Request $req)
+ {
+ $this->denyAccessUnlessGranted('static_content.list', null, 'No access.');
+
+ // build query
+ $qb = $this->getDoctrine()
+ ->getRepository(StaticContent::class)
+ ->createQueryBuilder('q');
+
+ // get datatable params
+ $datatable = $req->request->get('datatable');
+
+ // count total records
+ $tquery = $qb->select('COUNT(q)');
+
+ // add fitlers to count query
+ $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');
+
+ // add filters to query
+ $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();
+
+ // add row metadata
+ $row['meta'] = [
+ 'update_url' => '',
+ 'delete_url' => ''
+ ];
+
+ // add crud urls
+ if ($this->isGranted('static_content.update'))
+ $row['meta']['update_url'] = $this->generateUrl('static_content_update', ['id' => $row['id']]);
+ if ($this->isGranted('static_content.delete'))
+ $row['meta']['delete_url'] = $this->generateUrl('static_content_delete', ['id' => $row['id']]);
+
+ $rows[] = $row;
+ }
+
+ // response
+ return $this->json([
+ 'meta' => $meta,
+ 'data' => $rows
+ ]);
+ }
+
+ /**
+ * @Menu(selected="static_content_list")
+ */
+ public function addForm()
+ {
+ $this->denyAccessUnlessGranted('static_content.add', null, 'No access.');
+
+ $params = [];
+ $params['obj'] = new StaticContent();
+ $params['mode'] = 'create';
+
+ // response
+ return $this->render('static-content/form.html.twig', $params);
+ }
+
+ public function addSubmit(Request $req, ValidatorInterface $validator)
+ {
+ $this->denyAccessUnlessGranted('static_content.add', null, 'No access.');
+
+ // create new object
+ $em = $this->getDoctrine()->getManager();
+ $row = new StaticContent();
+
+ // set and save values
+ $id = $req->request->get('id');
+ $row->setID($id);
+ $row->setContent($req->request->get('content'));
+
+ // validate
+ $errors = $validator->validate($row);
+
+ // initialize error list
+ $error_array = [];
+
+ // check for duplicate ID
+ $result = $em->getRepository(StaticContent::class)->find($id);
+ if ($result != null)
+ {
+ error_log($id);
+ $error_array['id'] = 'Duplicate ID exists.';
+ }
+
+ // 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);
+ } else {
+ // validated! save the entity
+ $em->persist($row);
+ $em->flush();
+
+ // return successful response
+ return $this->json([
+ 'success' => 'Changes have been saved!'
+ ]);
+ }
+ }
+
+ /**
+ * @Menu(selected="static_content_list")
+ */
+ public function updateForm($id)
+ {
+ $this->denyAccessUnlessGranted('static_content.update', null, 'No access.');
+
+ $params = [];
+ $params['mode'] = 'update';
+
+ // get row data
+ $em = $this->getDoctrine()->getManager();
+ $row = $em->getRepository(StaticContent::class)->find($id);
+
+ // make sure this row exists
+ if (empty($row))
+ throw $this->createNotFoundException('The item does not exist');
+
+ $params['obj'] = $row;
+
+ // response
+ return $this->render('static-content/form.html.twig', $params);
+ }
+
+ public function updateSubmit(Request $req, ValidatorInterface $validator, $id)
+ {
+ $this->denyAccessUnlessGranted('static_content.update', null, 'No access.');
+
+ // get row data
+ $em = $this->getDoctrine()->getManager();
+ $row = $em->getRepository(StaticContent::class)->find($id);
+
+ // make sure this row exists
+ if (empty($row))
+ throw $this->createNotFoundException('The item does not exist');
+
+ // set and save values
+ $row->setID($req->request->get('id'))
+ ->setContent($req->request->get('content'));
+
+ // validate
+ $errors = $validator->validate($row);
+
+ // initialize error list
+ $error_array = [];
+
+ // check for duplicate ID
+ $result = $em->getRepository(StaticContent::class)->find($id);
+ if ($result != null)
+ {
+ error_log($id);
+ $error_array['id'] = 'Duplicate ID exists.';
+ }
+
+ // 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);
+ } else {
+ // validated! save the entity
+ $em->flush();
+
+ // return successful response
+ return $this->json([
+ 'success' => 'Changes have been saved!'
+ ]);
+ }
+ }
+
+ /**
+ * @Menu(selected="static_content_list")
+ */
+ public function destroy($id)
+ {
+ $this->denyAccessUnlessGranted('static_content.delete', null, 'No access.');
+
+ $params = [];
+
+ // get row data
+ $em = $this->getDoctrine()->getManager();
+ $row = $em->getRepository(StaticContent::class)->find($id);
+
+ if (empty($row))
+ throw $this->createNotFoundException('The item does not exist');
+
+ // delete this row
+ $em->remove($row);
+ $em->flush();
+
+ // response
+ $response = new Response();
+ $response->setStatusCode(Response::HTTP_OK);
+ $response->send();
+ }
+
+ protected function setQueryFilters($datatable, &$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'] . '%');
+ }
+ }
+}
diff --git a/src/Controller/WarrantyController.php b/src/Controller/WarrantyController.php
index 0dc5a43e..40afec1a 100644
--- a/src/Controller/WarrantyController.php
+++ b/src/Controller/WarrantyController.php
@@ -4,15 +4,23 @@ namespace App\Controller;
use App\Entity\Warranty;
use App\Entity\SAPBattery;
+use App\Entity\Battery;
use App\Entity\BatteryModel;
use App\Entity\BatterySize;
+use App\Entity\Invoice;
+use App\Entity\CustomerVehicle;
use App\Ramcar\WarrantyClass;
use App\Ramcar\WarrantyStatus;
+use App\Service\WarrantyHandler;
+
use Doctrine\ORM\Query;
+use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\StreamedResponse;
+use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
@@ -22,6 +30,11 @@ use Catalyst\MenuBundle\Annotation\Menu;
class WarrantyController extends Controller
{
+ const PURCHASE_DATE_EMPTY = 'Purchase date missing.';
+ const PLATE_NUM_EMPTY = 'Plate number missing.';
+ const SERIAL_EMPTY = 'Serial number missing.';
+ const PURCHASE_DATE_INVALID = 'Invalid purchase date.';
+
/**
* @Menu(selected="warranty_list")
*/
@@ -348,9 +361,239 @@ class WarrantyController extends Controller
'success' => 'Changes have been saved!'
]);
}
-
}
+ /**
+ * @Menu(selected="warranty_list")
+ */
+ public function uploadForm()
+ {
+ $this->denyAccessUnlessGranted('warranty.upload', null, 'No access.');
+
+ return $this->render('warranty/upload.form.html.twig');
+ }
+
+ /**
+ * @Menu(selected="warranty_list")
+ */
+ public function uploadSubmit(Request $req, EntityManagerInterface $em,
+ WarrantyHandler $wh)
+ {
+ // retrieve temporary info for file
+ $file = $req->files->get('csv_file');
+
+ // process the csv file
+ $inv_entries = $this->processWarrantyFile($file, $em, $wh);
+
+ $resp = new StreamedResponse();
+ $resp->setCallback(function() use($inv_entries) {
+ // csv output
+ $csv_handle = fopen('php://output', 'w+');
+ fputcsv($csv_handle, [
+ 'Owner First Name',
+ 'Owner Last Name',
+ 'Owner Email',
+ 'Owner Address',
+ 'Owner Mobile',
+ 'Owner Telephone',
+ 'Vehicle Make',
+ 'Vehicle Model',
+ 'Vehicle Year',
+ 'Vehicle Plate Number',
+ 'Battery Serial Number',
+ 'Battery Sales Invoice',
+ 'Battery Date of Purchase',
+ 'Distributor Name',
+ 'Distributor Address',
+ 'Application Type ID',
+ 'Battery ID',
+ 'Ownership Type',
+ 'Reason Warranty Not Added',
+ ]);
+ foreach ($inv_entries as $row)
+ {
+ fputcsv($csv_handle, $row);
+ }
+
+ fclose($csv_handle);
+ });
+
+ $filename = 'invalid_warranties' . '.csv';
+
+ $resp->setStatusCode(200);
+ $resp->headers->set('Content-Type', 'text/csv; charset=utf-8');
+ $resp->headers->set('Content-Disposition', 'attachment; filename="' . $filename . '"');
+
+ return $resp;
+ }
+
+ protected function processWarrantyFile(UploadedFile $csv_file, EntityManagerInterface $em,
+ WarrantyHandler $wh)
+ {
+ // attempt to open file
+ try
+ {
+ $fh = fopen($csv_file, "r");
+ }
+ catch (Exception $e)
+ {
+ throw new Exception('The file "' . $csv_file . '" could be read.');
+ }
+
+ // loop through the rows
+ // 0 - Owner First Name
+ // 1 - Owner Last Name
+ // 2 - Owner Email
+ // 3 - Owner Address
+ // 4 - Owner Mobile
+ // 5 - Owner Telephone
+ // 6 - Vehicle Make
+ // 7 - Vehicle Model
+ // 8 - Vehicle Year
+ // 9 - Vehicle Plate Number
+ // 10 - Battery Serial Number
+ // 11 - Battery Sales Invoice
+ // 12 - Battery Date of Purchase
+ // 13 - Distributor Name
+ // 14 - Distributor Address
+ // 15 - Application Type ID
+ // 16 - Battery ID
+ // 17 - Ownership Type
+
+ $row_num = 0;
+ $invalid_entries = [];
+ while (($fields = fgetcsv($fh)) !== false)
+ {
+ // start processing at row 1, not 0
+ if ($row_num < 1)
+ {
+ $row_num++;
+ continue;
+ }
+
+ // get the data
+ $first_name = trim($fields[0]);
+ $last_name = trim($fields[1]);
+ $mobile_number = trim($fields[4]);
+ $plate = trim($fields[9]);
+ $serial = trim($fields[10]);
+ $purchase_date = trim($fields[12]);
+ $battery_id = trim($fields[16]);
+ $batt_invoice = trim($fields[11]);
+
+ $plate_number = $wh->cleanPlateNumber($plate);
+
+ // check if purchase_date or plate_number or serial is empty or if
+ // purchase date is valid
+ $date_purchase = DateTime::createFromFormat('d-M-y', $purchase_date);
+
+ if (empty($purchase_date) ||
+ empty($plate_number) ||
+ empty($serial) ||
+ ($date_purchase == false))
+ {
+ $reason = '';
+ if (empty($plate_number))
+ $reason = $reason . self::PLATE_NUM_EMPTY . ' ';
+ if (empty($serial))
+ $reason = $reason . self::SERIAL_EMPTY . ' ';
+ if (empty($purchase_date))
+ $reason = $reason . self::PURCHASE_DATE_EMPTY . ' ';
+ else
+ {
+ if ($date_purchase == false)
+ $reason = $reason . self::PURCHASE_DATE_INVALID . ' ';
+ }
+
+ // add to invalid_entries
+ $invalid_entries[] = [
+ 'owner_first_name' => $first_name,
+ 'owner_last_name' => $last_name,
+ 'owner_email' => trim($fields[2]),
+ 'owner_address' => trim($fields[3]),
+ 'owner_mobile' => $mobile_number,
+ 'owner_telephone' => trim($fields[5]),
+ 'vehicle_make' => trim($fields[6]),
+ 'vehicle_model' => trim($fields[7]),
+ 'vehicle_year' => trim($fields[8]),
+ 'vehicle_plate_number' => $plate_number,
+ 'battery_serial_number' => $serial,
+ 'battery_sales_invoice' => $batt_invoice,
+ 'battery_date_purchase' => $purchase_date,
+ 'distributor_name' => trim($fields[13]),
+ 'distributor_address' => trim($fields[14]),
+ 'application_type_id' => trim($fields[15]),
+ 'battery_id' => $battery_id,
+ 'ownership_type' => trim($fields[17]),
+ 'reason' => $reason,
+ ];
+ }
+ else
+ {
+ // additional validation
+ // check if serial number and plate number already exists
+ $warr_results = $em->getRepository(Warranty::class)->findBy(['serial' => $serial, 'plate_number' => $plate_number]);
+
+ // get battery via the invoice because battery_id doesn't match what's in the live data
+ // get job order via invoice to get the warranty class
+ $warranty_class = '';
+ $batt_list = array();
+
+ // find invoice
+ $invoice = $em->getRepository(Invoice::class)->find($batt_invoice);
+ if (!empty($invoice))
+ {
+ // get job order
+ $jo = $invoice->getJobOrder();
+
+ // get warranty class
+ $warranty_class = $jo->getWarrantyClass();
+
+ // get battery
+ $invoice_items = $invoice->getItems();
+ foreach ($invoice_items as $item)
+ {
+ $battery = $item->getBattery();
+ if ($battery != null)
+ {
+ $batt_list[] = $item->getBattery();
+ }
+ }
+ }
+
+ if (!empty($warr_results))
+ {
+ foreach($warr_results as $warr)
+ {
+ // call service to check if warranty details is incomplete and then update warranty
+ // using details from csv file
+ error_log('Updating warranty for ' . $warr->getID());
+ $wh->updateWarranty($warr, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase);
+ }
+ }
+ else
+ {
+ // TODO: what if serial exists but plate number is different?
+ // check if just the serial exists
+ // if warranty exists, ignore for now
+ $w_results = $em->getRepository(Warranty::class)->findBy(['serial' => $serial]);
+ if (!empty($w_results))
+ {
+ continue;
+ }
+
+ error_log('Creating warranty for serial ' . $serial . ' and plate number ' . $plate_number);
+
+ $wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
+ }
+ }
+
+ $em->clear();
+ $row_num++;
+ }
+
+ return $invalid_entries;
+ }
protected function fillDropdownParameters(&$params)
{
@@ -371,4 +614,10 @@ class WarrantyController extends Controller
->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%');
}
}
+
+ protected function cleanPlateNumber($plate)
+ {
+ // remove spaces and make upper case
+ return strtoupper(str_replace(' ', '', $plate));
+ }
}
diff --git a/src/Entity/BatteryModel.php b/src/Entity/BatteryModel.php
index 86f3b666..b516e8a6 100644
--- a/src/Entity/BatteryModel.php
+++ b/src/Entity/BatteryModel.php
@@ -68,6 +68,7 @@ class BatteryModel
public function getBatteries()
{
+ // TODO: fix this to be a proper getter function
// has to return set of strings because symfony is trying to move away from role objects
$str_batteries = [];
foreach ($this->batteries as $battery)
diff --git a/src/Entity/BatterySize.php b/src/Entity/BatterySize.php
index 021e115c..9fff4d44 100644
--- a/src/Entity/BatterySize.php
+++ b/src/Entity/BatterySize.php
@@ -89,6 +89,7 @@ class BatterySize
public function getBatteries()
{
+ // TODO: fix this to be a proper getter function
// has to return set of strings because symfony is trying to move away from role objects
$str_batteries = [];
foreach ($this->batteries as $battery)
diff --git a/src/Entity/Customer.php b/src/Entity/Customer.php
index 5ae565a5..b96dfae9 100644
--- a/src/Entity/Customer.php
+++ b/src/Entity/Customer.php
@@ -10,13 +10,10 @@ use App\Ramcar\CustomerClassification;
/**
* @ORM\Entity
- * @ORM\Table(name="customer")
+ * @ORM\Table(name="customer", indexes={@ORM\Index(name="phone_mobile_idx", columns={"phone_mobile"})})
*/
class Customer
{
- // TODO: make this a setting somewhere
- const COUNTRY_CODE_PREFIX = '+60';
-
// unique id
/**
* @ORM\Id
@@ -266,16 +263,16 @@ class Customer
$phones = [];
if (!empty($this->phone_mobile))
- $phones[] = self::COUNTRY_CODE_PREFIX . $this->phone_mobile;
+ $phones[] = $this->phone_mobile;
if (!empty($this->phone_landline))
- $phones[] = self::COUNTRY_CODE_PREFIX . $this->phone_landline;
+ $phones[] = $this->phone_landline;
if (!empty($this->phone_office))
- $phones[] = self::COUNTRY_CODE_PREFIX . $this->phone_office;
+ $phones[] = $this->phone_office;
if (!empty($this->phone_fax))
- $phones[] = self::COUNTRY_CODE_PREFIX . $this->phone_fax;
+ $phones[] = $this->phone_fax;
return $phones;
}
diff --git a/src/Entity/CustomerVehicle.php b/src/Entity/CustomerVehicle.php
index 4f593ac3..a5525a38 100644
--- a/src/Entity/CustomerVehicle.php
+++ b/src/Entity/CustomerVehicle.php
@@ -10,7 +10,8 @@ use DateTime;
/**
* @ORM\Entity
- * @ORM\Table(name="customer_vehicle", indexes={@ORM\Index(columns={"plate_number"}, flags={"fulltext"})})
+ * @ORM\Table(name="customer_vehicle", indexes={@ORM\Index(columns={"plate_number"}, flags={"fulltext"}),
+ @ORM\Index(name="plate_number_idx", columns={"plate_number"})})
*/
class CustomerVehicle
{
@@ -54,7 +55,6 @@ class CustomerVehicle
// model year
/**
* @ORM\Column(type="smallint")
- * @Assert\NotBlank()
*/
protected $model_year;
diff --git a/src/Entity/StaticContent.php b/src/Entity/StaticContent.php
new file mode 100644
index 00000000..b450bb2a
--- /dev/null
+++ b/src/Entity/StaticContent.php
@@ -0,0 +1,54 @@
+id = $id;
+ return $this;
+ }
+
+ public function getID()
+ {
+ return $this->id;
+ }
+
+ public function setContent($content)
+ {
+ $this->content = $content;
+ return $this;
+ }
+
+ public function getContent()
+ {
+ return $this->content;
+ }
+}
+
diff --git a/src/Entity/Warranty.php b/src/Entity/Warranty.php
index 605d81ce..113fbb93 100644
--- a/src/Entity/Warranty.php
+++ b/src/Entity/Warranty.php
@@ -14,7 +14,8 @@ use Exception;
* name="warranty",
* uniqueConstraints={
* @ORM\UniqueConstraint(columns={"serial"})
- * }
+ * },
+ * indexes={@ORM\Index(name="plate_number_idx", columns={"plate_number"})})
* )
*/
class Warranty
diff --git a/src/Service/CustomerHandler/CMBCustomerHandler.php b/src/Service/CustomerHandler/CMBCustomerHandler.php
index a0f3ca2e..fb6a888e 100644
--- a/src/Service/CustomerHandler/CMBCustomerHandler.php
+++ b/src/Service/CustomerHandler/CMBCustomerHandler.php
@@ -25,17 +25,17 @@ use DateTime;
class CMBCustomerHandler implements CustomerHandlerInterface
{
- const COUNTRY_CODE_PREFIX = '+60';
-
protected $em;
protected $validator;
-
+ protected $country_code;
protected $template_hash;
- public function __construct(EntityManagerInterface $em, ValidatorInterface $validator)
+ public function __construct(EntityManagerInterface $em, ValidatorInterface $validator,
+ string $country_code)
{
$this->em = $em;
$this->validator = $validator;
+ $this->country_code = $country_code;
$this->loadTemplates();
}
@@ -121,7 +121,14 @@ class CMBCustomerHandler implements CustomerHandlerInterface
$row['flag_csat'] = $orow->isCSAT();
// TODO: properly add mobile numbers and plate numbers as searchable/sortable fields, use doctrine events
- $row['mobile_numbers'] = implode("
", $orow->getMobileNumberList());
+ // prepend the country code before each mobile number
+ $mobile_number_list = [];
+ $mobile_numbers = $orow->getMobileNumberList();
+ foreach ($mobile_numbers as $mobile_number)
+ {
+ $mobile_number_list[] = $this->country_code . $mobile_number;
+ }
+ $row['mobile_numbers'] = implode("
", $mobile_number_list);
$row['plate_numbers'] = implode("
", $orow->getPlateNumberList());
$rows[] = $row;
@@ -467,7 +474,7 @@ class CMBCustomerHandler implements CustomerHandlerInterface
$cust = $cv->getCustomer();
$vehicles[] = [
'id' => $cv->getID(),
- 'text' => $cv->getPlateNumber() . ' ' . $cust->getFirstName() . ' ' . $cust->getLastName() . ' ('. self::COUNTRY_CODE_PREFIX . $cust->getPhoneMobile() . ')',
+ 'text' => $cv->getPlateNumber() . ' ' . $cust->getFirstName() . ' ' . $cust->getLastName() . ' ('. $this->country_code . $cust->getPhoneMobile() . ')',
];
}
diff --git a/src/Service/CustomerHandler/ResqCustomerHandler.php b/src/Service/CustomerHandler/ResqCustomerHandler.php
index 8ea688cf..5f7e00e2 100644
--- a/src/Service/CustomerHandler/ResqCustomerHandler.php
+++ b/src/Service/CustomerHandler/ResqCustomerHandler.php
@@ -27,17 +27,17 @@ use DateTime;
class ResqCustomerHandler implements CustomerHandlerInterface
{
- const COUNTRY_CODE_PREFIX = '+63';
-
protected $em;
protected $validator;
-
+ protected $country_code;
protected $template_hash;
- public function __construct(EntityManagerInterface $em, ValidatorInterface $validator)
+ public function __construct(EntityManagerInterface $em, ValidatorInterface $validator,
+ string $country_code)
{
$this->em = $em;
$this->validator = $validator;
+ $this->country_code = $country_code;
$this->loadTemplates();
}
@@ -124,7 +124,14 @@ class ResqCustomerHandler implements CustomerHandlerInterface
$row['flag_csat'] = $orow->isCSAT();
// TODO: properly add mobile numbers and plate numbers as searchable/sortable fields, use doctrine events
- $row['mobile_numbers'] = implode("
", $orow->getMobileNumberList());
+ // prepend the country code before each mobile number
+ $mobile_number_list = [];
+ $mobile_numbers = $orow->getMobileNumberList();
+ foreach ($mobile_numbers as $mobile_number)
+ {
+ $mobile_number_list[] = $this->country_code . $mobile_number;
+ }
+ $row['mobile_numbers'] = implode("
", $mobile_number_list);
$row['plate_numbers'] = implode("
", $orow->getPlateNumberList());
$rows[] = $row;
@@ -465,7 +472,7 @@ class ResqCustomerHandler implements CustomerHandlerInterface
$cust = $cv->getCustomer();
$vehicles[] = [
'id' => $cv->getID(),
- 'text' => $cv->getPlateNumber() . ' ' . $cust->getFirstName() . ' ' . $cust->getLastName() . ' ('. self::COUNTRY_CODE_PREFIX . $cust->getPhoneMobile() . ')',
+ 'text' => $cv->getPlateNumber() . ' ' . $cust->getFirstName() . ' ' . $cust->getLastName() . ' ('. $this->country_code . $cust->getPhoneMobile() . ')',
];
}
diff --git a/src/Service/GeofenceTracker.php b/src/Service/GeofenceTracker.php
index b2052e02..5acc7564 100644
--- a/src/Service/GeofenceTracker.php
+++ b/src/Service/GeofenceTracker.php
@@ -11,25 +11,33 @@ use CrEOF\Spatial\PHP\Types\Geometry\Point;
class GeofenceTracker
{
protected $em;
+ protected $geofence_flag;
- public function __construct(EntityManagerInterface $em)
+ public function __construct(EntityManagerInterface $em, $geofence_flag)
{
$this->em = $em;
+ $this->geofence_flag = $geofence_flag;
}
public function isCovered($long, $lat)
{
- // see if the point is in any of the polygons
- $query = $this->em->createQuery('SELECT count(s) from App\Entity\SupportedArea s where st_contains(s.coverage_area, point(:long, :lat)) = true')
- ->setParameter('long', $long)
- ->setParameter('lat', $lat);
+ // check if geofence is enabled
+ if ($this->geofence_flag == 'true')
+ {
+ // see if the point is in any of the polygons
+ $query = $this->em->createQuery('SELECT count(s) from App\Entity\SupportedArea s where st_contains(s.coverage_area, point(:long, :lat)) = true')
+ ->setParameter('long', $long)
+ ->setParameter('lat', $lat);
- // number of polygons that contain the point
- $count = $query->getSingleScalarResult();
+ // number of polygons that contain the point
+ $count = $query->getSingleScalarResult();
- if ($count > 0)
- return true;
+ if ($count > 0)
+ return true;
- return false;
+ return false;
+ }
+
+ return true;
}
}
diff --git a/src/Service/JobOrderHandler/CMBJobOrderHandler.php b/src/Service/JobOrderHandler/CMBJobOrderHandler.php
index 1e4d8f9f..89dc9663 100644
--- a/src/Service/JobOrderHandler/CMBJobOrderHandler.php
+++ b/src/Service/JobOrderHandler/CMBJobOrderHandler.php
@@ -55,20 +55,20 @@ use FPDF;
class CMBJobOrderHandler implements JobOrderHandlerInterface
{
- const COUNTRY_CODE_PREFIX = '+60';
-
protected $em;
protected $ic;
protected $security;
protected $validator;
protected $translator;
protected $rah;
+ protected $country_code;
protected $template_hash;
public function __construct(Security $security, EntityManagerInterface $em,
InvoiceGeneratorInterface $ic, ValidatorInterface $validator,
- TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah)
+ TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah,
+ string $country_code)
{
$this->em = $em;
$this->ic = $ic;
@@ -76,6 +76,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$this->validator = $validator;
$this->translator = $translator;
$this->rah = $rah;
+ $this->country_code = $country_code;
$this->loadTemplates();
}
@@ -1860,7 +1861,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$pdf->SetXY($col2_x, $y);
$pdf->Cell($label_width, $line_height, 'Mobile Phone:');
- $pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneMobile() ? self::COUNTRY_CODE_PREFIX . $customer->getPhoneMobile() : '', 0, 'L');
+ $pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneMobile() ? $this->country_code . $customer->getPhoneMobile() : '', 0, 'L');
// get Y after right cell
$y2 = $pdf->GetY();
@@ -1877,7 +1878,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$pdf->SetXY($col2_x, $y);
$pdf->Cell($label_width, $line_height, 'Landline:');
- $pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneLandline() ? self::COUNTRY_CODE_PREFIX . $customer->getPhoneLandline() : '', 0, 'L');
+ $pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneLandline() ? $this->country_code . $customer->getPhoneLandline() : '', 0, 'L');
// get Y after right cell
$y2 = $pdf->GetY();
@@ -1887,11 +1888,11 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$pdf->SetXY($col2_x, $y);
$pdf->Cell($label_width, $line_height, 'Office Phone:');
- $pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneOffice() ? self::COUNTRY_CODE_PREFIX . $customer->getPhoneOffice() : '', 0, 'L');
+ $pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneOffice() ? $this->country_code . $customer->getPhoneOffice() : '', 0, 'L');
$pdf->SetX($col2_x);
$pdf->Cell($label_width, $line_height, 'Fax:');
- $pdf->MultiCell($val_width, $line_height, $customer && $customer->getPhoneFax() ? self::COUNTRY_CODE_PREFIX . $customer->getPhoneFax() : '', 0, 'L');
+ $pdf->MultiCell($val_width, $line_height, $customer && $customer->getPhoneFax() ? $this->country_code . $customer->getPhoneFax() : '', 0, 'L');
// insert vehicle info
$cv = $obj->getCustomerVehicle();
diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php
index f6f07188..e91e855e 100644
--- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php
+++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php
@@ -53,25 +53,25 @@ use FPDF;
class ResqJobOrderHandler implements JobOrderHandlerInterface
{
- const COUNTRY_CODE_PREFIX = '+60';
-
protected $em;
protected $ic;
protected $security;
protected $validator;
protected $translator;
+ protected $country_code;
protected $template_hash;
public function __construct(Security $security, EntityManagerInterface $em,
InvoiceGeneratorInterface $ic, ValidatorInterface $validator,
- TranslatorInterface $translator)
+ TranslatorInterface $translator, string $country_code)
{
$this->em = $em;
$this->ic = $ic;
$this->security = $security;
$this->validator = $validator;
$this->translator = $translator;
+ $this->country_code = $country_code;
$this->loadTemplates();
}
@@ -1868,7 +1868,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
$pdf->SetXY($col2_x, $y);
$pdf->Cell($label_width, $line_height, 'Mobile Phone:');
- $pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneMobile() ? self::COUNTRY_CODE_PREFIX . $customer->getPhoneMobile() : '', 0, 'L');
+ $pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneMobile() ? $this->country_code . $customer->getPhoneMobile() : '', 0, 'L');
// get Y after right cell
$y2 = $pdf->GetY();
@@ -1885,7 +1885,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
$pdf->SetXY($col2_x, $y);
$pdf->Cell($label_width, $line_height, 'Landline:');
- $pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneLandline() ? self::COUNTRY_CODE_PREFIX . $customer->getPhoneLandline() : '', 0, 'L');
+ $pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneLandline() ? $this->country_code . $customer->getPhoneLandline() : '', 0, 'L');
// get Y after right cell
$y2 = $pdf->GetY();
@@ -1895,11 +1895,11 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
$pdf->SetXY($col2_x, $y);
$pdf->Cell($label_width, $line_height, 'Office Phone:');
- $pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneOffice() ? self::COUNTRY_CODE_PREFIX . $customer->getPhoneOffice() : '', 0, 'L');
+ $pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneOffice() ? $this->country_code . $customer->getPhoneOffice() : '', 0, 'L');
$pdf->SetX($col2_x);
$pdf->Cell($label_width, $line_height, 'Fax:');
- $pdf->MultiCell($val_width, $line_height, $customer && $customer->getPhoneFax() ? self::COUNTRY_CODE_PREFIX . $customer->getPhoneFax() : '', 0, 'L');
+ $pdf->MultiCell($val_width, $line_height, $customer && $customer->getPhoneFax() ? $this->country_code . $customer->getPhoneFax() : '', 0, 'L');
// insert vehicle info
$cv = $obj->getCustomerVehicle();
diff --git a/src/Service/WarrantyHandler.php b/src/Service/WarrantyHandler.php
new file mode 100644
index 00000000..bfc30021
--- /dev/null
+++ b/src/Service/WarrantyHandler.php
@@ -0,0 +1,332 @@
+em = $em;
+ }
+
+ public function createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number,
+ $batt_list, DateTime $date_purchase, $warranty_class)
+ {
+ // new warranty
+ $warranty = new Warranty();
+
+ foreach ($batt_list as $battery)
+ {
+ // get the battery model and battery size
+ $model_id = $battery->getModel()->getID();
+ $size_id = $battery->getSize()->getID();
+
+ $bty_model = $this->em->getRepository(BatteryModel::class)->find($model_id);
+ $bty_size = $this->em->getRepository(BatterySize::class)->find($size_id);
+
+ if ($bty_model != null)
+ {
+ $warranty->setBatteryModel($bty_model);
+ }
+ if ($bty_size != null)
+ {
+ $warranty->setBatterySize($bty_size);
+ }
+
+ $sap_code = $battery->getSAPCode();
+ if (!empty($sap_code))
+ {
+ // find sap battery
+ $sap_battery = $this->em->getRepository(SAPBattery::class)->find($sap_code);
+ if ($sap_battery != null)
+ {
+ $warranty->setSAPBattery($sap_battery);
+ }
+ }
+ }
+
+ // compute expiry date
+ $date_expire = null;
+ if ((!empty($warranty_class)) &&
+ (count($batt_list) != 0))
+ {
+ $period = $this->getWarrantyPeriod($batt_list, $warranty_class);
+ $date_expire = $this->computeDateExpire($date_purchase, $period);
+
+ $warranty->setDateExpire($date_expire);
+ }
+
+ // set and save values
+ $warranty->setSerial($serial)
+ ->setPlateNumber($plate_number)
+ ->setFirstName($first_name)
+ ->setLastName($last_name)
+ ->setMobileNumber($mobile_number)
+ ->setDatePurchase($date_purchase);
+
+ $this->em->persist($warranty);
+ $this->em->flush();
+
+ // update customer vehicle with warranty info
+ $this->updateCustomerVehicle($serial, $batt_list, $plate_number, $date_expire);
+
+ $this->em->clear();
+ }
+
+ public function updateCustomerVehicle($serial, $batteries, $plate_number, $date_expire)
+ {
+ // find customer vehicle using plate number
+ error_log('Finding customer vehicle with plate number ' . $plate_number);
+ $cv_q = $this->em->createQuery('select count(cv) from App\Entity\CustomerVehicle cv where cv.plate_number = :plate_number')
+ ->setParameter('plate_number', $plate_number);
+ $cv_result = $cv_q->getSingleScalarResult();
+
+ $battery_id = null;
+ if ($cv_result != 0)
+ {
+ if (!empty($batteries))
+ {
+ // set current battery to the first battery in list.
+ // there are cases where multiple batteries linked to an SAP code.
+ $battery = $batteries[0];
+ $battery_id = $battery->getID();
+ }
+ //error_log('Serial/Warranty Code = ' . $serial);
+ $q = $this->em->createQuery('update App\Entity\CustomerVehicle cv
+ set cv.curr_battery = :batt_id,
+ cv.warranty_code = :serial,
+ cv.warranty_expiration = :expiry_date
+ where cv.plate_number = :plate_number')
+ ->setParameters([
+ 'batt_id' => $battery_id,
+ 'serial' => $serial,
+ 'expiry_date' => $date_expire,
+ 'plate_number' => $plate_number]);
+ $q->execute();
+ }
+ }
+
+ public function updateWarranty(Warranty $warr, $first_name, $last_name, $mobile_number, $batt_list, DateTime $date_purchase)
+ {
+ // TODO: add serial and plate number to update
+ // TODO: check if data from existing warranty matches the new data
+ // check if details are complete
+ if (empty($warr->getFirstName()))
+ {
+ if (!empty($first_name))
+ {
+ $warr->setFirstName($first_name);
+ }
+ }
+ if (empty($warr->getLastName()))
+ {
+ if (!empty($last_name))
+ {
+ $warr->setLastName($last_name);
+ }
+ }
+ if (empty($warr->getMobileNumber()))
+ {
+ if (!empty($mobile_number))
+ {
+ $warr->setMobileNumber($mobile_number);
+ }
+ }
+ if ((empty($warr->getBatteryModel())) ||
+ (empty($warr->getBatterySize())))
+ {
+ if (count($batt_list) != 0)
+ {
+ foreach ($batt_list as $battery)
+ {
+ // get the battery model and battery size
+ $model_id = $battery->getModel()->getID();
+ $size_id = $battery->getSize()->getID();
+
+ $bty_model = $this->em->getRepository(BatteryModel::class)->find($model_id);
+ $bty_size = $this->em->getRepository(BatterySize::class)->find($size_id);
+
+ if ($bty_model != null)
+ {
+ $warranty->setBatteryModel($bty_model);
+ }
+ if ($bty_size != null)
+ {
+ $warranty->setBatterySize($bty_size);
+ }
+
+ $sap_code = $battery->getSAPCode();
+ if (!empty($sap_code))
+ {
+ // find sap battery
+ $sap_battery = $this->em->getRepository(SAPBattery::class)->find($sap_code);
+ if ($sap_battery != null)
+ {
+ $warranty->setSAPBattery($sap_battery);
+ }
+ }
+ }
+ }
+ }
+
+ $purchase_date = $warr->getDatePurchase();
+ if (empty($purchase_date))
+ {
+ if (!empty($date_purchase))
+ {
+ $warr->setDatePurchase($date_purchase);
+ }
+ $purchase_date = $date_purchase;
+ }
+
+ if (empty($warr->getDateExpire()))
+ {
+ $batteries = [];
+ if (count($batt_list) == 0)
+ {
+ $batteries = $this->getBatteriesForWarranty($warr);
+ }
+ else
+ {
+ $batteries = $batt_list;
+ }
+
+ if (!empty($batteries))
+ {
+ $period = $this->getWarrantyPeriod($batteries, $warr->getWarrantyClass());
+ if (!empty($purchase_date))
+ {
+ $expire_date = $this->computeDateExpire($purchase_date, $period);
+ $warr->setDateExpire($expire_date);
+ }
+ }
+ }
+
+ $this->em->persist($warr);
+ $this->em->flush();
+ $this->em->clear();
+ }
+
+ public function computeDateExpire($date_create, $warranty_period)
+ {
+ $expire_date = clone $date_create;
+ $expire_date->add(new DateInterval('P'.$warranty_period.'M'));
+ return $expire_date;
+ }
+
+ public function getWarrantyPeriod($batteries, $warranty_class)
+ {
+ // set to -1 to show that we haven't set a warranty period yet
+ // cannot set initial value to 0 because warranty tnv can be 0
+ $least_warranty = -1;
+ $warr_period = 0;
+ foreach ($batteries as $battery)
+ {
+ // if multiple batteries, get the smallest warranty period
+ // check warranty class to get warranty period
+ if ($warranty_class == WarrantyClass::WTY_PRIVATE)
+ {
+ $warr_period = $battery->getWarrantyPrivate();
+ //error_log('Warranty Period for Private: ' . $warr_period);
+ }
+ if ($warranty_class == WarrantyClass::WTY_COMMERCIAL)
+ {
+ $warr_period = $battery->getWarrantyCommercial();
+ //error_log('Warranty Period for Commercial: ' . $warr_period);
+ }
+ if ($warranty_class == WarrantyClass::WTY_TNV)
+ {
+ $warr_period = $battery->getWarrantyTnv();
+ //error_log('Warranty Period for TNV: ' . $warr_period);
+ }
+
+ if ($least_warranty < 0)
+ {
+ // set least warranty to the first obtained warranty period
+ $least_warranty = $warr_period;
+ }
+
+ if ($least_warranty > $warr_period)
+ {
+ $least_warranty = $warr_period;
+ }
+ }
+
+ $warranty_period = $least_warranty;
+
+ return $warranty_period;
+ }
+
+ public function getBatteriesForWarranty($warr)
+ {
+ // find battery via sku/sap battery first
+ // if sku is null, use battery model and battery size to find battery
+ // if all three are null, do nothing
+ $batteries = null;
+
+ $sap_battery = $warr->getSAPBattery();
+ $batt_model = $warr->getBatteryModel();
+ $batt_size = $warr->getBatterySize();
+ $warranty_class = $warr->getWarrantyClass();
+
+ if (empty($warranty_class))
+ {
+ error_log('Warranty class is empty for warranty id ' . $warr->getID());
+ return null;
+ }
+
+ if ($sap_battery != null)
+ {
+ // get the battery linked to SAP Battery using sap_battery id
+ $batteries = $this->em->getRepository(Battery::class)->findBy(['sap_code' => $sap_battery->getID()]);
+ }
+ else
+ {
+ if ($batt_model == null)
+ {
+ error_log('Battery model is null for warranty id ' . $warr->getID());
+ return null;
+ }
+ if ($batt_size == null)
+ {
+ error_log('Battery size is null for warranty id ' . $warr->getID());
+ return null;
+ }
+
+ // find battery using battery model and battery size
+ $batteries = $this->em->getRepository(Battery::class)->findBy(['model' => $batt_model, 'size' => $batt_size]);
+ }
+
+ if (empty($batteries))
+ {
+ error_log('Battery not found for warranty id ' . $warr->getID());
+ return null;
+ }
+
+ return $batteries;
+ }
+
+
+ public function cleanPlateNumber($plate)
+ {
+ // remove spaces and make upper case
+ return strtoupper(str_replace(' ', '', $plate));
+ }
+
+}
diff --git a/symfony.lock b/symfony.lock
index 81b878d9..88d10d33 100644
--- a/symfony.lock
+++ b/symfony.lock
@@ -98,6 +98,9 @@
"doctrine/reflection": {
"version": "v1.0.0"
},
+ "edwinhoksberg/php-fcm": {
+ "version": "1.0.0"
+ },
"guzzlehttp/guzzle": {
"version": "6.3.0"
},
diff --git a/templates/base.html.twig b/templates/base.html.twig
index ad096362..ec13aa91 100644
--- a/templates/base.html.twig
+++ b/templates/base.html.twig
@@ -153,7 +153,7 @@