<?php

namespace RxConnexionBundle\Service;

use Doctrine\ORM\EntityManager;
use RxConnexionBundle\Entity\ConvertInventoryEntity;
use RxConnexionBundle\Entity\ConvertInventoryItemBiEntity;
use RxConnexionBundle\Entity\ConvertInventoryItemEntity;
use RxConnexionBundle\Entity\HealthFacilityEntity;
use RxConnexionBundle\Entity\InventoryPriceEntity;
use RxConnexionBundle\Entity\InventorySerialNoEntity;
use RxConnexionBundle\Entity\ItemEntity;
use RxConnexionBundle\Entity\PatientBillingBreakdownEntity;
use RxConnexionBundle\Entity\PatientBillingEntity;
use RxConnexionBundle\Entity\PatientBillingInventoryEntity;
use RxConnexionBundle\Entity\PurchaseOrderBreakdownItemDeliveryEntity;
use RxConnexionBundle\Entity\PurchaseOrderBreakdownItemDeliverySerialNoEntity;
use RxConnexionBundle\Entity\TransferInventoryDeliveryItemEntity;
use RxConnexionBundle\Entity\TransferInventoryDeliveryItemTransferInventoryItemInvSerialNoEntity;
use RxConnexionBundle\Entity\TransferInventoryEntity;
use RxConnexionBundle\Entity\TransferInventoryItemDeliveryEntity;
use RxConnexionBundle\Entity\TransferInventoryItemDeliveryInventorySerialNoEntity;
use Symfony\Component\DependencyInjection\ContainerInterface;

use RxConnexionBundle\Entity\InventoryEntity;
use RxConnexionBundle\Entity\InventoryMovementEntity;//use RxConnexionBundle\Entity\TransactionEntity;
//use RxConnexionBundle\Entity\TransactionJournalEntryEntity;
//use RxConnexionBundle\Entity\TransactionLinkEntity;
// use RxConnexionBundle\Entity\GeneralLedgerAccountEntity;
// use RxConnexionBundle\Entity\SubsidiaryLedgerAccountEntity;
//
//use RxConnexionBundle\Entity\SalesOrderInventoryPriceEntity;
//use RxConnexionBundle\Entity\JobOrderInventoryPriceEntity;
//
//use RxConnexionBundle\Entity\PurchaseOrderBreakdownEntity;

Class InventoryService {

    private $em;
    private $container;

    public function __construct(EntityManager $em, ContainerInterface $container) {

        $this->em = $em;
        $this->container = $container;
    }

    public function getInventoryStatuses() {

        return array(
            'Stock On Hand',
//            'In Transit',
//            'Used',
//            'In Processing',
//            'For Reprocessing',
//            'Deposit',
            'Sold',
//            'Rejected',
        );
    }

    public function recordMovement($source, $params = array()) {

        /**@var EntityManager $em*/
        $em = $this->em;

        switch($source) {

            case 'Purchasing Purchase Order Receive':

                /**@var PurchaseOrderBreakdownItemDeliveryEntity $purchaseOrderBreakdownItemDelivery*/
                $purchaseOrderBreakdownItemDelivery = $params['purchaseOrderBreakdownItemDelivery'];
                $materialRequisition = $purchaseOrderBreakdownItemDelivery->getPurchaseOrderBreakdownItem()->getPurchaseOrderBreakdown()->getPurchaseOrder()->getMaterialRequisition();
                $item = $purchaseOrderBreakdownItemDelivery->getPurchaseOrderBreakdownItem()->getPurchaseOrderItem()->getMaterialRequisitionItem()->getItem();

//                if($materialRequisition->getCanvassType() === 'Main') {
//                    $branch = $em->getRepository('RxConnexionBundle:BranchEntity')->findOneBy(array('isMain' => true));
//                } else {
//                    $branch = $materialRequisition->getHealthFacility();
//                }

                $branch = $materialRequisition->getHealthFacility();

//                $location = $branch->getFirstLocation();
                $location = null;
                //$inventory = $this->inventory($branch, $purchaseOrderBreakdownItemDelivery->getPurchaseOrderBreakdownItem()->getPurchaseOrderItem()->getMaterialRequisitionItem()->getLocation(), $item);
                $inventory = $this->inventory($branch, $location, $item, 'Stock On Hand', $purchaseOrderBreakdownItemDelivery);

                if($params['action'] === 'New') {

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setPurchaseOrderBreakdownItemDelivery($purchaseOrderBreakdownItemDelivery);
                    $inventoryMovement->setQuantity($purchaseOrderBreakdownItemDelivery->getQuantity());
                    $em->persist($inventoryMovement);

                    $inventoryPrice = new InventoryPriceEntity();
                    $inventoryPrice->setInventory($inventory);
                    $inventoryPrice->setQuantity($purchaseOrderBreakdownItemDelivery->getQuantity());
                    $inventoryPrice->setPrice($purchaseOrderBreakdownItemDelivery->getPurchaseOrderBreakdownItem()->getPurchaseOrderItem()->getPrice());
                    $inventoryPrice->setSource($source);
                    $inventoryPrice->setPurchaseOrderBreakdownItemDelivery($purchaseOrderBreakdownItemDelivery);
                    $em->persist($inventoryPrice);

                    $inventory->setQuantity($inventory->getQuantity() + $purchaseOrderBreakdownItemDelivery->getQuantity());

                } else {

                    $inventoryMovement = $em->getRepository('RxConnexionBundle:InventoryMovementEntity')->findOneBy(array(
                        'inventory' => $inventory,
                        'source' => $source,
                        'purchaseOrderBreakdownItemDelivery' => $purchaseOrderBreakdownItemDelivery
                    ));

                    $inventoryPrice = $em->getRepository('RxConnexionBundle:InventoryPriceEntity')->findOneBy(array(
                        'inventory' => $inventory,
                        'source' => $source,
                        'purchaseOrderBreakdownItemDelivery' => $purchaseOrderBreakdownItemDelivery
                    ));

                    if($params['action'] === 'Update') {

                        $inventory->setQuantity($inventory->getQuantity() - $inventoryMovement->getQuantity());
                        $inventoryMovement->setQuantity($purchaseOrderBreakdownItemDelivery->getQuantity());
                        $inventoryPrice->setQuantity($purchaseOrderBreakdownItemDelivery->getQuantity());
                        $inventoryPrice->setPrice($purchaseOrderBreakdownItemDelivery->getPurchaseOrderBreakdownItem()->getPurchaseOrderItem()->getPrice());
                        $inventory->setQuantity($inventory->getQuantity() + $inventoryMovement->getQuantity());

                    } else {

                    	if($inventoryMovement){
		                    $inventory->setQuantity($inventory->getQuantity() - $inventoryMovement->getQuantity());
		                    $purchaseOrderBreakdownItemDelivery->removeInventoryMovement($inventoryMovement);
		                    $em->remove($inventoryMovement);
	                    }
                    	if($inventoryPrice) {
		                    $purchaseOrderBreakdownItemDelivery->removeInventoryPrice($inventoryPrice);
		                    $em->remove($inventoryPrice);
	                    }

	                    $item->removeMaterialRequisitionItem($purchaseOrderBreakdownItemDelivery->getPurchaseOrderBreakdownItem()->getPurchaseOrderItem()->getMaterialRequisitionItem());

                    }
                }

                $em->flush();


	            // COMPUTE AVERAGE COST
	            $itemService = new ItemService($this->em, $this->container);
	            $itemService->computeAverageCostByBranch($item, $branch);

                break;

            case 'Purchasing Transmittal Send':

                $transmittal = $params['transmittal'];

                foreach($transmittal->getTransmittalItems() as $transmittalItem) {

                    $materialRequisitionItem = $transmittalItem->getMaterialRequisitionItem();
                    $item = $materialRequisitionItem->getItem();
                    $inventory = $this->inventory($transmittal->getBranchFrom(), $materialRequisitionItem->getLocation(), $item);
                    $inventoryInTransit = $this->inventory($transmittal->getBranchTo(), null, $item, 'In Transit');

                    $inventory->setQuantity($inventory->getQuantity() - $transmittalItem->getQuantity());
                    $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() + $transmittalItem->getQuantity());

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setTransmittalItem($transmittalItem);
                    $inventoryMovement->setQuantity($transmittalItem->getQuantity() * -1);
                    $em->persist($inventoryMovement);

                    $em->flush();
                }

                break;

            case 'Purchasing Transmittal Receive':

                $transmittalItemDelivery = $params['transmittalItemDelivery'];

                $branch = $transmittalItemDelivery->getTransmittalItem()->getTransmittal()->getBranchTo();
                $item = $transmittalItemDelivery->getTransmittalItem()->getMaterialRequisitionItem()->getItem();
                $inventory = $this->inventory($branch, $transmittalItemDelivery->getLocation(), $item);
                $inventoryInTransit = $this->inventory($branch, null, $item, 'In Transit');

                if($params['action'] === 'New') {

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setTransmittalItemDelivery($transmittalItemDelivery);
                    $inventoryMovement->setQuantity($transmittalItemDelivery->getQuantity());
                    $em->persist($inventoryMovement);

                    $inventoryPrice = new InventoryPriceEntity();
                    $inventoryPrice->setInventory($inventory);
                    $inventoryPrice->setQuantity($transmittalItemDelivery->getQuantity());
                    $inventoryPrice->setPrice($transmittalItemDelivery->getTransmittalItem()->getPurchaseOrderBreakdownItem()->getPurchaseOrderItem()->getPrice());
                    $inventoryPrice->setSource($source);
                    $inventoryPrice->setTransmittalItemDelivery($transmittalItemDelivery);
                    $em->persist($inventoryPrice);

                    $inventory->setQuantity($inventory->getQuantity() + $transmittalItemDelivery->getQuantity());
                    $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() - $transmittalItemDelivery->getQuantity());

                } else {

                    $inventoryMovement = $em->getRepository('RxConnexionBundle:InventoryMovementEntity')->findOneBy(array(
                        'inventory' => $inventory,
                        'source' => $source,
                        'transmittalItemDelivery' => $transmittalItemDelivery
                    ));

                    $inventoryPrice = $em->getRepository('RxConnexionBundle:InventoryPriceEntity')->findOneBy(array(
                        'inventory' => $inventory,
                        'source' => $source,
                        'transmittalItemDelivery' => $transmittalItemDelivery
                    ));

                    if($params['action'] === 'Update') {

                        $inventory->setQuantity($inventory->getQuantity() - $inventoryMovement->getQuantity());
                        $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() + $inventoryMovement->getQuantity());

                        $inventoryMovement->setQuantity($transmittalItemDelivery->getQuantity());
                        $inventoryPrice->setQuantity($transmittalItemDelivery->getQuantity());
                        $inventoryPrice->setPrice($transmittalItemDelivery->getTransmittalItem()->getPurchaseOrderBreakdownItem()->getPurchaseOrderItem()->getPrice());

                        $inventory->setQuantity($inventory->getQuantity() + $inventoryMovement->getQuantity());
                        $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() - $inventoryMovement->getQuantity());
                    } else {

                        $inventory->setQuantity($inventory->getQuantity() - $inventoryMovement->getQuantity());
                        $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() + $inventoryMovement->getQuantity());

                        $em->remove($inventoryMovement);
                        $em->remove($inventoryPrice);
                    }
                }

                $em->flush();

                break;

            case 'Inventory Add Inventory Send':

                $addInventory = $params['addInventory'];
                $branch = $addInventory->getHealthFacility();
                $amount = 0;

                foreach($addInventory->getAddInventoryItems() as $addInventoryItem) {

                    $inventory = $this->inventory($branch, $addInventoryItem->getLocation(), $addInventoryItem->getItem());

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setAddInventoryItem($addInventoryItem);
                    $inventoryMovement->setQuantity($addInventoryItem->getQuantity());
                    $em->persist($inventoryMovement);

                    $inventoryPrice = new InventoryPriceEntity();
                    $inventoryPrice->setInventory($inventory);
                    $inventoryPrice->setQuantity($addInventoryItem->getQuantity());
                    $inventoryPrice->setPrice($addInventoryItem->getPrice());
                    $inventoryPrice->setSource($source);
                    $inventoryPrice->setAddInventoryItem($addInventoryItem);
                    $em->persist($inventoryPrice);

                    $inventory->setQuantity($inventory->getQuantity() + $addInventoryItem->getQuantity());

                    $em->flush();

                    $amount += ($addInventoryItem->getQuantity() * $addInventoryItem->getPrice());
                }

