resq/src/Controller/CustomerAppAPI/InsuranceController.php
2024-02-22 16:51:26 +08:00

338 lines
11 KiB
PHP

<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Service\InsuranceConnector;
use App\Service\PayMongoConnector;
use App\Entity\InsuranceApplication;
use App\Entity\GatewayTransaction;
use App\Entity\CustomerVehicle;
use App\Ramcar\InsuranceApplicationStatus;
use App\Ramcar\InsuranceMVType;
use App\Ramcar\InsuranceClientType;
use App\Ramcar\TransactionStatus;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use DateTime;
class InsuranceController extends ApiController
{
protected $client;
public function __construct(EntityManagerInterface $em, KernelInterface $kernel, InsuranceConnector $client)
{
parent::__construct($em, $kernel);
$this->client = $client;
}
public function createApplication(Request $req, PayMongoConnector $paymongo, UrlGeneratorInterface $router)
{
// validate params
$validity = $this->validateRequest($req, [
// internal
'customer_vehicle_id',
// client info
'client_type',
'first_name',
//'middle_name', // not required
'surname',
'corporate_name',
// client contact info
'address_number',
//'address_street', // not required
//'address_building', // not required
'address_barangay',
'address_city',
'address_province',
'zipcode',
'mobile_number',
'email_address',
// car info
'make',
'model',
'series',
'color',
//'plate_number', // NOTE: we get this from the internal cv record instead
'mv_file_number',
'motor_number',
'serial_chasis', // NOTE: this is how it's spelled on their API
'year_model',
'mv_type_id',
'body_type',
//'is_public', // not required, boolean, only show field if mv_type_id in [4, 13]
//'orcr_file', // this is a file
// mv_type_id specific fields
//'vehicle_use_type', // not required, only show field if mv_type_id is not in [4, 13]. accepted values are: 'commercial', 'private'
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// conditionally require is_public or vehicle_use_type
switch ($req->request->get('mv_type_id')) {
case 4:
case 13:
if (empty($req->request->get('is_public'))) {
return new ApiResponse(false, 'Missing required parameter(s): is_public is required when mv_type_id is in [4, 13]');
}
break;
default:
if (empty($req->request->get('vehicle_use_type'))) {
return new ApiResponse(false, 'Missing required parameter(s): vehicle_use_type is required when mv_type_id is not in [4, 13]');
}
break;
}
// require the orcr file
if ($req->files->get('orcr_file') === null) {
return new ApiResponse(false, 'Missing required file: orcr_file');
}
// get our listener url
$notif_url = $router->generate('insurance_listener', [], UrlGeneratorInterface::ABSOLUTE_URL);
// get customer and cv info
$cust = $this->session->getCustomer();
$cv = $this->em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle_id'));
if ($cv == null) {
return new ApiResponse(false, 'Invalid customer vehicle id.');
}
// confirm that customer vehicle belongs to customer
if ($cv->getCustomer()->getID() != $cust->getID()) {
return new ApiResponse(false, 'Vehicle does not belong to customer.');
}
// process all our inputs first
$input = $req->request->all();
if (!isset($input['is_public'])) {
$input['is_public'] = false;
}
$input['line'] = $this->getLineType($input['mv_type_id'], $input['vehicle_use_type'], $input['is_public']);
// submit insurance application
$result = $this->client->createApplication(
$cv,
$notif_url,
$input,
$req->files->get('orcr_file')
);
if (!$result['success']) {
return new ApiResponse(false, $result['error']['message']);
}
$premium_amount_int = (int)bcmul($result['response']['premium'], 100);
// build checkout item and metadata
$items = [
[
'name' => "Insurance Premium",
'description' => "Premium fee for vehicle insurance",
'quantity' => 1,
'amount' => $premium_amount_int,
'currency' => 'PHP',
],
];
$now = new DateTime();
// create gateway transaction
$gt = new GatewayTransaction();
$gt->setCustomer($cust);
$gt->setDateCreate($now);
$gt->setAmount($premium_amount_int);
$gt->setStatus(TransactionStatus::PENDING);
$gt->setGateway('paymongo'); // TODO: define values elsewhere
$gt->setType('insurance_premium'); // TODO: define values elsewhere
$this->em->persist($gt);
$this->em->flush();
// create paymongo checkout resource
$checkout = $paymongo->createCheckout(
$cust,
$items,
$gt->getID(),
"Motolite RES-Q Vehicle Insurance",
$router->generate('paymongo_payment_success', [], UrlGeneratorInterface::ABSOLUTE_URL),
$router->generate('paymongo_payment_cancelled', [], UrlGeneratorInterface::ABSOLUTE_URL),
['transaction_id' => $gt->getID()], // NOTE: passing this here too for payment resource metadata
);
if (!$checkout['success']) {
return new ApiResponse(false, $checkout['error']['message']);
}
$checkout_url = $checkout['response']['data']['attributes']['checkout_url'];
// add checkout url and id to transaction metadata
$gt->setExtTransactionId($checkout['response']['data']['id']);
$gt->setMetadata([
'checkout_url' => $checkout_url,
]);
// store application in db
$app = new InsuranceApplication();
$app->setDateSubmit($now);
$app->setCustomer($cust);
$app->setCustomerVehicle($cv);
$app->setGatewayTransaction($gt);
$app->setStatus(InsuranceApplicationStatus::CREATED);
$app->setExtTransactionId($result['response']['id']);
$app->setMetadata($input);
$this->em->persist($app);
// save everything
$this->em->flush();
// return
return new ApiResponse(true, '', [
'app_id' => $app->getID(),
'checkout_url' => $checkout_url,
'premium_amount' => (string)$result['response']['premium'],
]);
}
public function getVehicleMakers(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get maker list
$result = $this->client->getVehicleMakers();
if (!$result['success']) {
return new ApiResponse(false, $result['error']['message']);
}
return new ApiResponse(true, '', [
'makers' => $result['response']['data']['vehicleMakers'],
]);
}
public function getVehicleModels($maker_id, Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get maker list
$result = $this->client->getVehicleModels($maker_id);
if (!$result['success']) {
return new ApiResponse(false, $result['error']['message']);
}
return new ApiResponse(true, '', [
'models' => $result['response']['data']['vehicleModels'],
]);
}
public function getVehicleTrims($model_id, Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get maker list
$result = $this->client->getVehicleTrims($model_id);
if (!$result['success']) {
return new ApiResponse(false, $result['error']['message']);
}
return new ApiResponse(true, '', [
'trims' => $result['response']['data']['vehicleTrims'],
]);
}
public function getMVTypes(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
return new ApiResponse(true, '', [
'mv_types' => InsuranceMVType::getCollection(),
]);
}
public function getClientTypes(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
return new ApiResponse(true, '', [
'mv_types' => InsuranceClientType::getCollection(),
]);
}
public function getPremiumsBanner(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
return new ApiResponse(true, '', [
'url' => $this->getParameter('insurance_premiums_banner_url'),
]);
}
protected function getLineType($mv_type_id, $vehicle_use_type, $is_public = false)
{
$line = '';
// NOTE: this is a bit of a hack since we're hardcoding values, but this is fine for now
switch ($mv_type_id) {
case '3':
$line = 'mcoc';
break;
case '4':
case '13':
if ($is_public) {
$line = 'lcoc';
} else {
$line = 'mcoc';
}
break;
default:
if ($vehicle_use_type === 'commercial') {
$line = 'ccoc';
} else {
$line = 'pcoc';
}
break;
}
return $line;
}
}