diff --git a/.gitignore b/.gitignore index bd8a680c..cf3b012e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ ###< symfony/framework-bundle ### *.swp +/public/warranty_uploads/* diff --git a/composer.json b/composer.json index d2f81e89..20b9c833 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ "data-dog/audit-bundle": "^0.1.10", "edwinhoksberg/php-fcm": "^1.0", "guzzlehttp/guzzle": "^6.3", + "microsoft/azure-storage-blob": "^1.5", "predis/predis": "^1.1", "sensio/framework-extra-bundle": "^5.1", "setasign/fpdf": "^1.8", diff --git a/composer.lock b/composer.lock index 1e76e914..6f8cb6bb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "f03b92d48946e8b2ee19466f931c826f", + "content-hash": "ad9d56a6dff26742f024917e58b919f9", "packages": [ { "name": "catalyst/auth-bundle", @@ -944,6 +944,7 @@ "cache", "caching" ], + "abandoned": true, "time": "2019-11-29T11:22:01+00:00" }, { @@ -1611,6 +1612,7 @@ "reflection", "static" ], + "abandoned": "roave/better-reflection", "time": "2020-03-27T11:06:43+00:00" }, { @@ -1901,6 +1903,94 @@ ], "time": "2014-01-12T16:20:24+00:00" }, + { + "name": "microsoft/azure-storage-blob", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/Azure/azure-storage-blob-php.git", + "reference": "2475330963372d519387cb8135d6a9cfd42272da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Azure/azure-storage-blob-php/zipball/2475330963372d519387cb8135d6a9cfd42272da", + "reference": "2475330963372d519387cb8135d6a9cfd42272da", + "shasum": "" + }, + "require": { + "microsoft/azure-storage-common": "~1.5", + "php": ">=5.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "MicrosoftAzure\\Storage\\Blob\\": "src/Blob" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Azure Storage PHP Client Library", + "email": "dmsh@microsoft.com" + } + ], + "description": "This project provides a set of PHP client libraries that make it easy to access Microsoft Azure Storage Blob APIs.", + "keywords": [ + "azure", + "blob", + "php", + "sdk", + "storage" + ], + "time": "2020-12-29T02:22:11+00:00" + }, + { + "name": "microsoft/azure-storage-common", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/Azure/azure-storage-common-php.git", + "reference": "e5738035891546075bd369954e8af121d65ebd6d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Azure/azure-storage-common-php/zipball/e5738035891546075bd369954e8af121d65ebd6d", + "reference": "e5738035891546075bd369954e8af121d65ebd6d", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "~6.0|^7.0", + "php": ">=5.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "MicrosoftAzure\\Storage\\Common\\": "src/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Azure Storage PHP Client Library", + "email": "dmsh@microsoft.com" + } + ], + "description": "This project provides a set of common code shared by Azure Storage Blob, Table, Queue and File PHP client libraries.", + "keywords": [ + "azure", + "common", + "php", + "sdk", + "storage" + ], + "time": "2020-12-28T07:59:51+00:00" + }, { "name": "nikic/php-parser", "version": "v4.3.0", @@ -2078,12 +2168,12 @@ "version": "v1.1.1", "source": { "type": "git", - "url": "https://github.com/nrk/predis.git", + "url": "https://github.com/predis/predis.git", "reference": "f0210e38881631afeafb56ab43405a92cafd9fd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nrk/predis/zipball/f0210e38881631afeafb56ab43405a92cafd9fd1", + "url": "https://api.github.com/repos/predis/predis/zipball/f0210e38881631afeafb56ab43405a92cafd9fd1", "reference": "f0210e38881631afeafb56ab43405a92cafd9fd1", "shasum": "" }, diff --git a/config/routes/capi.yaml b/config/routes/capi.yaml index 0c2e5ac1..856eb0ef 100644 --- a/config/routes/capi.yaml +++ b/config/routes/capi.yaml @@ -49,6 +49,11 @@ capi_vehicle_list: controller: App\Controller\CAPI\VehicleController::list methods: [GET] +capi_vehicle_by_mfg: + path: /capi/vehicle_manufacturer/{mfg_id} + controller: App\Controller\CAPI\VehicleController::getByManufacturer + methods: [GET] + # plate api @@ -149,3 +154,15 @@ capi_customer_register: path: /capi/quick_registration controller: App\Controller\CAPI\CustomerController::register methods: [POST] + +# customer warranty api +capi_cwarr_check: + path: /capi/customer_warranty/{serial} + controller: App\Controller\CAPI\CustomerWarrantyController::check + methods: [GET] + +capi_cwarr_register: + path: /capi/customer_warranty/{serial} + controller: App\Controller\CAPI\CustomerWarrantyController::register + methods: [POST] + diff --git a/config/routes/customer.yaml b/config/routes/customer.yaml index 90ac5591..9f952543 100644 --- a/config/routes/customer.yaml +++ b/config/routes/customer.yaml @@ -5,7 +5,7 @@ customer_list: customer_rows: path: /customers/rows controller: App\Controller\CustomerController::rows - methods: [POST] + methods: [GET,POST] customer_vehicle_search: path: /customers/vehicles diff --git a/public/.gitkeep b/public/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/public/cust_reports/.gitkeep b/public/cust_reports/.gitkeep new file mode 100644 index 00000000..8d1c8b69 --- /dev/null +++ b/public/cust_reports/.gitkeep @@ -0,0 +1 @@ + diff --git a/public/static/faq.html b/public/static/faq.html index 2e0cdea3..42b4110d 100644 --- a/public/static/faq.html +++ b/public/static/faq.html @@ -58,7 +58,7 @@ Yes, we accept Visa and Mastercard issued in the Philippines. How can I pay for your services/ products?

-We accept COD, local Credit Cards, Debit Cards, and ATM Cards only. +We accept COD, local credit cards, debit cards, and ATM cards for battery replacement transactions. We only accept cash payment for flat tire, refuel and overheat transactions.

@@ -93,7 +93,7 @@ Delivery for battery purchase is free of charge. Can you deliver anywhere in the Philippines?

-Not yet. Res-Q is offered initially in Metro Manila only. +Not yet. Res-Q is offered Metro Manila, Baguio City and Binan, Laguna only.

diff --git a/src/Controller/APIController.php b/src/Controller/APIController.php index 94e9fb38..1a1c6165 100644 --- a/src/Controller/APIController.php +++ b/src/Controller/APIController.php @@ -12,6 +12,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Dotenv\Dotenv; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpKernel\KernelInterface; use CrEOF\Spatial\PHP\Types\Geometry\Point; @@ -2751,6 +2752,31 @@ class APIController extends Controller implements LoggedController return $res->getReturnResponse(); } + protected function checkCustomerPlateNumber($plate_number, $cust) + { + // strip spaces and make all caps + $plate_number = preg_replace('/\s+/', '', strtoupper($plate_number)); + + // if there's no customer linked to session + if ($cust != null) + { + // check all the customer vehicles + $cvs = $cust->getVehicles(); + foreach ($cvs as $cv) + { + $cv_plate = preg_replace('/\s+/', '', strtoupper($cv->getPlateNumber())); + + // did we find a match? + if ($cv_plate == $plate_number) + { + return true; + } + } + } + + return false; + } + public function warrantyCheck($serial, EntityManagerInterface $em, Request $req) { // check required parameters and api key @@ -2759,24 +2785,6 @@ class APIController extends Controller implements LoggedController if ($res->isError()) return $res->getReturnResponse(); - /* - // initialize data - $data = [ - 'is_valid' => false, - 'is_registered' => false, - 'customer' => [ - 'first_name' => '', - 'last_name' => '', - 'mobile_number' => '', - 'plate_number' => '', - ], - 'battery' => [ - 'brand' => '', - 'size' => '', - ], - ]; - */ - // check if warranty serial is there $warr_serial = $em->getRepository(WarrantySerial::class)->find($serial); $warr = $em->getRepository(Warranty::class)->findOneBy(['serial' => $serial]); @@ -2790,100 +2798,224 @@ class APIController extends Controller implements LoggedController return $res->getReturnResponse(); } - // if warranty serial is there - if ($warr_serial != null) - { - // if we have a warranty entry for the serial already - if ($warr != null) - { - $is_registered = true; + $today = new DateTime(); - // null mobile number should be blank string instead - if ($warr->getMobileNumber() == null) - $mobile_num = ''; - else - $mobile_num = $warr->getMobileNumber(); + // if we have a warranty entry for the serial already + if ($warr != null) + { + $warr_plate = $warr->getPlateNumber(); + $is_registered = true; + $is_customer_warranty = false; + + // check if the warranty is registered to a car owned by the customer + $cust = $this->session->getCustomer(); + $is_customer_warranty = $this->checkCustomerPlateNumber($warr_plate, $cust); + + // null mobile number should be blank string instead + if ($warr->getMobileNumber() == null) + $mobile_num = ''; + else + $mobile_num = $warr->getMobileNumber(); + + $can_edit = $is_customer_warranty; + + // if customer plate number matches the one registered on the warranty + if ($is_customer_warranty) + { + // purchase date of customer + if ($warr->getDatePurchaseCustomer() != null) + $date_purchase_cust = $warr->getDatePurchaseCustomer()->format('Y-m-d'); + else + $date_purchase_cust = $today->format('Y-m-d'); + + + // invoice + if ($warr->getFileInvoice() != null) + $invoice_url = $req->getSchemeAndHttpHost() . '/warranty_uploads/' . $warr->getFileInvoice(); + else + $invoice_url = ''; + + // warranty card + if ($warr->getFileWarrantyCard() != null) + $warr_card_url = $req->getSchemeAndHttpHost() . '/warranty_uploads/' . $warr->getFileWarrantyCard(); + else + $warr_card_url = ''; $customer = [ - 'first_name' => $warr->getFirstName(), - 'last_name' => $warr->getLastName(), + 'first_name' => $warr->getFirstName() ?? '', + 'last_name' => $warr->getLastName() ?? '', 'mobile_number' => $mobile_num, - 'plate_number' => $warr->getPlateNumber(), + 'plate_number' => $warr_plate, + 'email' => $warr->getEmail() ?? '', + 'contact_num' => $warr->getContactNumber() ?? '', + 'address' => $warr->getCustomerAddress() ?? '', + ]; + $other_data = [ + 'odometer' => (int) $warr->getOdometer() ?? 0, + 'date_purchase' => $date_purchase_cust, + 'invoice' => $invoice_url, + 'warr_card' => $warr_card_url, + 'dealer_name' => $warr->getDealerName() ?? '', + 'dealer_address' => $warr->getDealerAddress() ?? '', ]; } else { + // hide customer information if customer is not the one registered $customer = [ 'first_name' => '', 'last_name' => '', 'mobile_number' => '', 'plate_number' => '', + 'email' => '', + 'contact_num' => '', + 'address' => '', + ]; + $other_data = [ + 'odometer' => 0, + 'date_purchase' => $today->format('Y-m-d'), + 'invoice' => '', + 'warr_card' => '', + 'dealer_name' => '', + 'dealer_address' => '', ]; } - - $sku = $warr_serial->getSKU(); - $batt = $em->getRepository(SAPBattery::class)->find($sku); - // TODO: put this in a config file - $image_url = $req->getSchemeAndHttpHost() . '/battery/generic.png'; - if ($batt != null) - { - $battery = [ - 'brand' => $batt->getBrand()->getName(), - 'size' => $batt->getSize()->getName(), - 'image_url' => $image_url, - ]; - } - else - { - $battery = [ - 'brand' => '', - 'size' => '', - 'image_url' => '', - ]; - } - - // populate data - $data = [ - 'is_valid' => true, - 'is_registered' => $is_registered, - 'customer' => $customer, - 'battery' => $battery, - 'message' => [ - 'register_error' => 'Warranty serial code has already been registered.', - ], + } + else + { + $can_edit = true; + $customer = [ + 'first_name' => '', + 'last_name' => '', + 'mobile_number' => '', + 'plate_number' => '', + 'email' => '', + 'contact_num' => '', + 'address' => '', + ]; + $other_data = [ + 'odometer' => 0, + 'date_purchase' => $today->format('Y-m-d'), + 'invoice' => '', + 'warr_card' => '', + 'dealer_name' => '', + 'dealer_address' => '', ]; } + $sku = $warr_serial->getSKU(); + $batt = $em->getRepository(SAPBattery::class)->find($sku); + // TODO: put this in a config file + $image_url = $req->getSchemeAndHttpHost() . '/battery/generic.png'; + if ($batt != null) + { + $battery = [ + 'brand' => $batt->getBrand()->getName(), + 'size' => $batt->getSize()->getName(), + 'image_url' => $image_url, + ]; + } + else + { + $battery = [ + 'brand' => '', + 'size' => '', + 'image_url' => '', + ]; + } + + // populate data + $data = [ + 'is_valid' => true, + 'is_registered' => $is_registered, + 'can_edit' => $can_edit, + 'customer' => $customer, + 'battery' => $battery, + 'odometer' => $other_data['odometer'], + 'invoice' => $other_data['invoice'], + 'warr_card' => $other_data['warr_card'], + 'date_purchase' => $other_data['date_purchase'], + 'dealer_name' => $other_data['dealer_name'], + 'dealer_address' => $other_data['dealer_address'], + 'message' => [ + 'register_error' => 'Warranty serial code has already been registered.', + 'edit_error' => 'Sorry, warranty is registered under another vehicle not in your list of vehicles.', + ], + ]; + $res->setData($data); return $res->getReturnResponse(); } - public function warrantyRegister($serial, EntityManagerInterface $em, Request $req) + protected function handlePictureUpload($file, $target_dir, $serial, $name) + { + error_log("handling $name upload"); + // no file sent + if ($file == null) + { + error_log('no file'); + return null; + } + + // create target dir if it doesn't exist + if (!file_exists($target_dir)) + { + if (!mkdir($target_dir, 0744, true)) + { + error_log('failed to create folder for warranty pictures'); + return null; + } + } + + // move file + $filename = $name . '.' . $file->getClientOriginalExtension(); + $file->move($target_dir . '/' . $serial, $filename); + + error_log("filename - $filename"); + error_log($target_dir . '/' . $serial . '/' . $filename); + + return $serial . '/' . $filename; + } + + public function warrantyRegister($serial, EntityManagerInterface $em, Request $req, KernelInterface $kernel) { // check required parameters and api key $required_params = [ 'first_name', 'last_name', - 'email', 'plate_number', + 'date_purchase', ]; + + // handle file uploads + $invoice = $req->files->get('invoice'); + $warr_card = $req->files->get('warr_card'); + + // normalize serial + $serial = trim(strtoupper($serial)); + + // process picture uploads + $upload_dir = $kernel->getProjectDir() . '/public/warranty_uploads'; + $inv_filename = $this->handlePictureUpload($invoice, $upload_dir, $serial, 'invoice'); + $wcard_filename = $this->handlePictureUpload($warr_card, $upload_dir, $serial, 'wcard'); + $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); // update customer information - $cust = $this->updateCustomerInfo($req, $em); + // $cust = $this->updateCustomerInfo($req, $em); // update warranty - $res = $this->updateWarranty($res, $em, $req, $serial); + $res = $this->updateWarranty($res, $em, $req, $serial, $inv_filename, $wcard_filename); $em->flush(); return $res->getReturnResponse(); } - protected function updateWarranty($res, $em, $req, $serial) + protected function updateWarranty($res, $em, $req, $serial, $inv_filename = null, $wcard_filename = null) { // get serial $warr_serial = $em->getRepository(WarrantySerial::class)->find($serial); @@ -2900,9 +3032,29 @@ class APIController extends Controller implements LoggedController // skip warranty if it already exists if ($warr != null) { + /* + // NOTE: we could not update in the old version $res->setError(true) ->setErrorMessage('Warranty registration entry already exists.'); return $res; + */ + + // check if warranty is registered to a serial owned by customer + $warr_plate = $warr->getPlateNumber(); + $cust = $this->session->getCustomer(); + $is_customer_warranty = $this->checkCustomerPlateNumber($warr_plate, $cust); + + if (!$is_customer_warranty) + { + $res->setError(true) + ->setErrorMessage('Warranty registred to a vehicle not in your list of vehicles.'); + return $res; + } + + } + else + { + $warr = new Warranty(); } // get sap battery @@ -2915,11 +3067,21 @@ class APIController extends Controller implements LoggedController return $res; } + // default date purchase to today + // NOTE: might need to change this later $date_pur = new DateTime(); + // get date purchase specified by customer + $date_pur_cust = DateTime::createFromFormat('Y-m-d', $req->request->get('date_purchase')); + if (!$date_pur_cust) + { + $res->setError(true) + ->setErrorMessage('Invalid date format for date of purchase.'); + return $res; + } - // create new warranty entry - $warr = new Warranty(); + + // create or update warranty entry $warr->setSerial($serial) ->setFirstName($req->request->get('first_name')) ->setLastName($req->request->get('last_name')) @@ -2934,7 +3096,20 @@ class APIController extends Controller implements LoggedController // ->setBatteryModel() ->setSAPBattery($sap_bty) ->setMobileNumber(substr($this->session->getPhoneNumber(), 2)) - ->setActivated(true); + ->setActivated(true) + + // files + ->setFileInvoice($inv_filename) + ->setFileWarrantyCard($wcard_filename) + + // new fields + ->setOdometer($req->request->get('odometer', 0)) + ->setDatePurchaseCustomer($date_pur_cust) + ->setContactNumber($req->request->get('contact_num')) + ->setCustomerAddress($req->request->get('cust_address')) + ->setDealerName($req->request->get('dealer_name')) + ->setDealerAddress($req->request->get('dealer_address')) + ->setValidated(false); // TODO: check for date purchase and date expire diff --git a/src/Controller/BatterySizeController.php b/src/Controller/BatterySizeController.php index 5dc2906a..177780e8 100644 --- a/src/Controller/BatterySizeController.php +++ b/src/Controller/BatterySizeController.php @@ -129,7 +129,8 @@ class BatterySizeController extends Controller $obj->setName($req->request->get('name')) ->setTIPriceMotolite($req->request->get('tip_motolite')) ->setTIPricePremium($req->request->get('tip_premium')) - ->setTIPriceOther($req->request->get('tip_other')); + ->setTIPriceOther($req->request->get('tip_other')) + ->setTIPriceLazada($req->request->get('tip_lazada')); } public function addSubmit(Request $req, ValidatorInterface $validator) diff --git a/src/Controller/CAPI/BatteryController.php b/src/Controller/CAPI/BatteryController.php index 0cf12d8f..056a765f 100644 --- a/src/Controller/CAPI/BatteryController.php +++ b/src/Controller/CAPI/BatteryController.php @@ -49,6 +49,7 @@ class BatteryController extends APIController 'container_size_name' => $csize_name, 'date_update' => $batt->getDateUpdate()->format('YmdHis'), 'flag_new' => $batt->isNew(), + 'flag_inventory' => $batt->isInventory(), ]; } diff --git a/src/Controller/CAPI/CustomerWarrantyController.php b/src/Controller/CAPI/CustomerWarrantyController.php new file mode 100644 index 00000000..7c5ce230 --- /dev/null +++ b/src/Controller/CAPI/CustomerWarrantyController.php @@ -0,0 +1,469 @@ +acl_gen = $acl_gen; + } + + protected function checkMissingParameters(Request $req, $params = []) + { + $missing = []; + + // check if parameters are there + foreach ($params as $param) + { + if ($req->getMethod() == 'GET') + { + $check = $req->query->get($param); + if (empty($check)) + $missing[] = $param; + } + else if ($req->getMethod() == 'POST') + { + $check = $req->request->get($param); + if (empty($check)) + $missing[] = $param; + } + else + return $params; + } + + return $missing; + } + + protected function checkRequiredParams(Request $req, $params) + { + // check required parameters + $missing = $this->checkMissingParameters($req, $params); + if (count($missing) > 0) + { + $miss_string = implode(', ', $missing); + return new APIResponse(false, 'Missing parameter(s): ' . $miss_string); + } + + return true; + } + + protected function cleanSerial($serial) + { + return trim(strtoupper($serial)); + } + + protected function cleanPlateNumber($plate_num) + { + return preg_replace('/\s+/', '', strtoupper($plate_num)); + } + + public function check($serial, EntityManagerInterface $em, Request $req) + { + // check required parameters + $required_params = []; + $res = $this->checkRequiredParams($req, $required_params); + if (!$res) + return $res; + + error_log('check warranty serial'); + + // check if warranty serial is there + $warr_serial = $em->getRepository(WarrantySerial::class)->find($serial); + $warr = $em->getRepository(Warranty::class)->findOneBy(['serial' => $serial]); + $batt = null; + $is_registered = false; + + if ($warr_serial == null) + { + return new APIResponse(false, 'Invalid warranty serial code.'); + } + + $today = new DateTime(); + + // if we have a warranty entry for the serial already + if ($warr != null) + { + error_log('already have warranty.'); + + $warr_plate = $warr->getPlateNumber(); + $is_registered = true; + + // null mobile number should be blank string instead + if ($warr->getMobileNumber() == null) + $mobile_num = ''; + else + $mobile_num = $warr->getMobileNumber(); + + // purchase date of customer + if ($warr->getDatePurchaseCustomer() != null) + $date_purchase_cust = $warr->getDatePurchaseCustomer()->format('Y-m-d'); + else + $date_purchase_cust = $today->format('Y-m-d'); + + + // invoice + if ($warr->getFileInvoice() != null) + $invoice_url = $req->getSchemeAndHttpHost() . '/warranty_uploads/' . $warr->getFileInvoice(); + else + $invoice_url = ''; + + // warranty card + if ($warr->getFileWarrantyCard() != null) + $warr_card_url = $req->getSchemeAndHttpHost() . '/warranty_uploads/' . $warr->getFileWarrantyCard(); + else + $warr_card_url = ''; + + // vehicle + if ($warr->getVehicle() != null) + { + $v = $warr->getVehicle(); + $vmfg_id = $v->getManufacturer()->getID(); + $vmake_id = $v->getID(); + } + else + { + $vmfg_id = null; + $vmake_id = null; + } + + // customer + $cust = $warr->getCustomer(); + if ($cust != null) + { + $cust_exists = true; + $priv_promo = $cust->getPrivacyPromo(); + } + else + { + $cust_exists = false; + $priv_promo = false; + } + + $customer = [ + 'first_name' => $warr->getFirstName(), + 'last_name' => $warr->getLastName(), + 'mobile_number' => $mobile_num, + 'plate_number' => $warr_plate, + 'email' => $warr->getEmail(), + 'contact_num' => $warr->getContactNumber(), + 'address' => $warr->getCustomerAddress(), + 'priv_promo' => $priv_promo, + 'exists' => $cust_exists, + ]; + $other_data = [ + 'odometer' => $warr->getOdometer(), + 'date_purchase' => $date_purchase_cust, + 'invoice' => $invoice_url, + 'warr_card' => $warr_card_url, + 'vmfg_id' => $vmfg_id, + 'vmake_id' => $vmake_id, + 'vmodel' => $warr->getVehicleModelYear(), + 'dealer_name' => $warr->getDealerName(), + 'dealer_address' => $warr->getDealerAddress(), + ]; + } + else + { + $customer = [ + 'first_name' => '', + 'last_name' => '', + 'mobile_number' => '', + 'plate_number' => '', + 'email' => '', + 'contact_num' => '', + 'address' => '', + 'priv_promo' => false, + 'exists' => false, + ]; + $other_data = [ + 'odometer' => 0, + 'date_purchase' => $today->format('Y-m-d'), + 'invoice' => '', + 'warr_card' => '', + 'vmfg_id' => null, + 'vmake_id' => null, + 'vmodel' => '', + 'dealer_name' => '', + 'dealer_address' => '', + ]; + } + + $sku = $warr_serial->getSKU(); + $batt = $em->getRepository(SAPBattery::class)->find($sku); + // TODO: put this in a config file + $image_url = $req->getSchemeAndHttpHost() . '/battery/generic.png'; + if ($batt != null) + { + $battery = [ + 'brand' => $batt->getBrand()->getName(), + 'size' => $batt->getSize()->getName(), + 'image_url' => $image_url, + ]; + } + else + { + $battery = [ + 'brand' => '', + 'size' => '', + 'image_url' => '', + ]; + } + + // populate data + $data = [ + 'is_valid' => true, + 'is_registered' => $is_registered, + 'customer' => $customer, + 'battery' => $battery, + 'odometer' => $other_data['odometer'], + 'invoice' => $other_data['invoice'], + 'warr_card' => $other_data['warr_card'], + 'date_purchase' => $other_data['date_purchase'], + 'vmfg_id' => $other_data['vmfg_id'], + 'vehicle_id' => $other_data['vmake_id'], + 'vmodel' => $other_data['vmodel'], + 'dealer_name' => $other_data['dealer_name'], + 'dealer_address' => $other_data['dealer_address'], + ]; + + return new APIResponse(true, 'Warranty found.', $data); + } + + + public function register($serial, EntityManagerInterface $em, Request $req, KernelInterface $kernel) + { + error_log('HERE - register'); + // check required parameters + $required_params = [ + 'first_name', + 'last_name', + 'plate_num' + ]; + $res = $this->checkRequiredParams($req, $required_params); + if (!$res) + return $res; + + // file uploads + $invoice = $req->files->get('invoice'); + $warr_card = $req->files->get('warr_card'); + + error_log('handling file uploads'); + // process picture uploads + $upload_dir = $kernel->getProjectDir() . '/public/warranty_uploads'; + $inv_filename = $this->handlePictureUpload($invoice, $upload_dir, $serial, 'invoice'); + $wcard_filename = $this->handlePictureUpload($warr_card, $upload_dir, $serial, 'wcard'); + + // do actual registering + $res = $this->updateWarranty($em, $req, $serial, $inv_filename, $wcard_filename); + + // flush to db + $em->flush(); + + return $res; + + return new APIResponse(true, 'Warranty registered.'); + } + + // TODO: move this to a service, since it's shared by all warranty updaters + protected function handlePictureUpload($file, $target_dir, $serial, $name) + { + error_log("handling $name upload"); + // no file sent + if ($file == null) + { + error_log('no file'); + return null; + } + + // create target dir if it doesn't exist + if (!file_exists($target_dir)) + { + if (!mkdir($target_dir, 0744, true)) + { + error_log('failed to create folder for warranty pictures'); + return null; + } + } + + // move file + $filename = $name . '.' . $file->getClientOriginalExtension(); + $file->move($target_dir . '/' . $serial, $filename); + + error_log("filename - $filename"); + error_log($target_dir . '/' . $serial . '/' . $filename); + + return $serial . '/' . $filename; + } + + protected function updateWarranty($em, $req, $serial, $inv_filename = null, $wcard_filename = null) + { + $plate_num = $this->cleanPlateNumber($req->request->get('plate_num')); + + error_log('warranty serial check'); + // get serial + $warr_serial = $em->getRepository(WarrantySerial::class)->find($serial); + if ($warr_serial == null) + { + return new APIResponse(false, 'Invalid warranty serial code.'); + } + + // check if warranty exists already + $warr = $em->getRepository(Warranty::class)->findOneBy(['serial' => $serial]); + + // skip warranty if it already exists + $cust = null; + if ($warr != null) + { + $warr_plate_num = $this->cleanPlateNumber($warr->getPlateNumber()); + + if ($plate_num != $warr_plate_num) + { + return new APIResponse(false, 'Plate number does not match vehicle registered to warranty.'); + } + + // get customer + $cust = $warr->getCustomer(); + } + else + { + $warr = new Warranty(); + } + + error_log('sap battery check'); + // get sap battery + $sku = $warr_serial->getSKU(); + $sap_bty = $em->getRepository(SAPBattery::class)->find($sku); + if ($sap_bty == null) + { + return new APIResponse(false, 'Could not find battery entry for warranty.'); + } + + // vehicle fetch + $vmake_id = $req->request->get('vmake_id'); + $vehicle = null; + if ($vmake_id != null) + { + $vehicle = $em->getRepository(Vehicle::class)->find($vmake_id); + if ($vehicle == null) + { + return new APIResponse(false, 'Could not find vehicle specified for warranty.'); + } + } + + error_log('date check'); + // default date purchase to today + // NOTE: might need to change this later + $date_pur = new DateTime(); + + // get date purchase specified by customer + $date_pur_cust = DateTime::createFromFormat('Y-m-d', $req->request->get('date_purchase')); + if (!$date_pur_cust) + { + return new APIResponse(false, 'Invalid date format for date of purchase.'); + } + + // chstomer check + $priv_promo = $req->request->get('priv_promo', false); + if ($cust == null) + { + // if no customer yet, create one and fill in fields + $cust = new Customer(); + $cust->setFirstName($req->request->get('first_name')) + ->setLastName($req->request->get('last_name')) + ->setEmail($req->request->get('email')) + ->setCreateSource('web_warranty') + ->setPrivacyPromo($priv_promo) + ->setPhoneMobile($req->request->get('contact_num')); + + $em->persist($cust); + } + else + { + // only update privacy promo + $cust->setPrivacyPromo($priv_promo); + } + + + error_log('update entity / database'); + // create or update warranty entry + $warr->setSerial($serial) + ->setFirstName($req->request->get('first_name')) + ->setLastName($req->request->get('last_name')) + ->setEmail($req->request->get('email')) + ->setPlateNumber($req->request->get('plate_num')) + // TODO: figure out how to compute date of purchase + ->setDatePurchase($date_pur) + // TODO: set status + // ->setStatus() + // TODO: set battery model and size id + // ->setBatterySize() + // ->setBatteryModel() + ->setSAPBattery($sap_bty) + // ->setMobileNumber(substr($this->session->getPhoneNumber(), 2)) + ->setActivated(true) + + // files + ->setFileInvoice($inv_filename) + ->setFileWarrantyCard($wcard_filename) + + // new fields + ->setOdometer($req->request->get('odometer', 0)) + ->setDatePurchaseCustomer($date_pur_cust) + ->setContactNumber($req->request->get('contact_num')) + ->setCustomerAddress($req->request->get('cust_address')) + ->setDealerName($req->request->get('dealer_name')) + ->setDealerAddress($req->request->get('dealer_address')) + ->setVehicle($vehicle) + ->setVehicleModelYear($req->request->get('vmodel')) + ->setDealerName($req->request->get('dealer_name')) + ->setDealerAddress($req->request->get('dealer_address')) + ->setCustomer($cust) + ->setValidated(false); + + // TODO: check for date purchase and date expire + + $em->persist($warr); + + // TODO: check if we need to do anyting else + $data = []; + + return new APIResponse(true, 'Warranty registered.', $data); + } + +} diff --git a/src/Controller/CAPI/VehicleController.php b/src/Controller/CAPI/VehicleController.php index e28fbe88..02de2d8e 100644 --- a/src/Controller/CAPI/VehicleController.php +++ b/src/Controller/CAPI/VehicleController.php @@ -44,6 +44,35 @@ class VehicleController extends APIController return new APIResponse(true, 'Vehicle manufacturers loaded.', $data); } + public function getByManufacturer($mfg_id, EntityManagerInterface $em) + { + $this->denyAccessUnlessGranted('vehicle.list', null, 'No access.'); + + $mfg = $this->em->getRepository(VehicleManufacturer::class)->find($mfg_id); + + // manufacturer not found + if ($mfg == null) + { + return new APIResponse(false, 'No vehicle manufacturer found with that Id.', null, 404); + } + + // get all vehicles from manufacturer + $vehicles = $mfg->getVehicles(); + foreach($vehicles as $vehicle) + { + $make_data[] = [ + 'id' => $vehicle->getID(), + 'mfg_id' => $vehicle->getManufacturer()->getID(), + 'make' => $vehicle->getMake(), + 'model' => $vehicle->getModelYearFormatted(), + ]; + } + + // TODO: need to add manufacturer details + + return new APIResponse(true, 'Vehicles loaded.', $data); + } + public function list(EntityManagerInterface $em) { $this->denyAccessUnlessGranted('vehicle.list', null, 'No access.'); diff --git a/src/Controller/SAPBatteryController.php b/src/Controller/SAPBatteryController.php index 099c1998..a06f4ef9 100644 --- a/src/Controller/SAPBatteryController.php +++ b/src/Controller/SAPBatteryController.php @@ -171,9 +171,12 @@ class SAPBatteryController extends Controller $error_array['id'] = 'SAP code is required.'; $flag_new = $req->request->get('flag_new', false); + $flag_inventory = $req->request->get('flag_inventory', false); + // set and save values $row->setID($id) - ->setNew($flag_new); + ->setNew($flag_new) + ->setInventory($flag_inventory); // custom validation for battery brand $brand = $em->getRepository(SAPBatteryBrand::class) @@ -277,9 +280,12 @@ class SAPBatteryController extends Controller $error_array['id'] = 'SAP code is required.'; $flag_new = $req->request->get('flag_new', false); + $flag_inventory = $req->request->get('flag_inventory', false); + // set and save values $row->setID($id) - ->setNew($flag_new); + ->setNew($flag_new) + ->setInventory($flag_inventory); // custom validation for battery brand $brand = $em->getRepository(SAPBatteryBrand::class) diff --git a/src/Entity/BatterySize.php b/src/Entity/BatterySize.php index 9fff4d44..8b47d6af 100644 --- a/src/Entity/BatterySize.php +++ b/src/Entity/BatterySize.php @@ -51,12 +51,19 @@ class BatterySize */ protected $tip_other; + // lazada trade-in price + /** + * @ORM\Column(type="decimal", precision=7, scale=2) + */ + protected $tip_lazada; + public function __construct() { $this->batteries = new ArrayCollection(); $this->tip_motolite = 0; $this->tip_premium = 0; $this->tip_other = 0; + $this->tip_lazada = 0; } public function getID() @@ -130,4 +137,16 @@ class BatterySize { return $this->tip_other; } + + public function setTIPriceLazada($price) + { + $this->tip_lazada = $price; + return $this; + } + + public function getTIPriceLazada() + { + return $this->tip_lazada; + } + } diff --git a/src/Entity/Customer.php b/src/Entity/Customer.php index 281c9fa9..f5e8e4e9 100644 --- a/src/Entity/Customer.php +++ b/src/Entity/Customer.php @@ -192,6 +192,22 @@ class Customer */ protected $date_create; + /** + * @ORM\Column(type="boolean", options={"default":false}) + */ + protected $flag_research_sms; + + /** + * @ORM\Column(type="boolean", options={"default":false}) + */ + protected $flag_research_email; + + // where customer was created from + /** + * @ORM\Column(type="string", length=80, options={"default": "legacy"}) + */ + protected $create_source; + public function __construct() { $this->numbers = new ArrayCollection(); @@ -222,8 +238,12 @@ class Customer $this->flag_promo_email = false; $this->flag_promo_sms = false; $this->flag_dpa_consent = false; + $this->flag_research_sms = false; + $this->flag_research_email = false; $this->date_create = new DateTime(); + + $this->create_source = 'unknown'; } public function getID() @@ -555,4 +575,37 @@ class Customer { return $this->flag_dpa_consent; } + + public function setResearchSms($flag_research_sms = true) + { + $this->flag_research_sms = $flag_research_sms; + return $this; + } + + public function isResearchSms() + { + return $this->flag_research_sms; + } + + public function setResearchEmail($flag_research_email = true) + { + $this->flag_research_email = $flag_research_email; + return $this; + } + + public function isResearchEmail() + { + return $this->flag_research_email; + } + + public function setCreateSource($source) + { + $this->create_source = $source; + return $this; + } + + public function getCreateSource() + { + return $this->create_source; + } } diff --git a/src/Entity/SAPBattery.php b/src/Entity/SAPBattery.php index 284e2e32..df4303d4 100644 --- a/src/Entity/SAPBattery.php +++ b/src/Entity/SAPBattery.php @@ -58,10 +58,17 @@ class SAPBattery */ protected $container_size; + // flag to indicate if this SAP battery is inventory or non-inventory + /** + * @ORM\Column(type="boolean") + */ + protected $flag_inventory; + public function __construct() { $this->date_create = new DateTime(); $this->flag_new = false; + $this->flag_inventory = false; } public function setID($id) @@ -129,4 +136,14 @@ class SAPBattery return $this->container_size; } + public function setInventory($inventory = false) + { + $this->flag_inventory = $inventory; + return $this; + } + + public function isInventory() + { + return $this->flag_inventory; + } } diff --git a/src/Entity/Warranty.php b/src/Entity/Warranty.php index 0f3f5c6c..16a08a5b 100644 --- a/src/Entity/Warranty.php +++ b/src/Entity/Warranty.php @@ -141,6 +141,87 @@ class Warranty */ protected $privacy_policy; + + // NOTE: the following were added later on, so they should all be nullable or have defaults, + // otherwise we get issues + + // invoice picture + /** + * @ORM\Column(type="string", length=80, nullable=true) + */ + protected $file_invoice; + + // warranty card picture + /** + * @ORM\Column(type="string", length=80, nullable=true) + */ + protected $file_warr_card; + + // vehicle + /** + * @ORM\ManyToOne(targetEntity="Vehicle") + * @ORM\JoinColumn(name="vehicle_id", referencedColumnName="id", nullable=true) + */ + protected $vehicle; + + // vehicle model year + /** + * @ORM\Column(type="string", length=10, nullable=true) + */ + protected $v_model_year; + + // odometer reading + /** + * @ORM\Column(type="integer", nullable=true) + */ + protected $odometer; + + // dealer name + /** + * @ORM\Column(type="string", length=80, nullable=true) + */ + protected $dealer_name; + + // dealer address + /** + * @ORM\Column(type="string", length=180, nullable=true) + */ + protected $dealer_address; + + // customer contact number + /** + * @ORM\Column(type="string", length=30, nullable=true) + */ + protected $contact_num; + + // customer address + /** + * @ORM\Column(type="string", length=280, nullable=true) + */ + protected $cust_address; + + // date purchase as specified by customer + // TODO: currently this does not affect warranty, someone will have to view this and set + // actual purchase date + /** + * @ORM\Column(type="date", nullable=true) + */ + protected $date_purchase_cust; + + // if the warranty has been validated by an agent + /** + * @ORM\Column(type="boolean", options={"default": false}) + */ + protected $flag_validated; + + // link to customer + // TODO: check if this is the best way to do it, we'll be creating a new customer for every warranty since there is no reliable way to match customer to existing + /** + * @ORM\ManyToOne(targetEntity="Customer") + * @ORM\JoinColumn(name="customer_id", referencedColumnName="id", nullable=true) + */ + protected $customer; + public function __construct() { $this->date_create = new DateTime(); @@ -149,6 +230,8 @@ class Warranty $this->date_claim = null; $this->flag_activated = false; $this->email = ''; + $this->odometer = 0; + $this->flag_validated = false; } public function getID() @@ -412,4 +495,135 @@ class Warranty return $this->privacy_policy; } + public function setFileInvoice($file = null) + { + $this->file_invoice = $file; + return $this; + } + + public function getFileInvoice() + { + return $this->file_invoice; + } + + public function setFileWarrantyCard($file = null) + { + $this->file_warr_card = $file; + return $this; + } + + public function getFileWarrantyCard() + { + return $this->file_warr_card; + } + + public function setVehicle(Vehicle $v) + { + $this->vehicle = $v; + return $this; + } + + public function getVehicle() + { + return $this->vehicle; + } + + public function setVehicleModelYear($year) + { + $this->v_model_year = $year; + return $this; + } + + public function getVehicleModelYear() + { + return $this->v_model_year; + } + + public function setOdometer($odometer) + { + $this->odometer = $odometer; + return $this; + } + + public function getOdometer() + { + return $this->odometer; + } + + public function setDealerName($name) + { + $this->dealer_name = $name; + return $this; + } + + public function getDealerName() + { + return $this->dealer_name; + } + + public function setDealerAddress($address) + { + $this->dealer_address = $address; + return $this; + } + + public function getDealerAddress() + { + return $this->dealer_address; + } + + public function setContactNumber($contact_num) + { + $this->contact_num = $contact_num; + return $this; + } + + public function getContactNumber() + { + return $this->contact_num; + } + + public function setCustomerAddress($address) + { + $this->cust_address = $address; + return $this; + } + + public function getCustomerAddress() + { + return $this->cust_address; + } + + public function setDatePurchaseCustomer($date) + { + $this->date_purchase_cust = $date; + return $this; + } + + public function getDatePurchaseCustomer() + { + return $this->date_purchase_cust; + } + + public function setValidated($bool = true) + { + $this->flag_validated = $bool; + return $this; + } + + public function isValidated() + { + return $this->flag_validated; + } + + public function setCustomer(Customer $customer) + { + $this->customer = $customer; + return $this; + } + + public function getCustomer() + { + return $this->customer; + } } diff --git a/src/Service/CustomerHandler/ResqCustomerHandler.php b/src/Service/CustomerHandler/ResqCustomerHandler.php index 5f3653dd..76d20054 100644 --- a/src/Service/CustomerHandler/ResqCustomerHandler.php +++ b/src/Service/CustomerHandler/ResqCustomerHandler.php @@ -539,6 +539,8 @@ class ResqCustomerHandler implements CustomerHandlerInterface 'flag_dpa_consent' => $customer->isDpaConsent(), 'flag_promo_sms' => $customer->isPromoSms(), 'flag_promo_email' => $customer->isPromoEmail(), + 'flag_research_sms' => $customer->isResearchSms(), + 'flag_research_email' => $customer->isResearchEmail(), ], 'vehicle' => [ 'id' => $vehicle->getID(), @@ -599,7 +601,9 @@ class ResqCustomerHandler implements CustomerHandlerInterface ->setActive($req->request->get('flag_active') ? true : false) ->setPromoSms($req->request->get('flag_promo_sms', false)) ->setPromoEmail($req->request->get('flag_promo_email', false)) - ->setDpaConsent($is_dpa_checked); + ->setDpaConsent($is_dpa_checked) + ->setResearchSms($req->request->get('flag_research_sms', false)) + ->setResearchEmail($req->request->get('flag_research_email', false)); // phone numbers $obj->setPhoneMobile($req->request->get('phone_mobile')) diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index 70cac92d..10d5b2f8 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -320,6 +320,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $customer->setEmail($req->request->get('customer_email')) ->setPromoSms($req->request->get('flag_promo_sms', false)) ->setPromoEmail($req->request->get('flag_promo_email', false)) + ->setResearchSms($req->request->get('flag_research_sms', false)) + ->setResearchEmail($req->request->get('flag_research_email', false)) ->setDpaConsent($is_dpa_checked); } diff --git a/symfony.lock b/symfony.lock index 900434cc..c699229c 100644 --- a/symfony.lock +++ b/symfony.lock @@ -113,6 +113,12 @@ "jdorn/sql-formatter": { "version": "v1.2.17" }, + "microsoft/azure-storage-blob": { + "version": "1.5.2" + }, + "microsoft/azure-storage-common": { + "version": "1.5.1" + }, "nikic/php-parser": { "version": "v4.1.0" }, diff --git a/templates/battery-size/form.html.twig b/templates/battery-size/form.html.twig index 1af1f342..06d3fadd 100644 --- a/templates/battery-size/form.html.twig +++ b/templates/battery-size/form.html.twig @@ -70,7 +70,16 @@
- + +
+ +
+ + +
+
diff --git a/templates/customer/form.html.twig b/templates/customer/form.html.twig index 97b80884..eeae4bbe 100644 --- a/templates/customer/form.html.twig +++ b/templates/customer/form.html.twig @@ -122,6 +122,27 @@
+
+
+ +
+ + +
+
+
+ +
{% if is_granted('customer.dpa') %} @@ -129,9 +150,7 @@ {% endif %}
-
-
-
+
+
+ + + +
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ +
+ + +
+
+
+
{% if is_granted('customer.dpa') %} @@ -219,6 +266,15 @@
+
+ + + +
{% if obj.getCustomerVehicle %}
@@ -353,7 +409,7 @@
- +
@@ -375,34 +431,6 @@
-
-
-
-
- -
- - -
-
-
-
-
- - - -
-