src/Controller/BackOffice/Accounting/Report/CIPVReportController.php line 166

Open in your IDE?
  1. <?php
  2. namespace App\Controller\BackOffice\Accounting\Report;
  3. use App\Controller\BaseController;
  4. use App\COREapi\CoreApi;
  5. use App\COREapi\Factory\ReportQueryBuilder;
  6. use App\Entity\QBInvoice;
  7. use App\Entity\Quote;
  8. use App\Entity\QuoteItem;
  9. use App\Entity\User;
  10. use App\ExportExcel\PhpSpreadsheet\ExportExcelBase;
  11. use App\Form\Accounting\Report\CIPVSearchType;
  12. use App\Repository\QBInvoiceRepository;
  13. use Symfony\Component\Form\FormErrorIterator;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\HttpFoundation\Response;
  16. use Symfony\Component\Validator\ConstraintViolation;
  17. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
  18. use Symfony\Component\Routing\Annotation\Route;
  19. use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
  20. /**
  21.  * @Route("/backoffice/accounting/reports/cipv")
  22.  * @Security("is_granted('ROLE_ACCOUNTING_ALL')")
  23.  */
  24. class CIPVReportController extends BaseController
  25. {
  26.     /**
  27.      * @Route("/", name="accounting_reports_cipv_index", methods={"GET","POST"})
  28.      */
  29.     public function index(Request $request): Response
  30.     {
  31.         $form $this->createForm(CIPVSearchType::class);
  32.         $form->handleRequest($request);
  33.         $params['form'] = $form->createView();
  34.         //Parameters for default view
  35.         $params['excelSearchPath'] = "";
  36.         $params['tableSearchBy'] = "";
  37.         $params['parentMenu'] = 'Accounting Reports';
  38.         $params['viewTitle'] = 'CIPV Report';
  39.         $params['viewPluralTitle'] = 'CIPV Report';
  40.         $params['roleCreate'] = '';
  41.         $params['routeDataTable'] = 'accounting_reports_cipv_table';
  42.         $params['routeExcelReport'] = 'accounting_reports_cipv_excel_report';
  43.         $params['routeNew'] = '';
  44.         //        $params['tableHeader'] = array("Amount", "Client Name", "Agent", "Supplier City", "Supplier",
  45. //            "Check-In","Check-Out","Confirmation #","Invoice #", "Agency",
  46. //            "Pending Comm...","Balance Due to...","Amount Due From client less Comm","Quote #");
  47. //        $params['tableColumnsDef'] = array("total", "clientFullName","agentName","supplierCity","supplierName",
  48. //            "checkIn","checkOut","confirmationNumber", "invoiceNumber", "customerAccountName",
  49. //            "pendingCommFromSupp",  "balanceDueToSuppUSD","amountDueFromClientLessComm","quoteNumber","action");
  50.         $params['tableHeader'] = array("Name""OLG Agent",
  51.             "Supplier City""Supplier",
  52.             "Check-In","Check-Out",
  53.             "Confirmation #","Invoice #""Agency""Booking Status","Invoice Status","Canc. Policy Penalty Date","Canc. Policy");
  54.         $params['tableColumnsDef'] = array("clientFullName","agentName","supplierCity","supplierName",
  55.             "checkIn","checkOut","confirmationNumber""invoiceNumber""customerAccountName"'reservationStatus''accountingStatus','cancellationPolicyPenaltyDate','cancellationPolicy' ,"action");
  56. //        $params['tableFooter'] = array('<th></th>', '<th  colspan="11"></th>', '<th></th>','<th></th>','<th></th>');
  57.         $params['totalRows'] = 30;
  58.         $params['orderByColumn'] = 4;
  59.         $params['orderByColumnD'] = 'desc';
  60.         try {
  61.             if ($form->isSubmitted()) {
  62.                 if (!$form->isValid()) {
  63.                     /**
  64.                      * @var FormErrorIterator $formErrors
  65.                      * @var ConstraintViolation $cause
  66.                      */
  67.                     $formErrors $form->getErrors(true);
  68.                     $errors $formErrors->getChildren();
  69.                     $cause $errors->getCause();
  70.                     throw new \Exception("Form is not valid. " $errors->getMessage() . " " $cause->getPropertyPath() . " " $cause->getInvalidValue());
  71.                 }
  72.                 $search $request->request->all();
  73.                 if ($search && key_exists('cipv_search'$search)) {
  74.                     unset($search['cipv_search']['_token']);
  75.                     $search $this->removeNullElemslOnTheArrayToSearchOnDoctrine($search);
  76.                     $params array_merge($params$search);
  77.                     $params['excelSearchPath'] = $this->excelSearchPath($search['cipv_search']);
  78.                     $params['tableSearchBy'] = $search['cipv_search'];
  79.                 } else {
  80.                     unset($search);
  81.                 }
  82.             }
  83.         } catch (\Exception $e) {
  84.             $request->getSession()->getFlashBag()->add('error'$e->getMessage());
  85.         }
  86. //        dd($params);
  87.         return $this->render('backOffice/accounting/report/CIPV/index.html.twig'$params);
  88.     }
  89.     /**
  90.      * TABLE AJAX GENERATOR
  91.      * @Route("/list/table/", name="accounting_reports_cipv_table",methods={"GET","POST"})
  92.      * @param Request $request
  93.      * @param \Symfony\Component\Asset\Packages $assetsManager
  94.      * @param QBInvoiceRepository $qbInvoiceRepository
  95.      * @param CoreApi $coreApi
  96.      * @return Response
  97.      * @Security("is_granted('IS_AUTHENTICATED_FULLY')")
  98.      */
  99.     public function tableIndexAction(Request $request\Symfony\Component\Asset\Packages $assetsManagerQBInvoiceRepository $qbInvoiceRepository,CoreApi $coreApi)
  100.     {
  101.         $result $this->getDataTable($request$assetsManager$qbInvoiceRepository,true,$coreApi);
  102.         return new Response(json_encode($result), Response::HTTP_OK, ['content-type' => 'application/json']);
  103.     }
  104.     /**
  105.      * Excel Report
  106.      * @Route("/report/excel", name="accounting_reports_cipv_excel_report", methods={"GET"})
  107.      */
  108.     public function excelReportAction(Request $request\Symfony\Component\Asset\Packages $assetsManagerQBInvoiceRepository $qbInvoiceRepository,CoreApi $coreApi)
  109.     {
  110.         try {
  111.             $logo $this->getParameter('ovn_logo_directory') . "/overseas-xpress-logo-scondary.png";
  112.             //Get report data
  113.             $reportInfo $this->getDataTable($request$assetsManager$qbInvoiceRepositoryfalse$coreApi);
  114.             //reorder the date to match the columns
  115.             $resortedInfo = [];
  116.             $orderedReportColumns = array("clientFullName","agentName","supplierCity","supplierName",
  117.                 "checkIn","checkOut","confirmationNumber""invoiceNumber""customerAccountName"'reservationStatus''accountingStatus','cancellationPolicyPenaltyDate','cancellationPolicy');
  118.             foreach($reportInfo['data'] as $reportRow){
  119.                 $orderedRow = array();
  120.                 foreach($orderedReportColumns as $nextColumn){
  121.                     $orderedRow[] = $reportRow[$nextColumn];
  122.                 }
  123.                 $resortedInfo[] = $orderedRow;
  124.             }
  125.             $reportInfo['data'] = $resortedInfo;
  126.             $headerTable=array("Name""OLG Agent",
  127.                 "Supplier City""Supplier",
  128.                 "Check-In","Check-Out",
  129.                 "Confirmation #","Invoice #""Agency""Booking Status","Invoice Status","Canc. Policy Penalty Date","Canc. Policy");
  130.             $reportInfo array_merge($reportInfo,['headerTable' => $headerTable]);
  131.             $reportName "CIPV Report";
  132.             $today = new \DateTime('now');
  133.             $todayStr=$today->format('Y-M-d');
  134.             $filename $reportName.' '.$todayStr".xlsx";
  135.             $spreadsheet = new ExportExcelBase(
  136.                 reportInfo$reportInfo,
  137.                 reportName$filename,
  138.                 logo$logo,
  139.                 subject$reportName,
  140.                 category'Accounting Report',
  141.                 description'Accounting Report '.$reportName
  142.             );
  143.             return $spreadsheet->create();
  144.         } catch (\Exception $e) {
  145.             //TODO HOW TO HANDLE THIS??
  146.             exit(0);
  147.         }
  148.     }
  149.     private function getDataTable(Request $request\Symfony\Component\Asset\Packages $assetsManagerQBInvoiceRepository $qbInvoiceRepository$isView true,CoreApi $coreApi)
  150.     {
  151.         $countOfSkippedItems 0;
  152.         $offset $request->get('start');
  153.         $limit $request->get('length');
  154.         //Default sort: Here add the columns
  155.         $sort = array("createdAt" => "desc");
  156.         $params=array();
  157.         //Search Fields: Add here all the fields to do the SQL search...
  158. //        $params['supplierCity'] = $request->get('supplierCity');
  159. //        $params['supplierName'] = $request->get('supplierName');
  160.         $params['confirmationNumber'] = $request->get('confirmationNumber');
  161.         //Range Types. Ex. "06/18/2021 - 06/23/2021"
  162.         $params['checkIn'] = $request->get('checkIn');
  163.         $params['checkOut'] = $request->get('checkOut');
  164.         $params['clientFullName'] = $request->get('clientFullName');
  165.         $params['accountingStatus'] = $request->get('accountingStatus');
  166.         $params['reservationStatus'] = $request->get('reservationStatus');
  167.         //Search Fields: Add here all the fields to do the SQL search...
  168.         $paramsInvoice['invoiceNumber'] = $request->get('invoiceNumber');
  169.         $paramsInvoice['isVoid'] = 0;
  170.         //Search Fields: Add here all the fields to do the SQL search...
  171.         $paramsUser['agentName'] = $request->get('agentName');
  172.         //End Search Fields
  173.         //Remove the null elems
  174.         $searchBy $this->removeNullElemslOnTheArrayToSearchOnDoctrine($params);
  175.         $dateRanges = ['checkIn' => 0'checkOut' => 0];
  176.         $em $this->getDoctrine()->getManager();
  177. //----------------------------------------------------------------------------------------------------------------------
  178.         //Search by Invoice Number
  179.         $searchByInvoice $this->removeNullElemslOnTheArrayToSearchOnDoctrine($paramsInvoice);
  180.         $rowsQBInvoice null;
  181.         if ($searchByInvoice) {
  182.             //Do the search first by the invoice
  183.             $reportQueryBuilderInvoice = new ReportQueryBuilder($emQBInvoice::class);
  184.             $different null;
  185.             $like = array('invoiceNumber' => 0);
  186.             $extraSqlInvoice null;
  187.             $rowsInvoiceResponse $reportQueryBuilderInvoice->findByCriteria(
  188.                 $searchByInvoice, array(), nullnulltrue$like$different,null,null,$extraSqlInvoice);
  189.             foreach ($rowsInvoiceResponse as $invoice) {
  190.                 $rowsQBInvoice[] = $invoice->getId();
  191.             }
  192.         }
  193. //----------------------------------------------------------------------------------------------------------------------
  194.         //Search by Agent Name
  195.         $searchByAgent $this->removeNullElemslOnTheArrayToSearchOnDoctrine($paramsUser);
  196.         $rowsAgent null;
  197.         if ($searchByAgent) {
  198.             $searchByAgent['id']=$searchByAgent['agentName'];
  199.             unset($searchByAgent['agentName']);
  200.             //Do the search
  201.             $reportQueryBuilderAgent = new ReportQueryBuilder($emUser::class);
  202.             $different null;
  203.             $like = array();
  204.             $rowsAgentResponse $reportQueryBuilderAgent->findByCriteria(
  205.                 $searchByAgent, array(), nullnulltrue,
  206.                 $like$different,null,null);
  207.             foreach ($rowsAgentResponse as $user) {
  208.                 $rowsAgent[] = $user->getId();
  209.             }
  210.         }
  211. //----------------------------------------------------------------------------------------------------------------------
  212.         $different null;
  213.         $like = array('confirmationNumber'=>0);
  214.         $andIn = [];
  215.         $extraSQL="";
  216.         if(key_exists('clientFullName',$searchBy)){
  217.             $searchBy['clientFullName']=strtolower($searchBy['clientFullName']);
  218.             $extraSQL ="(lower(n.clientName) like '%".$searchBy['clientFullName']."%' or lower(n.clientLastName) like '%".$searchBy['clientFullName']."%')";
  219.             unset($searchBy['clientFullName']);
  220.         }
  221.         if(key_exists('accountingStatus',$searchBy)){
  222.             $searchBy['accountingStatus']=strtolower($searchBy['accountingStatus']);
  223.         }
  224.         if(key_exists('reservationStatus',$searchBy)){
  225.             $searchBy['reservationStatus']=strtolower($searchBy['reservationStatus']);
  226.         }
  227.         if ($rowsQBInvoice) {
  228.             $invoiceList implode(",",$rowsQBInvoice);
  229.             $searchBy['qbInvoice'] = $invoiceList;
  230.             $andIn array_merge($andIn,array('qbInvoice' => $invoiceList));
  231.         }
  232.         $rowsQuote=null;
  233.         if ($rowsAgent) {
  234.             $searchByQuote['agent'] = implode(", "$rowsAgent);
  235.             //Do the search
  236.             $reportQueryBuilderQuote = new ReportQueryBuilder($emQuote::class);
  237.             $different null;
  238.             $like = array();
  239.             $rowsQuoteResponse $reportQueryBuilderQuote->findByCriteria(
  240.                 $searchByQuote, array(), nullnulltrue,
  241.                 $like$different);
  242.             foreach ($rowsQuoteResponse as $quote) {
  243.                 $rowsQuote[] = $quote->getId();
  244.             }
  245.         }
  246.         if ($rowsQuote) {
  247.             $quoteList implode(",",$rowsQuote);
  248.             $searchBy['quote'] = $quoteList;
  249.             $andIn array_merge($andIn,array('quote' => $quoteList));
  250.         }
  251.         //Do the search on QuoteItem
  252.         $reportQueryBuilder = new ReportQueryBuilder($emQuoteItem::class);
  253.         //Get total
  254. //        $totalArray = $reportQueryBuilder->findByCriteriaTotalByColumns(array('retailTotal'),$searchBy, $like, $different, $andIn, $dateRanges,$extraSQL);
  255. //        $footerTotalQCAmount = $totalArray['retailTotal'];
  256. //        $footerTotalAmountDueFromClientLessComm =0; //TODO: CHECK WHERE THIS DATA COMES
  257. //        if($isView){
  258. //            $footerTotalQCAmount = '$'.number_format($totalArray['retailTotal'], 2, ',', '.');
  259. //            $footerTotalAmountDueFromClientLessComm ='$'.number_format($footerTotalAmountDueFromClientLessComm, 2, ',', '.');
  260. //        }
  261.         $recordsTotal $reportQueryBuilder->findByCriteriaCount($searchBy$like$different$andIn$dateRanges,$extraSQL);
  262. //        if ($request->get('order')) {
  263.         //This corresponds with the columns on the view (header)
  264. //            $column =
  265. //                array("retailTotal", "clientName","agentName","supplierCity","supplierName",
  266. //                "checkIn","checkOut","confirmationNumber", "invoiceNumber", "customerAccountName",
  267. //                "pendingCommFromSupp",  "balanceDueToSuppUSD","amountDueFromClientLessComm","quoteNumber");
  268. //
  269. //            $search = $column[$request->get('order')[0]["column"]];
  270. //            $order = strtoupper($request->get('order')[0]["dir"]);
  271. //            $sort = array($search => $order);
  272. //        }
  273.         $inners=null;
  274.         if ($request->get('order')) {
  275.             //This corresponds with the columns on the view (header)
  276.             $column = array("clientFullName","agentName","supplierCity","supplierName",
  277.                 "checkIn","checkOut","confirmationNumber""invoiceNumber""customerAccountName""reservationStatus"'accountingStatus','cancellationPolicyPenaltyDate','cancellationPolicy');
  278.             $search $column[$request->get('order')[0]["column"]];//index of column
  279.             $order strtoupper($request->get('order')[0]["dir"]);//asc or desc
  280.             $sort = [];
  281.             if(in_array($search,["clientFullName","agentName","invoiceNumber""customerAccountName""reservationStatus""accountingStatus"])){
  282. //            if(in_array($search,["clientFullName","agentName","invoiceNumber", "customerAccountName", "reservationStatus", "accountingStatus","cancellationPolicyPenaltyDate","cancellationPolicy"])){
  283.                 if ($search == "clientFullName") {
  284.                     $sort = array("clientName" => $order);
  285.                 }
  286.                 if ($search == "agentName") {
  287.                     $alias 'j';
  288.                     if ($inners) {
  289.                         $alias .= count($inners);
  290.                     }
  291.                     $innerSingle["type"]='leftJoin';
  292.                     $innerSingle["table"] = "quote";
  293.                     $innerSingle["condition"] = $alias ".id=n.quoteId'";
  294.                     $inners[] = $innerSingle;
  295.                     $alias2 $alias.count($inners);
  296.                     $innerSingle["type"]='leftJoin';
  297.                     $innerSingle["table"] = $alias.".agent";
  298.                     $innerSingle["noAddAlias"] = true;
  299.                     $innerSingle["condition"] = $alias2 ".id=j.agentId'";
  300.                     $innerSingle["orderBy"]['field'] = $alias2 '.firstName';
  301.                     $innerSingle["orderBy"]['order'] = $order;
  302.                     $inners[] = $innerSingle;
  303.                 }
  304.                 if ($search == "accountingStatus") {
  305.                     $sort[] = array("accountingStatus" => $order);
  306.                 }
  307.                 if ($search == "reservationStatus") {
  308.                     $sort[] = array("reservationStatus" => $order);
  309.                 }
  310.                 if ($search == "invoiceNumber") {
  311.                     $alias 'j';
  312.                     if ($inners) {
  313.                         $alias .= count($inners);
  314.                     }
  315.                     $innerSingle["type"]='leftJoin';
  316.                     $innerSingle["table"] = "qbInvoice";
  317.                     $innerSingle["condition"] = $alias ".id=n.qbInvoice'";
  318.                     $innerSingle["orderBy"]['field'] = $alias '.invoiceNumber';
  319.                     $innerSingle["orderBy"]['order'] = $order;
  320.                     $inners[] = $innerSingle;
  321.                 }
  322.                 if ($search == "customerAccountName") {
  323.                     $alias 'j';
  324.                     if ($inners) {
  325.                         $alias .= count($inners);
  326.                     }
  327.                     $innerSingle["type"]='leftJoin';
  328.                     $innerSingle["table"] = "quote";
  329.                     $innerSingle["condition"] = $alias ".id=n.quoteId'";
  330.                     $inners[] = $innerSingle;
  331.                     $alias2 $alias.count($inners);
  332.                     $innerSingle["type"]='leftJoin';
  333.                     $innerSingle["table"] = $alias.".customerAccount";
  334.                     $innerSingle["noAddAlias"] = true;
  335.                     $innerSingle["condition"] = $alias2 ".id=j.customerAccountId'";
  336.                     $innerSingle["orderBy"]['field'] = $alias2 '.name';
  337.                     $innerSingle["orderBy"]['order'] = $order;
  338.                     $inners[] = $innerSingle;
  339.                 }
  340.             }
  341.             else{
  342.                 //Order default
  343.                 $sort = array($search => $order);
  344.             }
  345.         }
  346.         $data = array();
  347.         // The query to search by specifics fields. $limit, $offset
  348.         if($rows $reportQueryBuilder->findByCriteria(
  349.             $searchBy$sortnullnulltrue$like$different$andIn$dateRanges,$extraSQL,$inners)){
  350.             $suppliers=$coreApi->getActivitySupplierList();
  351.             $hotels=$coreApi->getHotelList();
  352.             $penaltyStartDate $penaltyEndDate null;
  353.             if($request->get('penaltyDateRange') !== null && strlen($request->get('penaltyDateRange')>0)){
  354.                 $dates explode('-'$request->get('penaltyDateRange'));
  355.                 $penaltyStartDate \DateTime::createFromFormat('m/d/Y H:i:s'trim($dates[0])." 00:00:00");
  356.                 $penaltyEndDate \DateTime::createFromFormat('m/d/Y H:i:s'trim($dates[1])." 23:59:59");
  357.             }
  358.             /**
  359.              * @var $quoteItem QuoteItem
  360.              */
  361.             foreach ($rows as $key => $quoteItem) {
  362.                 //error_log(print_r($key,true).PHP_EOL,3, '/var/www/app/var/log/brian.log');
  363.                 $supplier=$this->getSupplierInfo($suppliers$hotels$quoteItem);
  364.                 $values = array();
  365.                 $values["cancellationPolicyPenaltyDate"] = "";
  366.                 $values["cancellationPolicy"] = "";
  367.                 try {
  368.                     if ($cancellationPolicy $quoteItem->getCancellationPolicy()) {
  369.                         if (!array_key_exists("penaltyDate"$cancellationPolicy)) {
  370.                             $cancellationPolicy reset($cancellationPolicy);
  371.                         }
  372.                         if(array_key_exists("penaltyDate"$cancellationPolicy) && $cancellationPolicy['penaltyDate'] == null ){
  373.                             continue;
  374.                         }
  375.                         $values["cancellationPolicy"] = $quoteItem->makeCancellationPolicyLabel($cancellationPolicy);
  376.                         if (is_array($cancellationPolicy) && key_exists('penaltyDate'$cancellationPolicy)) {
  377.                             $penaltyDate $cancellationPolicy['penaltyDate'];
  378.                             if (is_string($cancellationPolicy['penaltyDate'])) {
  379.                                 $penaltyDate = new \DateTime($cancellationPolicy['penaltyDate']);
  380.                             }
  381.                             if($penaltyDate == null){
  382.                                 continue;
  383.                             }
  384.                             if ($penaltyStartDate != null && ($penaltyDate $penaltyStartDate || $penaltyDate $penaltyEndDate)) {
  385.                                 continue;
  386.                             }
  387.                             $values["cancellationPolicyPenaltyDate"] = $penaltyDate->format("Y-m-d");
  388.                         }
  389.                     } else if ($quoteItem->getCancellationPolicy() == null && $penaltyStartDate != null) {
  390.                         continue;
  391.                     }
  392.                 } catch (\Exception $e) {
  393.                     //error_log($e->getMessage().PHP_EOL,3, '/var/www/app/var/log/CIPV_error.log');
  394.                 }
  395. //            $values["total"] = $quoteItem->getRetailTotal();
  396.                 $values["clientFullName"] = $quoteItem->getClientFullName();
  397.                 $values["agentName"] = $quoteItem->getQuote()->getCreatedBy()?$quoteItem->getQuote()->getCreatedBy()->getName():"";
  398.                 $values["supplierCity"] =  $supplier["cityName"];
  399.                 $values["supplierName"] =  $supplier["name"];
  400.                 $values["checkIn"] = $quoteItem->getCheckIn() ? $quoteItem->getCheckIn()->format("Y-m-d") : "";
  401.                 $values["checkOut"] = $quoteItem->getCheckOut() ? $quoteItem->getCheckOut()->format("Y-m-d") : "";
  402.                 $values["confirmationNumber"] = $quoteItem->getConfirmationNumber();
  403.                 $values["invoiceNumber"] = $quoteItem->getQbInvoice()?$quoteItem->getQbInvoice()->getInvoiceNumber():"";
  404.                 $values["customerAccountName"] = $quoteItem->getQuote()->getCustomerAccount()?$quoteItem->getQuote()->getCustomerAccount()->getName():"";
  405.                 $values["reservationStatus"] = $quoteItem->getReservationStatus();
  406.                 $values["accountingStatus"] = $quoteItem->getAccountingStatus();
  407. //            $values["pendingCommFromSupp"] = 0;
  408. //            $values["balanceDueToSuppUSD"] = 0;
  409. //            $values["amountDueFromClientLessComm"] = 0;
  410. //            $values["quoteNumber"] = $quoteItem->getQuote()->getQuoteNumber();
  411.                 if($isView){
  412. //                $values["total"] = '$'.number_format($values["total"], 2, ',', '.');
  413. //                $values["pendingCommFromSupp"] = '$'.number_format($values["pendingCommFromSupp"], 2, ',', '.');
  414. //                $values["balanceDueToSuppUSD"] = '$'.number_format($values["balanceDueToSuppUSD"], 2, ',', '.');
  415. //                $values["amountDueFromClientLessComm"] = '$'.number_format($values["amountDueFromClientLessComm"], 2, ',', '.');
  416.                     $url $this->generateUrl('quality_control_index', array('quoteItemId' => $quoteItem->getId()));
  417.                     $values["action"] = '<a href="' $url '" class="text-blue-color-custom" title="Go to QC"><i class="fas fa-external-link-alt"></i></a>';
  418.                 }
  419.                 $data[] = $values;
  420.             }
  421.         }
  422.         $recordsTotal count($data);
  423.         $data array_slice($data,$offset,$limit);
  424.         return array(
  425.             "recordsTotal" => $recordsTotal,
  426.             "recordsFiltered" => $recordsTotal,
  427.             "data" => $data,
  428. //            "footerTotalQCAmount" => $footerTotalQCAmount,
  429. //            "footerTotalAmountDueFromClientLessComm" => $footerTotalAmountDueFromClientLessComm
  430.         );
  431.     }
  432. }