<?php
namespace Diplix\KMGBundle\Entity\Accounting;
use Diplix\KMGBundle\Entity\BasicEntity;
use Diplix\KMGBundle\Entity\Customer;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="acc_billing", indexes={@ORM\Index(name="be_deleted",columns={"be_deleted"})})
* @ORM\Entity()
*
*
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="type", type="string")
* @ORM\DiscriminatorMap({"K" = "BillingForCustomer", "M" = "BillingForMember"})
*
*/
abstract class Billing extends BasicEntity
{
const TYPE_MEMBER = 'M';
const TYPE_CUSTOMER = 'K';
/**
* @ORM\Column(type="integer",name="id")
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(name="bill_from", type="datetime",nullable=false)
*/
protected $from;
/**
* @ORM\Column(name="bill_until",type="datetime",nullable=false)
*/
protected $until;
/**
* @ORM\ManyToOne(targetEntity="Diplix\KMGBundle\Entity\Accounting\CoopMember")
* @ORM\JoinColumn(nullable=true)
*/
protected $member;
/**
* @ORM\ManyToOne(targetEntity="Diplix\KMGBundle\Entity\Customer")
* @ORM\JoinColumn(nullable=true)
*/
protected $customer;
/**
* @ORM\Column(type="json")
* @var array ( item => amount )
*/
protected $extras = [];
/**
* @ORM\Column(type="decimal", nullable=false, precision=5, scale=2,options={"unsigned":true})
*/
protected $deductionPercent = 0.0;
/**
* @ORM\Column(type="decimal", nullable=false, precision=7, scale=2,options={"unsigned":false})
*/
protected $totalNet = 0.0;
/////////////////////////////////////
public static function createFor($type)
{
if ($type===self::TYPE_CUSTOMER)
return new BillingForCustomer();
if ($type===self::TYPE_MEMBER)
return new BillingForMember();
throw new \RuntimeException('Unknown type');
}
public function recalculateTotal()
{
$total = 0;
foreach ($this->getJobList() as $j)
{
if ($this->getType()=== self::TYPE_CUSTOMER)
{
$total += $j->getTotalCustomerNet();
}
else
if ($this->getType()=== self::TYPE_MEMBER)
{
$total += $j->getTotalMemberNet();
}
else
{
throw new \RuntimeException('unknown type');
}
}
$total = (1 - ($this->getDeductionPercent()/100)) * $total;
if ($this->extras!==null)
{
foreach ($this->extras as $k=>$e)
{
$total += $e;
}
}
$this->setTotalNet($total);
return $total;
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @return mixed
*/
public function getFrom()
{
return $this->from;
}
/**
* @param mixed $from
*/
public function setFrom($from)
{
$this->from = $from;
}
/**
* @return mixed
*/
public function getUntil()
{
return $this->until;
}
/**
* @param mixed $until
*/
public function setUntil($until)
{
$this->until = $until;
}
/**
* @return ArrayCollection|Job[]
*/
abstract public function getJobList();
/**
* @param ArrayCollection $jobList
*/
abstract public function setJobList($jobList);
/**
* @return string
*/
abstract public function getType();
/**
* @return CoopMember|null
*/
public function getMember()
{
return $this->member;
}
/**
* @param mixed $member
*/
public function setMember($member)
{
if (!($this instanceof BillingForMember)) throw new \RuntimeException('Cannot assign a member to a Billing which is not of type MEMBER');
$this->member = $member;
}
/**
* @return Customer|null
*/
public function getCustomer()
{
return $this->customer;
}
/**
* @param mixed $customer
*/
public function setCustomer($customer)
{
if (!($this instanceof BillingForCustomer)) throw new \RuntimeException('Cannot assign a customer to a Billing which is not of type customer');
$this->customer = $customer;
}
/**
* @return float
*/
public function getTotalNet()
{
return $this->totalNet;
}
/**
* @param float $totalNet
*/
public function setTotalNet($totalNet)
{
$this->totalNet = $totalNet;
}
/**
* @return float
*/
public function getDeductionPercent()
{
return $this->deductionPercent;
}
/**
* @param float $deductionPercent
*/
public function setDeductionPercent($deductionPercent)
{
$this->deductionPercent = $deductionPercent;
}
/**
* @return array
*/
public function getExtras()
{
if ($this->extras === null) return [];
return $this->extras;
}
public function addExtra($text,$amount,$overwrite=false)
{
if ((array_key_exists($text,$this->extras)) && (!$overwrite) )
{
throw new \RuntimeException('Duplicate key for extra: '.$text);
}
$this->extras[$text] = $amount;
}
public function setExtras($val)
{
if ($val===null) $val = [];
$this->extras = $val;
}
}