<?php

namespace RxConnexionBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;

/**
 * @ORM\Entity(repositoryClass="RxConnexionBundle\Repository\PurchaseOrderBreakdownRepository")
 * @ORM\Table(name="purchase_order_breakdown")
 * @ORM\HasLifecycleCallbacks()
 */

class PurchaseOrderBreakdownEntity
{
    /**
     * @ORM\Column(type="bigint")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(name="po_no", type="string", nullable=true)
     */
    protected $poNo;

    /**
     * @ORM\Column(name="po_date", type="datetime")
     */
    protected $poDate;

    /**
     * @ORM\Column(name="purchase_order_no", type="decimal", precision=12, scale=0)
     */
    protected $purchaseOrderNo;

    /**
     * @ORM\Column(name="status", type="string")
     */
    protected $status;

    /**
     * @ORM\Column(name="payment_method", type="string")
     */
    protected $paymentMethod;

    /**
     * @ORM\Column(name="created_by", type="string", length=50)
     */
    protected $createdBy;

    /**
     * @ORM\Column(name="created_at", type="datetime")
     */
    protected $createdAt;

    /**
     * @ORM\Column(name="updated_by", type="string", length=50)
     */
    protected $updatedBy;

    /**
     * @ORM\Column(name="updated_at", type="datetime")
     */
    protected $updatedAt;

    /**
     * @ORM\ManyToOne(targetEntity="PurchaseOrderEntity", inversedBy="purchaseOrderBreakdowns")
     * @ORM\JoinColumn(name="purchase_order_id", referencedColumnName="id")
     */
    protected $purchaseOrder;

    /**
     * @ORM\OneToOne(targetEntity="PurchaseInvoiceEntity", mappedBy="purchaseOrderBreakdown")
     */
    protected $purchaseInvoice;
//
//    /**
//     * @ORM\OneToOne(targetEntity="TransactionLinkEntity", mappedBy="purchaseOrderBreakdown")
//     */
//    protected $transactionLink;

    /**
     * @ORM\OneToMany(targetEntity="PurchaseOrderBreakdownItemEntity", mappedBy="purchaseOrderBreakdown", cascade={"remove"})
     */
    protected $purchaseOrderBreakdownItems;

    /**
     * @ORM\OneToMany(targetEntity="PurchaseOrderBreakdownInvoiceEntity", mappedBy="purchaseOrderBreakdown", cascade={"remove"})
     */
    protected $purchaseOrderBreakdownInvoices;

    /**
     * Set createdAt
     *
     * @ORM\PrePersist
     */
    public function setCreatedAtValue()
    {
        $this->createdBy = isSet($_COOKIE['username']) ? $_COOKIE['username'] : 'System';
        $this->createdAt = new \DateTime();
        $this->updatedBy = isSet($_COOKIE['username']) ? $_COOKIE['username'] : 'System';
        $this->updatedAt = new \DateTime();
        $this->status = 'New';
        $this->paymentMethod = 'Cash';
    }

    /**
     * Set updatedAt
     *
     * @ORM\PreUpdate
     */
    public function setUpdatedAtValue()
    {
        $this->updatedBy = $_COOKIE['username'];
        $this->updatedAt = new \DateTime();
    }

    public function updateStatus() {

        if($this->status !== 'Voided') {

            $this->status = $this->getIsAllQuantityReceived() ? 'Received' : 'Sent';
        }

        return $this;
    }

    public function doVoid() {

        $isAllQuantityVoidedSelf = true;

        foreach($this->purchaseOrderBreakdownItems as $purchaseOrderBreakdownItem) {
            if(!$purchaseOrderBreakdownItem->getIsAllQuantityVoided()) $isAllQuantityVoidedSelf = false;

        }

        if($isAllQuantityVoidedSelf) $this->status = 'Voided';

        $this->purchaseOrder->doVoid();

        return $this;
    }


    public function __construct($data=null)
    {
        if(!is_null($data)) {
            $this->id = $data->getId();
            $this->purchaseOrderNo = $data->getPurchaseOrderNo();
            $this->paymentMethod = $data->getPaymentMethod();
            $this->status = $data->getStatus();
            $this->purchaseOrder = $data->getPurchaseOrder();
            $this->purchaseInvoice = $data->getPurchaseInvoice();
        }

        $this->purchaseOrderBreakdownItems = new ArrayCollection();
        $this->purchaseOrderBreakdownInvoices = new ArrayCollection();
    }

    /*--------------------------------------------------------------------------------------------------------*/
    /*					User Defined Setters and Getters													  */
    /*--------------------------------------------------------------------------------------------------------*/

