<?php

namespace RxConnexionBundle\Controller;

use RxConnexionBundle\Entity\HealthFacilityEntity;
use RxConnexionBundle\Entity\ItemAveCostEntity;
use RxConnexionBundle\Entity\ItemEntity;
use RxConnexionBundle\Entity\ItemItemEntity;
use RxConnexionBundle\Entity\ItemPriceEntity;
use RxConnexionBundle\Entity\ItemTaxCodeEntity;
use RxConnexionBundle\Form\ItemAveCostForm;
use RxConnexionBundle\Form\ItemPriceForm;
use RxConnexionBundle\Form\Type\ItemTaxCodeForm;
use RxConnexionBundle\Service\ItemService;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;

use RxConnexionBundle\Entity\AuditTrailEntity;

use RxConnexionBundle\Form\ItemForm;

/**
 * @Route("/main/item")
 */
class ItemController extends Controller
{
    /**
     * @Route("", name="item")
     */
    public function indexAction() {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Items'))) return $authService->redirectToHome();

        return $this->render('@RxConnexion/Item/index.html.twig', array(
            'title' => 'Manage Item',
            'page_title' => 'Manage Item',
            'javascripts' => array('rxconnexion/admin/js/item/item.js?v=1.0.3')
        ));
    }

    /**
     * @Route("/ajax_list", name="item_ajax_list")
     */
    public function ajax_list(Request $request) {

        $get = $request->query->all();

        $result = array(
            "draw" => intval($get['draw']),
            "recordsTotal" => 0,
            "recordsFiltered" => 0,
            "data" => array()
        );

        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn()) {

            $hasUpdate = $authService->isUserHasAccesses(array('Admin Items Update'), false);
            $hasDetail = $authService->isUserHasAccesses(array('Admin Items Detail'), false);

            $data = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:ItemEntity')->ajax_list($get, $this->get('session')->get('userData'));

            foreach($data['results'] as $row) {

                $id = base64_encode($row['id']);
                $action = '';

                if($hasUpdate) {
                    $url = $this->generateUrl('item_form', array(
                        'action' => 'u',
                        'id' => $id
                    ));
                    $action = "<a class='action-button-style' href='$url'>Update</a>";
                }

                if($hasDetail){
                    $detailsUrl = $this->generateUrl('item_detail', array(
                        'item_id' => base64_encode($row['id'])

                    ));
                    $action .= "<a class='action-button-style' href='$detailsUrl'>Details</a>";
                }

                $values = array(
                    $row['supplierDesc'],
                    $row['itemCat'],
                    $row['itemSubCat'],
                    $row['itemCompany'],
                    $row['code'],
                    $row['type'],
                    $row['description'],
                    $row['startDate'],
                    $row['endDate'],
                    $action
                );

                $result['data'][] = $values;
            }

            $result['recordsTotal'] = $data['total'];
            $result['recordsFiltered'] = $data['total'];
        }

        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/form/{action}/{id}",
     *      defaults = {
     *          "action":  "n",
     *          "id": 0
     *      },
     *      requirements = {
     *          "action": "n|u"
     *      },
     *      name = "item_form"
     * )
     */
    public function formAction($action, $id, Request $request) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Items New', 'Admin Items Update'))) return $authService->redirectToHome();

        $em = $this->getDoctrine()->getManager();

        $item = $em->getRepository('RxConnexionBundle:ItemEntity')->find(base64_decode($id));
        if(!$item) {
            $item = new ItemEntity();
        }

        $formOptions = array('action' => $action);
        $form = $this->createForm(ItemForm::class, $item, $formOptions);

        if($request->getMethod() === 'POST') {

            $item_form = $request->get($form->getName());
            $result = $this->processForm($item_form, $item, $form, $request);

            if($result['success']) {
                if($result['redirect'] === 'index') {
                    return $this->redirect($this->generateUrl('item'), 302);
                } else if($result['redirect'] === 'form') {
                    return $this->redirect($this->generateUrl('item_form', array(
                        'action' => 'u',
                        'id' => base64_encode($result['id'])
                    )), 302);
                } else if($result['redirect'] === 'detail') {
                    return $this->redirect($this->generateUrl('item_detail', array(
                        'item_id' => base64_encode($result['id'])
                    )), 302);
                } else if($result['redirect'] === 'form with error') {
                    return $this->redirect($this->generateUrl('item_form'), 302);
                }
            } else {
                $form->submit($item_form, false);
            }
        }

        $title = ($action === 'n' ? 'New' : 'Update') . ' Item';

        return $this->render('@RxConnexion/Item/form.html.twig', array(
            'title' => $title,
            'page_title' => $title,
            'javascripts' => array('rxconnexion/admin/js/item/item_form.js?v=1.0.1'),
            'form' => $form->createView(),
            'action' => $action,
            'id' => $id
        ));
    }

    private function processForm($item_form, $item, $form, Request $request) {

        $em = $this->getDoctrine()->getManager();

        $errors = $em->getRepository('RxConnexionBundle:ItemEntity')->validate($item_form);

        if(!count($errors)) {

            switch($item_form['action']) {

                case 'n': // new

                    $form->handleRequest($request);

                    if ($form->isValid()) {

                        $em->persist($item);
                        $em->flush();

                        $newAT = new AuditTrailEntity(
                            'Item',
                            $em->getClassMetadata(ItemEntity::class)->getTableName(),
                            AuditTrailEntity::AXN_NEW
                        );
                        $newAT->entity = $item;
                        $newAT->parseDetails();
                        $em->persist($newAT);
                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Saved.');

                        $result['redirect'] = 'detail';
                        $result['id'] = $item->getId();

                    } else {

                        $this->get('session')->getFlashBag()->set('error_messages', 'Something went wrong. Please try again.');
                        $result['redirect'] = 'form with error';
                    }

                    break;

                case 'u': // update

                    $newAT = new AuditTrailEntity(
                        'Item',
                        $em->getClassMetadata(ItemEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_UPDATE
                    );
                    $newAT->entity = $item;
                    $newAT->parseOriginalDetails();

                    $form->handleRequest($request);

                    if ($form->isValid()) {

                        $newAT->parseDetails();
                        $em->persist($newAT);

                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Updated.');

                        $result['redirect'] = 'detail';
                        $result['id'] = $item->getId();

                    } else {

                        $this->get('session')->getFlashBag()->set('error_messages', 'Something went wrong. Please try again.');
                        $result['redirect'] = 'form with error';
                    }

                    break;

                case 'd': // delete

                    $newAT = new AuditTrailEntity(
                        'Item',
                        $em->getClassMetadata(ItemEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_DELETE
                    );
                    $newAT->entity = $item;
                    $newAT->parseDetails();
                    $em->persist($newAT);

                    $form->handleRequest($request);

                    if ($form->isValid()) {

                        //$em->remove($item);
                        $item->setIsDeleted(true);

                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Deleted.');

                        $result['redirect'] = 'index';

                    } else {

                        $this->get('session')->getFlashBag()->set('error_messages', 'Something went wrong. Please try again.');
                        $result['redirect'] = 'form with error';
                    }

                    break;
            }

            $result['success'] = true;

        } else {

            foreach($errors as $error) {
                $this->get('session')->getFlashBag()->add('error_messages', $error);
            }

            $result['success'] = false;
        }

        return $result;
    }

    /**
     * @Route(
     *      "/detail/{item_id}",
     *      name = "item_detail"
     * )
     */
    public function detailAction($item_id, Request $request) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Items Detail'))) return $authService->redirectToHome();

        $em = $this->getDoctrine()->getManager();
        $item = $em->getRepository('RxConnexionBundle:ItemEntity')->find(base64_decode($item_id));

//        $itemService = new ItemService($em, $this->container);
//		$itemService->computeAverageCostByBranch($item, $em->getRepository(HealthFacilityEntity::class)->findOneBy(['description' => 'Alberta CPAP Sales']));

        $title = 'Manage Item - ' . $item->getDescription();
        return $this->render('@RxConnexion/Item/detail.html.twig', array(
            'title' => $title,
            'page_title' => $title,
            'javascripts' => array(
                'rxconnexion/admin/js/item/item_detail.js?v=1.0.3'
            ),
            'item_id' => $item_id,
            'item' => $item,
            'tab' => $request->query->get('tab')
        ));
    }

    /**
     * @Route("/item_price_ajax_list", name="item_price_ajax_list")
     */
    public function item_price_ajax_list(Request $request) {

        $get = $request->query->all();

        $result = array(
            "draw" => intval($get['draw']),
            "recordsTotal" => 0,
            "recordsFiltered" => 0,
            "data" => array()
        );

        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn()) {

            $hasUpdate = $authService->isUserHasAccesses(array('Admin Items Price Update'), false);

            $data = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:ItemPriceEntity')->ajax_list($get, $this->get('session')->get('userData'));

            foreach($data['results'] as $row) {

                $id = base64_encode($row['id']);
                $action = '';

                if($hasUpdate) {
                    $action = "<a class='action-button-style href-item-price-form' data-action='u' data-id='$id'>Update</a>";
                }

                $values = array(
                    number_format($row['price'], 2),
                    $row['startDate'],
                    $row['endDate'],
                    $action
                );

                $result['data'][] = $values;
            }

            $result['recordsTotal'] = $data['total'];
            $result['recordsFiltered'] = $data['total'];
        }

        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/item_price/form/{item_id}/{action}/{id}",
     *      defaults = {
     *          "action":  "n",
     *          "id": 0
     *      },
     *      requirements = {
     *          "action": "n|u"
     *      },
     *      name = "item_price_form"
     * )
     */
    public function item_price_formAction($item_id, $action, $id, Request $request) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Items Price New', 'Admin Items Price Update'))) return $authService->redirectToHome();

        $em = $this->getDoctrine()->getManager();

        $itemPrice = $em->getRepository('RxConnexionBundle:ItemPriceEntity')->find(base64_decode($id));
        if(!$itemPrice) {
            $itemPrice = new ItemPriceEntity();
        }

        $formOptions = array(
            'action' => $action,
            'item_id' => $item_id
        );
        $form = $this->createForm(ItemPriceForm::class, $itemPrice, $formOptions);


        $title = $action === 'n' ? 'Add Price' : 'Update ' . $itemPrice->getPrice()    ;

        $result['html'] =  $this->renderView('@RxConnexion/Item/item_price_form.html.twig', array(
            'title' => $title,
            'page_title' => $title,
            'form' => $form->createView(),
            'item_id' => $item_id,
            'action' => $action,
            'id' => $id
        ));
        $result['success'] = true;
        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/item_price/save_action",
     *      name = "item_price_save"
     * )
     */
    public function item_price_saveAction(Request $request) {

        $result['success'] = false;
        $result['successMessages'] = array();
        $result['errorMessages'] = array();

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Items Price New', 'Admin Items Price Update'))) return $authService->redirectToHome();

        $itemPrice_form = $request->get('item_price');
        $em = $this->getDoctrine()->getManager();
        $itemPrice = $em->getRepository('RxConnexionBundle:ItemPriceEntity')->find($itemPrice_form['id'] );
        if(!$itemPrice) {
            $itemPrice = new ItemPriceEntity();
        }
        $formOptions = array(
            'action' => $itemPrice_form['action'],
            'item_id' => $itemPrice_form['item']
        );
        $form = $this->createForm(ItemPriceForm::class, $itemPrice, $formOptions);
        $errors = $em->getRepository('RxConnexionBundle:ItemPriceEntity')->validate($itemPrice_form);

        if(!count($errors)) {

            switch($itemPrice_form['action']) {

                case 'n': // new

                    $form->handleRequest($request);

                    if($form->isValid()) {

                        $em->persist($itemPrice);
                        $em->flush();

                        $newAT = new AuditTrailEntity(
                            'Item Price',
                            $em->getClassMetadata(ItemPriceEntity::class)->getTableName(),
                            AuditTrailEntity::AXN_NEW
                        );
                        $newAT->entity = $itemPrice;
                        $newAT->parseDetails();
                        $em->persist($newAT);
                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Saved.');
                        $result['success'] = true;
                        $result['successMessages'][] = 'Record Successfully Saved.';

                    } else {
                        $result['errorMessages'][] = 'Something went wrong. Please try again.';
                    }

                    break;

                case 'u': // update

                    $em->persist($itemPrice);
                    $em->flush();

                    $newAT = new AuditTrailEntity(
                        'Item Price',
                        $em->getClassMetadata(ItemPriceEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_UPDATE
                    );
                    $newAT->entity = $itemPrice;
                    $newAT->parseOriginalDetails();

                    $form->handleRequest($request);
                    if ($form->isValid()) {

                        $newAT->parseDetails();
                        $em->persist($newAT);

                        $em->flush();
                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Updated.');
                        $result['success'] = true;
                        $result['successMessages'][] = 'Record Successfully Updated.';
                    }else{
                        $result['errorMessages'][] = 'Something went wrong. Please try again.';
                    }

                    break;

                case 'd': // delete

                    $newAT = new AuditTrailEntity(
                        'Item Price',
                        $em->getClassMetadata(ItemPriceEntity::class)->getTableName(),
                        AuditTrailEntity::AXN_DELETE
                    );
                    $newAT->entity = $itemPrice;
                    $newAT->parseDetails();
                    $em->persist($newAT);

                    $form->handleRequest($request);

                    if ($form->isValid()) {

                        //$em->remove($itemPrice);
                        $itemPrice->setIsDeleted(true);

                        $em->flush();

                        $this->get('session')->getFlashBag()->set('success_messages', 'Record Successfully Deleted.');

                        $result['success'] = true;
                        $result['successMessages'][] = 'Record Successfully Deleted.';

                    } else {

                        $result['errorMessages'][] = 'Something went wrong. Please try again.';
                    }

                    break;
            }
        } else {

            foreach ($errors as $error) {
                $result['errorMessages'][] = $error;
            }
        }
        return new JsonResponse($result);
    }

    /**
     * @Route("/ajax_list_transfer_inventory", name="item_ajax_list_transfer_inventory")
     */
    public function ajax_list_transfer_inventory(Request $request) {

        $get = $request->query->all();

        $result = array(
            "draw" => intval($get['draw']),
            "recordsTotal" => 0,
            "recordsFiltered" => 0,
            "data" => array()
        );

        if($this->get('rx_connexion.authService')->isLoggedIn()) {
            $result = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:ItemEntity')->ajax_list_transfer_inventory($get, $this->get('session')->get('userData'));
        }

        return new JsonResponse($result);
    }

    /**
     * @Route("/ajax_list_material_requisition", name="item_ajax_list_material_requisition")
     */
    public function ajax_list_material_requisition(Request $request) {

        $get = $request->query->all();

        $result = array(
            "draw" => intval($get['draw']),
            "recordsTotal" => 0,
            "recordsFiltered" => 0,
            "data" => array()
        );

        if($this->get('rx_connexion.authService')->isLoggedIn()) {
            $result = $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:ItemEntity')->ajax_list_material_requisition($get, $this->get('session')->get('userData'));
        }

        return new JsonResponse($result);
    }

    /**
     * @Route("/item/ajax_list", name="item_item_ajax_list")
     */
    public function item_ajax_list(Request $request) {

        $get = $request->query->all();

        $result = array(
            "draw" => intval($get['draw']),
            "recordsTotal" => 0,
            "recordsFiltered" => 0,
            "data" => array()
        );

        if($this->get('rx_connexion.authService')->isLoggedIn()) {
            $result = $this->getDoctrine()->getManager()->getRepository(ItemEntity::class)->ajax_list_item($get, $this->get('session')->get('userData'));
        }

        return new JsonResponse($result);
    }

    /**
     * @Route("/autocomplete", name="item_autocomplete")
     */
    public function autocompleteAction(Request $request) {

        $result = array(
            'query' => 'items',
            'suggestions' => $this->getDoctrine()->getManager()->getRepository('RxConnexionBundle:ItemEntity')->autocomplete_suggestions($request)
        );

        return new JsonResponse($result);
    }

    /**
     * @Route("/export_to_excel", name="item_export_to_excel")
     */
    public function item_export_to_excelAction(Request $request) {

        $authService = $this->get('rx_connexion.authService');
        if(!$authService->isLoggedIn()) return $authService->redirectToLogin();
        if(!$authService->isUserHasAccesses(array('Admin Items Export to Excel', 'Admin Items Export to Excel'))) return $authService->redirectToHome();

        ini_set('memory_limit', '2048M');
        set_time_limit(0);

        $session = $this->get('session');
        $userData = $session->get('userData');

        $status = $request->get('status');

        $em = $this->getDoctrine()->getManager();
        $records = $em->getRepository('RxConnexionBundle:ItemEntity')->itemExportToExcel($status);

        $columnRange = range('A', 'H');
        $cellsData = array(
            array('cell' => 'A1', 'data' => 'ID'),
            array('cell' => 'B1', 'data' => 'Sub Category'),
            array('cell' => 'C1', 'data' => 'Company'),
            array('cell' => 'D1', 'data' => 'Code'),
            array('cell' => 'E1', 'data' => 'Type'),
            array('cell' => 'F1', 'data' => 'Description'),
            array('cell' => 'G1', 'data' => 'Start Date'),
            array('cell' => 'H1', 'data' => 'End Date'),
            array('cell' => 'H1', 'data' => 'End Date'),
        );
        $rowCtr = 1;
        $totalCount = 0;

        foreach($records as $record) {

            $rowCtr++;
            $totalCount++;

            $cellsData[] = array('cell' => "A$rowCtr", 'data' => $record['id']);
            $cellsData[] = array('cell' => "B$rowCtr", 'data' => $record['subCat']);
            $cellsData[] = array('cell' => "C$rowCtr", 'data' => $record['company']);
            $cellsData[] = array('cell' => "D$rowCtr", 'data' => $record['code']);
            $cellsData[] = array('cell' => "E$rowCtr", 'data' => $record['type']);
            $cellsData[] = array('cell' => "F$rowCtr", 'data' => $record['description']);
            $cellsData[] = array('cell' => "G$rowCtr", 'data' => $record['start_date']);
            $cellsData[] = array('cell' => "H$rowCtr", 'data' => $record['end_date']);
        }

        $page_title = 'Item List';
        return $this->export_to_excel($columnRange, $cellsData, $page_title);
    }

    /**
     * @Route(
     *      "/item/form/{item_id}/{action}/{id}",
     *      defaults = {
     *          "action":  "n",
     *          "id": 0
     *      },
     *      requirements = {
     *          "action": "n|u"
     *      },
     *      name = "item_item_form"
     * )
     * @param $item_id
     * @param $action
     * @param $id
     * @param Request $request
     * @return JsonResponse
     */
    public function item_formAction($item_id, $action, $id, Request $request) {

        $result['success'] = false;

        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn() && $authService->isUserHasAccesses(array('Admin Items Item New', 'Admin Items Item Update'))) {

            $em = $this->getDoctrine()->getManager();
            /**@var ItemEntity $item*/
            /**@var ItemEntity $itemMain*/
            $item = $em->getRepository(ItemEntity::class)->find(base64_decode($id));
            $itemMain = $em->getRepository(ItemEntity::class)->find(base64_decode($item_id));

            if($request->getMethod() === 'POST') {

                $item_item_form = $request->get('itemItem');

                $errors = [];

                if(empty($item_item_form['item']))
                    $errors[] = 'Item should not be blank';

                if($item_item_form['action'] !== 'd') {
                    /*foreach ($itemMain->getItems() as $subItem) {
                        if ($subItem->getId() == $item_item_form['item'])
                            $errors[] = 'Item already in the package.';
                    }*/
                }

                if(!count($errors)) {

                    switch($item_item_form['action']) {

                        case 'n': // new

                            /**@var ItemEntity $item*/
                            $item = $em->getRepository(ItemEntity::class)->find($item_item_form['item']);
                            $item->setItem($em->getReference(ItemEntity::class, base64_decode($item_id)));
                            $item->setPackageItemQuantity($item_item_form['quantity']);
                            $em->flush();

                            break;

                        case 'u': // update

                            $item->setItem(null);
                            $item->setPackageItemQuantity(null);

                            $newItem = $em->getRepository(ItemEntity::class)->find($item_item_form['item']);
                            $newItem->setItem($em->getReference(ItemEntity::class, base64_decode($item_id)));
                            $newItem->setPackageItemQuantity($item_item_form['quantity']);
                            $em->flush();

                            break;

                        case 'd': // delete

                            $item->setItem(null);
                            $item->setPackageItemQuantity(null);

                            $em->flush();


                            break;
                    }

                    $result['success'] = true;

                } else {

                    foreach($errors as $error) {
                        $result['messages'][] = $error;
                    }

                    $result['success'] = false;
                }

                return new JsonResponse($result);
            }


            $result['html'] = $this->renderView('@RxConnexion/Item/item_form.html.twig', array(
                'action' => $action,
                'id' => $id,
                'item_id' => $item_id,
                'item' => $item,
            ));
            $result['success'] = true;
        };

        return new JsonResponse($result);
    }

    /**
     * @Route("/tax-code/ajax_list", name="item_tax_code_ajax_list")
     */
    public function tax_code_ajax_list(Request $request) {
        $get = $request->query->all();

        $result = array(
            "draw" => intval($get['draw']),
            "recordsTotal" => 0,
            "recordsFiltered" => 0,
            "data" => array()
        );

        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn()) {

            $hasUpdate = $authService->isUserHasAccesses(array('Admin Items Tax Code Update'), false);

            $data = $this->getDoctrine()->getManager()->getRepository(ItemTaxCodeEntity::class)->ajax_list($get, $this->get('session')->get('userData'));

            foreach($data['results'] as $row) {

                $id = base64_encode($row['id']);
                $action = '';

                if($hasUpdate) {
                    $action = "<a class='action-button-style href-tax-form' data-action='u' data-id='$id'>Update</a>";
                }

                $values = array(
                    $row['branch_description'],
                    $row['percent'],
                    $action
                );

                $result['data'][] = $values;
            }

            $result['recordsTotal'] = $data['total'];
            $result['recordsFiltered'] = $data['total'];
        }

        return new JsonResponse($result);
    }

    /**
     * @Route(
     *      "/tax-code/form/{item_id}/{action}/{id}",
     *      defaults = {
     *          "action":  "n",
     *          "id": 0
     *      },
     *      requirements = {
     *          "action": "n|u"
     *      },
     *      name = "item_tax_code_form"
     * )
     */
    public function tax_code_formAction($item_id, $action, $id, Request $request) {

        $result['success'] = false;

        $authService = $this->get('rx_connexion.authService');
        if($authService->isLoggedIn() && $authService->isUserHasAccesses(array('Admin Items Tax Code New', 'Admin Items Tax Code Update'))) {

            $em = $this->getDoctrine()->getManager();
            $itemTaxCode = $em->getRepository(ItemTaxCodeEntity::class)->find(base64_decode($id));
            if(!$itemTaxCode) {
                $itemTaxCode = new ItemTaxCodeEntity();
            }

            $formOptions = array('action' => $action);
            $form = $this->createForm(ItemTaxCodeForm::class, $itemTaxCode, $formOptions);

            if($request->getMethod() === 'POST') {

                $item_tax_code_form = $request->get($form->getName());

                $errors = $em->getRepository(ItemTaxCodeEntity::class)->validate($item_tax_code_form);

                if(!count($errors)) {

                    switch($item_tax_code_form['action']) {

                        case 'n': // new

                            $form->handleRequest($request);

                            if ($form->isValid()) {

                                $em->persist($itemTaxCode);
                                $em->flush();

                                /*$newAT = new AuditTrailEntity();
                                $newAT->setUser($em->getReference('RxConnexionBundle:UserEntity', base64_decode($_COOKIE['userId'])));
                                $newAT->entity = $tax_codeItem;
                                $newAT->setRefTable('tax_code');
                                $newAT->parseInformation('New');
                                $em->persist($newAT);
                                $em->flush();*/

                                $result['messages'][] = 'Record Successfully Saved.';

                            } else {

                                $result['messages'][] = 'Something went wrong. Please try again.';
                            }

                            $result['redirect'] = 'index';

                            break;

                        case 'u': // update

                            $form->handleRequest($request);

                            /*$newAT = new AuditTrailEntity();
                            $newAT->setUser($em->getReference('RxConnexionBundle:UserEntity', base64_decode($_COOKIE['userId'])));
                            $newAT->entity = $tax_code;
                            $newAT->setRefTable('tax_code');
                            $newAT->parseOriginalDetails();*/

                            if ($form->isValid()) {

                                $em->flush();

                                //$newAT->parseInformation('Update');
                                //$em->persist($newAT);

                                $result['messages'][] = 'Record Successfully Updated.';

                            } else {

                                $result['messages'][] = 'Something went wrong. Please try again.';
                            }

                            break;

                        case 'd': // delete

                            $form->handleRequest($request);

                            /*$newAT = new AuditTrailEntity();
                            $newAT->setUser($em->getReference('RxConnexionBundle:UserEntity', base64_decode($_COOKIE['userId'])));
                            $newAT->entity = $tax_code;
                            $newAT->setRefTable('tax_code');
                            $newAT->parseInformation('Delete');
                            $em->persist($newAT);*/

                            if ($form->isValid()) {

                                $em->remove($itemTaxCode);
                                $em->flush();

                                $result['messages'][] = 'Record Successfully Deleted.';

                            } else {

                                $result['messages'][] = 'Something went wrong. Please try again.';
                            }

                            break;
                    }

                    $result['success'] = true;

                } else {

                    foreach($errors as $error) {
                        $result['messages'][] = $error;
                    }

                    $result['success'] = false;
                }

                return new JsonResponse($result);
            }

            $title = ($action === 'n' ? 'New' : 'Update') . ' Tax Code';

            $result['html'] = $this->renderView('@RxConnexion/Item/tax_code_form.html.twig', array(
                'title' => $title,
                'page_title' => $title,
                'form' => $form->createView(),
                'action' => $action,
                'id' => $id,
                'item_id' => $item_id,
            ));
            $result['success'] = true;
        };

        return new JsonResponse($result);
    }

	/**
	 * @Route("/ave-cost/ajax_list", name="item_ave_cost_ajax_list")
	 */
	public function ave_cost_ajax_list(Request $request) {
		$get = $request->query->all();

		$result = array(
			"draw" => intval($get['draw']),
			"recordsTotal" => 0,
			"recordsFiltered" => 0,
			"data" => array()
		);

		$authService = $this->get('rx_connexion.authService');
		if($authService->isLoggedIn()) {

			$hasUpdate = $authService->isUserHasAccesses(array('Admin Items Ave Cost Update'), false);

			$data = $this->getDoctrine()->getManager()->getRepository(ItemAveCostEntity::class)->ajax_list($get, $this->get('session')->get('userData'));

			foreach($data['results'] as $row) {

				$id = base64_encode($row['id']);
				$action = '';

				if($hasUpdate) {
					$action = "<a class='action-button-style href-cost-form' data-action='u' data-id='$id'>Update</a>";
				}

				$values = array(
					$row['branch_description'],
					$row['ave_cost'],
					$action
				);

				$result['data'][] = $values;
			}

			$result['recordsTotal'] = $data['total'];
			$result['recordsFiltered'] = $data['total'];
		}

		return new JsonResponse($result);
	}

	/**
	 * @Route(
	 *      "/ave-cost/form/{item_id}/{action}/{id}",
	 *      defaults = {
	 *          "action":  "n",
	 *          "id": 0
	 *      },
	 *      requirements = {
	 *          "action": "n|u"
	 *      },
	 *      name = "item_ave_cost_form"
	 * )
	 */
	public function ave_cost_formAction($item_id, $action, $id, Request $request) {

		$result['success'] = false;

		$authService = $this->get('rx_connexion.authService');
		if($authService->isLoggedIn() && $authService->isUserHasAccesses(array('Admin Items Ave Cost New', 'Admin Items Ave Cost Update'))) {

			$em = $this->getDoctrine()->getManager();
			$itemAveCost = $em->getRepository(ItemAveCostEntity::class)->find(base64_decode($id));
			if(!$itemAveCost) {
				$itemAveCost = new ItemAveCostEntity();
			}

			$formOptions = array('action' => $action);
			$form = $this->createForm(ItemAveCostForm::class, $itemAveCost, $formOptions);

			if($request->getMethod() === 'POST') {

				$item_ave_cost_form = $request->get($form->getName());

				$errors = $em->getRepository(ItemAveCostEntity::class)->validate($item_ave_cost_form);

				if(!count($errors)) {

					switch($item_ave_cost_form['action']) {

						case 'n': // new

							$form->handleRequest($request);

							if ($form->isValid()) {

								$em->persist($itemAveCost);
								$em->flush();

								/*$newAT = new AuditTrailEntity();
								$newAT->setUser($em->getReference('RxConnexionBundle:UserEntity', base64_decode($_COOKIE['userId'])));
								$newAT->entity = $ave_costItem;
								$newAT->setRefTable('ave_cost');
								$newAT->parseInformation('New');
								$em->persist($newAT);
								$em->flush();*/

								$result['messages'][] = 'Record Successfully Saved.';

							} else {

								$result['messages'][] = 'Something went wrong. Please try again.';
							}

							$result['redirect'] = 'index';

							break;

						case 'u': // update

							$form->handleRequest($request);

							/*$newAT = new AuditTrailEntity();
							$newAT->setUser($em->getReference('RxConnexionBundle:UserEntity', base64_decode($_COOKIE['userId'])));
							$newAT->entity = $ave_cost;
							$newAT->setRefTable('ave_cost');
							$newAT->parseOriginalDetails();*/

							if ($form->isValid()) {

								$em->flush();

								//$newAT->parseInformation('Update');
								//$em->persist($newAT);

								$result['messages'][] = 'Record Successfully Updated.';

							} else {

								$result['messages'][] = 'Something went wrong. Please try again.';
							}

							break;

						case 'd': // delete

							$form->handleRequest($request);

							/*$newAT = new AuditTrailEntity();
							$newAT->setUser($em->getReference('RxConnexionBundle:UserEntity', base64_decode($_COOKIE['userId'])));
							$newAT->entity = $ave_cost;
							$newAT->setRefTable('ave_cost');
							$newAT->parseInformation('Delete');
							$em->persist($newAT);*/

							if ($form->isValid()) {

								$em->remove($itemAveCost);
								$em->flush();

								$result['messages'][] = 'Record Successfully Deleted.';

							} else {

								$result['messages'][] = 'Something went wrong. Please try again.';
							}

							break;
					}

					$result['success'] = true;

				} else {

					foreach($errors as $error) {
						$result['messages'][] = $error;
					}

					$result['success'] = false;
				}

				return new JsonResponse($result);
			}

			$title = ($action === 'n' ? 'New' : 'Update') . ' Ave Cost';

			$result['html'] = $this->renderView('@RxConnexion/Item/ave_cost_form.html.twig', array(
				'title' => $title,
				'page_title' => $title,
				'form' => $form->createView(),
				'action' => $action,
				'id' => $id,
				'item_id' => $item_id,
			));
			$result['success'] = true;
		};

		return new JsonResponse($result);
	}

    //***************************************************************************************************//

    /* ===================================================================================== */
    /* =====================P R I V A T E   F U N C T I O N S=============================== */
    /* ===================================================================================== */


    private function export_to_excel($columnRange, $cellsData, $page_title, $customStyle=array()) {

        $phpExcelObject = $this->get('phpexcel')->createPHPExcelObject();
        $activeSheet = $phpExcelObject->setActiveSheetIndex(0);

        foreach($cellsData as $cellData) {
            $activeSheet->setCellValue($cellData['cell'], $cellData['data']);
        }

        //foreach($columnRange as $column) {
        //    $phpExcelObject->getActiveSheet()->getColumnDimension($column)->setAutoSize(true);
        //}

        $activeSheet->getStyle($columnRange[0] . '1:' . $columnRange[count($columnRange) - 1] . '1')->applyFromArray(array(
            'fill' => array(
                'type' => \PHPExcel_Style_Fill::FILL_SOLID,
                'color' => array('rgb' => 'ADD8E6')
            ),
            'font' => array(
                'bold' => true,
                'color' => array('rgb' => '000000')
            )
        ));

        foreach($customStyle as $cs) {
            $activeSheet->getStyle($cs['cell'])->applyFromArray($cs['style']);
        }

        $phpExcelObject->getActiveSheet()->setTitle(str_replace(':', '-', $page_title));
        // Set active sheet index to the first sheet, so Excel opens this as the first sheet
        $phpExcelObject->setActiveSheetIndex(0);

        // create the writer
        $writer = $this->get('phpexcel')->createWriter($phpExcelObject, 'Excel5');
        // create the response
        $response = $this->get('phpexcel')->createStreamedResponse($writer);
        // adding headers
        $response->headers->set('Content-Type', 'text/vnd.ms-excel; charset=utf-8');
        $response->headers->set('Content-Disposition', 'attachment;filename="' . $page_title . '.xls"');
        $response->headers->set('Pragma', 'public');
        $response->headers->set('Cache-Control', 'maxage=1');

        return $response;
    }

}
