<?php

namespace RxConnexionBundle\Entity;

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

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

class InventoryEntity
{
    const STATUS_STOCK_ON_HAND = 'Stock On Hand';
//    const STATUS_IN_TRANSIT = 'In Transit';
//    const STATUS_USED = 'Used';
//    const STATUS_IN_PROCESSING = 'In Processing';
//    const STATUS_FOR_REPROCESSING = 'For Reprocessing';
//    const STATUS_DEPOSIT = 'Deposit';
    const STATUS_SOLD = 'Sold';
//    const STATUS_REJECTED = 'Rejected';

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

    /**
     * @ORM\Column(name="quantity", type="decimal", precision=12, scale=2, nullable=true)
     */
    protected $quantity;

    /**
     * @ORM\Column(name="initial_quantity", type="decimal", precision=12, scale=2, nullable=true)
     */
    protected $initialQuantity;

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

    /**
     * @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="ItemEntity", inversedBy="inventories")
     * @ORM\JoinColumn(name="item_id", referencedColumnName="id")
     */
    protected $item;

    /**
     * @ORM\ManyToOne(targetEntity="RxConnexionBundle\Entity\HealthFacilityEntity", inversedBy="inventories")
     * @ORM\JoinColumn(name="health_facility_id", referencedColumnName="id")
     */
    protected $healthFacility;

    /**
     * @ORM\ManyToOne(targetEntity="LocationEntity", inversedBy="inventories")
     * @ORM\JoinColumn(name="location_id", referencedColumnName="id")
     */
    protected $location;

    /**
     * @ORM\ManyToOne(targetEntity="PurchaseOrderBreakdownItemDeliveryEntity", inversedBy="inventories")
     * @ORM\JoinColumn(name="purchase_order_breakdown_item_delivery_id", referencedColumnName="id")
     */
    protected $purchaseOrderBreakdownItemDelivery;

    /**
     * @ORM\OneToMany(targetEntity="InventoryMovementEntity", mappedBy="inventory", cascade="remove")
     */
    protected $inventoryMovements;

    /**
     * @ORM\OneToMany(targetEntity="InventoryPriceEntity", mappedBy="inventory", cascade="remove")
     */
    protected $inventoryPrices;

//    /**
//     * @ORM\OneToMany(targetEntity="UseInventoryItemEntity", mappedBy="inventory")
//     */
//    protected $useInventoryItems;

    /**
     * @ORM\OneToMany(targetEntity="ConvertInventoryItemEntity", mappedBy="inventory")
     */
    protected $convertInventoryItems;

    /**
     * @ORM\OneToMany(targetEntity="TransferInventoryItemEntity", mappedBy="inventory")
     */
    protected $transferInventoryItems;

    /**
     * @ORM\OneToMany(targetEntity="TransferInventoryDeliveryItemEntity", mappedBy="inventory", cascade={"remove"})
     */
    protected $transferInventoryDeliveryItems;

//    /**
//     * @ORM\OneToMany(targetEntity="SalesOrderInventoryEntity", mappedBy="inventory")
//     */
//    protected $salesOrderInventories;

//    /**
//     * @ORM\OneToMany(targetEntity="JobOrderInventoryEntity", mappedBy="inventory")
//     */
//    protected $jobOrderInventories;

    /**
     * @ORM\OneToMany(targetEntity="InventorySerialNoEntity", mappedBy="inventory", cascade={"persist", "remove"}, orphanRemoval=true)
     */
    protected $inventorySerialNos;

    /**
     * @ORM\OneToMany(targetEntity="RxConnexionBundle\Entity\PatientBillingInventoryEntity", mappedBy="inventory", cascade={"remove"})
     */
    protected $patientBillingInventories;

