Add checking for duplicate generated ids when flushing. #638

This commit is contained in:
Korina Cordero 2021-11-16 09:54:58 +00:00
parent f29c69cad1
commit c40143dced
8 changed files with 152 additions and 22 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,59 @@
<?php
namespace App\Service;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Customer;
use App\Service\UniqueIdGenerator;
class CustomerGeneratedIdService
{
protected $em;
protected $id_gen;
public function __construct(EntityManagerInterface $em, UniqueIdGenerator $id_gen)
{
$this->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;
}
}
}

View file

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

View file

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