diff --git a/config/routes/apiv2.yaml b/config/routes/apiv2.yaml index af7d0084..4ae55e05 100644 --- a/config/routes/apiv2.yaml +++ b/config/routes/apiv2.yaml @@ -260,4 +260,10 @@ apiv2_account_delete_resend_code: apiv2_account_delete_code_validate: path: /apiv2/account_delete_code_validate controller: App\Controller\CustomerAppAPI\AccountController::validateDeleteCode - methods: [POST] \ No newline at end of file + methods: [POST] + +# trade-in support +apiv2_cust_vehicle_trade_in_estimate: + path: /apiv2/vehicles/{id}/trade_in_estimate + controller: App\Controller\CustomerAppAPI\VehicleController::getTradeInEstimate + methods: [GET] diff --git a/src/Controller/CustomerAppAPI/VehicleController.php b/src/Controller/CustomerAppAPI/VehicleController.php index 51a8ce80..f5a3f869 100644 --- a/src/Controller/CustomerAppAPI/VehicleController.php +++ b/src/Controller/CustomerAppAPI/VehicleController.php @@ -6,9 +6,11 @@ use Symfony\Component\HttpFoundation\Request; use Catalyst\ApiBundle\Component\Response as ApiResponse; use App\Entity\CustomerVehicle; +use App\Entity\JobOrder; use App\Entity\VehicleManufacturer; use App\Entity\Vehicle; - +use App\Ramcar\JOStatus; +use App\Ramcar\ServiceType; use DateTime; class VehicleController extends ApiController @@ -141,6 +143,74 @@ class VehicleController extends ApiController ]); } + public function getTradeInEstimate(Request $req, $id) + { + // check requirements + $validity = $this->validateRequest($req); + + if (!$validity['is_valid']) { + return new ApiResponse(false, $validity['error']); + } + + // get customer vehicle + $cv = $this->em->getRepository(CustomerVehicle::class)->find($id); + + // check if it exists + if ($cv == null) { + return new ApiResponse(false, 'Vehicle does not exist.'); + } + + // check if it's owned by customer + if ($cv->getCustomer()->getID() != $this->session->getCustomer()->getID()) { + return new ApiResponse(false, 'Invalid vehicle.'); + } + + // compute for trade in value + $trade_in_value = 0; + $previous_jo_found = false; + + // check for last battery replacement JO + $last_jo = $this->em->getRepository(JobOrder::class)->findOneBy([ + 'service_type' => [ + ServiceType::BATTERY_REPLACEMENT_NEW, ServiceType::BATTERY_REPLACEMENT_WARRANTY + ], + 'status' => JOStatus::FULFILLED, + 'cus_vehicle' => $cv, + ], ['date_create' => 'desc']); + + if (!empty($last_jo)) { + $items = $last_jo->getInvoice()->getItems(); + + foreach ($items as $item) { + // find the first battery item and get its trade-in value + $item_battery = $item->getBattery(); + if (!empty($item_battery)) { + $previous_jo_found = true; + $trade_in_value = $item_battery->getSize()->getTIPriceMotolite(); + break; + } + } + } + + // TODO: possibly refactor this bit + // if no valid previous JO is found, use lowest value we can find based on battery compatibility + if (!$previous_jo_found) { + $comp_batteries = $cv->getVehicle()->getBatteries(); + + // default order of association is price desc, so we get the last row for the cheapest value possible. this is due to the assumption that we can have multiple battery sizes compatible with a vehicle + if (!empty($comp_batteries)) { + $lp_battery = array_reverse($comp_batteries->toArray())[0]; + $trade_in_value = $lp_battery->getSize()->getTIPriceOther(); + } + } + + // response + return new ApiResponse(true, '', [ + 'previous_jo_found' => $previous_jo_found, + 'trade_in_value' => $trade_in_value, + ]); + } + public function listVehicles(Request $req) { // validate params