    /**
     * 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->quantity = 0;
    }

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

    public function __construct($data=null)
    {
        if(!is_null($data)) {
            $this->id = $data->getId();
            $this->quantity = $data->getQuantity();
            $this->status = $data->getStatus();
            $this->item = $data->getItem();
            $this->healthFacility = $data->getHealthFacility();
            $this->location = $data->getLocation();
        }

        $this->inventoryMovements = new ArrayCollection();
        $this->inventoryPrices = new ArrayCollection();
//        $this->useInventoryItems = new ArrayCollection();
        $this->convertInventoryItems = new ArrayCollection();
//        $this->salesOrderInventories = new ArrayCollection();
//        $this->jobOrderInventories = new ArrayCollection();
        $this->transferInventoryDeliveryItems = new ArrayCollection();
        $this->transferInventoryItems = new ArrayCollection();
        $this->inventorySerialNos = new ArrayCollection();
    }

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

	public function getInitialQuantity__old()
	{
		if ($this->createdBy === 'Import') {
			$initialQuantity = 0;
			$soldQuantity = 0;
			foreach ($this->inventoryMovements as $inventoryMovement) {
				// if there has been an order transaction
				if ($inventoryMovement->getSource() === 'Purchasing Purchase Order Receive') {
					$initialQuantity += $inventoryMovement->getQuantity();
				}
				// sum of sold
				if ($inventoryMovement->getSource() === 'Patient Billing - Invoice') {
					$soldQuantity -= $inventoryMovement->getQuantity();
				}
			}
			$initialQuantity = $initialQuantity == 0 ? ($this->quantity + $soldQuantity) : $initialQuantity;
		} else {
			$initialQuantity = 0;
		}
		return $initialQuantity;
	}

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

        return base64_encode($this->id);
    }


    /**
     * Get availableInventorySerialNos
     * @return array
     */
    public function getAvailableInventorySerialNos()
    {
        /**@var InventorySerialNoEntity $inventorySerialNo*/
        $serialNos = [];
        foreach ($this->getInventorySerialNos() as $inventorySerialNo) {
            if($inventorySerialNo->getStatus() === InventorySerialNoEntity::STATUS_1) {
                $serialNos[] = $inventorySerialNo;
            }
        }
        return $serialNos;
    }

    /**
     * Get availableInventorySerialNosAsArray
     * @return array
     */
    public function getAvailableInventorySerialNosAsArray()
    {
        /**@var InventorySerialNoEntity $inventorySerialNo*/
        $serialNos = [];
        foreach ($this->getInventorySerialNos() as $inventorySerialNo) {
            if($inventorySerialNo->getStatus() === InventorySerialNoEntity::STATUS_1) {
                $serialNos[] = array(
                    'id' => $inventorySerialNo->getId(),
                    'serialNo' => $inventorySerialNo->getSerialNo(),
                );
            }
        }
        return $serialNos;
    }

    /**
     * Get availableInventorySerialNosForSelectInputAsArray
     * @return array
     */
    public function getAvailableInventorySerialNosForSelectInputAsArray()
    {
        /**@var InventorySerialNoEntity $inventorySerialNo*/
        $serialNos = [];
        foreach ($this->getInventorySerialNos() as $inventorySerialNo) {
            if($inventorySerialNo->getStatus() === InventorySerialNoEntity::STATUS_1) {
                $serialNos[] = implode('~', array(
                    $inventorySerialNo->getId(),
                    $inventorySerialNo->getSerialNo(),
                ));
            }
        }
        return $serialNos;
    }

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



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

    /**
     * Set quantity
     *
     * @param string $quantity
     *
     * @return InventoryEntity
     */
    public function setQuantity($quantity)
    {
        $this->quantity = str_replace(',', '', $quantity);

        return $this;
    }

    /**
     * Get quantity
     *
     * @return float
     */
    public function getQuantity()
    {
        return $this->quantity;
    }

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

