diff --git a/config/services.yaml b/config/services.yaml index 65576192..0ba337cf 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -306,3 +306,9 @@ services: App\Service\UniqueIdGenerator: arguments: $em: "@doctrine.orm.entity_manager" + + # service to generate id for customer and to save customer + App\Service\CustomerGeneratedIdService: + arguments: + $em: "@doctrine.orm.entity_manager" + $id_gen: "@App\\Service\\UniqueIdGenerator" diff --git a/src/Controller/APIController.php b/src/Controller/APIController.php index b072d8e4..da2703be 100644 --- a/src/Controller/APIController.php +++ b/src/Controller/APIController.php @@ -47,6 +47,7 @@ use App\Service\HubSelector; use App\Service\HubDistributor; use App\Service\HubFilterLogger; use App\Service\HubFilteringGeoChecker; +use App\Service\CustomerGeneratedIdService; use App\Entity\MobileSession; use App\Entity\Customer; @@ -442,7 +443,7 @@ class APIController extends Controller implements LoggedController return $cust; } - public function updateInfo(Request $req, EntityManagerInterface $em) + public function updateInfo(Request $req, EntityManagerInterface $em, CustomerGeneratedIdService $cust_gen_id) { // check required parameters and api key $required_params = [ @@ -468,8 +469,26 @@ class APIController extends Controller implements LoggedController { $cust->setPrivacyPolicyMobile($mobile_policy); } - - $em->flush(); + + // need to check if it's a new customer or updated existing customer + // a new customer would not have a generated id while an existing one + // already have one. + if ($cust->getGeneratedId() == null) + { + // TODO: temporary fix on how to save customer with a generated id + // since we need to keep generating an id until we are sure that there + // are no duplicates for generated id + // when saving the customer. This is an additional check. + // This will keep generating an id until a unique id is generated + // and the customer entity can then be inserted + $cust_gen_id->saveCustomerWithGeneratedId($cust); + } + else + { + // we do a simple flush with no id generation for updated existing + // customers + $em->flush(); + } return $res->getReturnResponse(); } diff --git a/src/Controller/CAPI/CustomerController.php b/src/Controller/CAPI/CustomerController.php index 9148321e..0d89a0e9 100644 --- a/src/Controller/CAPI/CustomerController.php +++ b/src/Controller/CAPI/CustomerController.php @@ -15,6 +15,8 @@ use App\Entity\Customer; use App\Entity\CustomerVehicle; use App\Entity\Vehicle; +use App\Service\CustomerGeneratedIdService; + use Catalyst\APIBundle\Access\Generator as ACLGenerator; class CustomerController extends APIController @@ -26,7 +28,7 @@ class CustomerController extends APIController $this->acl_gen = $acl_gen; } - public function register(Request $req, EntityManagerInterface $em) + public function register(Request $req, EntityManagerInterface $em, CustomerGeneratedIdService $cust_gen_id) { $this->denyAccessUnlessGranted('customer.register', null, 'No access.'); @@ -150,6 +152,8 @@ class CustomerController extends APIController ]; } } + + $em->flush(); } else { @@ -194,9 +198,16 @@ class CustomerController extends APIController 'condition' => $condition, 'fuel_type' => $fuel_type, ]; + + // TODO: temporary fix on how to save customer with a generated id + // since we need to keep generating an id until we are sure that there + // are no duplicates for generated id + // when saving the customer. This is an additional check. + // This will keep generating an id until a unique id is generated + // and the customer entity can then be inserted + $cust_gen_id->saveCustomerWithGeneratedId($new_cust); } - $em->flush(); $em->clear(); return new APIResponse(true, $message, $data); diff --git a/src/Controller/CAPI/CustomerWarrantyController.php b/src/Controller/CAPI/CustomerWarrantyController.php index edf00e2e..bc942b22 100644 --- a/src/Controller/CAPI/CustomerWarrantyController.php +++ b/src/Controller/CAPI/CustomerWarrantyController.php @@ -15,6 +15,7 @@ use Catalyst\APIBundle\Response\APIResponse; use App\Service\RisingTideGateway; use App\Service\WarrantyAPILogger; +use App\Service\CustomerGeneratedIdService; use App\Entity\WarrantySerial; use App\Entity\Warranty; @@ -301,7 +302,7 @@ class CustomerWarrantyController extends APIController public function register($serial, EntityManagerInterface $em, Request $req, KernelInterface $kernel, RisingTideGateway $rt, TranslatorInterface $trans, - WarrantyAPILogger $logger) + WarrantyAPILogger $logger, CustomerGeneratedIdService $cust_gen_id) { error_log('HERE - register'); @@ -325,7 +326,7 @@ class CustomerWarrantyController extends APIController $username = $this->getUser()->getName(); $source = 'CAPI_USER_' . $username; - error_log('SOURCE: ' . $source); + // error_log('SOURCE: ' . $source); // TODO: maybe add vmake_id? since warranty cannot be created with no vmake // TODO: maybe also add mobile and email since customer creation won't let mobile and email be null @@ -353,7 +354,7 @@ class CustomerWarrantyController extends APIController // do actual registering $res = $this->updateWarranty($em, $rt, $trans, $req, $serial, $inv_filename, $wcard_filename, - $logger, $log_data, $user_id, $action, $source); + $logger, $log_data, $user_id, $action, $source, $cust_gen_id); // flush to db $em->flush(); @@ -395,7 +396,7 @@ class CustomerWarrantyController extends APIController } protected function updateWarranty($em, $rt, $trans, $req, $serial, $inv_filename = null, $wcard_filename = null, - $logger, $log_data, $user_id, $action, $source) + $logger, $log_data, $user_id, $action, $source, $cust_gen_id) { $plate_num = $this->cleanPlateNumber($req->request->get('plate_num')); @@ -512,7 +513,6 @@ class CustomerWarrantyController extends APIController $cust->setPrivacyPromo($priv_promo); } - error_log('update entity / database'); // create or update warranty entry $warr->setSerial($serial) @@ -556,15 +556,30 @@ class CustomerWarrantyController extends APIController $em->persist($warr); - $logger->logWarrantyInfo($log_data, '', $user_id, $action, $source); + // need to check if it's a new customer or updated existing customer + // a new customer would not have a generated id while an existing one + // already have one. + if ($cust->getGeneratedId() == null) + { + // TODO: temporary fix on how to save customer with a generated id + // since we need to keep generating an id until we are sure that there + // are no duplicates for generated id + // when saving the customer. This is an additional check. + // This will keep generating an id until a unique id is generated + // and the customer entity can then be inserted + $cust_gen_id->saveCustomerWithGeneratedId($cust); + } // TODO: check if we need to do anything else $data = []; - // send sms confirmation $this->sendSMSConfirmation($rt, $req->request->get('contact_num'), $sms_message); + $logger->logWarrantyInfo($log_data, '', $user_id, $action, $source); + + $em->flush(); + return new APIResponse(true, 'Warranty registered.', $data); } diff --git a/src/Controller/CAPI/WarrantyController.php b/src/Controller/CAPI/WarrantyController.php index 4db8051c..b2f9c5c8 100644 --- a/src/Controller/CAPI/WarrantyController.php +++ b/src/Controller/CAPI/WarrantyController.php @@ -23,6 +23,7 @@ use App\Entity\Vehicle; use App\Entity\WarrantyAPILog; use App\Service\WarrantyAPILogger; +use App\Service\CustomerGeneratedIdService; use App\Ramcar\NameValue; use App\Ramcar\WarrantyClass; @@ -146,7 +147,7 @@ class WarrantyController extends APIController return new APIResponse(true, 'Warranties found.', $data); } - public function register(Request $req, EntityManagerInterface $em, WarrantyAPILogger $logger) + public function register(Request $req, EntityManagerInterface $em, WarrantyAPILogger $logger, CustomerGeneratedIdService $cust_gen_id) { $this->denyAccessUnlessGranted('warranty.register.battery', null, 'No access.'); @@ -287,7 +288,7 @@ class WarrantyController extends APIController { $em->persist($warr); - $this->getCustomerFromMobile($em, $warr); + $this->getCustomerFromMobile($em, $warr, $cust_gen_id); $em->flush(); } @@ -638,7 +639,7 @@ class WarrantyController extends APIController return new APIResponse(true, 'Warranties found.', $data); } - protected function getCustomerFromMobile($em, $warranty) + protected function getCustomerFromMobile($em, $warranty, $cust_gen_id) { $w_mobile = $warranty->getMobileNumber(); if (empty($w_mobile)) @@ -717,6 +718,7 @@ class WarrantyController extends APIController $this->createCustomerVehicle($em, $customer, $this->getDefaultVehicle($em), $w_plate_number); } } + $em->flush(); } // customer not found else @@ -738,9 +740,17 @@ class WarrantyController extends APIController $em->persist($new_cust); $this->createCustomerVehicle($em, $new_cust, $this->getDefaultVehicle($em), $w_plate_number); + + // TODO: temporary fix on how to save customer with a generated id + // since we need to keep generating an id until we are sure that there + // are no duplicates for generated id + // when saving the customer. This is an additional check. + // This will keep generating an id until a unique id is generated + // and the customer entity can then be inserted + $cust_gen_id->saveCustomerWithGeneratedId($new_cust); } - $em->flush(); + // $em->flush(); $em->clear(); } diff --git a/src/Service/CustomerGeneratedIdService.php b/src/Service/CustomerGeneratedIdService.php new file mode 100644 index 00000000..92c85836 --- /dev/null +++ b/src/Service/CustomerGeneratedIdService.php @@ -0,0 +1,59 @@ +em = $em; + $this->id_gen = $id_gen; + } + + public function saveCustomerWithGeneratedId(Customer $cust) + { + $em = $this->em; + $id_gen = $this->id_gen; + + // need to generate id + // have to try catch the flush because of the generated id + // need to retry until we get a unique generated id + while (true) + { + try + { + $generated_id = $id_gen->generateCustomerUniqueId(40); + $cust->setGeneratedId($generated_id); + + // reopen in case we get an exception + if (!$em->isOpen()) + { + $em = $em->create( + $em->getConnection(), + $em->getConfiguration() + ); + } + + $em->flush(); + } + catch (UniqueConstraintViolationException $e) + { + error_log($e->getMessage()); + // delay one second and try again + sleep(1); + continue; + + } + break; + } + } +} diff --git a/src/Service/CustomerHandler/ResqCustomerHandler.php b/src/Service/CustomerHandler/ResqCustomerHandler.php index f8685801..7a0a4204 100644 --- a/src/Service/CustomerHandler/ResqCustomerHandler.php +++ b/src/Service/CustomerHandler/ResqCustomerHandler.php @@ -4,12 +4,15 @@ namespace App\Service\CustomerHandler; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\DBAL\Exception\UniqueConstraintViolationException; + use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Security\Core\Security; use App\Service\CustomerHandlerInterface; +use App\Service\CustomerGeneratedIdService; use App\Ramcar\CustomerClassification; use App\Ramcar\FuelType; @@ -34,14 +37,16 @@ class ResqCustomerHandler implements CustomerHandlerInterface protected $country_code; protected $security; protected $template_hash; + protected $cust_gen_id; public function __construct(EntityManagerInterface $em, ValidatorInterface $validator, - string $country_code, Security $security) + string $country_code, Security $security, CustomerGeneratedIdService $cust_gen_id) { $this->em = $em; $this->validator = $validator; $this->country_code = $country_code; $this->security = $security; + $this->cust_gen_id = $cust_gen_id; $this->loadTemplates(); } @@ -292,7 +297,16 @@ class ResqCustomerHandler implements CustomerHandlerInterface { // validated! save the entity $em->persist($row); - $em->flush(); + + // TODO: temporary fix on how to save customer with a generated id + // since we need to keep generating an id until we are sure that there + // are no duplicates for generated id + // when saving the customer. This is an additional check. + // This will keep generating an id until a unique id is generated + // and the customer entity can then be inserted + $this->cust_gen_id->saveCustomerWithGeneratedId($row); + + //$em->flush(); $result = [ 'id' => $row->getID(), diff --git a/src/Service/UniqueIdGenerator.php b/src/Service/UniqueIdGenerator.php index 0e8f05b0..cfca4779 100644 --- a/src/Service/UniqueIdGenerator.php +++ b/src/Service/UniqueIdGenerator.php @@ -9,13 +9,10 @@ use App\Entity\Customer; class UniqueIdGenerator { protected $em; - protected $cust_generated_ids; public function __construct(EntityManagerInterface $em) { $this->em = $em; - - $this->loadGeneratedIds(); } public function generateCustomerUniqueId($str_length) @@ -36,7 +33,6 @@ class UniqueIdGenerator sleep(1); } - } protected function generateUniqueId($str_length)