    /**
     * Get idEncoded
     *
     * @return string
     */
    public function getIdEncoded() {

        return base64_encode($this->id);
    }

    /**
     * Get poDateAsString
     *
     * @return string
     */
    public function getPoDateAsString() {

        $dttst = new DateTimeToStringTransformer();

        return !empty($this->poDate) ? date('m/d/Y', strtotime($dttst->transform($this->poDate))) : '';
    }

    /**
     * Get poDateAsLongString
     *
     * @return string
     */
    public function getPoDateAsLongString() {

        $dttst = new DateTimeToStringTransformer();

        return !empty($this->poDate) ? date('F d, Y', strtotime($dttst->transform($this->poDate))) : '';
    }

    /**
     * Get hasPurchaseOrderItem
     *
     * @param PurchaseOrderItemEntity $purchaseOrderItem
     *
     * @return boolean
     */
    public function getHasPurchaseOrderItem(\RxConnexionBundle\Entity\PurchaseOrderItemEntity $purchaseOrderItem) {

        $hasPurchaseOrderItem = false;

        foreach($this->purchaseOrderBreakdownItems as $purchaseOrderBreakdownItem) {
            if($purchaseOrderBreakdownItem->getPurchaseOrderItem() === $purchaseOrderItem) $hasPurchaseOrderItem = true;
        }

        return $hasPurchaseOrderItem;
    }


    /**
     * Get totalQuantity
     *
     * @return string
     */
    public function getTotalQuantity() {

        $totalQuantity = 0;

        foreach($this->purchaseOrderBreakdownItems as $purchaseOrderBreakdownItem) {
            $totalQuantity += $purchaseOrderBreakdownItem->getQuantity() + $purchaseOrderBreakdownItem->getQuantityAdded() ;
        }

        return $totalQuantity;
    }

    /**
     * Get totalQuantityAdded
     *
     * @return string
     */
    public function getTotalQuantityAdded() {

        $totalQuantityAdded = 0;

        foreach($this->purchaseOrderBreakdownItems as $purchaseOrderBreakdownItem) {
            $totalQuantityAdded += $purchaseOrderBreakdownItem->getQuantityAdded() + $totalQuantityAdded;
        }

        return $totalQuantityAdded;
    }

    /**
     * Get totalQuantityForReceiving
     *
     * @return string
     */
    public function getTotalQuantityForReceiving() {

        $totalQuantityForReceiving = 0;

        foreach($this->purchaseOrderBreakdownItems as $purchaseOrderBreakdownItem) {
            $totalQuantityForReceiving += $purchaseOrderBreakdownItem->getQuantityForReceiving();
        }

        return $totalQuantityForReceiving;
    }

    /**
     * Get totalQuantityVoided
     *
     * @return string
     */
    public function getTotalQuantityVoided() {

        $totalQuantityVoided = 0;

        foreach($this->purchaseOrderBreakdownItems as $purchaseOrderBreakdownItem) {
            $totalQuantityVoided += $purchaseOrderBreakdownItem->getQuantityVoided();
        }

        return $totalQuantityVoided;
    }

    /**
     * Get totalQuantityReceived
     *
     * @return string
     */
    public function getTotalQuantityReceived() {

        $totalQuantityReceived = 0;

        foreach($this->purchaseOrderBreakdownItems as $purchaseOrderBreakdownItem) {
            $totalQuantityReceived += $purchaseOrderBreakdownItem->getQuantityReceived();
        }

        return $totalQuantityReceived;
    }

    /**
     * Get isVoidable
     *
     * @return boolean
     */
    public function getIsVoidable() {

        return $this->status === 'Received' || $this->status === 'Voided' ? false : true;
    }

    /**
     * Get isAllQuantityReceived
     *
     * @return boolean
     */
    public function getIsAllQuantityReceived() {

        return $this->getTotalQuantityReceived() == $this->getTotalQuantityForReceiving();
    }

    /**
     * Get purchaseOrderBreakdownItemsCtr
     *
     * @return string
     */
    public function getPurchaseOrderBreakdownItemsCtr() {

        return count($this->purchaseOrderBreakdownItems);
    }

    /**
     * Get totalAmount
     *
     * @return string
     */
    public function getTotalAmount() {

        $amt = 0;

        foreach($this->purchaseOrderBreakdownItems as $purchaseOrderBreakdownItem) {
            $amt += ($purchaseOrderBreakdownItem->getPurchaseOrderItem()->getPrice() * ($purchaseOrderBreakdownItem->getQuantity() - $purchaseOrderBreakdownItem->getQuantityVoided() + $purchaseOrderBreakdownItem->getQuantityAdded() ));
        }

        return $amt;
    }

