Compare commits
3 commits
master
...
370-prowar
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e14947e486 | ||
|
|
efba8f1f48 | ||
|
|
33c76d6d78 |
7 changed files with 619 additions and 0 deletions
47
src/Command/TestWarrantyComputationCommand.php
Normal file
47
src/Command/TestWarrantyComputationCommand.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use App\Service\Prowar\WarrantyComputationCriteria;
|
||||
use App\Service\Prowar\WarrantyComputationService;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class TestWarrantyComputationCommand extends Command
|
||||
{
|
||||
protected $wcs;
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('test:generatewarrantycomputation')
|
||||
->setDescription('Test Prowar generate warranty computation service.')
|
||||
->setHelp('Test Prowar generate warranty computation service.');
|
||||
}
|
||||
|
||||
public function __construct(WarrantyComputationService $wcs)
|
||||
{
|
||||
$this->wcs = $wcs;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$warr_criteria = new WarrantyComputationCriteria();
|
||||
|
||||
// set test values
|
||||
$warr_criteria->setTotalWarranty(24)
|
||||
->setPurchaseDate(DateTime::createFromFormat('Y-m-d', '2019-01-15'))
|
||||
->setClaimDate(new DateTime())
|
||||
->setBatteryPrice(100.00)
|
||||
->setWarrantyLimit(12);
|
||||
|
||||
$amount = $this->wcs->generateWarrantyComputation($warr_criteria);
|
||||
|
||||
error_log('Customer pays ' . $amount);
|
||||
}
|
||||
}
|
||||
222
src/Service/Prowar/Entity/Customer.php
Normal file
222
src/Service/Prowar/Entity/Customer.php
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service\Prowar\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="customer")
|
||||
*/
|
||||
class Customer
|
||||
{
|
||||
// unique id
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
// first name
|
||||
/**
|
||||
* @ORM\Column(type="string", length=80)
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $first_name;
|
||||
|
||||
// last name
|
||||
/**
|
||||
* @ORM\Column(type="string", length=80)
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $last_name;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", length=65535)
|
||||
*/
|
||||
protected $customer_notes;
|
||||
|
||||
// mobile phone
|
||||
/**
|
||||
* @ORM\Column(type="string", length=30)
|
||||
*/
|
||||
protected $phone_mobile;
|
||||
|
||||
// landline
|
||||
/**
|
||||
* @ORM\Column(type="string", length=30)
|
||||
*/
|
||||
protected $phone_landline;
|
||||
|
||||
// office phone
|
||||
/**
|
||||
* @ORM\Column(type="string", length=30)
|
||||
*/
|
||||
protected $phone_office;
|
||||
|
||||
// fax
|
||||
/**
|
||||
* @ORM\Column(type="string", length=30)
|
||||
*/
|
||||
protected $phone_fax;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=80)
|
||||
*/
|
||||
protected $email;
|
||||
|
||||
// vehicles linked to customer
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="CustomerVehicle", mappedBy="customer", cascade={"persist"})
|
||||
*/
|
||||
protected $vehicles;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->vehicles = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getID()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
|
||||
public function setFirstName($first_name)
|
||||
{
|
||||
$this->first_name = $first_name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFirstName()
|
||||
{
|
||||
return $this->first_name;
|
||||
}
|
||||
|
||||
public function setLastName($last_name)
|
||||
{
|
||||
$this->last_name = $last_name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLastName()
|
||||
{
|
||||
return $this->last_name;
|
||||
}
|
||||
|
||||
public function getNameDisplay()
|
||||
{
|
||||
return $this->first_name . ' ' . $this->last_name;
|
||||
}
|
||||
|
||||
public function setCustomerNotes($customer_notes)
|
||||
{
|
||||
$this->customer_notes = $customer_notes;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCustomerNotes()
|
||||
{
|
||||
return $this->customer_notes;
|
||||
}
|
||||
|
||||
public function getMobileNumberList()
|
||||
{
|
||||
$phones = [];
|
||||
|
||||
if (!empty($this->phone_mobile))
|
||||
$phones[] = $this->phone_mobile;
|
||||
|
||||
if (!empty($this->phone_landline))
|
||||
$phones[] = $this->phone_landline;
|
||||
|
||||
if (!empty($this->phone_office))
|
||||
$phones[] = $this->phone_office;
|
||||
|
||||
if (!empty($this->phone_fax))
|
||||
$phones[] = $this->phone_fax;
|
||||
|
||||
return $phones;
|
||||
}
|
||||
|
||||
public function setPhoneMobile($phone)
|
||||
{
|
||||
$this->phone_mobile = $phone;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPhoneMobile()
|
||||
{
|
||||
return $this->phone_mobile;
|
||||
}
|
||||
|
||||
public function setPhoneLandline($phone)
|
||||
{
|
||||
$this->phone_landline = $phone;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPhoneLandline()
|
||||
{
|
||||
return $this->phone_landline;
|
||||
}
|
||||
|
||||
public function setPhoneOffice($phone)
|
||||
{
|
||||
$this->phone_office = $phone;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPhoneOffice()
|
||||
{
|
||||
return $this->phone_office;
|
||||
}
|
||||
|
||||
public function setPhoneFax($phone)
|
||||
{
|
||||
$this->phone_fax = $phone;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPhoneFax()
|
||||
{
|
||||
return $this->phone_fax;
|
||||
}
|
||||
|
||||
public function setEmail($email)
|
||||
{
|
||||
$this->email = $email;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function addVehicle(CustomerVehicle $vehicle)
|
||||
{
|
||||
$this->vehicles->add($vehicle);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function clearVehicles()
|
||||
{
|
||||
$this->vehicles->clear();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeVehicle($vehicle)
|
||||
{
|
||||
$this->vehicles->removeElement($vehicle);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVehicles()
|
||||
{
|
||||
return $this->vehicles;
|
||||
}
|
||||
}
|
||||
77
src/Service/Prowar/Entity/CustomerVehicle.php
Normal file
77
src/Service/Prowar/Entity/CustomerVehicle.php
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="customer_vehicle", indexes={@ORM\Index(columns={"plate_number"}, flags={"fulltext"}),
|
||||
@ORM\Index(name="plate_number_idx", columns={"plate_number"})})
|
||||
*/
|
||||
class CustomerVehicle
|
||||
{
|
||||
// unique id
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
// link to customer
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="Customer", inversedBy="vehicles")
|
||||
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $customer;
|
||||
|
||||
// plate number
|
||||
/**
|
||||
* @ORM\Column(type="string", length=100)
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $plate_number;
|
||||
|
||||
|
||||
public function getID()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setCustomer(Customer $customer)
|
||||
{
|
||||
$this->customer = $customer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCustomer()
|
||||
{
|
||||
return $this->customer;
|
||||
}
|
||||
|
||||
public function setPlateNumber($plate_number)
|
||||
{
|
||||
// make it upper case
|
||||
$plate_number = trim(strtoupper($plate_number));
|
||||
|
||||
// remove spaces
|
||||
$plate_number = str_replace(' ', '', $plate_number);
|
||||
|
||||
// upper case
|
||||
$plate_number = strtoupper($plate_number);
|
||||
|
||||
$this->plate_number = $plate_number;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPlateNumber()
|
||||
{
|
||||
return strtoupper($this->plate_number);
|
||||
}
|
||||
}
|
||||
82
src/Service/Prowar/Entity/Distributor.php
Normal file
82
src/Service/Prowar/Entity/Distributor.php
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service\Prowar\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="distributor")
|
||||
*/
|
||||
class Distributor
|
||||
{
|
||||
// unique id
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
// name
|
||||
/**
|
||||
* @ORM\Column(type="string", length=80)
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
// retailers
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity="Retailer", inversedBy="distributors", indexBy="id")
|
||||
* @ORM\JoinTable(name="distributor_retailer")
|
||||
*/
|
||||
protected $retailers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->retailers = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getID()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function addRetailer(Retailer $retailer)
|
||||
{
|
||||
if (!isset($this->retailers[$retailer->getID()]))
|
||||
$this->retailers[$retailer->getID()] = $retailer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeRetailer(Retailer $retailer)
|
||||
{
|
||||
if (isset($this->retailers[$retailer->getID()]))
|
||||
unset($this->retailers[$retailer->getID()]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function clearRetailers()
|
||||
{
|
||||
$this->retailers->clear();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRetailers()
|
||||
{
|
||||
return $this->retailers;
|
||||
}
|
||||
}
|
||||
61
src/Service/Prowar/Entity/Retailer.php
Normal file
61
src/Service/Prowar/Entity/Retailer.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service\Prowar\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="retailer")
|
||||
*/
|
||||
class Retailer
|
||||
{
|
||||
// unique id
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\Column(type="integer")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
// name
|
||||
/**
|
||||
* @ORM\Column(type="string", length=80)
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
// distributors
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity="Distributor", mappedBy="retailers", indexBy="id", fetch="EXTRA_LAZY")
|
||||
*/
|
||||
protected $distributors;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->distributors = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getID()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getDistributors()
|
||||
{
|
||||
return $this->distributors;
|
||||
}
|
||||
}
|
||||
68
src/Service/Prowar/WarrantyComputationCriteria.php
Normal file
68
src/Service/Prowar/WarrantyComputationCriteria.php
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service\Prowar;
|
||||
|
||||
class WarrantyComputationCriteria
|
||||
{
|
||||
protected $total_warranty;
|
||||
protected $purchase_date; // DateTime
|
||||
protected $claim_date; // DateTime
|
||||
protected $battery_price;
|
||||
protected $warranty_limit;
|
||||
|
||||
public function setTotalWarranty($total_warranty)
|
||||
{
|
||||
$this->total_warranty = $total_warranty;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTotalWarranty()
|
||||
{
|
||||
return $this->total_warranty;
|
||||
}
|
||||
|
||||
public function setPurchaseDate($purchase_date)
|
||||
{
|
||||
$this->purchase_date = $purchase_date;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPurchaseDate()
|
||||
{
|
||||
return $this->purchase_date;
|
||||
}
|
||||
|
||||
public function setClaimDate($claim_date)
|
||||
{
|
||||
$this->claim_date = $claim_date;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getClaimDate()
|
||||
{
|
||||
return $this->claim_date;
|
||||
}
|
||||
|
||||
public function setBatteryPrice($battery_price)
|
||||
{
|
||||
$this->battery_price = $battery_price;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBatteryPrice()
|
||||
{
|
||||
return $this->battery_price;
|
||||
}
|
||||
|
||||
public function setWarrantyLimit($warranty_limit)
|
||||
{
|
||||
$this->warranty_limit = $warranty_limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getWarrantyLimit()
|
||||
{
|
||||
return $this->warranty_limit;
|
||||
}
|
||||
|
||||
}
|
||||
62
src/Service/Prowar/WarrantyComputationService.php
Normal file
62
src/Service/Prowar/WarrantyComputationService.php
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service\Prowar;
|
||||
|
||||
use App\Service\Prowar\WarrantyComputationCriteria;
|
||||
|
||||
use DateTime;
|
||||
use DateInterval;
|
||||
|
||||
class WarrantyComputationService
|
||||
{
|
||||
public function generateWarrantyComputation(WarrantyComputationCriteria $criteria)
|
||||
{
|
||||
$customer_amount = 0;
|
||||
|
||||
// get purchase dates and claim dates
|
||||
// assumption is that these are already DateTime objects
|
||||
// if not, convert string to DateTime objects
|
||||
// $purchase_date = DateTime::createFromFormat('Y-m-d', $criteria->getPurchaseDate());
|
||||
// $claim_date = DateTime::createFromFormat('Y-m-d', $criteria->getClaimDate());
|
||||
$purchase_date = $criteria->getPurchaseDate();
|
||||
$claim_date = $criteria->getClaimDate();
|
||||
|
||||
// compute number of months between purchase date and claim date
|
||||
$interval = $purchase_date->diff($claim_date);
|
||||
|
||||
// format the computed difference in months + days
|
||||
$diff_in_years = $interval->y;
|
||||
$diff_in_months = $interval->m;
|
||||
$diff_in_days = $interval->d;
|
||||
|
||||
// convert the difference in years to months
|
||||
// then add to diff_in_months
|
||||
$year_diff = $diff_in_years * 12;
|
||||
$diff_in_months +=$year_diff;
|
||||
|
||||
// check if difference in months is greater than the total warranty
|
||||
// meaning out of warranty
|
||||
$total_warranty = $criteria->getTotalWarranty();
|
||||
if ($diff_in_months > $total_warranty)
|
||||
$customer_amount = $criteria->getBatteryPrice();
|
||||
else
|
||||
{
|
||||
// check if difference in months is greater than warranty limit
|
||||
$warranty_limit = $criteria->getWarrantyLimit();
|
||||
if (($diff_in_months > $warranty_limit) && ($diff_in_days > 0))
|
||||
{
|
||||
// compute pro-rate
|
||||
// formula: remaining months/total warranty = percent discount
|
||||
$percent_discount = ($total_warranty - $diff_in_months)/$total_warranty;
|
||||
|
||||
$battery_price = $criteria->getBatteryPrice();
|
||||
|
||||
$discount_amount = $battery_price * $percent_discount;
|
||||
$customer_amount = $battery_price - $discount_amount;
|
||||
}
|
||||
}
|
||||
|
||||
return $customer_amount;
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue