Compare commits

...

3 commits

7 changed files with 619 additions and 0 deletions

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

View 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;
}
}

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

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}