    /**
     * Get totalAmountReceived
     *
     * @return string
     */
    public function getTotalAmountReceived() {

        $amt = 0;

        foreach($this->purchaseOrderBreakdownItems as $purchaseOrderBreakdownItem) {
            $amt += ($purchaseOrderBreakdownItem->getPurchaseOrderItem()->getPrice() * $purchaseOrderBreakdownItem->getQuantityReceived());
        }

        return $amt;
    }

    /**
     * Get totalPaymentBalance
     *
     * @return string
     */
    public function getTotalPaymentBalance() {

        return $this->getTotalAmount() - $this->getPurchaseInvoice()->getTotalPayment() ;
    }

    /**
     * Get purchaseOrderBreakdownInvoiceByInvoiceNo
     *
     * @param $invoiceNo
     * @return \RxConnexionBundle\Entity\PurchaseOrderBreakdownInvoiceEntity|null
     */
    public function getPurchaseOrderBreakdownInvoiceByInvoiceNo($invoiceNo) {

        $pobi = null;

        foreach($this->purchaseOrderBreakdownInvoices as $purchaseOrderBreakdownInvoice) {
            if($purchaseOrderBreakdownInvoice->getInvoiceNo() == $invoiceNo) {
                $pobi = $purchaseOrderBreakdownInvoice;
                break;
            }
        }

        return $pobi;
    }

    /**
     * Get totalAmountReceivedBelowAndEqualToDate
     *
     * @param $date
     * @return string
     */
    public function getTotalAmountReceivedBelowAndEqualToDate($date) {

        $dttst = new DateTimeToStringTransformer();
        $refDT = strtotime($date);
        $amt = 0;

        foreach($this->purchaseOrderBreakdownInvoices as $purchaseOrderBreakdownInvoice) {
            if(strtotime($dttst->transform($purchaseOrderBreakdownInvoice->getInvoiceDate())) <= $refDT) {
                $amt += $purchaseOrderBreakdownInvoice->getTotalAmountReceived();
            }
        }

        return $amt;
    }

    /*--------------------------------------------------------------------------------------------------------*/
    /*					Setters and Getters																	  */
    /*--------------------------------------------------------------------------------------------------------*/

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set purchaseOrderNo
     *
     * @param string $purchaseOrderNo
     * @return PurchaseOrderBreakdownEntity
     */
    public function setPurchaseOrderNo($purchaseOrderNo)
    {
        $this->purchaseOrderNo = str_replace(',', '', $purchaseOrderNo);

        return $this;
    }

    /**
     * Get purchaseOrderNo
     *
     * @return string 
     */
    public function getPurchaseOrderNo()
    {
        return $this->purchaseOrderNo;
    }

    /**
     * Set status
     *
     * @param string $status
     * @return PurchaseOrderBreakdownEntity
     */
    public function setStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    /**
     * Get status
     *
     * @return string 
     */
    public function getStatus()
    {
        return $this->status;
    }

    /**
     * Set paymentMethod
     *
     * @param string $paymentMethod
     * @return PurchaseOrderBreakdownEntity
     */
    public function setPaymentMethod($paymentMethod)
    {
        $this->paymentMethod = $paymentMethod;

        return $this;
    }

    /**
     * Get paymentMethod
     *
     * @return string 
     */
    public function getPaymentMethod()
    {
        return $this->paymentMethod;
    }

    /**
     * Set createdBy
     *
     * @param string $createdBy
     * @return PurchaseOrderBreakdownEntity
     */
    public function setCreatedBy($createdBy)
    {
        $this->createdBy = $createdBy;

        return $this;
    }

    /**
     * Get createdBy
     *
     * @return string 
     */
    public function getCreatedBy()
    {
        return $this->createdBy;
    }

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     * @return PurchaseOrderBreakdownEntity
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime 
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set updatedBy
     *
     * @param string $updatedBy
     * @return PurchaseOrderBreakdownEntity
     */
    public function setUpdatedBy($updatedBy)
    {
        $this->updatedBy = $updatedBy;

        return $this;
    }

