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'), ]); } public function getBodyTypes(Request $req) { // validate params $validity = $this->validateRequest($req); if (!$validity['is_valid']) { return new ApiResponse(false, $validity['error']); } $bt_collection = InsuranceBodyType::getCollection(); $body_types = []; // NOTE: formatting it this way to match how insurance third party API returns their own stuff, so it's all handled one way on the app foreach ($bt_collection as $bt_key => $bt_name) { $body_types[] = [ 'id' => $bt_key, 'name' => $bt_name, ]; } return new ApiResponse(true, '', [ 'body_types' => $body_types, ]); } 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; } }