<?php

namespace RxConnexionBundle\Service;

use Doctrine\ORM\EntityManager;
use RxConnexionBundle\Entity\InventoryPriceEntity;
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 ZapconBundle\Entity\GeneralLedgerAccountEntity;
// use ZapconBundle\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()) {

        $em = $this->em;

        switch($source) {

            case 'Purchasing Purchase Order Receive':

                $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->getBranch();
                }

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

                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('RxConnexionBundleBundle: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 {

                        $inventory->setQuantity($inventory->getQuantity() - $inventoryMovement->getQuantity());
                        $em->remove($inventoryMovement);
                        $em->remove($inventoryPrice);
                    }
                }

                $em->flush();

                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->getBranch();

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

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

                    $inventory->setQuantity($inventory->getQuantity() - $convertInventoryItem->getQuantity());
                    $inventoryInProcessing->setQuantity($inventoryInProcessing->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->getBranch();

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

                    $item = $convertInventoryItem->getInventory()->getItem();
                    $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());

                    $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':

                $convertInventory = $params['convertInventory'];
                $amount = 0;
                $branch = $convertInventory->getBranch();
                $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) {

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

                        $item = $convertInventoryItem->getInventory()->getItem();
                        $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());

                        $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();
                    }

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

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

                }

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

                    $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();

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

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

                        } else {

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

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

                    $em->flush();
                }

                break;

            case 'Inventory Transfer Inventory Item Receive':

                $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());

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

                    } else {

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

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

                $em->flush();

                break;

            case 'Sales Order Complete':

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

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

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

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

                    $inventory->setQuantity($inventory->getQuantity() - $salesOrderInventory->getQuantity());
                    $inventory2->setQuantity($inventory2->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());
                    $inventory2 = $this->inventory($branch, null, $item, $salesOrderItem->getIsDeposit() ? 'Deposit' : 'Sold');

                    $inventory->setQuantity($inventory->getQuantity() + $salesOrderReturnItem->getQuantity());
                    $inventory2->setQuantity($inventory2->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':

                $patientBilling = $params['patientBilling'];

                foreach($patientBilling->getPatientBillingBreakdowns() as $patientBillingBreakdown) {

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


                    if ($inventory) {
                        $inventory2 = $this->inventory($patientBilling->getHealthFacilityForAddress(), null, $patientBillingBreakdown->getItem(), 'Sold');
                        $inventory->setQuantity($inventory->getQuantity() - $patientBillingBreakdown->getQuantity());
                        $inventory2->setQuantity($inventory2->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->getHealthFacilityForAddress());
                        $inventory->setStatus('Sold');
                        $inventory->setItem($patientBillingBreakdown->getItem());
                        $inventory->setLocation(null);
                        $inventory->setQuantity((0 - $patientBillingBreakdown->getQuantity()));
                        $em->persist($inventory);
                        $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 - Refund':
//
//                $patientBillingRefund = $params['patientBillingRefund'];
//
//                foreach($patientBillingRefund->getPatientBilling()->getPatientBillingBreakdowns() as $patientBillingBreakdown) {
//
//                    $inventory = $em->getRepository('RxConnexionBundle:InventoryEntity')->findOneBy(array(
//                        'healthFacility' => $patientBillingRefund->getPatientBilling()->getHealthFacilityForAddress(),
//                        'item' => $patientBillingBreakdown->getItem(),
//                        'status' => 'Stock On Hand'
//                    ));
//
//
//                    $inventory2 = $this->inventory($patientBillingRefund->getPatientBilling()->getHealthFacilityForAddress(), 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('zapcon.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=null, $item, $status = 'Stock On Hand') {

        $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);
            $em->flush();
        }

        return $inventory;
    }
}