    /**
     * Get updatedBy
     *
     * @return string 
     */
    public function getUpdatedBy()
    {
        return $this->updatedBy;
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     * @return PurchaseOrderBreakdownEntity
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime 
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

    /**
     * Set purchaseOrder
     *
     * @param \RxConnexionBundle\Entity\PurchaseOrderEntity $purchaseOrder
     * @return PurchaseOrderBreakdownEntity
     */
    public function setPurchaseOrder(\RxConnexionBundle\Entity\PurchaseOrderEntity $purchaseOrder = null)
    {
        $this->purchaseOrder = $purchaseOrder;

        return $this;
    }

    /**
     * Get purchaseOrder
     *
     * @return \RxConnexionBundle\Entity\PurchaseOrderEntity
     */
    public function getPurchaseOrder()
    {
        return $this->purchaseOrder;
    }

    /**
     * Add purchaseOrderBreakdownItems
     *
     * @param \RxConnexionBundle\Entity\PurchaseOrderBreakdownItemEntity $purchaseOrderBreakdownItems
     * @return PurchaseOrderBreakdownEntity
     */
    public function addPurchaseOrderBreakdownItem(\RxConnexionBundle\Entity\PurchaseOrderBreakdownItemEntity $purchaseOrderBreakdownItems)
    {
        $this->purchaseOrderBreakdownItems[] = $purchaseOrderBreakdownItems;

        return $this;
    }

    /**
     * Remove purchaseOrderBreakdownItems
     *
     * @param \RxConnexionBundle\Entity\PurchaseOrderBreakdownItemEntity $purchaseOrderBreakdownItems
     */
    public function removePurchaseOrderBreakdownItem(\RxConnexionBundle\Entity\PurchaseOrderBreakdownItemEntity $purchaseOrderBreakdownItems)
    {
        $this->purchaseOrderBreakdownItems->removeElement($purchaseOrderBreakdownItems);
    }

    /**
     * Get purchaseOrderBreakdownItems
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getPurchaseOrderBreakdownItems()
    {
        return $this->purchaseOrderBreakdownItems;
    }

    /**
     * Set purchaseInvoice
     *
     * @param \RxConnexionBundle\Entity\PurchaseInvoiceEntity $purchaseInvoice
     * @return PurchaseOrderBreakdownEntity
     */
    public function setPurchaseInvoice(\RxConnexionBundle\Entity\PurchaseInvoiceEntity $purchaseInvoice = null)
    {
        $this->purchaseInvoice = $purchaseInvoice;
    
        return $this;
    }

    /**
     * Get purchaseInvoice
     *
     * @return \RxConnexionBundle\Entity\PurchaseInvoiceEntity
     */
    public function getPurchaseInvoice()
    {
        return $this->purchaseInvoice;
    }

    /**
     * Add purchaseOrderBreakdownInvoices
     *
     * @param \RxConnexionBundle\Entity\PurchaseOrderBreakdownInvoiceEntity $purchaseOrderBreakdownInvoices
     * @return PurchaseOrderBreakdownEntity
     */
    public function addPurchaseOrderBreakdownInvoice(\RxConnexionBundle\Entity\PurchaseOrderBreakdownInvoiceEntity $purchaseOrderBreakdownInvoices)
    {
        $this->purchaseOrderBreakdownInvoices[] = $purchaseOrderBreakdownInvoices;
    
        return $this;
    }

    /**
     * Remove purchaseOrderBreakdownInvoices
     *
     * @param \RxConnexionBundle\Entity\PurchaseOrderBreakdownInvoiceEntity $purchaseOrderBreakdownInvoices
     */
    public function removePurchaseOrderBreakdownInvoice(\RxConnexionBundle\Entity\PurchaseOrderBreakdownInvoiceEntity $purchaseOrderBreakdownInvoices)
    {
        $this->purchaseOrderBreakdownInvoices->removeElement($purchaseOrderBreakdownInvoices);
    }

    /**
     * Get purchaseOrderBreakdownInvoices
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getPurchaseOrderBreakdownInvoices()
    {
        return $this->purchaseOrderBreakdownInvoices;
    }

    /**
     * Set poNo
     *
     * @param string $poNo
     * @return PurchaseOrderBreakdownEntity
     */
    public function setPoNo($poNo)
    {
        $this->poNo = $poNo;

        return $this;
    }

    /**
     * Get poNo
     *
     * @return string 
     */
    public function getPoNo()
    {
        return $this->poNo;
    }

    /**
     * Set poDate
     *
     * @param \DateTime $poDate
     * @return PurchaseOrderBreakdownEntity
     */
    public function setPoDate($poDate)
    {
        $this->poDate = empty($poDate) ? NULL : new \DateTime($poDate);

        return $this;
    }

    /**
     * Get poDate
     *
     * @return \DateTime 
     */
    public function getPoDate()
    {
        return $this->poDate;
    }
}