        return $this;
    }

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

    /**
     * Set createdBy
     *
     * @param string $createdBy
     *
     * @return InventoryEntity
     */
    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 InventoryEntity
     */
    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 InventoryEntity
     */
    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 InventoryEntity
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

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

    /**
     * Set item
     *
     * @param \RxConnexionBundle\Entity\ItemEntity $item
     *
     * @return InventoryEntity
     */
    public function setItem(\RxConnexionBundle\Entity\ItemEntity $item = null)
    {
        $this->item = $item;

        return $this;
    }

    /**
     * Get item
     *
     * @return \RxConnexionBundle\Entity\ItemEntity
     */
    public function getItem()
    {
        return $this->item;
    }


    /**
     * Set location
     *
     * @param \RxConnexionBundle\Entity\LocationEntity $location
     *
     * @return InventoryEntity
     */
    public function setLocation(\RxConnexionBundle\Entity\LocationEntity $location = null)
    {
        $this->location = $location;

        return $this;
    }

    /**
     * Get location
     *
     * @return \RxConnexionBundle\Entity\LocationEntity
     */
    public function getLocation()
    {
        return $this->location;
    }

    /**
     * Add inventoryMovement
     *
     * @param \RxConnexionBundle\Entity\InventoryMovementEntity $inventoryMovement
     *
     * @return InventoryEntity
     */
    public function addInventoryMovement(\RxConnexionBundle\Entity\InventoryMovementEntity $inventoryMovement)
    {
        $this->inventoryMovements[] = $inventoryMovement;

        return $this;
    }

    /**
     * Remove inventoryMovement
     *
     * @param \RxConnexionBundle\Entity\InventoryMovementEntity $inventoryMovement
     */
    public function removeInventoryMovement(\RxConnexionBundle\Entity\InventoryMovementEntity $inventoryMovement)
    {
        $this->inventoryMovements->removeElement($inventoryMovement);
    }

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

    /**
     * Set healthFacility
     *
     * @param \RxConnexionBundle\Entity\HealthFacilityEntity $healthFacility
     *
     * @return InventoryEntity
     */
    public function setHealthFacility(\RxConnexionBundle\Entity\HealthFacilityEntity $healthFacility = null)
    {
        $this->healthFacility = $healthFacility;

        return $this;
    }

    /**
     * Get healthFacility
     *
     * @return \RxConnexionBundle\Entity\HealthFacilityEntity
     */
    public function getHealthFacility()
    {
        return $this->healthFacility;
    }

    /**
     * Add inventoryPrice
     *
     * @param \RxConnexionBundle\Entity\InventoryPriceEntity $inventoryPrice
     *
     * @return InventoryEntity
     */
    public function addInventoryPrice(\RxConnexionBundle\Entity\InventoryPriceEntity $inventoryPrice)
    {
        $this->inventoryPrices[] = $inventoryPrice;

        return $this;
    }

    /**
     * Remove inventoryPrice
     *
     * @param \RxConnexionBundle\Entity\InventoryPriceEntity $inventoryPrice
     */
    public function removeInventoryPrice(\RxConnexionBundle\Entity\InventoryPriceEntity $inventoryPrice)
    {
        $this->inventoryPrices->removeElement($inventoryPrice);
    }

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

    /**
     * Add transferInventoryItem
     *
     * @param \RxConnexionBundle\Entity\TransferInventoryItemEntity $transferInventoryItem
     *
     * @return InventoryEntity
     */
    public function addTransferInventoryItem(\RxConnexionBundle\Entity\TransferInventoryItemEntity $transferInventoryItem)
    {
        $this->transferInventoryItems[] = $transferInventoryItem;

        return $this;
    }

    /**
     * Remove transferInventoryItem
     *
     * @param \RxConnexionBundle\Entity\TransferInventoryItemEntity $transferInventoryItem
     */
    public function removeTransferInventoryItem(\RxConnexionBundle\Entity\TransferInventoryItemEntity $transferInventoryItem)
    {
        $this->transferInventoryItems->removeElement($transferInventoryItem);
    }

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

    /**
     * Add transferInventoryDeliveryItem
     *
     * @param \RxConnexionBundle\Entity\TransferInventoryDeliveryItemEntity $transferInventoryDeliveryItem
     *
     * @return InventoryEntity
     */
    public function addTransferInventoryDeliveryItem(\RxConnexionBundle\Entity\TransferInventoryDeliveryItemEntity $transferInventoryDeliveryItem)
    {
        $this->transferInventoryDeliveryItems[] = $transferInventoryDeliveryItem;

        return $this;
    }

    /**
     * Remove transferInventoryDeliveryItem
     *
     * @param \RxConnexionBundle\Entity\TransferInventoryDeliveryItemEntity $transferInventoryDeliveryItem
     */
    public function removeTransferInventoryDeliveryItem(\RxConnexionBundle\Entity\TransferInventoryDeliveryItemEntity $transferInventoryDeliveryItem)
    {
        $this->transferInventoryDeliveryItems->removeElement($transferInventoryDeliveryItem);
    }

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

    /**
     * Add convertInventoryItem
     *
     * @param \RxConnexionBundle\Entity\ConvertInventoryItemEntity $convertInventoryItem
     *
     * @return InventoryEntity
     */
    public function addConvertInventoryItem(\RxConnexionBundle\Entity\ConvertInventoryItemEntity $convertInventoryItem)
    {
        $this->convertInventoryItems[] = $convertInventoryItem;

        return $this;
    }

    /**
     * Remove convertInventoryItem
     *
     * @param \RxConnexionBundle\Entity\ConvertInventoryItemEntity $convertInventoryItem
     */
    public function removeConvertInventoryItem(\RxConnexionBundle\Entity\ConvertInventoryItemEntity $convertInventoryItem)
    {
        $this->convertInventoryItems->removeElement($convertInventoryItem);
    }

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

    /**
     * Set purchaseOrderBreakdownItemDelivery
     *
     * @param \RxConnexionBundle\Entity\PurchaseOrderBreakdownItemDeliveryEntity $purchaseOrderBreakdownItemDelivery
     *
     * @return InventoryEntity
     */
    public function setPurchaseOrderBreakdownItemDelivery(\RxConnexionBundle\Entity\PurchaseOrderBreakdownItemDeliveryEntity $purchaseOrderBreakdownItemDelivery = null)
    {
        $this->purchaseOrderBreakdownItemDelivery = $purchaseOrderBreakdownItemDelivery;

        return $this;
    }

    /**
     * Get purchaseOrderBreakdownItemDelivery
     *
     * @return \RxConnexionBundle\Entity\PurchaseOrderBreakdownItemDeliveryEntity
     */
    public function getPurchaseOrderBreakdownItemDelivery()
    {
        return $this->purchaseOrderBreakdownItemDelivery;
    }

    /**
     * Add inventorySerialNo
     *
     * @param \RxConnexionBundle\Entity\InventorySerialNoEntity $inventorySerialNo
     *
     * @return InventoryEntity
     */
    public function addInventorySerialNo(\RxConnexionBundle\Entity\InventorySerialNoEntity $inventorySerialNo)
    {
        $this->inventorySerialNos[] = $inventorySerialNo;

        return $this;
    }

    /**
     * Remove inventorySerialNo
     *
     * @param \RxConnexionBundle\Entity\InventorySerialNoEntity $inventorySerialNo
     */
    public function removeInventorySerialNo(\RxConnexionBundle\Entity\InventorySerialNoEntity $inventorySerialNo)
    {
        $this->inventorySerialNos->removeElement($inventorySerialNo);
    }

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

    /**
     * Add patientBillingInventory
     *
     * @param \RxConnexionBundle\Entity\PatientBillingInventoryEntity $patientBillingInventory
     *
     * @return InventoryEntity
     */
    public function addPatientBillingInventory(\RxConnexionBundle\Entity\PatientBillingInventoryEntity $patientBillingInventory)
    {
        $this->patientBillingInventories[] = $patientBillingInventory;

        return $this;
    }

    /**
     * Remove patientBillingInventory
     *
     * @param \RxConnexionBundle\Entity\PatientBillingInventoryEntity $patientBillingInventory
     */
    public function removePatientBillingInventory(\RxConnexionBundle\Entity\PatientBillingInventoryEntity $patientBillingInventory)
    {
        $this->patientBillingInventories->removeElement($patientBillingInventory);
    }

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

    /**
     * Set initialQuantity
     *
     * @param string $initialQuantity
     *
     * @return InventoryEntity
     */
    public function setInitialQuantity($initialQuantity)
    {
        $this->initialQuantity = $initialQuantity;

        return $this;
    }

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