//                $this->recordAccountingAddSupplies($addInventory, $amount);

                break;

            case 'Inventory Use Inventory Send':

                $useInventory = $params['useInventory'];
                $amount = 0;

                foreach($useInventory->getUseInventoryItems() as $useInventoryItem) {

                    $inventory = $useInventoryItem->getInventory();
                    $inventoryUsed = $this->inventory($inventory->getBranch(), null, $useInventoryItem->getInventory()->getItem(), 'Used');

                    $inventory->setQuantity($inventory->getQuantity() - $useInventoryItem->getQuantity());
                    $inventoryUsed->setQuantity($inventoryUsed->getQuantity() + $useInventoryItem->getQuantity());

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setUseInventoryItem($useInventoryItem);
                    $inventoryMovement->setQuantity($useInventoryItem->getQuantity() * -1);
                    $em->persist($inventoryMovement);

                    $em->flush();

                    $inventoryPrices = $em->getRepository('RxConnexionBundle:InventoryPriceEntity')->findAllAvailableForAccounting(
                        $useInventoryItem->getInventory()->getId()
                    );

                    $quantity = $useInventoryItem->getQuantity();

                    foreach($inventoryPrices as $inventoryPrice) {
                        if($quantity <= 0) {
                            break;
                        } else if($inventoryPrice->getQuantityAccounted() + $quantity >= $inventoryPrice->getQuantity()) {
                            $amount += $inventoryPrice->getPrice() * ($inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted());
                            $quantity -= $inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted();
                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantity());
                        } else {
                            $amount += $inventoryPrice->getPrice() * $quantity;
                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantityAccounted() + $quantity);
                            break;
                        }
                    }

                    $em->flush();
                }

                $this->recordAccountingConsumeSupplies($useInventory, $amount);

                break;

            case 'Inventory Convert Inventory Send In Processing':

                $convertInventory = $params['convertInventory'];
                $branch = $convertInventory->getHealthFacility();

                foreach($convertInventory->getConvertInventoryItems() as $convertInventoryItem) {

                    $inv_obj = $convertInventoryItem->getInventory();
                    $item = $inv_obj->getItem();
                    $location = $inv_obj->getLocation();
                    $inventory = $this->inventory($branch, $location, $item);
                    $inventoryUsed = $this->inventory($branch, null, $item, 'In Processing');

                    $inventory->setQuantity($inventory->getQuantity() - $convertInventoryItem->getQuantity());
                    $inventoryUsed->setQuantity($inventoryUsed->getQuantity() + $convertInventoryItem->getQuantity());

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setConvertInventoryItem($convertInventoryItem);
                    $inventoryMovement->setQuantity($convertInventoryItem->getQuantity() * -1);
                    $em->persist($inventoryMovement);

                    $em->flush();
                }

                break;

            case 'Inventory Convert Inventory Send Costing':

                $convertInventory = $params['convertInventory'];
                $amount = 0;
                $branch = $convertInventory->getHealthFacility();

                foreach($convertInventory->getConvertInventoryItems() as $convertInventoryItem) {

                    $item = $convertInventoryItem->getInventory()->getItem();
                    $inventoryUsed = $this->inventory($branch, null, $item, 'In Processing');
                    $inventoryUsed = $this->inventory($branch, null, $item, 'Used');

                    $inventoryUsed->setQuantity($inventoryUsed->getQuantity() - $convertInventoryItem->getQuantity());
                    $inventoryUsed->setQuantity($inventoryUsed->getQuantity() + $convertInventoryItem->getQuantity());

                    $em->flush();

                    $inventoryPrices = $em->getRepository('RxConnexionBundle:InventoryPriceEntity')->findAllAvailableForAccounting(
                        $convertInventoryItem->getInventory()->getId()
                    );

                    $quantity = $convertInventoryItem->getQuantity();

                    foreach($inventoryPrices as $inventoryPrice) {
                        if($quantity <= 0) {
                            break;
                        } else if($inventoryPrice->getQuantityAccounted() + $quantity >= $inventoryPrice->getQuantity()) {
                            $amount += $inventoryPrice->getPrice() * ($inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted());
                            $quantity -= $inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted();
                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantity());
                        } else {
                            $amount += $inventoryPrice->getPrice() * $quantity;
                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantityAccounted() + $quantity);
                            break;
                        }
                    }

                    $em->flush();
                }

                $convertInventory->setTotalCost($amount);
                $em->flush();
                $em->refresh($convertInventory);

                //$this->recordAccountingConsumeSuppliesFromConvert($convertInventory, $amount);

                break;

            case 'Inventory Convert Inventory Send Completed':

                /**@var ConvertInventoryEntity $convertInventory*/
                $convertInventory = $params['convertInventory'];
                $amount = 0;
                $branch = $convertInventory->getHealthFacility();
                $itemBiCtr = $convertInventory->getItemBiCtr();

                // Check if bi product count is only then do the consume supplies
                // If the bi product count is greater than 1 then it already undergone consume supplies
                //if($itemBiCtr == 1) {

                    /**@var ConvertInventoryItemEntity $convertInventoryItem*/
                    foreach($convertInventory->getConvertInventoryItems() as $convertInventoryItem) {

                        $item = $convertInventoryItem->getInventory()->getItem();

                        // NOTE: NO IN PROCESSING AND USED WERE CREATED BECAUSE WE SKIPPED THIS PART SO WE WILL CREATE A USED HERE 2/10/2021*/
                        /*$inventoryInProcessing = $this->inventory($branch, null, $item, 'In Processing');
                        $inventoryUsed = $this->inventory($branch, null, $item, 'Used');

                        $inventoryInProcessing->setQuantity($inventoryInProcessing->getQuantity() - $convertInventoryItem->getQuantity());
                        $inventoryUsed->setQuantity($inventoryUsed->getQuantity() + $convertInventoryItem->getQuantity());*/

                        $inv_obj = $convertInventoryItem->getInventory();
                        $item = $inv_obj->getItem();
                        $location = $inv_obj->getLocation();
                        $inventory = $this->inventory($branch, $location, $item);
                        $inventoryUsed = $this->inventory($branch, null, $item, 'Used');

                        $inventory->setQuantity($inventory->getQuantity() - $convertInventoryItem->getQuantity());
                        $inventoryUsed->setQuantity($inventoryUsed->getQuantity() + $convertInventoryItem->getQuantity());

                        $inventoryMovement = new InventoryMovementEntity();
                        $inventoryMovement->setInventory($inventory);
                        $inventoryMovement->setSource($source);
                        $inventoryMovement->setConvertInventoryItem($convertInventoryItem);
                        $inventoryMovement->setQuantity($convertInventoryItem->getQuantity() * -1);
                        $em->persist($inventoryMovement);


                        $em->flush();

                        $inventoryPrices = $em->getRepository('RxConnexionBundle:InventoryPriceEntity')->findAllAvailableForAccounting(
                            $convertInventoryItem->getInventory()->getId()
                        );

                        $quantity = $convertInventoryItem->getQuantity();

                        foreach($inventoryPrices as $inventoryPrice) {
                            if($quantity <= 0) {
                                break;
                            } else if($inventoryPrice->getQuantityAccounted() + $quantity >= $inventoryPrice->getQuantity()) {
                                $amount += $inventoryPrice->getPrice() * ($inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted());
                                $quantity -= $inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted();
                                $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantity());
                            } else {
                                $amount += $inventoryPrice->getPrice() * $quantity;
                                $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantityAccounted() + $quantity);
                                break;
                            }
                        }

                        $em->flush();
                    }

                    /*No Accounting for now 1-29-2021*/
                    //$this->recordAccountingConsumeSuppliesFromConvert($convertInventory, $amount);

                    $convertInventory->setTotalCost($amount);
                    $em->flush();
                    $em->refresh($convertInventory);

                //}

                /**@var ConvertInventoryItemBiEntity $convertInventoryItemBi*/
                foreach($convertInventory->getConvertInventoryItemBis() as $convertInventoryItemBi) {

                    if($itemBiCtr == 1) {
                        $convertInventoryItemBi->setTotalCost($convertInventory->getTotalCost());
                    }

                    $inventory = $this->inventory($branch, $convertInventoryItemBi->getLocation(), $convertInventoryItemBi->getItem());

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setConvertInventoryItemBi($convertInventoryItemBi);
                    $inventoryMovement->setQuantity($convertInventoryItemBi->getQuantity());
                    $em->persist($inventoryMovement);

                    if(!is_null($convertInventoryItemBi->getSerialNo()) && !empty($convertInventoryItemBi->getSerialNo())) {
                        $serialNos = explode(',', $convertInventoryItemBi->getSerialNo());
                        foreach ($serialNos as $serialNo) {
                            $isn = new InventorySerialNoEntity();
                            $isn->setSerialNo($serialNo);
                            $isn->setInventory($inventory);
                            $isn->setStatus(InventorySerialNoEntity::STATUS_1);
                            $inventory->addInventorySerialNo($isn);
                            $em->persist($isn);
                        }
                    }

                    $inventoryPrice = new InventoryPriceEntity();
                    $inventoryPrice->setInventory($inventory);
                    $inventoryPrice->setQuantity($convertInventoryItemBi->getQuantity());
                    $inventoryPrice->setPrice(round($convertInventoryItemBi->getTotalCost() / $convertInventoryItemBi->getQuantity(), 2));
                    $inventoryPrice->setSource($source);
                    $inventoryPrice->setConvertInventoryItemBi($convertInventoryItemBi);
                    $em->persist($inventoryPrice);

                    $inventory->setQuantity($inventory->getQuantity() + $convertInventoryItemBi->getQuantity());

                    $em->flush();
                }

                // NO NEED!!!
                //$this->recordAccountingAddSuppliesFromConvert($convertInventory);

                break;

            case 'Inventory Transfer Inventory Send':

                $transferInventory = $params['transferInventory'];

                foreach($transferInventory->getTransferInventoryItems() as $transferInventoryItem) {

                    $inventory = $transferInventoryItem->getInventory();
                    $inventoryInTransit = $this->inventory($transferInventory->getBranchTo(), null, $inventory->getItem(), 'In Transit');

                    $inventory->setQuantity($inventory->getQuantity() - $transferInventoryItem->getQuantity());
                    $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() + $transferInventoryItem->getQuantity());

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setTransferInventoryItem($transferInventoryItem);
                    $inventoryMovement->setQuantity($transferInventoryItem->getQuantity() * -1);
                    $em->persist($inventoryMovement);

                    $em->flush();
                }

                break;

            case 'Inventory Transfer Inventory Delivery':

                $transferInventoryDelivery = $params['transferInventoryDelivery'];
                $transferInventory = $transferInventoryDelivery->getTransferInventory();

                /**@var TransferInventoryDeliveryItemEntity $transferInventoryDeliveryItem*/
                /**@var TransferInventoryEntity $transferInventory*/
                foreach($transferInventoryDelivery->getTransferInventoryDeliveryItems() as $transferInventoryDeliveryItem) {

                    $inventory = $transferInventoryDeliveryItem->getInventory();
                    $inventoryInTransit = $this->inventory($transferInventory->getBranchTo(), $transferInventory->getLocationTo(), $inventory->getItem(), 'In Transit');
                    if('New' === $params['action']) {

                        $inventory->setQuantity($inventory->getQuantity() - $transferInventoryDeliveryItem->getQuantity());
                        $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() + $transferInventoryDeliveryItem->getQuantity());

                        $inventoryMovement = new InventoryMovementEntity();
                        $inventoryMovement->setInventory($inventory);
                        $inventoryMovement->setSource($source);
                        $inventoryMovement->setTransferInventoryDeliveryItem($transferInventoryDeliveryItem);
                        $inventoryMovement->setQuantity($transferInventoryDeliveryItem->getQuantity() * -1);
                        $em->persist($inventoryMovement);

	                    /**@var TransferInventoryDeliveryItemTransferInventoryItemInvSerialNoEntity $transferInventoryDeliveryItemTransferInventoryItemInvSerialNo*/
	                    foreach ($transferInventoryDeliveryItem->getTransferInventoryDeliveryItemTransferInventoryItemInvSerialNos() as $transferInventoryDeliveryItemTransferInventoryItemInvSerialNo) {
		                    $transferInventoryDeliveryItemTransferInventoryItemInvSerialNo->getTransferInventoryItemInventorySerialNo()->getInventorySerialNo()->setStatus(InventorySerialNoEntity::STATUS_4);
	                    }

                    } else {

                        $inventoryMovement = $em->getRepository('RxConnexionBundle:InventoryMovementEntity')->findOneBy(array(
                            'inventory' => $inventory,
                            'source' => $source,
                            'transferInventoryDeliveryItem' => $transferInventoryDeliveryItem
                        ));

                        if('Update' === $params['action']) {

                            $inventory->setQuantity($inventory->getQuantity() - $inventoryMovement->getQuantity());
                            $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() + $inventoryMovement->getQuantity());

                            $inventoryMovement->setQuantity($transferInventoryDeliveryItem->getQuantity() * -1);

                            $inventory->setQuantity($inventory->getQuantity() + $inventoryMovement->getQuantity());
                            $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() - $inventoryMovement->getQuantity());

	                        /**@var TransferInventoryDeliveryItemTransferInventoryItemInvSerialNoEntity $transferInventoryDeliveryItemTransferInventoryItemInvSerialNo*/
	                        foreach ($transferInventoryDeliveryItem->getTransferInventoryDeliveryItemTransferInventoryItemInvSerialNos() as $transferInventoryDeliveryItemTransferInventoryItemInvSerialNo) {
		                        $transferInventoryDeliveryItemTransferInventoryItemInvSerialNo->getTransferInventoryItemInventorySerialNo()->getInventorySerialNo()->setStatus(InventorySerialNoEntity::STATUS_4);
	                        }

                        } else {

	                        /**@var TransferInventoryDeliveryItemTransferInventoryItemInvSerialNoEntity $transferInventoryDeliveryItemTransferInventoryItemInvSerialNo*/
	                        foreach ($transferInventoryDeliveryItem->getTransferInventoryDeliveryItemTransferInventoryItemInvSerialNos() as $transferInventoryDeliveryItemTransferInventoryItemInvSerialNo) {
		                        $transferInventoryDeliveryItemTransferInventoryItemInvSerialNo->getTransferInventoryItemInventorySerialNo()->getInventorySerialNo()->setStatus(InventorySerialNoEntity::STATUS_1);
	                        }

                        	if($inventoryMovement) {
		                        $inventory->setQuantity($inventory->getQuantity() - $inventoryMovement->getQuantity());
		                        $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() + $inventoryMovement->getQuantity());

		                        $em->remove($inventoryMovement);
	                        }
                        }
                    }

                    $em->flush();
                }

                break;

            case 'Inventory Transfer Inventory Item Receive':

            	/**@var TransferInventoryItemDeliveryEntity $transferInventoryItemDelivery*/
                $transferInventoryItemDelivery = $params['transferInventoryItemDelivery'];

                $transferInventory = $transferInventoryItemDelivery->getTransferInventoryItem()->getTransferInventory();
                $branch = $transferInventory->getBranchTo();
                $location = $transferInventory->getLocationTo();

                //$item = $transferInventoryItemDelivery->getTransferInventoryItem()->getInventory()->getItem();
                $item = $transferInventoryItemDelivery->getTransferInventoryItem()->getItem();
                $inventoryItem = $transferInventoryItemDelivery->getTransferInventoryItem();
                $inventory = $this->inventory($branch, $transferInventoryItemDelivery->getLocation(), $item);
                $inventoryInTransit = $this->inventory($branch, $location, $item, 'In Transit');

                if($params['action'] === 'New') {

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setTransferInventoryItemDelivery($transferInventoryItemDelivery);
                    $inventoryMovement->setQuantity($transferInventoryItemDelivery->getQuantity());
                    $em->persist($inventoryMovement);

                    $inventory->setQuantity($inventory->getQuantity() + $transferInventoryItemDelivery->getQuantity());
                    /*if($inventoryItem->getIsConsumable()){
                        $inventory->setStatus(InventoryEntity::STATUS_USED);
                    }*/
                    $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() - $transferInventoryItemDelivery->getQuantity());

                    /**@var TransferInventoryItemDeliveryInventorySerialNoEntity $transferInventoryItemDeliveryInventorySerialNo*/
	                foreach ($transferInventoryItemDelivery->getTransferInventoryItemDeliveryInventorySerialNos() as $transferInventoryItemDeliveryInventorySerialNo) {
		                $transferInventoryItemDeliveryInventorySerialNo->getInventorySerialNo()->setStatus(InventorySerialNoEntity::STATUS_5);
		                $newIsn = new InventorySerialNoEntity();
		                $newIsn->setInventory($inventory);
		                $newIsn->setSerialNo($transferInventoryItemDeliveryInventorySerialNo->getInventorySerialNo()->getSerialNo());
		                $newIsn->setTransferInventoryItemDelivery($transferInventoryItemDelivery);
		                $newIsn->setStatus(InventorySerialNoEntity::STATUS_1);
		                $em->persist($newIsn);
                    }

                } else {

                    $inventoryMovement = $em->getRepository('RxConnexionBundle:InventoryMovementEntity')->findOneBy(array(
                        'inventory' => $inventory,
                        'source' => $source,
                        'transferInventoryItemDelivery' => $transferInventoryItemDelivery
                    ));
                    /*if(!$inventoryMovement){
                        die(var_dump($inventory->getId(), $source, $transferInventoryItemDelivery->getId()));
                    }*/

                    if($params['action'] === 'Update') {

                        $inventory->setQuantity($inventory->getQuantity() - $inventoryMovement->getQuantity());
                        $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() + $inventoryMovement->getQuantity());

                        $inventoryMovement->setQuantity($transferInventoryItemDelivery->getQuantity());

                        $inventory->setQuantity($inventory->getQuantity() + $inventoryMovement->getQuantity());
                        $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() - $inventoryMovement->getQuantity());

	                    /**@var TransferInventoryItemDeliveryInventorySerialNoEntity $transferInventoryItemDeliveryInventorySerialNo*/
	                    foreach ($transferInventoryItemDelivery->getTransferInventoryItemDeliveryInventorySerialNos() as $transferInventoryItemDeliveryInventorySerialNo) {
	                    	/**@var InventorySerialNoEntity $inventorySerialNo*/
	                    	$addFlag = true;
		                    foreach ($inventory->getInventorySerialNos() as $inventorySerialNo) {
			                    if($inventorySerialNo->getTransferInventoryItemDelivery() === $transferInventoryItemDelivery && $inventorySerialNo->getSerialNo() === $transferInventoryItemDeliveryInventorySerialNo->getInventorySerialNo()->getSerialNo()) {
				                    $addFlag = false;
				                    break;
			                    }
	                    	}
		                    if($addFlag) {
			                    $transferInventoryItemDeliveryInventorySerialNo->getInventorySerialNo()->setStatus(InventorySerialNoEntity::STATUS_5);
			                    $newIsn = new InventorySerialNoEntity();
			                    $newIsn->setInventory($inventory);
			                    $newIsn->setSerialNo($transferInventoryItemDeliveryInventorySerialNo->getInventorySerialNo()->getSerialNo());
			                    $newIsn->setTransferInventoryItemDelivery($transferInventoryItemDelivery);
			                    $newIsn->setStatus(InventorySerialNoEntity::STATUS_1);
			                    $em->persist($newIsn);
		                    }
	                    }

                    } else {


                        /**@var InventorySerialNoEntity $inventorySerialNo*/
	                    foreach ($transferInventoryItemDelivery->getInventorySerialNos() as $inventorySerialNo) {
	                    	$em->remove($inventorySerialNo);
		                    $transferInventoryItemDelivery->removeInventorySerialNo($inventorySerialNo);
                        }
	                    /**@var TransferInventoryItemDeliveryInventorySerialNoEntity $transferInventoryItemDeliveryInventorySerialNo*/
	                    foreach ($transferInventoryItemDelivery->getTransferInventoryItemDeliveryInventorySerialNos() as $transferInventoryItemDeliveryInventorySerialNo) {
		                    $transferInventoryItemDeliveryInventorySerialNo->getInventorySerialNo()->setStatus(InventorySerialNoEntity::STATUS_4);
	                    }

	                    if($inventoryMovement) {
		                    $inventory->setQuantity($inventory->getQuantity() - $inventoryMovement->getQuantity());
		                    $inventoryInTransit->setQuantity($inventoryInTransit->getQuantity() + $inventoryMovement->getQuantity());
		                    $em->remove($inventoryMovement);
	                    }

	                    $item->removeTransferInventoryItem($transferInventoryItemDelivery->getTransferInventoryItem());
                    }
                }

                $em->flush();

	            // COMPUTE AVERAGE COST
	            $itemService = new ItemService($this->em, $this->container);
	            $itemService->computeAverageCostByBranch($item, $branch);
                break;

            case 'Sales Order Complete':

                $salesOrder = $params['salesOrder'];
                $amount = 0;
                $amountDeposit = 0;

                foreach($salesOrder->getSalesOrderInventories() as $salesOrderInventory) {

                    $isDeposit = $salesOrderInventory->getSalesOrderItem()->getIsDeposit();

                    $inventory = $salesOrderInventory->getInventory();
                    $inventory_SOLD = $this->inventory($inventory->getBranch(), null, $inventory->getItem(), $isDeposit ? 'Deposit' : 'Sold');

                    $inventory->setQuantity($inventory->getQuantity() - $salesOrderInventory->getQuantity());
                    $inventory_SOLD->setQuantity($inventory_SOLD->getQuantity() + $salesOrderInventory->getQuantity());

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setSalesOrderInventory($salesOrderInventory);
                    $inventoryMovement->setQuantity($salesOrderInventory->getQuantity() * -1);
                    $em->persist($inventoryMovement);

                    $em->flush();

                    $inventoryPrices = $em->getRepository('RxConnexionBundle:InventoryPriceEntity')->findAllAvailableForAccounting(
                        $inventory->getId()
                    );

                    $quantity = $salesOrderInventory->getQuantity();

                    foreach($inventoryPrices as $inventoryPrice) {
                        if($quantity <= 0) {
                            break;
                        } else if($inventoryPrice->getQuantityAccounted() + $quantity >= $inventoryPrice->getQuantity()) {

                            $refQty = $inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted();
                            if($isDeposit) {
                                $amountDeposit += $inventoryPrice->getPrice() * $refQty;
                            } else {
                                $amount += $inventoryPrice->getPrice() * $refQty;
                            }
                            $quantity -= $refQty;
                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantity());

                            $newSalesOrderInventoryPrice = new SalesOrderInventoryPriceEntity();
                            $newSalesOrderInventoryPrice->setSalesOrderInventory($salesOrderInventory);
                            $newSalesOrderInventoryPrice->setQuantity($refQty);
                            $newSalesOrderInventoryPrice->setPrice($inventoryPrice->getPrice());
                            $em->persist($newSalesOrderInventoryPrice);

                        } else {

                            if($isDeposit) {
                                $amountDeposit += $inventoryPrice->getPrice() * $quantity;
                            } else {
                                $amount += $inventoryPrice->getPrice() * $quantity;
                            }
                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantityAccounted() + $quantity);

                            $newSalesOrderInventoryPrice = new SalesOrderInventoryPriceEntity();
                            $newSalesOrderInventoryPrice->setSalesOrderInventory($salesOrderInventory);
                            $newSalesOrderInventoryPrice->setQuantity($quantity);
                            $newSalesOrderInventoryPrice->setPrice($inventoryPrice->getPrice());
                            $em->persist($newSalesOrderInventoryPrice);

                            break;
                        }
                    }

                    $em->flush();
                }

                $this->recordAccountingSalesOrder($salesOrder, $amount, $amountDeposit);

                break;

            case 'Sales Order Pending Payment' :

                $salesOrder = $params['salesOrder'];

                $this->recordAccountingSalesOrderPendingPayment($salesOrder);

                break;

            case 'Sales Order Return Complete':

                $salesOrderReturn = $params['salesOrderReturn'];
                $branch = $salesOrderReturn->getSalesOrder()->getBranch();

                $amount = 0;

                foreach($salesOrderReturn->getSalesOrderReturnItems() as $salesOrderReturnItem) {

                    $salesOrderItem = $salesOrderReturnItem->getSalesOrderItem();
                    $item = $salesOrderItem->getItem();
                    $inventory = $this->inventory($branch, $salesOrderReturnItem->getLocation(), $item, $salesOrderReturnItem->getStatus());
                    $inventory_SOLD = $this->inventory($branch, null, $item, $salesOrderItem->getIsDeposit() ? 'Deposit' : 'Sold');

                    $inventory->setQuantity($inventory->getQuantity() + $salesOrderReturnItem->getQuantity());
                    $inventory_SOLD->setQuantity($inventory_SOLD->getQuantity() - $salesOrderReturnItem->getQuantity());

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setSalesOrderReturnItem($salesOrderReturnItem);
                    $inventoryMovement->setQuantity($salesOrderReturnItem->getQuantity() * 1);
                    $em->persist($inventoryMovement);

                    $em->flush();

                    $quantity = $salesOrderReturnItem->getQuantity();

                    foreach($salesOrderItem->getSalesOrderInventories() as $salesOrderInventory) {
                        if($quantity <= 0) {
                            foreach($salesOrderInventory->getSalesOrderInventoryPricesAvailableForReturn() as $salesOrderInventoryPrice) {
                                if($quantity <= 0) {
                                    break;
                                } else if($salesOrderInventoryPrice->getQuantityReturned() + $quantity >= $salesOrderInventoryPrice->getQuantity()) {

                                    $refQty = $salesOrderInventoryPrice->getQuantity() - $salesOrderInventoryPrice->getQuantityReturned();
                                    $amount += $salesOrderInventoryPrice->getPrice() * $refQty;
                                    $quantity -= $refQty;
                                    $salesOrderInventoryPrice->setQuantityReturned($salesOrderInventoryPrice->getQuantity());

                                    $newInventoryPrice = new InventoryPriceEntity();
                                    $newInventoryPrice->setInventory($inventory);
                                    $newInventoryPrice->setQuantity($refQty);
                                    $newInventoryPrice->setPrice($salesOrderInventoryPrice->getPrice());
                                    $newInventoryPrice->setSource($source);
                                    $newInventoryPrice->setSalesOrderReturnItem($salesOrderReturnItem);
                                    $em->persist($newInventoryPrice);

                                } else {

                                    $amount += $salesOrderInventoryPrice->getPrice() * $quantity;
                                    $salesOrderInventoryPrice->setQuantityReturned($salesOrderInventoryPrice->getQuantityReturned() + $quantity);

                                    $newInventoryPrice = new InventoryPriceEntity();
                                    $newInventoryPrice->setInventory($inventory);
                                    $newInventoryPrice->setQuantity($quantity);
                                    $newInventoryPrice->setPrice($salesOrderInventoryPrice->getPrice());
                                    $newInventoryPrice->setSource($source);
                                    $newInventoryPrice->setSalesOrderReturnItem($salesOrderReturnItem);
                                    $em->persist($newInventoryPrice);

                                    break;
                                }
                            }
                        }
                    }

                    $em->flush();
                }

                $this->recordAccountingSalesOrderReturn($salesOrderReturn, $amount);

                break;

            case 'Job Order Complete':

                $jobOrder = $params['jobOrder'];
                $amount = 0;

                foreach($jobOrder->getJobOrderInventories() as $jobOrderInventory) {

                    $inventory = $jobOrderInventory->getInventory();
                    $inventoryUsed = $this->inventory($inventory->getBranch(), null, $inventory->getItem(), 'Used');

                    $inventory->setQuantity($inventory->getQuantity() - $jobOrderInventory->getQuantity());
                    $inventoryUsed->setQuantity($inventoryUsed->getQuantity() + $jobOrderInventory->getQuantity());

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setJobOrderInventory($jobOrderInventory);
                    $inventoryMovement->setQuantity($jobOrderInventory->getQuantity() * -1);
                    $em->persist($inventoryMovement);

                    $em->flush();

                    $inventoryPrices = $em->getRepository('RxConnexionBundle:InventoryPriceEntity')->findAllAvailableForAccounting(
                        $inventory->getId()
                    );

                    $quantity = $jobOrderInventory->getQuantity();

                    foreach($inventoryPrices as $inventoryPrice) {
                        if($quantity <= 0) {
                            break;
                        } else if($inventoryPrice->getQuantityAccounted() + $quantity >= $inventoryPrice->getQuantity()) {

                            $refQty = $inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted();
                            $amount += $inventoryPrice->getPrice() * $refQty;
                            $quantity -= $refQty;
                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantity());

                            $newJobOrderInventoryPrice = new JobOrderInventoryPriceEntity();
                            $newJobOrderInventoryPrice->setJobOrderInventory($jobOrderInventory);
                            $newJobOrderInventoryPrice->setQuantity($refQty);
                            $newJobOrderInventoryPrice->setPrice($inventoryPrice->getPrice());
                            $em->persist($newJobOrderInventoryPrice);

                        } else {

                            $amount += $inventoryPrice->getPrice() * $quantity;
                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantityAccounted() + $quantity);

                            $newJobOrderInventoryPrice = new JobOrderInventoryPriceEntity();
                            $newJobOrderInventoryPrice->setJobOrderInventory($jobOrderInventory);
                            $newJobOrderInventoryPrice->setQuantity($quantity);
                            $newJobOrderInventoryPrice->setPrice($inventoryPrice->getPrice());
                            $em->persist($newJobOrderInventoryPrice);

                            break;
                        }
                    }

                    $em->flush();
                }

                $this->recordAccountingConsumeSuppliesFromJobOrder($jobOrder, $amount);

                break;

            case 'Patient Billing - Invoice OLD':

                /**@var PatientBillingEntity $patientBilling*/
                $patientBilling = $params['patientBilling'];
                $action = $params['action'];

                if($action === 'n') {

                } elseif($action === 'u') {

                }

                /**@var PatientBillingBreakdownEntity $patientBillingBreakdown*/
                foreach($patientBilling->getPatientBillingBreakdowns() as $patientBillingBreakdown) {

                    if($patientBillingBreakdown->getInventorySerialNo()){
                        $patientBillingBreakdown->getInventorySerialNo()->setStatus(InventorySerialNoEntity::STATUS_2);

                        $inventory = $patientBillingBreakdown->getInventorySerialNo()->getInventory();
                    } else {

                        $inventory = $em->getRepository('RxConnexionBundle:InventoryEntity')->findOneBy(array(
                            'healthFacility' => $patientBilling->getHealthFacility(),
                            'item' => $patientBillingBreakdown->getItem(),
                            'status' => 'Stock On Hand'
                        ));
                    }


                    if ($inventory) {
                        $inventory_SOLD = $this->inventory($patientBilling->getHealthFacility(), null, $patientBillingBreakdown->getItem(), 'Sold');
                        $inventory->setQuantity($inventory->getQuantity() - $patientBillingBreakdown->getQuantity());
                        $inventory_SOLD->setQuantity($inventory_SOLD->getQuantity() + $patientBillingBreakdown->getQuantity());

                        $inventoryMovement = new InventoryMovementEntity();
                        $inventoryMovement->setInventory($inventory);
                        $inventoryMovement->setSource($source);
                        $inventoryMovement->setQuantity($patientBillingBreakdown->getQuantity() * -1);
                        $em->persist($inventoryMovement);
                        $em->flush();
                    } else {
                        $inventory = new InventoryEntity();
                        $inventory->setHealthFacility($patientBilling->getHealthFacility());
                        $inventory->setStatus('Sold');
                        $inventory->setItem($patientBillingBreakdown->getItem());
                        $inventory->setLocation(null);
                        $inventory->setQuantity((0 - $patientBillingBreakdown->getQuantity()));
                        $em->persist($inventory);
                        $em->flush();
                    }


                    /*$patientBillingInventory = new PatientBillingInventoryEntity();
                    $patientBillingInventory->setPatientBilling($patientBilling);
                    $patientBillingInventory->setItem($patientBillingBreakdown->getItem());
                    $patientBillingInventory->setInventory($inventory);
                    $patientBillingInventory->setInventorySerialNo($patientBillingBreakdown->getInventorySerialNo());
                    $patientBillingInventory->setSerialNo($patientBillingBreakdown->getSerialNumber());
                    $patientBillingInventory->setQuantity($patientBillingBreakdown->getQuantity());
                    $em->persist($patientBillingInventory);*/


                    $em->flush();

//                    $inventoryPrices = $em->getRepository('RxConnexionBundle:InventoryPriceEntity')->findAllAvailableForAccounting(
//                        $inventory->getId()
//                    );
//
//                    $quantity = $salesOrderInventory->getQuantity();

//                    foreach($inventoryPrices as $inventoryPrice) {
//                        if($quantity <= 0) {
//                            break;
//                        } else if($inventoryPrice->getQuantityAccounted() + $quantity >= $inventoryPrice->getQuantity()) {
//
//                            $refQty = $inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted();
//                            if($isDeposit) {
//                                $amountDeposit += $inventoryPrice->getPrice() * $refQty;
//                            } else {
//                                $amount += $inventoryPrice->getPrice() * $refQty;
//                            }
//                            $quantity -= $refQty;
//                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantity());
//
//                            $newSalesOrderInventoryPrice = new SalesOrderInventoryPriceEntity();
//                            $newSalesOrderInventoryPrice->setSalesOrderInventory($salesOrderInventory);
//                            $newSalesOrderInventoryPrice->setQuantity($refQty);
//                            $newSalesOrderInventoryPrice->setPrice($inventoryPrice->getPrice());
//                            $em->persist($newSalesOrderInventoryPrice);
//
//                        } else {
//
//                            if($isDeposit) {
//                                $amountDeposit += $inventoryPrice->getPrice() * $quantity;
//                            } else {
//                                $amount += $inventoryPrice->getPrice() * $quantity;
//                            }
//                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantityAccounted() + $quantity);
//
//                            $newSalesOrderInventoryPrice = new SalesOrderInventoryPriceEntity();
//                            $newSalesOrderInventoryPrice->setSalesOrderInventory($salesOrderInventory);
//                            $newSalesOrderInventoryPrice->setQuantity($quantity);
//                            $newSalesOrderInventoryPrice->setPrice($inventoryPrice->getPrice());
//                            $em->persist($newSalesOrderInventoryPrice);
//
//                            break;
//                        }
//                    }

//                    $em->flush();
                }

//                $this->recordAccountingSalesOrder($salesOrder, $amount, $amountDeposit);

                break;
            case 'Patient Billing - Invoice':

                /**@var PatientBillingEntity $patientBilling*/
                $patientBilling = $params['patientBilling'];
                $action = $params['action'];


                /**@var PatientBillingInventoryEntity $patientBillingInventory*/
                foreach($patientBilling->getPatientBillingInventories() as $patientBillingInventory) {

                    /**@var InventorySerialNoEntity $inventorySerialNo*/
                    foreach ($patientBillingInventory->getInventorySerialNos() as $inventorySerialNo) {
                        $inventorySerialNo->setStatus(InventorySerialNoEntity::STATUS_2);
                    }
                    $inventory = $this->inventory($patientBilling->getHealthFacility(), null, $patientBillingInventory->getItem(), 'Stock On Hand');
                    $inventory_SOLD = $this->inventory($patientBilling->getHealthFacility(), null, $patientBillingInventory->getItem(), 'Sold');

                    // NEW
                    if($action === 'n' || !$patientBillingInventory->getInventory()) {

                        $inventory->setQuantity($inventory->getQuantity() - $patientBillingInventory->getQuantity());
                        $inventory_SOLD->setQuantity($inventory_SOLD->getQuantity() + $patientBillingInventory->getQuantity());

                        $inventoryMovement = new InventoryMovementEntity();
                        $inventoryMovement->setInventory($inventory);
                        $inventoryMovement->setSource($source);
                        $inventoryMovement->setQuantity($patientBillingInventory->getQuantity() * -1);
                        $inventoryMovement->setPatientBillingInventory($patientBillingInventory);
                        $em->persist($inventoryMovement);

                        $patientBillingInventory->setInventory($inventory);

                        $inventory->addInventoryMovement($inventoryMovement);
                        $inventory->addPatientBillingInventory($patientBillingInventory);
                        $patientBillingInventory->addInventoryMovement($inventoryMovement);

                    }
                    // UPDATE
                    else {

                        $inventory = $patientBillingInventory->getInventory();

                        $inventoryMovement = $em->getRepository(InventoryMovementEntity::class)->findOneBy(array(
                            'inventory' => $inventory,
                            'source' => $source,
                            'patientBillingInventory' => $patientBillingInventory
                        ));


                        // return the quantities recorded in movement from inventory
                        $inventory->setQuantity($inventory->getQuantity() - $inventoryMovement->getQuantity());
                        $inventory_SOLD->setQuantity($inventory_SOLD->getQuantity() + $inventoryMovement->getQuantity());

                        // update the quantity recorded in movement
                        $inventoryMovement->setQuantity($patientBillingInventory->getQuantity() * -1);

                        // recompute inventories base on new movement
                        $inventory->setQuantity($inventory->getQuantity() - $patientBillingInventory->getQuantity());
                        $inventory_SOLD->setQuantity($inventory_SOLD->getQuantity() + $patientBillingInventory->getQuantity());


                    }


                }


                $em->flush();

                break;
            case 'Patient Billing Inventory Removed':

                /**@var PatientBillingInventoryEntity $patientBillingInventory*/

                $patientBillingInventory = $params['patientBillingInventory'];
                $patientBilling = $patientBillingInventory->getPatientBilling();

                foreach ($patientBillingInventory->getInventorySerialNos() as $inventorySerialNo) {
                    $inventorySerialNo->setStatus(InventorySerialNoEntity::STATUS_1);
                    $inventorySerialNo->setPatientBillingInventory(null);
                    $patientBillingInventory->removeInventorySerialNo($inventorySerialNo);
                }

                $inventory = $patientBillingInventory->getInventory();
                $inventory_SOLD = $this->inventory($patientBilling->getHealthFacility(), null, $patientBillingInventory->getItem(), 'Sold');

                $inventoryMovement = $em->getRepository(InventoryMovementEntity::class)->findOneBy(array(
                    'inventory' => $inventory,
                    'source' => 'Patient Billing - Invoice',
                    'patientBillingInventory' => $patientBillingInventory
                ));


                // return the quantities recorded in movement from inventory
                $inventory->setQuantity($inventory->getQuantity() - $inventoryMovement->getQuantity());
                $inventory_SOLD->setQuantity($inventory_SOLD->getQuantity() + $inventoryMovement->getQuantity());

                $em->remove($inventoryMovement);
                $em->remove($patientBillingInventory);
                $patientBilling->removePatientBillingInventory($patientBillingInventory);
                return $patientBilling;
                //$em->flush();

                break;
            case 'Patient Billing - Return Item':

                /**@var PatientBillingBreakdownEntity $patientBillingBreakdown*/
                $patientBillingBreakdown = $params['patientBillingBreakdown'];
                $patientBilling = $patientBillingBreakdown->getPatientBilling();


                if($patientBillingBreakdown->getInventorySerialNo()){
                    $patientBillingBreakdown->getInventorySerialNo()->setStatus(InventorySerialNoEntity::STATUS_1);

                    $inventory = $patientBillingBreakdown->getInventorySerialNo()->getInventory();
                } else {

                    $inventory = $em->getRepository('RxConnexionBundle:InventoryEntity')->findOneBy(array(
                        'healthFacility' => $patientBilling->getHealthFacility(),
                        'item' => $patientBillingBreakdown->getItem(),
                        'status' => 'Stock On Hand'
                    ));
                }


                if ($inventory) {
                    $inventory->setQuantity($inventory->getQuantity() + $patientBillingBreakdown->getQuantity());


                    $inventory_SOLD = $this->inventory($patientBilling->getHealthFacility(), null, $patientBillingBreakdown->getItem(), 'Sold');
                    $inventory_SOLD->setQuantity($inventory_SOLD->getQuantity() - $patientBillingBreakdown->getQuantity());

                    $inventoryMovement = new InventoryMovementEntity();
                    $inventoryMovement->setInventory($inventory);
                    $inventoryMovement->setSource($source);
                    $inventoryMovement->setQuantity($patientBillingBreakdown->getQuantity() * -1);
                    $em->persist($inventoryMovement);
                    $em->flush();

                } else {
                    $inventory = new InventoryEntity();
                    $inventory->setHealthFacility($patientBilling->getHealthFacility());
                    $inventory->setStatus('Stock On Hand');
                    $inventory->setItem($patientBillingBreakdown->getItem());
                    $inventory->setLocation(null);
                    $inventory->setQuantity((0 - $patientBillingBreakdown->getQuantity()));
                    $em->persist($inventory);
                    $em->flush();
                }

                break;

//            case 'Patient Billing - Refund':
//
//                $patientBillingRefund = $params['patientBillingRefund'];
//
//                foreach($patientBillingRefund->getPatientBilling()->getPatientBillingBreakdowns() as $patientBillingBreakdown) {
//
//                    $inventory = $em->getRepository('RxConnexionBundle:InventoryEntity')->findOneBy(array(
//                        'healthFacility' => $patientBillingRefund->getPatientBilling()->getHealthFacility(),
//                        'item' => $patientBillingBreakdown->getItem(),
//                        'status' => 'Stock On Hand'
//                    ));
//
//
//                    $inventory2 = $this->inventory($patientBillingRefund->getPatientBilling()->getHealthFacility(), null, $patientBillingBreakdown->getItem(), 'Refunded');
//
//                    $inventory->setQuantity($inventory->getQuantity() + $patientBillingBreakdown->getQuantity());
//                    $inventory2->setQuantity($inventory2->getQuantity() - $patientBillingBreakdown->getQuantity());
//
//                    $inventoryMovement = new InventoryMovementEntity();
//                    $inventoryMovement->setInventory($inventory);
//                    $inventoryMovement->setSource($source);
////                    $inventoryMovement->setSalesOrderInventory($salesOrderInventory);
//                    $inventoryMovement->setQuantity($patientBillingBreakdown->getQuantity() * +1);
//                    $em->persist($inventoryMovement);
//
//                    $em->flush();
//
////                    $inventoryPrices = $em->getRepository('RxConnexionBundle:InventoryPriceEntity')->findAllAvailableForAccounting(
////                        $inventory->getId()
////                    );
////
////                    $quantity = $salesOrderInventory->getQuantity();
//
////                    foreach($inventoryPrices as $inventoryPrice) {
////                        if($quantity <= 0) {
////                            break;
////                        } else if($inventoryPrice->getQuantityAccounted() + $quantity >= $inventoryPrice->getQuantity()) {
////
////                            $refQty = $inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted();
////                            if($isDeposit) {
////                                $amountDeposit += $inventoryPrice->getPrice() * $refQty;
////                            } else {
////                                $amount += $inventoryPrice->getPrice() * $refQty;
////                            }
////                            $quantity -= $refQty;
////                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantity());
////
////                            $newSalesOrderInventoryPrice = new SalesOrderInventoryPriceEntity();
////                            $newSalesOrderInventoryPrice->setSalesOrderInventory($salesOrderInventory);
////                            $newSalesOrderInventoryPrice->setQuantity($refQty);
////                            $newSalesOrderInventoryPrice->setPrice($inventoryPrice->getPrice());
////                            $em->persist($newSalesOrderInventoryPrice);
////
////                        } else {
////
////                            if($isDeposit) {
////                                $amountDeposit += $inventoryPrice->getPrice() * $quantity;
////                            } else {
////                                $amount += $inventoryPrice->getPrice() * $quantity;
////                            }
////                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantityAccounted() + $quantity);
////
////                            $newSalesOrderInventoryPrice = new SalesOrderInventoryPriceEntity();
////                            $newSalesOrderInventoryPrice->setSalesOrderInventory($salesOrderInventory);
////                            $newSalesOrderInventoryPrice->setQuantity($quantity);
////                            $newSalesOrderInventoryPrice->setPrice($inventoryPrice->getPrice());
////                            $em->persist($newSalesOrderInventoryPrice);
////
////                            break;
////                        }
////                    }
//
////                    $em->flush();
//                }
//
////                $this->recordAccountingSalesOrder($salesOrder, $amount, $amountDeposit);
//
//                break;
        }
    }

    public function recordAccountingPurchaseOrderReceive(PurchaseOrderBreakdownEntity $purchaseOrderBreakdown) {

        $em = $this->em;
        $em->refresh($purchaseOrderBreakdown);

        $transactionLink = $purchaseOrderBreakdown->getTransactionLink();
        $amount = $purchaseOrderBreakdown->getTotalAmountReceived();

        if($amount > 0) {

            if($transactionLink) {

                $transaction = $transactionLink->getTransaction();
                $transaction->setAmount($amount);

                foreach($transaction->getTransactionJournalEntries() as $transactionJournalEntry) {
                    $transactionJournalEntry->setAmount($amount);
                    if($transactionJournalEntry->getDebitAmount() > 0) {
                        $transactionJournalEntry->setDebitAmount($amount);
                    } else {
                        $transactionJournalEntry->setCreditAmount($amount);
                    }
                }

            } else {

                $branch = $em->getRepository('RxConnexionBundle:BranchEntity')->findOneBy(array('isMain' => true));
                $supplier = $purchaseOrderBreakdown->getPurchaseOrder()->getSupplier();
                $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Purchase Order - Receive'));
                $slAccount_debit = $accountingTransaction->getSubsidiaryLedgerAccountDebit();
                $glAccount_credit = $accountingTransaction->getGeneralLedgerAccountCredit();
                $slAccount_credit = $glAccount_credit->getSlAccountLinkedBySupplier($supplier);

                if(!$slAccount_credit) {
                    $glAccountService = $this->container->get('rx_connexion.glAccountService');
                    $slAccount_credit = $glAccountService->processCmsSlByGl('Supplier', $glAccount_credit, $supplier);
                }

                $newTransaction = new TransactionEntity();
                $newTransaction->setTransactionType($accountingTransaction->getTransactionType());
                $newTransaction->setBranch($branch);
                $newTransaction->setTransactionDate(date('m/d/Y'));
                $newTransaction->setTransactionNo('001');
                $newTransaction->setAmount($amount);
                $em->persist($newTransaction);

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setDebitAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($slAccount_debit);
                $em->persist($newTransactionJournalEntry);

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setCreditAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($slAccount_credit);
                $em->persist($newTransactionJournalEntry);

                $newTransactionLink = new TransactionLinkEntity();
                $newTransactionLink->setTransaction($newTransaction);
                $newTransactionLink->setPurchaseOrderBreakdown($purchaseOrderBreakdown);
                $em->persist($newTransactionLink);
            }

            $em->flush();

        } else if($transactionLink) {
            $em->remove($transactionLink);
            $em->flush();
        }
    }

    public function recordAccountingAddSupplies($addInventory, $amount) {

        $em = $this->em;

        foreach($addInventory->getAddInventoryPayments() as $addInventoryPayment) {

            switch($addInventoryPayment->getType()) {
                case 'Check':
                    $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Add Supplies - Send - Check'));
                    $slAccount_credit = $accountingTransaction->getGeneralLedgerAccountCredit()->getSlAccountLinkedByBank($addInventoryPayment->getBank());
                    break;
                case 'Credit':
                    $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Add Supplies - Send - Credit'));
                    $slAccount_credit = $accountingTransaction->getGeneralLedgerAccountCredit()->getSlAccountLinkedBySupplier($addInventory->getSupplier());
                    break;
                default:
                    $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Add Supplies - Send - Cash'));
                    $slAccount_credit = $accountingTransaction->getSubsidiaryLedgerAccountCredit();
                    break;
            }

            $newTransaction = new TransactionEntity();
            $newTransaction->setTransactionType($accountingTransaction->getTransactionType());
            $newTransaction->setBranch($addInventory->getBranch());
            $newTransaction->setTransactionDate($addInventory->getAddDateAsString());
            $newTransaction->setTransactionNo('001');
            $newTransaction->setAmount($amount);
            $em->persist($newTransaction);
            $em->flush();

            $newTransactionJournalEntry = new TransactionJournalEntryEntity();
            $newTransactionJournalEntry->setTransaction($newTransaction);
            $newTransactionJournalEntry->setDebitAmount($amount);
            $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountDebit());
            $em->persist($newTransactionJournalEntry);

            $newTransactionJournalEntry = new TransactionJournalEntryEntity();
            $newTransactionJournalEntry->setTransaction($newTransaction);
            $newTransactionJournalEntry->setCreditAmount($amount);
            $newTransactionJournalEntry->setSubsidiaryLedgerAccount($slAccount_credit);
            $em->persist($newTransactionJournalEntry);

            $em->flush();
        }
    }

    /*public function recordAccountingAddSuppliesFromConvert($convertInventory) {

        $em = $this->em;
        $amount = $convertInventory->getTotalCost();

        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Add Supplies - Send'));

        $newTransaction = new TransactionEntity();
        $newTransaction->setTransactionType($accountingTransaction->getTransactionType());
        $newTransaction->setBranch($convertInventory->getBranch());
        $newTransaction->setTransactionDate($convertInventory->getConvertDateAsString());
        $newTransaction->setTransactionNo('001');
        $newTransaction->setAmount($amount);
        $em->persist($newTransaction);
        $em->flush();

        $newTransactionJournalEntry = new TransactionJournalEntryEntity();
        $newTransactionJournalEntry->setTransaction($newTransaction);
        $newTransactionJournalEntry->setDebitAmount($amount);
        $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountDebit());
        $em->persist($newTransactionJournalEntry);

        $newTransactionJournalEntry = new TransactionJournalEntryEntity();
        $newTransactionJournalEntry->setTransaction($newTransaction);
        $newTransactionJournalEntry->setCreditAmount($amount);
        $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountCredit());
        $em->persist($newTransactionJournalEntry);

        $em->flush();
    }*/

    public function recordAccountingConsumeSupplies($useInventory, $amount) {

        $em = $this->em;

        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Consume Supplies - Send'));

        $newTransaction = new TransactionEntity();
        $newTransaction->setTransactionType($accountingTransaction->getTransactionType());
        $newTransaction->setBranch($useInventory->getBranch());
        $newTransaction->setTransactionDate($useInventory->getUseDateAsString());
        $newTransaction->setTransactionNo('001');
        $newTransaction->setAmount($amount);
        $em->persist($newTransaction);
        $em->flush();

        $newTransactionJournalEntry = new TransactionJournalEntryEntity();
        $newTransactionJournalEntry->setTransaction($newTransaction);
        $newTransactionJournalEntry->setDebitAmount($amount);
        $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountDebit());
        $em->persist($newTransactionJournalEntry);

        $newTransactionJournalEntry = new TransactionJournalEntryEntity();
        $newTransactionJournalEntry->setTransaction($newTransaction);
        $newTransactionJournalEntry->setCreditAmount($amount);
        $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountCredit());
        $em->persist($newTransactionJournalEntry);

        $em->flush();
    }

    public function recordAccountingConsumeSuppliesFromJobOrder($jobOrder, $amount) {

        $em = $this->em;

        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Consume Supplies - Send'));

        $newTransaction = new TransactionEntity();
        $newTransaction->setTransactionType($accountingTransaction->getTransactionType());
        $newTransaction->setBranch($jobOrder->getBranch());
        $newTransaction->setTransactionDate($jobOrder->getOrderDateAsString());
        $newTransaction->setTransactionNo('001');
        $newTransaction->setAmount($amount);
        $em->persist($newTransaction);
        $em->flush();

        $newTransactionJournalEntry = new TransactionJournalEntryEntity();
        $newTransactionJournalEntry->setTransaction($newTransaction);
        $newTransactionJournalEntry->setDebitAmount($amount);
        $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountDebit());
        $em->persist($newTransactionJournalEntry);

        $newTransactionJournalEntry = new TransactionJournalEntryEntity();
        $newTransactionJournalEntry->setTransaction($newTransaction);
        $newTransactionJournalEntry->setCreditAmount($amount);
        $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountCredit());
        $em->persist($newTransactionJournalEntry);

        $em->flush();
    }

    public function recordAccountingConsumeSuppliesFromConvert($convertInventory, $amount) {

        $em = $this->em;

        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Consume Supplies - Send'));

        $newTransaction = new TransactionEntity();
        $newTransaction->setTransactionType($accountingTransaction->getTransactionType());
        $newTransaction->setBranch($convertInventory->getBranch());
        $newTransaction->setTransactionDate($convertInventory->getConvertDateAsString());
        $newTransaction->setTransactionNo('001');
        $newTransaction->setAmount($amount);
        $em->persist($newTransaction);
        $em->flush();

        $newTransactionJournalEntry = new TransactionJournalEntryEntity();
        $newTransactionJournalEntry->setTransaction($newTransaction);
        $newTransactionJournalEntry->setDebitAmount($amount);
        $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountDebit());
        $em->persist($newTransactionJournalEntry);

        $newTransactionJournalEntry = new TransactionJournalEntryEntity();
        $newTransactionJournalEntry->setTransaction($newTransaction);
        $newTransactionJournalEntry->setCreditAmount($amount);
        $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountCredit());
        $em->persist($newTransactionJournalEntry);

        $em->flush();
    }

    /*public function recordAccountingTransferSupplies($source, $params=array()) {

        $em = $this->em;
        $amount = 0;

        switch($source) {

            case 'Transmittal':

                $transmittal = $params['transmittal'];

                foreach($transmittal->getTransmittalItems() as $transmittalItem) {

                    $inventory = $this->inventory($transmittal->getBranchFrom(), $transmittalItem->getMaterialRequisitionItem()->getLocation(), $transmittalItem->getMaterialRequisitionItem()->getItem());

                    $inventoryPrices = $em->getRepository('RxConnexionBundle:InventoryPriceEntity')->findAllAvailableForAccounting(
                        $inventory->getId()
                    );

                    $quantity = $transmittalItem->getQuantity();

                    foreach($inventoryPrices as $inventoryPrice) {
                        if($quantity <= 0) {
                            break;
                        } else if($inventoryPrice->getQuantityAccounted() + $quantity >= $inventoryPrice->getQuantity()) {
                            $amount += $inventoryPrice->getPrice() * ($inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted());
                            $quantity -= $inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted();
                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantity());
                        } else {
                            $amount += $inventoryPrice->getPrice() * $quantity;
                            $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantityAccounted() + $quantity);
                            break;
                        }
                    }

                    $em->flush();
                }

                $accountingTransactionTransmittalReceiveFrom = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Transmittal - Receive - From'));
                $slAccountDueFromBranch = $accountingTransactionTransmittalReceiveFrom->getGeneralLedgerAccountDebit()->getSlAccountLinkedByBranch($transmittal->getBranchTo());

                $em->flush();

                $newTransaction = new TransactionEntity();
                $newTransaction->setTransactionType($accountingTransactionTransmittalReceiveFrom->getTransactionType());
                $newTransaction->setBranch($transmittal->getBranchFrom());
                $newTransaction->setTransactionDate($transmittal->getDeliveryDateAsString());
                $newTransaction->setTransactionNo('001');
                $newTransaction->setAmount($amount);
                $em->persist($newTransaction);
                $em->flush();

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setDebitAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($slAccountDueFromBranch);
                $em->persist($newTransactionJournalEntry);

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setCreditAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransactionTransmittalReceiveFrom->getSubsidiaryLedgerAccountCredit());
                $em->persist($newTransactionJournalEntry);

                $em->flush();

                $accountingTransactionTransmittalReceiveTo = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Transmittal - Receive - To'));
                $slAccountDueToBranch = $accountingTransactionTransmittalReceiveTo->getGeneralLedgerAccountCredit()->getSlAccountLinkedByBranch($transmittal->getBranchFrom());

                $em->flush();

                $newTransaction = new TransactionEntity();
                $newTransaction->setTransactionType($accountingTransactionTransmittalReceiveTo->getTransactionType());
                $newTransaction->setBranch($transmittal->getBranchTo());
                $newTransaction->setTransactionDate($transmittal->getDeliveryDateAsString());
                $newTransaction->setTransactionNo('002');
                $newTransaction->setAmount($amount);
                $em->persist($newTransaction);
                $em->flush();

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setDebitAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransactionTransmittalReceiveTo->getSubsidiaryLedgerAccountDebit());
                $em->persist($newTransactionJournalEntry);

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setCreditAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($slAccountDueToBranch);
                $em->persist($newTransactionJournalEntry);

                $em->flush();

                break;

            case 'Transfer Inventory':

                $transferInventory = $params['transferInventory'];
                $branchTo = $transferInventory->getBranchTo();

                foreach($transferInventory->getTransferInventoryItems() as $transferInventoryItem) {

                    $inventory = $transferInventoryItem->getInventory();
                    $item = $inventory->getItem();

                    $inventoryPrices = $em->getRepository('RxConnexionBundle:InventoryPriceEntity')->findAllAvailableForAccounting(
                        $inventory->getId()
                    );

                    foreach($transferInventoryItem->getTransferInventoryItemDeliveries() as $transferInventoryItemDelivery) {

                        $quantity = $transferInventoryItemDelivery->getQuantity();
                        $refInventory = $this->inventory($branchTo, $transferInventoryItemDelivery->getLocation(), $item);

                        foreach($inventoryPrices as $inventoryPrice) {
                            if($quantity <= 0) {
                                break;
                            } else if($inventoryPrice->getQuantityAccounted() + $quantity >= $inventoryPrice->getQuantity()) {

                                $refQty = $inventoryPrice->getQuantity() - $inventoryPrice->getQuantityAccounted();
                                $amount += $inventoryPrice->getPrice() * $refQty;
                                $quantity -= $refQty;
                                $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantity());

                                $newInventoryPrice = new InventoryPriceEntity();
                                $newInventoryPrice->setInventory($refInventory);
                                $newInventoryPrice->setQuantity($refQty);
                                $newInventoryPrice->setPrice($inventoryPrice->getPrice());
                                $newInventoryPrice->setSource($source);
                                $newInventoryPrice->setTransferInventoryItemDelivery($transferInventoryItemDelivery);
                                $em->persist($newInventoryPrice);
                                $em->flush();

                            } else {

                                $amount += $inventoryPrice->getPrice() * $quantity;
                                $inventoryPrice->setQuantityAccounted($inventoryPrice->getQuantityAccounted() + $quantity);

                                $newInventoryPrice = new InventoryPriceEntity();
                                $newInventoryPrice->setInventory($refInventory);
                                $newInventoryPrice->setQuantity($quantity);
                                $newInventoryPrice->setPrice($inventoryPrice->getPrice());
                                $newInventoryPrice->setSource($source);
                                $newInventoryPrice->setTransferInventoryItemDelivery($transferInventoryItemDelivery);
                                $em->persist($newInventoryPrice);
                                $em->flush();

                                break;
                            }
                        }
                    }
                }

                $accountingTransactionTransferInventoryReceiveFrom = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Transfer Inventory - Receive - From'));
                $slAccountDueFromBranch = $accountingTransactionTransferInventoryReceiveFrom->getGeneralLedgerAccountDebit()->getSlAccountLinkedByBranch($transferInventory->getBranchTo());

                $em->flush();

                $newTransaction = new TransactionEntity();
                $newTransaction->setTransactionType($accountingTransactionTransferInventoryReceiveFrom->getTransactionType());
                $newTransaction->setBranch($transferInventory->getBranchFrom());
                $newTransaction->setTransactionDate($transferInventory->getTransferDateAsString());
                $newTransaction->setTransactionNo('001');
                $newTransaction->setAmount($amount);
                $em->persist($newTransaction);
                $em->flush();

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setDebitAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($slAccountDueFromBranch);
                $em->persist($newTransactionJournalEntry);

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setCreditAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransactionTransferInventoryReceiveFrom->getSubsidiaryLedgerAccountCredit());
                $em->persist($newTransactionJournalEntry);

                $em->flush();

                $accountingTransactionTransferInventoryReceiveTo = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Transfer Inventory - Receive - To'));
                $slAccountDueToBranch = $accountingTransactionTransferInventoryReceiveTo->getGeneralLedgerAccountCredit()->getSlAccountLinkedByBranch($transferInventory->getBranchFrom());

                $em->flush();

                $newTransaction = new TransactionEntity();
                $newTransaction->setTransactionType($accountingTransactionTransferInventoryReceiveTo->getTransactionType());
                $newTransaction->setBranch($transferInventory->getBranchTo());
                $newTransaction->setTransactionDate($transferInventory->getTransferDateAsString());
                $newTransaction->setTransactionNo('002');
                $newTransaction->setAmount($amount);
                $em->persist($newTransaction);
                $em->flush();

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setDebitAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransactionTransferInventoryReceiveTo->getSubsidiaryLedgerAccountDebit());
                $em->persist($newTransactionJournalEntry);

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setCreditAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($slAccountDueToBranch);
                $em->persist($newTransactionJournalEntry);

                $em->flush();

                break;
        }
    }*/

    public function recordAccountingSalesOrder($salesOrder, $amount, $amountDeposit) {

        $em = $this->em;
        $branch = $salesOrder->getBranch();
        $cust = $salesOrder->getCust();

        // Transact Cost of Goods
        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order - Complete - CGS'));

        $newTransaction = new TransactionEntity();
        $newTransaction->setTransactionType($accountingTransaction->getTransactionType());
        $newTransaction->setBranch($branch);
        $newTransaction->setTransactionDate($salesOrder->getSalesDateAsString());
        $newTransaction->setTransactionNo('001');
        $newTransaction->setAmount($amount);
        $em->persist($newTransaction);

        $newTransactionJournalEntry = new TransactionJournalEntryEntity();
        $newTransactionJournalEntry->setTransaction($newTransaction);
        $newTransactionJournalEntry->setDebitAmount($amount);
        $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountDebit());
        $em->persist($newTransactionJournalEntry);

        $newTransactionJournalEntry = new TransactionJournalEntryEntity();
        $newTransactionJournalEntry->setTransaction($newTransaction);
        $newTransactionJournalEntry->setCreditAmount($amount);
        $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountCredit());
        $em->persist($newTransactionJournalEntry);

        $newTransactionLink = new TransactionLinkEntity();
        $newTransactionLink->setTransaction($newTransaction);
        $newTransactionLink->setSalesOrder($salesOrder);
        $em->persist($newTransactionLink);

        $em->flush();

        foreach($salesOrder->getSalesOrderPayments() as $salesOrderPayment) {

            $type = $salesOrderPayment->getType();
            $amount = $salesOrderPayment->getAmount();

            if($amountDeposit > 0) {

                if($amountDeposit > $amount) {
                    $accAmtDeposit = $amount;
                } else {
                    $accAmtDeposit = $amountDeposit;
                }

                $amount -= $accAmtDeposit;
                $amountDeposit -= $accAmtDeposit;

                switch($type) {
                    case 'Check':
                        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order - Complete - Customer Deposit - Check'));
                        $slAccount_debit = $accountingTransaction->getGeneralLedgerAccountDebit()->getSlAccountLinkedByCustomer($cust);
                        break;
                    case 'Credit':
                        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order - Complete - Customer Deposit - Credit'));
                        $slAccount_debit = $accountingTransaction->getGeneralLedgerAccountDebit()->getSlAccountLinkedByCustomer($cust);
                        break;
                    case 'AP':
                        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order - Complete - Customer Deposit - AP'));
                        $slAccount_debit = $accountingTransaction->getGeneralLedgerAccountDebit()->getSlAccountLinkedByCustomer($cust);
                        break;
                    default: // Cash
                        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order - Complete - Customer Deposit - Cash'));
                        $slAccount_debit = $accountingTransaction->getSubsidiaryLedgerAccountDebit();
                        break;
                }

                $newTransaction = new TransactionEntity();
                $newTransaction->setTransactionType($accountingTransaction->getTransactionType());
                $newTransaction->setBranch($branch);
                $newTransaction->setTransactionDate($salesOrderPayment->getPayDateAsString());
                $newTransaction->setTransactionNo('001');
                $newTransaction->setAmount($accAmtDeposit);
                $em->persist($newTransaction);

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setDebitAmount($accAmtDeposit);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($slAccount_debit);
                $em->persist($newTransactionJournalEntry);

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setCreditAmount($accAmtDeposit);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountCredit());
                $em->persist($newTransactionJournalEntry);

                $newTransactionLink = new TransactionLinkEntity();
                $newTransactionLink->setTransaction($newTransaction);
                $newTransactionLink->setSalesOrderPaymentCustDep($salesOrderPayment);
                $em->persist($newTransactionLink);

                $em->flush();
            }

            if($amount > 0) {

                switch($type) {
                    case 'Check':
                        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order - Complete - Check'));
                        $slAccount_debit = $accountingTransaction->getGeneralLedgerAccountDebit()->getSlAccountLinkedByCustomer($cust);
                        break;
                    case 'Credit':
                        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order - Complete - Credit'));
                        $slAccount_debit = $accountingTransaction->getGeneralLedgerAccountDebit()->getSlAccountLinkedByCustomer($cust);
                        break;
                    case 'AP':
                        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order - Complete - AP'));
                        $slAccount_debit = $accountingTransaction->getGeneralLedgerAccountDebit()->getSlAccountLinkedByCustomer($cust);
                        break;
                    default: // Cash
                        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order - Complete - Cash'));
                        $slAccount_debit = $accountingTransaction->getSubsidiaryLedgerAccountDebit();
                        break;
                }

                $newTransaction = new TransactionEntity();
                $newTransaction->setTransactionType($accountingTransaction->getTransactionType());
                $newTransaction->setBranch($branch);
                $newTransaction->setTransactionDate($salesOrderPayment->getPayDateAsString());
                $newTransaction->setTransactionNo('001');
                $newTransaction->setAmount($amount);
                $em->persist($newTransaction);

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setDebitAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($slAccount_debit);
                $em->persist($newTransactionJournalEntry);

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setCreditAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountCredit());
                $em->persist($newTransactionJournalEntry);

                $newTransactionLink = new TransactionLinkEntity();
                $newTransactionLink->setTransaction($newTransaction);
                $newTransactionLink->setSalesOrderPayment($salesOrderPayment);
                $em->persist($newTransactionLink);

                $em->flush();
            }
        }
    }

    public function recordAccountingSalesOrderPendingPayment($salesOrder) {

        $em = $this->em;
        $branch = $salesOrder->getBranch();
        $cust = $salesOrder->getCust();


        foreach($salesOrder->getSalesOrderCreditPayments() as $salesOrderPayment) {

            $type = $salesOrderPayment->getType();
            $amount = $salesOrderPayment->getAmount();

            if($amount > 0) {

                switch($type) {
                    case 'Check':
                        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order - Complete - After Credit - Check'));
                        $slAccount_debit = $accountingTransaction->getGeneralLedgerAccountDebit()->getSlAccountLinkedByCustomer($cust);
                        break;
                    case 'Cash On Bank':
                        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order - Complete - After Cash On Bank - Check'));
                        $slAccount_debit = $accountingTransaction->getGeneralLedgerAccountDebit()->getSlAccountLinkedByCustomer($cust);
                        break;
                    default: // Cash
                        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order - Complete - After Credit - Cash'));
                        $slAccount_debit = $accountingTransaction->getSubsidiaryLedgerAccountDebit();
                        break;
                }

                $newTransaction = new TransactionEntity();
                $newTransaction->setTransactionType($accountingTransaction->getTransactionType());
                $newTransaction->setBranch($branch);
                $newTransaction->setTransactionDate($salesOrderPayment->getPayDateAsString());
                $newTransaction->setTransactionNo('001');
                $newTransaction->setAmount($amount);
                $em->persist($newTransaction);

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setDebitAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($slAccount_debit);
                $em->persist($newTransactionJournalEntry);

                $newTransactionJournalEntry = new TransactionJournalEntryEntity();
                $newTransactionJournalEntry->setTransaction($newTransaction);
                $newTransactionJournalEntry->setCreditAmount($amount);
                $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountCredit());
                $em->persist($newTransactionJournalEntry);

                $newTransactionLink = new TransactionLinkEntity();
                $newTransactionLink->setTransaction($newTransaction);
                $newTransactionLink->setSalesOrderPayment($salesOrderPayment);
                $em->persist($newTransactionLink);

                $em->flush();
            }
        }
    }

    public function recordAccountingSalesOrderReturn($salesOrderReturn, $amount) {

        $em = $this->em;
        $salesOrder = $salesOrderReturn->getSalesOrder();
        $branch = $salesOrder->getBranch();
        $cust = $salesOrder->getCust();

        // Transact Inventory
        $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order Return - Complete - Inventory'));

        $newTransaction = new TransactionEntity();
        $newTransaction->setTransactionType($accountingTransaction->getTransactionType());
        $newTransaction->setBranch($branch);
        $newTransaction->setTransactionDate($salesOrderReturn->getReturnDateAsString());
        $newTransaction->setTransactionNo('001');
        $newTransaction->setAmount($amount);
        $em->persist($newTransaction);

        $newTransactionJournalEntry = new TransactionJournalEntryEntity();
        $newTransactionJournalEntry->setTransaction($newTransaction);
        $newTransactionJournalEntry->setDebitAmount($amount);
        $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountDebit());
        $em->persist($newTransactionJournalEntry);

        $newTransactionJournalEntry = new TransactionJournalEntryEntity();
        $newTransactionJournalEntry->setTransaction($newTransaction);
        $newTransactionJournalEntry->setCreditAmount($amount);
        $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountCredit());
        $em->persist($newTransactionJournalEntry);

        $newTransactionLink = new TransactionLinkEntity();
        $newTransactionLink->setTransaction($newTransaction);
        $newTransactionLink->setSalesOrderReturn($salesOrderReturn);
        $em->persist($newTransactionLink);

        $em->flush();

        foreach($salesOrderReturn->getSalesOrderReturnPayments() as $salesOrderReturnPayment) {

            $type = $salesOrderReturnPayment->getType();
            $amount = $salesOrderReturnPayment->getAmount();

            switch($type) {
                case 'Check':
                    $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order Return - Complete - Check'));
                    $slAccount_credit = $accountingTransaction->getGeneralLedgerAccountCredit()->getSlAccountLinkedByCustomer($cust);
                    break;
                case 'Credit':
                    $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order Return - Complete - Credit'));
                    $slAccount_credit = $accountingTransaction->getGeneralLedgerAccountCredit()->getSlAccountLinkedByCustomer($cust);
                    break;
                default: // Cash
                    $accountingTransaction = $em->getRepository('RxConnexionBundle:AccountingTransactionEntity')->findOneBy(array('description' => 'Sales Order Return - Complete - Cash'));
                    $slAccount_credit = $accountingTransaction->getSubsidiaryLedgerAccountCredit();
                    break;
            }

            $newTransaction = new TransactionEntity();
            $newTransaction->setTransactionType($accountingTransaction->getTransactionType());
            $newTransaction->setBranch($branch);
            $newTransaction->setTransactionDate($salesOrderReturnPayment->getPayDateAsString());
            $newTransaction->setTransactionNo('001');
            $newTransaction->setAmount($amount);
            $em->persist($newTransaction);

            $newTransactionJournalEntry = new TransactionJournalEntryEntity();
            $newTransactionJournalEntry->setTransaction($newTransaction);
            $newTransactionJournalEntry->setDebitAmount($amount);
            $newTransactionJournalEntry->setSubsidiaryLedgerAccount($accountingTransaction->getSubsidiaryLedgerAccountDebit());
            $em->persist($newTransactionJournalEntry);

            $newTransactionJournalEntry = new TransactionJournalEntryEntity();
            $newTransactionJournalEntry->setTransaction($newTransaction);
            $newTransactionJournalEntry->setCreditAmount($amount);
            $newTransactionJournalEntry->setSubsidiaryLedgerAccount($slAccount_credit);
            $em->persist($newTransactionJournalEntry);

            $newTransactionLink = new TransactionLinkEntity();
            $newTransactionLink->setTransaction($newTransaction);
            $newTransactionLink->setSalesOrderReturnPayment($salesOrderReturnPayment);
            $em->persist($newTransactionLink);

            $em->flush();
        }
    }

    private function old__inventory($branch, $location=null, $item, $status = 'Stock On Hand') {

        $em = $this->em;

        $inventory = $em->getRepository('RxConnexionBundle:InventoryEntity')->findOneBy(array(
            'branch' => $branch,
            'location' => $location,
            'item' => $item,
            'status' => $status
        ));

        if(!$inventory) {

            $inventory = new InventoryEntity();
            $inventory->setBranch($branch);
            $inventory->setLocation($location);
            $inventory->setItem($item);
            $inventory->setStatus($status);
            $inventory->setQuantity(0);
            $em->persist($inventory);
            $em->flush();
        }

        return $inventory;
    }

    private function inventory($branch, $location, $item, $status = 'Stock On Hand', PurchaseOrderBreakdownItemDeliveryEntity $purchaseOrderBreakdownItemDelivery = null) {

        $em = $this->em;

        $inventory = $em->getRepository('RxConnexionBundle:InventoryEntity')->findOneBy(array(
            'healthFacility' => $branch,
            'location' => $location,
            'item' => $item,
            'status' => $status
        ));

        if(!$inventory) {

            $inventory = new InventoryEntity();
            $inventory->setHealthFacility($branch);
            $inventory->setLocation($location);
            $inventory->setItem($item);
            $inventory->setStatus($status);
            $inventory->setQuantity(0);
            $em->persist($inventory);
            $item->addInventory($inventory);
        }

        if(!is_null($purchaseOrderBreakdownItemDelivery)) {

            $serialNoIds = [];
            $inventorySerialNos = [];
            foreach ($purchaseOrderBreakdownItemDelivery->getPurchaseOrderBreakdownItem()->getPurchaseOrderItem()->getMaterialRequisitionItem()->getItem()->getAllSerialNos() as $key => $serialNo) {
                $serialNoIds[] = $serialNo->getId();
            }

            /**@var InventorySerialNoEntity $inventorySerialNo*/
            foreach ($inventory->getInventorySerialNos() as $inventorySerialNo) {
                if(!in_array($inventorySerialNo->getPurchaseOrderBreakdownItemDeliverySerialNo()->getId(), $serialNoIds)) {
                    $em->remove($inventorySerialNo);
                    $inventory->removeInventorySerialNo($inventorySerialNo);
                } else {
                    $inventorySerialNos[] = $inventorySerialNo->getPurchaseOrderBreakdownItemDeliverySerialNo()->getId();
                }
            }

            /**@var PurchaseOrderBreakdownItemDeliverySerialNoEntity $purchaseOrderBreakdownItemDeliverySerialNo*/
            foreach ($purchaseOrderBreakdownItemDelivery->getPurchaseOrderBreakdownItemDeliverySerialNos() as $purchaseOrderBreakdownItemDeliverySerialNo) {
                if(!in_array($purchaseOrderBreakdownItemDeliverySerialNo->getId(), $inventorySerialNos)){
                    $inventorySN = new InventorySerialNoEntity();
                    $inventorySN->setPurchaseOrderBreakdownItemDeliverySerialNo($purchaseOrderBreakdownItemDeliverySerialNo);
                    $inventorySN->setInventory($inventory);
                    $inventorySN->setSerialNo($purchaseOrderBreakdownItemDeliverySerialNo->getSerialNo());
                    $inventorySN->setCost($purchaseOrderBreakdownItemDeliverySerialNo->getPurchaseOrderBreakdownItemDelivery()->getPurchaseOrderBreakdownItem()->getPurchaseOrderItem()->getMaterialRequisitionItem()->getPrice());
                    $em->persist($inventorySN);
                    $inventory->addInventorySerialNo($inventorySN);
                }
            }
        }


        return $inventory;
    }
}