<?php
require_once (PATH_CONTROLLERS . "Common.php") ;
require_once (PATH_LIB    . 'ImageResize.php');

require_once (PATH_MODELS . "admin/UserClass.php");
require_once (PATH_MODELS . "admin/CompanyClass.php");

require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationAttachmentClass.php");

require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationItemsClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationItemsDetailClass.php");

require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationAppendixClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationTemplateClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationAppendixTemplateClass.php");

require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationProjectPlanClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationProjectPlanDetailClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationProjectPlanTemplateClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationProjectPlanHeaderTemplateClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationProjectPlanDetailTemplateClass.php");

require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationMaintenanceClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationMaintenanceDetailClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationMaintenanceTemplateClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationMaintenanceHeaderTemplateClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationMaintenanceDetailTemplateClass.php");

require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationCoverClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationCoverTemplateClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationCoverDetailTemplateClass.php");

require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationAdditionalInformationClass.php");
require_once (PATH_MODELS . "activity/salesquotation/SalesQuotationAdditionalAttachmentClass.php");

require_once (PATH_MODELS . "activity/CustomerClass.php");
require_once (PATH_MODELS . "activity/CustomerContactClass.php");
require_once (PATH_MODELS . "activity/CurrencyClass.php");

require_once (PATH_MODELS . "activity/invoice/InvoiceHeaderClass.php");

class PortalSalesQuotation extends ActivityBase {

    private $itemCounter = 0;
    private $currentPage = 0;
    private $totalPagesY = 0;
    private $totalPages = 0;
    private $appendixPagesDesc = "";

	function __construct() {
		$this->db 		= $_SESSION[SE_DB] ;
		$this->orgid 	= $_SESSION[SE_ORGID] ;
		$this->fldorg   = SalesQuotationTable::C_ORG_ID ;
	}
	
	function __destruct() {
		unset($this->db) ;
	}
	
	public function processRequest($params) {
        // log::write(print_r($params,true));
		$this->type = REQ_VIEW ;
		try {
			$this->db->open() ;
			$this->loadSetting() ;
			if (isset($params) && count($params) > 0) {
				if (isset($params['type']))
					$this->type = $params['type'] ;
            }

			switch ($this->type) {
                case "RESET_QUOTATION_RN":
                    $this->processResetQuotationRN($params);
                    break;
                // case Command::PortalSalesQuotation:
                //     $this->processSalesQuotationInfo() ;
                //     break ;
                case Command::PortalSalesQuotationAddView:
                    $this->processSalesQuotationAddView($params);
                    break;
                case Command::PortalSalesQuotationAdd:
                    $this->processSalesQuotationAdd($params);
                    break;
                case Command::PortalSalesQuotationFilter:
                    $this->processSalesQuotationFilter($params);
                    break;
                case Command::PortalSalesQuotationUpdateView:
                case Command::PortalSalesQuotationApprovalView:
                    $this->processSalesQuotationUpdateView($params);
                    break;
                case Command::PortalSalesQuotationUpdate:
                    $this->processSalesQuotationUpdate($params);
                    break;
                case Command::PortalSalesQuotationDelete:
                    $this->processSalesQuotationDelete($params);
                    break;
                case Command::PortalSalesQuotationCopy:
                    $this->processSalesQuotationCopy($params);
                    break;
                case Command::PortalSalesQuotationPrintPreview:
                    $this->processSalesQuotationPrintPreview($params) ;
                    break ;
                case '_CUSTOMER_CONTACT':
                    $this->getCustomerContact($params) ;
                    break ;
                case '_CONTACT_DETAIL':
                    $this->getContactDetail($params) ;
                    break ;

                //appendix
                case 'C_SAVE_APPENDIX_TEMPLATE':
                    $this->saveAppendixTemplate($params) ;
                    break ;
                case 'C_VIEW_LOAD_APPENDIX_TEMPLATE':
                    $this->loadViewAppendixTemplate($params) ;
                    break ;
                case 'C_LOAD_APPENDIX_TEMPLATE':
                    $this->loadAppendixTemplate($params) ;
                    break ;
                case 'C_DELETE_APPENDIX_TEMPLATE':
                    $this->deleteAppendixTemplate($params) ;
                    break ;
                case 'C_VIEW_LOAD_APPENDIX_TEMPLATE_LIST':
                    $this->loadViewAppendixTemplateList($params) ;
                    break ;

                //project plan
                case 'C_SAVE_PROJECTPLAN_TEMPLATE':
                    $this->saveProjectPlanTemplate($params) ;
                    break ;
                case 'C_VIEW_LOAD_PROJECTPLAN_TEMPLATE':
                    $this->loadViewProjectPlanTemplate($params) ;
                    break ;
                case 'C_LOAD_PROJECTPLAN_TEMPLATE':
                    $this->loadProjectPlanTemplate($params) ;
                    break ;
                case 'C_DELETE_PROJECTPLAN_TEMPLATE':
                    $this->deleteProjectPlanTemplate($params) ;
                    break ;
                case 'C_VIEW_LOAD_PROJECTPLAN_TEMPLATE_LIST':
                    $this->loadViewProjectPlanTemplateList($params) ;
                    break ;

                //maintenance & support
                case 'C_SAVE_MAINTENANCE_TEMPLATE':
                    $this->saveMaintenanceTemplate($params) ;
                    break ;
                case 'C_VIEW_LOAD_MAINTENANCE_TEMPLATE':
                    $this->loadViewMaintenanceTemplate($params) ;
                    break ;
                case 'C_LOAD_MAINTENANCE_TEMPLATE':
                    $this->loadMaintenanceTemplate($params) ;
                    break ;
                case 'C_DELETE_MAINTENANCE_TEMPLATE':
                    $this->deleteMaintenanceTemplate($params) ;
                    break ;
                case 'C_VIEW_LOAD_MAINTENANCE_TEMPLATE_LIST':
                    $this->loadViewMaintenanceTemplateList($params) ;
                    break ;

                //cover
                case 'C_SAVE_COVER_TEMPLATE':
                    $this->saveCoverTemplate($params) ;
                    break ;
                case 'C_VIEW_LOAD_COVER_TEMPLATE':
                    $this->loadViewCoverTemplate($params) ;
                    break ;
                case 'C_LOAD_COVER_TEMPLATE':
                    $this->loadCoverTemplate($params) ;
                    break ;
                case 'C_DELETE_COVER_TEMPLATE':
                    $this->deleteCoverTemplate($params) ;
                    break ;
                case 'C_VIEW_LOAD_COVER_TEMPLATE_LIST':
                    $this->loadViewCoverTemplateList($params) ;
                    break ;

                case 'SEND_SALES_QUOTATION_SUBMIT':
                    $this->processSalesQuotationSubmit($params) ;
                    break ;
                case 'SEND_SALES_QUOTATION_ISSUE':
                    $this->processSalesQuotationIssue($params) ;
                    break ;
                case 'SEND_SALES_QUOTATION_REVISE':
                    $this->processSalesQuotationRevise($params) ;
                    break ;
                case Command::PortalSalesQuotationReviseList:
                    $this->getReviseListSalesQuotation($params) ;
                    break ;
                case Command::PortalSalesQuotationReviseUpdate:
                    $this->processSalesQuotationUpdateRevise($params) ;
                    break ; 
                case 'SALES_QUOTATION_ACCEPT':
                    $this->processSalesQuotationAccept($params) ;
                    break ;
                case Command::PortalSalesQuotationClosed:
                    $this->processSalesQuotationClosed($params) ;
                    break ; 
                case Command::PortalSalesQuotationUpdateExpected:
                    $this->processSalesQuotationUpdateExpected($params) ;
                    break ; 

                //document
                case Command::PortalSalesQuotationAddUploadDocView:
                    $this->processViewSalesQuotationAddUpload($params['id']);
                    break;
                case Command::PortalSalesQuotationAddUploadDoc:
                    $this->addUploadDoc($params);
                    break;
                case Command::PortalSalesQuotationSaveDoc:
                    $this->saveDocument($params);
                    break;
                case Command::PortalSalesQuotationDownloadDoc:
                    $this->processDownloadFile($params);
                    break;
                case Command::PortalSalesQuotationDeleteDoc:
                    $this->deleteDocument($params);
                    break;
                case Command::PortalSalesQuotationAddUploadReviseDocView:
                    $this->processViewSalesQuotationReviseAddUpload($params['id']);
                    break;
                case "C_SALES_QUOTATION_SUBMIT_ATTACH_VIEW":
                    $this->processSalesQuotationSubmitApprovalAttachView($params['id']);
                    break;
                    
                //APPROVAL
                case Command::PortalSalesQuotationApprovalListView:
                    $this->processSalesQuotationApprovalListView($params);
                    break;
                case Command::PortalSalesQuotationApprovalList:
                    $this->processSalesQuotationApprovalList($params);
                    break;
                case Command::PortalSalesQuotationApprovalConfirm:
                    $this->processSalesQuotationApprovalConfirm($params);
                    break;
                    
                //PROFORMA INVOICE
                case Command::PortalGenerateInvoice:
                    $this->generateInvoiceNumber($params) ;
                    break ;
                case Command::PortalInvoicePrintPreview:
                    $this->processInvoicePrintPreview($params) ;
                    break ;
                case Command::PortalRetrieveInvoice:
                    $this->retrieveInvoiceDetail($params) ;
                    break ;
                case Command::PortalExportInvoiceFilter:
                    $this->filterExportInvoice($params) ;
                    break ;
                case Command::PortalExportInvoiceExcel:
                    $this->exportInvoiceToExcel($params) ;
                    break ;
                
                //update view
                case "C_UPDATE_VIEW_DETAIL":
                    $this->updateViewDetail($params) ;
                    break ;
                    
				default:
					$this->sendJsonResponse(Status::Error,"invalid request.","",$this->type) ;
					break ;
			}
			$this->db->close() ;
			return true ;
		} catch (Exception $e) {
			$this->db->close() ;
			die ($e->getMessage()) ;
		}
    }

    private function updateViewDetail($params){
        try {
            if(isset($params['id'])){
                $id = $params['id'];
                $cls = new SalesQuotationClass($this->db);
                $modifyby   = $_SESSION[SE_USERID] ;
                $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
                $datas = array();
                $datas[] = $this->db->fieldValue(SalesQuotationTable::C_VIEWED,1) ;
                $datas[] = $this->db->fieldValue(SalesQuotationTable::C_VIEWED_DATE,$modifydate) ;
                $datas[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_BY,$modifyby) ;
                $datas[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_DATE,$modifydate) ;
                $cls->updateRecord($id, $datas);
                
                $totalApproval = intVal(count($cls->getApprovalList($_SESSION[SE_USERID]))) + intVal(count($cls->getPendingApprovalList($_SESSION[SE_USERID]))) ;

                $this->sendJsonResponse(Status::Ok,"View detail successfully saved.",$totalApproval,$this->type);
            }
        }catch(Exception $e) {
            Log::write("[updateViewDetail] ".$e->getMessage());
            $this->sendJsonResponse(Status::Error,"Sorry, there is a error in database operation.","",$this->type);
        }
    }

    private function processResetQuotationRN() { 
        $clsCompany = new CompanyClass($this->db);
        $coys = $clsCompany->getTable();
        if(!is_null($coys) && count($coys) > 0) {
            foreach($coys as $coy) {
                $cls = new SalesQuotationClass($this->db);     
                $max_code   = $cls->getMaxSalesQuotationNumber($coy[CompanyTable::C_COY_ID]);

                if(intVal($max_code) == 10) {
                    $row_com    = $clsCompany->getRecord($coy[CompanyTable::C_COY_ID]) ;
                    $opt        = new CompanyOptions() ;
                    $opt->loadXml($row_com[CompanyTable::C_OPTIONS]) ;
                    $op         = $opt->getOption() ;
                    
                    $max_code = 10;
                    $op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_CODE_RN] = $max_code;
                    $opt->setOption($op) ;
                    // log::write($opt->getXml());

                    $data_coy       = array() ;
                    $data_coy[]     = $this->db->fieldValue(CompanyTable::C_OPTIONS,$opt->getXml());
                    $clsCompany->updateRecord($coy[CompanyTable::C_COY_ID],$data_coy) ;
                }
                unset($cls);
            }
        }
        unset($clsCompany);
        
        $this->sendJsonResponse(Status::Ok,"Sales Quotation RN successfully resetted.","",$this->type);
    }

    private function processSalesQuotationFilter($params) {
        $cls            = new SalesQuotationClass($this->db);
        $clsCompany     = new CompanyClass($this->db);
        $opt 		    = new CompanyOptions() ;
        $clsCustomer    = new CustomerClass($this->db);
        $clsContact     = new CustomerContactClass($this->db);
        $clsCurrency    = new CurrencyClass($this->db);

        $htmlStr = "";

        $coy_id     = $params['coy_id'];
        $prospect   = $params['prospect'];
        $filter_date   = $params['filter_date'];
        $status     = $params['status'];

        $fromdte    = str_replace('/', '-', $params['from_date'] );
        $from_date   = date_create($fromdte)->format('Y-m-d');
        $todte      = str_replace('/', '-', $params['to_date'] );
        $to_date     = date_create($todte)->format('Y-m-d');

        $rows       = $cls->getSalesQuotationList($coy_id, $prospect, $filter_date, $from_date, $to_date, $status);

        if(!is_null($rows) && count($rows) > 0){
            foreach ($rows as $row) {
                $rowCompany = $clsCompany->getRecord($row[SalesQuotationTable::C_BU]);
                $opt->loadXml($rowCompany[CompanyTable::C_OPTIONS]) ;
                $op = $opt->getOption() ;

                $name = "";
                if($row[SalesQuotationTable::C_PROSPECT]) {
                    $company = $row[SalesQuotationTable::C_PROSPECT_NAME];
                    $contact = $row[SalesQuotationTable::C_PROSPECT_CONTACT];
                } else {
                    $rowCustomer = $clsCustomer->getRecord($row[SalesQuotationTable::C_CUSTOMER_ID]);
                    $company = $rowCustomer[CustomerTable::C_NAME] . " (" . $rowCustomer[CustomerTable::C_CODE] . ")" ;                    
                    $contact = $clsContact->getRecord($row[SalesQuotationTable::C_CONTACT_ID])[CustomerContactTable::C_NAME];
                }

                $quot_type = "";
                switch($row[SalesQuotationTable::C_TYPE]) {
                    case SalesQuotationType::Service:
                        $quot_type = "Service";
                        break;
                    case SalesQuotationType::Project:
                        $quot_type = "Project";
                        break;
                    case SalesQuotationType::Contract:
                        $quot_type = "Contract";
                        break;
                    case SalesQuotationType::Item:
                        $quot_type = "Item";
                        break;
                    case SalesQuotationType::License:
                        $quot_type = "Renew";
                        break;
                    case SalesQuotationType::NewSub:
                        $quot_type = "New-Sub";
                        break;
                    default:
                        $quot_type = "";
                        break;
                }

                $status = $row[SalesQuotationTable::C_STATUS];
                $quot_status = "";
                switch($row[SalesQuotationTable::C_STATUS]) {
                    case SalesQuotationStatus::Open:
                        $quot_status = "Open";
                        break;
                    case SalesQuotationStatus::Issued:
                        $quot_status = "Issued";
                        break;
                    case SalesQuotationStatus::Revised:
                        $quot_status = "Revised";
                        break;
                    case SalesQuotationStatus::Accepted:
                        $quot_status = "Accepted";
                        break;
                    case SalesQuotationStatus::Closed:
                        $quot_status = "Closed";
                        break;
                    case SalesQuotationStatus::Submitted:
                        $quot_status = "Submitted";
                        break;
                    case SalesQuotationStatus::Approved:
                        $quot_status = "Approved";
                        break;
                    case SalesQuotationStatus::Rejected:
                        $quot_status = "Rejected";
                        break;
                    default:
                        $quot_status = "";
                        break;
                }

                // $quotation_number = $row[SalesQuotationTable::C_REVISE_TYPE] == SalesQuotationReviseType::Internal ? trim($row[SalesQuotationTable::C_NUMBER]) : trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]);

                /* if($row[SalesQuotationTable::C_STATUS] == SalesQuotationStatus::Open) {
                    $btnStr  = '<td class="kt-datatable__cell"><button type="button"  class="btn btn-icon btn-success btn-sm btn-icon btn-icon-md" title="Edit" onclick="return showEditSalesQuotation('.$row[SalesQuotationTable::C_ID].',this);"><i class="fa fa-edit"></i></button></td>';
                }  */ 
                
                $closed   = $row[SalesQuotationTable::C_IS_CLOSED];
                if($closed) {
                    $quot_status = "Closed";
                    $status = SalesQuotationStatus::Closed;
                }
                
                // if($row[SalesQuotationTable::C_STATUS] == SalesQuotationStatus::Open || $row[SalesQuotationTable::C_STATUS] == SalesQuotationStatus::Revised || $row[SalesQuotationTable::C_STATUS] == SalesQuotationStatus::Issued || $row[SalesQuotationTable::C_STATUS] == SalesQuotationStatus::Accepted || $closed || $row[SalesQuotationTable::C_STATUS] == SalesQuotationStatus::Submitted) {
                    $btnStr  = "<td class=\"kt-datatable__cell\"><button type=\"button\"  class=\"btn btn-icon btn-success btn-sm btn-icon btn-icon-md\" title=\"Edit\" onclick='return openModalRevisionSalesQuotation(\"".$row[SalesQuotationTable::C_REF_ID]."\",\"".$status."\",\"".$row[SalesQuotationTable::C_APPROVED_BY]."\");'><i class=\"fa fa-edit\"></i></button></td>";
                // }
                 /* else if($row[SalesQuotationTable::C_STATUS] == SalesQuotationStatus::Accepted){
                    $btnStr  = '<td class="kt-datatable__cell"><button type="button"  class="btn btn-icon btn-success btn-sm btn-icon btn-icon-md" title="Edit" onclick="return showEditSalesQuotation('.$row[SalesQuotationTable::C_ID].',this);"><i class="fa fa-edit"></i></button></td>';
                } */
                
                $btnStr  .= '<td class="kt-datatable__cell"><button type="button" class="btn btn-icon btn-danger btn-sm btn-icon btn-icon-md" title="Delete" onclick="javascript:deleteSalesQuotation('.$row[SalesQuotationTable::C_ID].',this);"><i class="fa fa-trash-alt"></i></button></td>';

                $btnStr  .= '<td class="kt-datatable__cell"><button type="button"  class="btn btn-icon btn-primary btn-sm btn-icon btn-icon-md" title="Print Preview" onclick="javascript:printPreviewSalesQuotationPDF('.$row[SalesQuotationTable::C_ID].', 0);"><i class="fa fa-print"></i></button></td>';

                $htmlStr .= '<tr data-row="sales-quotation-rows-'.$row[SalesQuotationTable::C_ID].'" class="kt-datatable__row" style="left: 0px;">'.
                            '<td class="kt-datatable__cell" style="display:none;">'.$row[SalesQuotationTable::C_ID].'</td>'.
                            '<td class="kt-datatable__cell">'.$op[CompanyOptions::C_SETTING][CompanyOptions::C_SET_CODE].'</td>'.
                            '<td class="kt-datatable__cell">'.$row[SalesQuotationTable::C_NUMBER].'</td>'.
                            '<td class="kt-datatable__cell">'.$row[SalesQuotationTable::C_CUSTOMER_NUMBER].'</td>'.
                            '<td class="kt-datatable__cell">'.$quot_type.'</td>'.
                            '<td class="kt-datatable__cell">'.$company.'</td>'.
                            '<td class="kt-datatable__cell">'.$contact.'</td>'.
                            '<td class="kt-datatable__cell">'.trim($row[SalesQuotationTable::C_TITLE]).'</td>'.
                            // '<td class="kt-datatable__cell">'.trim($row[SalesQuotationTable::C_CONTACT_EMAIL]).'</td>'.
                            // '<td class="kt-datatable__cell">'.trim($row[SalesQuotationTable::C_CONTACT_MOBILE]).'</td>'.
                            '<td class="kt-datatable__cell" style="text-align: center;">'.$clsCurrency->getRecord($row[SalesQuotationTable::C_CURRENCY])[CurrencyTable::C_REF].'</td>'.
                            '<td class="kt-datatable__cell">'.$quot_status.'</td>';
                $htmlStr .= '<td class="kt-datatable__cell">'.$row[InvoiceHeaderTable::C_INVOICE_NUMBER].'</td>';

                switch ($filter_date) {
                    case 0:
                        $htmlStr .= '<td class="kt-datatable__cell">'.date_create($row[SalesQuotationTable::C_CREATE_DATE])->format('d/m/Y').'</td>';
                        break;
                    case 1:
                        $htmlStr .= '<td class="kt-datatable__cell">'.date_create($row[SalesQuotationTable::C_ISSUE_DATE])->format('d/m/Y').'</td>';
                        break;
                    case 2:
                        $htmlStr .= '<td class="kt-datatable__cell">'.date_create($row[SalesQuotationTable::C_REVISE_DATE])->format('d/m/Y').'</td>';
                        break;
                    case 3:
                        $htmlStr .= '<td class="kt-datatable__cell">'.date_create($row[SalesQuotationTable::C_ACCEPT_DATE])->format('d/m/Y').'</td>';
                        break;
                    case 4:
                        $htmlStr .= '<td class="kt-datatable__cell">'.date_create($row[SalesQuotationTable::C_CLOSED_DATE])->format('d/m/Y').'</td>';
                        break;
                    case 5:
                        $htmlStr .= '<td class="kt-datatable__cell">'.date_create($row[SalesQuotationTable::C_PREFERRED_INVOICE_DATE])->format('d/m/Y').'</td>';
                        break;
                    case 6: //proforma invoice date
                        $htmlStr .= '<td class="kt-datatable__cell">'.date_create($row['INVOICE_DATE'])->format('d/m/Y').'</td>';
                        break;
                    case 7: //submit date
                        $htmlStr .= '<td class="kt-datatable__cell">'.date_create($row[SalesQuotationTable::C_SUBMIT_DATE])->format('d/m/Y').'</td>';
                        break;
                    case 8: //approval date
                        $htmlStr .= '<td class="kt-datatable__cell">'.date_create($row[SalesQuotationTable::C_APPROVED_DATE])->format('d/m/Y').'</td>';
                        break;
                    case 9:
                        $htmlStr .= '<td class="kt-datatable__cell">'.date_create($row[SalesQuotationTable::C_EXPECTED_ACCEPT_DATE])->format('d/m/Y').'</td>';
                        break;
                    case 10:
                        $htmlStr .= '<td class="kt-datatable__cell">'.date_create($row[SalesQuotationTable::C_EXPECTED_PAY_DATE])->format('d/m/Y').'</td>';
                        break;
                    default:
                        $htmlStr .= '<td class="kt-datatable__cell">'.date_create($row[SalesQuotationTable::C_CREATE_DATE])->format('d/m/Y').'</td>';
                        break;
                }

                $htmlStr .= $btnStr.'</tr>';
            }
        }
        
        $datasReturn = array();
        $datasReturn['htmlStr'] = $htmlStr;
        
        $this->sendJsonResponse(Status::Ok,"",$datasReturn,$this->type);
    }

    private function processSalesQuotationAddView($params) {
        ob_start() ;
        $clsUser = new UserClass($this->db) ;
        $coyId   = $clsUser->getRecord($_SESSION[SE_USERID])[UserTable::C_COY_ID];

        $clsCoy = new CompanyClass($this->db) ;
        $rowCoy = $clsCoy->getRecord($coyId) ;
        $baseCurrency=0;
        if (!is_null($rowCoy)) {
            if (!is_null($rowCoy[CompanyTable::C_OPTIONS]) && $rowCoy[CompanyTable::C_OPTIONS] != "") {

                $opt = new CompanyOptions() ;
                $opt->loadXml($rowCoy[CompanyTable::C_OPTIONS]) ;
                $op = $opt->getOption() ;

                $baseCurrency=$op[CompanyOptions::C_SETTING][CompanyOptions::C_BASE_CURRENCY];
            }
        }

        $clsInformation = new SalesQuotationAdditionalInformationClass($this->db);
        $rowsInfo = $clsInformation->getTable(); 

        $clsAttachment = new SalesQuotationAdditionalAttachmentClass($this->db);
        $rowsAttach = $clsAttachment->getAttachmentList(0);

        include (PATH_VIEWS . "portal/salesquotation/AddView.php") ;
        $datasReturn= array() ;
        $datasReturn["htmlContent"] =  str_replace("[index]",$params['index'], Util::minifyHtml(ob_get_clean())) ;
        $datasReturn['headTitle']   =  "New Sales Quotation";
        // $datasReturn['coyId'] = $coyId;
        $datasReturn['baseCurrency'] = $baseCurrency;

        $this->sendJsonResponse(Status::Ok,"Sales Quotation Add View",$datasReturn,$this->type);
    }

    private function processSalesQuotationAdd($params) {
        // log::write(print_r($params,true));
        $cls            = new SalesQuotationClass($this->db) ;
        $clsCustomer    = new CustomerClass($this->db) ;

        $datas      = array() ;
        $dataReturn = array();
        $orgid      = $_SESSION[SE_ORGID] ;
        $modifyby   = $_SESSION[SE_USERID] ;
        $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
        $dte        = date_create('now')->format('Y-m-d') ;
        $ws         = $_SESSION[SE_REMOTE_IP];
        
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_BU,$this->getParamInt($params,'bu_id',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_TYPE,$this->getParamInt($params,'type_id',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CUSTOMER_ID,$this->getParamInt($params,'cust_id',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PROSPECT,$this->getParamInt($params,'is_prospect',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PROSPECT_NAME,$this->getParam($params,'prospect_name',"")) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PROSPECT_CONTACT,$this->getParam($params,'prospect_contact',"")) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_DATE,$dte) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CONTACT_ID,$this->getParamInt($params,'contact_id',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CONTACT_EMAIL,$this->getParam($params,'contact_email',"")) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CONTACT_MOBILE,$this->getParam($params,'contact_mobile',"")) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CONTACT_TELEPHONE,$this->getParam($params,'contact_phone',"")) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CURRENCY,$this->getParamInt($params,'curr_id',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ISSUE_DATE,NULL_DATE) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_REVISE_DATE,NULL_DATE) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ACCEPT_DATE,NULL_DATE) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CUSTOMER_REVISE_DATE,NULL_DATE) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_REVISE_VERSION,"0") ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_FOOTER,htmlspecialchars($this->getParam($params,'footer',""))) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ISSUE,htmlspecialchars($this->getParam($params,'issue',""))) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_TITLE,$this->getParam($params,'title',"")) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ADDITIONAL_CONTACT,$this->getParam($params,'add_contact',"")) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CLOSED_DATE,NULL_DATE) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PREFERRED_INVOICE_DATE,$this->getParam($params,'preferred_inv_date',NULL_DATE)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_EXPECTED_ACCEPT_DATE,$this->getParam($params,'exp_accept_date',NULL_DATE)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_EXPECTED_PAY_DATE,$this->getParam($params,'exp_pay_date',NULL_DATE)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PERCENTAGE_PAYMENT,$this->getParamInt($params,'percentage_payment',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PROBABILITY,$this->getParamInt($params,'probability',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_USER_DEFINED_1,$this->getParam($params,'user_defined_1',"")) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_USER_DEFINED_2,$this->getParam($params,'user_defined_2',"")) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_USER_DEFINED_3,$this->getParam($params,'user_defined_3',"")) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_USER_DEFINED_4,$this->getParam($params,'user_defined_4',"")) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_SUBMIT_DATE,NULL_DATE) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_APPROVED_DATE,NULL_DATE) ;

        //print preview selection and sequence no
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ISSUE_PRINT,$this->getParamInt($params,'issue_print',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ISSUE_PRINT_PAGE,$this->getParamInt($params,'issue_print_page',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ITEMS_PRINT,$this->getParamInt($params,'items_print',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ITEMS_PRINT_PAGE,$this->getParamInt($params,'items_print_page',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_MAINTENANCE_PRINT,$this->getParamInt($params,'maintenance_print',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_MAINTENANCE_PRINT_PAGE,$this->getParamInt($params,'maintenance_print_page',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PROJECT_PLAN_PRINT,$this->getParamInt($params,'project_print',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PROJECT_PLAN_PRINT_PAGE,$this->getParamInt($params,'project_print_page',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_COVER_PRINT,$this->getParamInt($params,'cover_print',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_COVER_PRINT_PAGE,$this->getParamInt($params,'cover_print_page',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_FOOTER_PRINT,$this->getParamInt($params,'footer_print',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_FOOTER_PRINT_PAGE,$this->getParamInt($params,'footer_print_page',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_APPENDIX_PRINT,$this->getParamInt($params,'appendix_print',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_APPENDIX_PRINT_PAGE,$this->getParamInt($params,'appendix_print_page',0)) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ADDITIONAL_APPENDIX,$this->getParam($params,'add_appendix',"")) ;

        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ORG_ID,$orgid) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_WS_ID,$ws) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_BY,$modifyby) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CREATE_BY,$modifyby) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_DATE,$modifydate) ;
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CREATE_DATE,$modifydate) ;

        //running number
        $companyCls = new CompanyClass($this->db) ;
        $row_com    = $companyCls->getRecord($params['bu_id']) ;
        $opt        = new CompanyOptions() ;
        $opt->loadXml($row_com[CompanyTable::C_OPTIONS]) ;
        $op         = $opt->getOption() ;
        $max_code   = intval($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_CODE_RN]);
        // $max_code   = $cls->getMaxSalesQuotationNumber($params['bu_id']);
        $key_code = date_create('now')->format('ym') . str_pad($max_code, intval($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_CODE_LENGTH]), "0", STR_PAD_LEFT);
        $result_code = $op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_INTERNAL_PREFIX].$op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_CODE_PREFIX] . $key_code;
        $result_code_cust = $op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_CODE_PREFIX] . $key_code;
        // $result_code = $op[CompanyOptions::C_SETTING][CompanyOptions::C_SET_CODE].date_create('now')->format('ym').$max_code;
        $datas[]    = $this->db->fieldValue(SalesQuotationTable::C_NUMBER, $result_code) ;
        $datas[]    = $this->db->fieldValue(SalesQuotationTable::C_CUSTOMER_NUMBER, $result_code_cust) ;
        // var_dump($result_code);
        
        // log::write($key_code);
        $quotation_ref_id = Util::randomKey($key_code);
        // log::write($quotation_ref_id);
        $datas[] = $this->db->fieldValue(SalesQuotationTable::C_REF_ID,$quotation_ref_id) ;
        
        try {
            $this->db->beginTran();
            $id = $cls->addRecord($datas) ;
            if ($id > 0) {
                $dataReturn['id'] = $id;
                $dataReturn['quot_number'] = $result_code;
                $dataReturn['customer_quot_number'] = $result_code_cust;

                //running number
                $max_code += 1;
                $op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_CODE_RN] = $max_code;
                $opt->setOption($op) ;
                // log::write($opt->getXml());

                $data_coy= array() ;
                $data_coy[]    = $this->db->fieldValue(CompanyTable::C_OPTIONS,$opt->getXml());
                $companyCls->updateRecord($params['bu_id'],$data_coy) ;
                //==== 

                //item
                $params['id'] = $id;
                $dataReturn['items_id'] = $this->processSalesQuotationAddItems($params);
                
                //appendix
                $appendix = $this->getParam($params,'appendix',"") ;
                $this->addSalesQuotationAppendix($id,$appendix) ;

                //project plan
                $project_plan = $this->getParam($params,'project_plan',"") ;
                $project_plan_amount = $this->getParam($params,'project_plan_amount',"") ;
                $project_plan_currency = $this->getParam($params,'project_plan_currency',"") ;
                $this->addSalesQuotationProjectPlan($params, $id, $project_plan) ;

                //maintenance & support
                $maintenance = $this->getParam($params,'maintenance',"") ;
                // $maintenance_currency = $this->getParam($params,'maintenance_currency',"") ;
                // $maintenance_amount = $this->getParam($params,'maintenance_amount',"") ;
                $this->addSalesQuotationMaintenance($params, $id, $maintenance) ;
                
                //cover
                $this->processSalesQuotationAddCover($id, $result_code, $this->getParam($params,'cover',""));

                $this->db->commitTran();
				$this->sendJsonResponse(Status::Ok,"Sales Quotation successfully added to the system.",$dataReturn,$this->type);
			} else {
                $this->db->rollbackTran();
				$this->sendJsonResponse(Status::Error,"Sorry, there is a error in adding new Sales Quotation to the system.",$dataReturn, $this->type) ;
			}
		} catch (Exception $e) {
            $this->db->rollbackTran();
			Log::write('[SalesQuotation]' . $e->getMessage());
			$this->sendJsonResponse(Status::Error,"Sorry, there is a error in database operation.","",$this->type) ;
		}
		unset($cls) ;
    }

    private function processSalesQuotationAddItems($params) {
        $cls            = new SalesQuotationClass($this->db) ;
        $clsItems       = new SalesQuotationItemsClass($this->db) ;

        $items_id = -1;

        $datas      = array() ;
        $orgid      = $_SESSION[SE_ORGID] ;
        $modifyby   = $_SESSION[SE_USERID] ;
        $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
        $dte        = date_create('now')->format('Y-m-d') ;
        $ws         = $_SESSION[SE_REMOTE_IP];
        
        try {     
            $items = json_decode($params['items'],true);
            if(!is_null($items) && count($items) > 0) {
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_ID,$this->getParamInt($params,'id',0)) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_SUBTOTAL,$this->getParam($params,'sub_total',"0.0000")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_DISC_TYPE,$this->getParam($params,'disc_type',"")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_DISC_PERCENTAGE,$this->getParam($params,'disc_percentage',"0.00")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_DISC,$this->getParam($params,'disc_total',"0.0000")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_GST_PERCENTAGE,$this->getParam($params,'gst_percentage',"0.00")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_GST,$this->getParam($params,'gst_total',"0.0000")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_GRAND_TOTAL,$this->getParam($params,'grand_total',"0.0000")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_QTY_TOTAL,$this->getParam($params,'qty_total',"0")) ;

                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_WS_ID,$ws) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_MODIFY_BY,$modifyby) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_CREATE_BY,$modifyby) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_MODIFY_DATE,$modifydate) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_CREATE_DATE,$modifydate) ;

                $items_id = $clsItems->addRecord($datas) ;

                $cls->updateItemsTotal($this->getParamInt($params,'id',0), $this->getParam($params,'grand_total',"0.0000"), $this->getParam($params,'gst_total',"0.0000"));

                if($items_id > 0) {
                    $params['items_id'] = $items_id;
                    if(isset($params['items'])) {
                        $this->processSalesQuotationAddItemsDetail($params);
                    }
                }
            }
		} catch (Exception $e) {
			Log::write('[SalesQuotation]' . $e->getMessage());
		}
		unset($cls) ;
        unset($clsItems) ;
        
        $dataReturn['items_id'] = $items_id;
    }

    private function processSalesQuotationAddItemsDetail($params) {
        // log::write(print_r($params,true));
        $clsDetail      = new SalesQuotationItemsDetailClass($this->db) ;

        $items = json_decode($params['items'],true);

        $orgid      = $_SESSION[SE_ORGID] ;
        $modifyby   = $_SESSION[SE_USERID] ;
        $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
        $dte        = date_create('now')->format('Y-m-d') ;
        $ws         = $_SESSION[SE_REMOTE_IP];
                    
        $line_no  = 0;
        $serial_no  = 0;
        if(!is_null($items) && count($items) > 0) {
            // log::write($items);
            foreach($items as $item) {
                $datas = array();

                if($this->getParamInt($item,'item_no',0) == 0) {
                    $line_no += 1000;
                    $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_LINE_NO,$line_no) ;
                } else {                    
                    $serial_no = substr($line_no, 0, 3) . $this->getParamInt($item,'item_no',0);
                    $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_LINE_NO,$serial_no) ;
                }

                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_ITEMS_ID,$this->getParamInt($params,'items_id',0)) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_QUOTATION_ID,$this->getParamInt($params,'id',0)) ;
                // $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_LINE_NO,$line_no) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_LINE_DESC,htmlspecialchars($this->getParam($item,'item_desc',""))) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_LINE_COMMENT,htmlspecialchars($this->getParam($item,'item_comment',""))) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_LINE_AMOUNT,$this->getParam($item,'item_amount',0)) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_LINE_DISC,$this->getParam($item,'item_disc',0)) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_LINE_DISC_DESC,htmlspecialchars($this->getParam($item,'item_disc_reason',""))) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_LINE_UNIT_PRICE,$this->getParam($item,'item_unit_price',0)) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_LINE_QTY,$this->getParamInt($item,'item_qty',0)) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_LINE_PHASE,$this->getParam($item,'item_phase',"")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_LINE_ADDITIONAL,$this->getParamInt($item,'item_additional',0)) ;

                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_WS_ID,$ws) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_MODIFY_BY,$modifyby) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_CREATE_BY,$modifyby) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_MODIFY_DATE,$modifydate) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsDetailTable::C_CREATE_DATE,$modifydate) ;
                
                $detail_id = $clsDetail->addRecord($datas) ;
                // $line_no += 1;
                unset($datas) ;
            }
        }
    }

    private function addSalesQuotationAppendix($id, $appendix){
        $cls     = new SalesQuotationAppendixClass($this->db);

        try{
            $encodes = json_decode($appendix,true);
            if(!is_null($encodes) && count($encodes)>0){
                foreach ($encodes as $encode) {
                    $orgid      = $_SESSION[SE_ORGID] ;
                    $modifyby   = $_SESSION[SE_USERID] ;
                    $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
                    $ws         = $_SESSION[SE_REMOTE_IP];

                    $datas = array();
                    $datas[] = $this->db->fieldValue(SalesQuotationAppendixTable::C_ORG_ID,$orgid) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationAppendixTable::C_WS_ID,$ws) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationAppendixTable::C_MODIFY_BY,$modifyby) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationAppendixTable::C_CREATE_BY,$modifyby) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationAppendixTable::C_MODIFY_DATE,$modifydate) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationAppendixTable::C_CREATE_DATE,$modifydate) ;

                    $datas[] = $this->db->fieldValue(SalesQuotationAppendixTable::C_ID,$id) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationAppendixTable::C_SECTION,$encode['section']) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationAppendixTable::C_SUBJECT,htmlspecialchars($encode['subject'])) ;                  
                    $datas[] = $this->db->fieldValue(SalesQuotationAppendixTable::C_DESC,htmlspecialchars($encode['desc'])) ;        

                    if($encode['id'] != -1){
                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTable::C_APPENDIX_ID,$encode['id']) ;
                    }else{
                        $line_id = $cls->getMaxFieldBySalesQuotationAppendixId($id,SalesQuotationAppendixTable::C_APPENDIX_ID) ;
                        if(is_null($line_id) ){
                            $line_id = 1;
                        }else{
                            $line_id +=1;
                        }

                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTable::C_APPENDIX_ID,$line_id) ;
                    }
                
                    $cls->addRecord($datas) ;                    
                }
    
            }
            return;
        } catch(Exception $e){
            Log::write("[PortalSalesQuotationAppendix]" . $e->getMessage());
            return;
        }
    }

    private function addSalesQuotationProjectPlan($params, $quot_id, $project_plan){
        $cls            = new SalesQuotationProjectPlanClass($this->db);
        $clsDetail      = new SalesQuotationProjectPlanDetailClass($this->db);

        $orgid      = $_SESSION[SE_ORGID] ;
        $modifyby   = $_SESSION[SE_USERID] ;
        $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
        $ws         = $_SESSION[SE_REMOTE_IP];

        $datas = array();
        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTable::C_ORG_ID,$orgid) ;
        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTable::C_WS_ID,$ws) ;
        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTable::C_MODIFY_BY,$modifyby) ;
        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTable::C_CREATE_BY,$modifyby) ;
        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTable::C_MODIFY_DATE,$modifydate) ;
        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTable::C_CREATE_DATE,$modifydate) ;

        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTable::C_QUOTATION_ID,$quot_id) ;
        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTable::C_CURRENCY,$params['project_plan_currency']) ;
        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTable::C_AMOUNT,floatval(str_replace(',', '', $params['project_plan_amount']))) ;

        try{
            $encodes = json_decode($project_plan,true);
            if(!is_null($encodes) && count($encodes)>0){

                $project_plan_id = $cls->addRecord($datas) ;                

                if ($project_plan_id > 0) {
                    foreach ($encodes as $encode) {
                        $orgid      = $_SESSION[SE_ORGID] ;
                        $modifyby   = $_SESSION[SE_USERID] ;
                        $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
                        $ws         = $_SESSION[SE_REMOTE_IP];

                        $datas = array();
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_ORG_ID,$orgid) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_WS_ID,$ws) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_MODIFY_BY,$modifyby) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_CREATE_BY,$modifyby) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_MODIFY_DATE,$modifydate) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_CREATE_DATE,$modifydate) ;

                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_ID,$project_plan_id) ;
                        
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_QUOTATION_ID,$quot_id) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_PHASE,htmlspecialchars($encode['phase'])) ;        
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_DESC,htmlspecialchars($encode['desc'])) ;                  
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_DAYS,$encode['days']) ;

                        if($encode['id'] != -1){
                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_DETAIL_ID,$encode['id']) ;
                        }else{
                            $line_id = $clsDetail->getMaxFieldBySalesQuotationProjectPlanId($quot_id,SalesQuotationProjectPlanDetailTable::C_DETAIL_ID) ;

                            if(is_null($line_id) ){
                                $line_id = 1;
                            }else{
                                $line_id +=1;
                            }

                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTable::C_DETAIL_ID,$line_id) ;
                        }

                        $clsDetail->addRecord($datas) ;                    
                    }            
                }
            }

            return;
        } catch(Exception $e){
            Log::write("[PortalSalesQuotationProjectPlan]" . $e->getMessage());
            return;
        }
    }

    private function addSalesQuotationMaintenance($params, $quot_id, $maintenance){
        $cls            = new SalesQuotationMaintenanceClass($this->db);
        $clsDetail      = new SalesQuotationMaintenanceDetailClass($this->db);

        $orgid      = $_SESSION[SE_ORGID] ;
        $modifyby   = $_SESSION[SE_USERID] ;
        $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
        $ws         = $_SESSION[SE_REMOTE_IP];

        $datas = array();
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_ORG_ID,$orgid) ;
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_WS_ID,$ws) ;
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_MODIFY_BY,$modifyby) ;
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_CREATE_BY,$modifyby) ;
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_MODIFY_DATE,$modifydate) ;
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_CREATE_DATE,$modifydate) ;

        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_QUOTATION_ID,$quot_id) ;
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_CURRENCY,$params['maintenance_currency']) ;
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_SUBTOTAL,$this->getParam($params,'subtotal_maintenance',"0.0000"));
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_DISC_TYPE,$this->getParam($params,'disc_type_maintenance',""));
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_DISC_PERCENTAGE,$this->getParam($params,'disc_percentage_maintenance',"0.00"));
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_DISC_TOTAL,$this->getParam($params,'disc_total_maintenance',"0.0000"));
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_GST_PERCENTAGE,$this->getParam($params,'gst_percentage_maintenance',"7.00"));
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_GST_TOTAL,$this->getParam($params,'gst_total_maintenance',"0.0000"));
        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTable::C_GRAND_TOTAL,$this->getParam($params,'grand_total_maintenance',"0.0000"));

        try{
            $encodes = json_decode($maintenance,true);
            if(!is_null($encodes) && count($encodes)>0){

                $maintenance_id = $cls->addRecord($datas) ;            

                if ($maintenance_id > 0) {
                    foreach ($encodes as $encode) {
                        $orgid      = $_SESSION[SE_ORGID] ;
                        $modifyby   = $_SESSION[SE_USERID] ;
                        $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
                        $ws         = $_SESSION[SE_REMOTE_IP];

                        $datas = array();
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_ORG_ID,$orgid) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_WS_ID,$ws) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_MODIFY_BY,$modifyby) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_CREATE_BY,$modifyby) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_MODIFY_DATE,$modifydate) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_CREATE_DATE,$modifydate) ;

                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_ID,$maintenance_id) ;
                        

                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_QUOTATION_ID,$quot_id) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_DESC,htmlspecialchars($encode['desc']));        
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_COMMENT,htmlspecialchars($encode['comment'])) ;                  
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_AMOUNT,floatval(str_replace(',', '', $encode['amount']))) ;

                        if($encode['id'] != -1){
                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_DETAIL_ID,$encode['id']) ;
                        }else{
                            $line_id = $clsDetail->getMaxFieldBySalesQuotationMaintenanceId($quot_id,SalesQuotationMaintenanceDetailTable::C_DETAIL_ID) ;

                            if(is_null($line_id) ){
                                $line_id = 1;
                            }else{
                                $line_id +=1;
                            }

                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTable::C_DETAIL_ID,$line_id) ;
                        }

                        $clsDetail->addRecord($datas) ;                    
                    }
                }
            }

            return;
        } catch(Exception $e){
            Log::write("[PortalSalesQuotationMaintenance]" . $e->getMessage());
            return;
        }
    }

    private function processSalesQuotationAddCover($id, $quot_no, $cover){
        $cls     = new SalesQuotationCoverClass($this->db);
        
        $orgid      = $_SESSION[SE_ORGID] ;
        $modifyby   = $_SESSION[SE_USERID] ;
        $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
        $ws         = $_SESSION[SE_REMOTE_IP];

        try{
            $encodes = json_decode($cover,true);
            if(!is_null($encodes) && count($encodes)>0){
                $line_no = 1000;
                foreach ($encodes as $encode) {
                    $datas = array();
                    $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_WS_ID,$ws) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_MODIFY_BY,$modifyby) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_CREATE_BY,$modifyby) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_MODIFY_DATE,$modifydate) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_CREATE_DATE,$modifydate) ;

                    $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_QUOTATION_ID,$id) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_LINE_NO, $line_no) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_PAGE,$this->getParamInt($encode, 'cover_page', 0)) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_PAGE_LINE,$this->getParamInt($encode, 'cover_page_line', 0)) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_DESC,htmlspecialchars($this->getParam($encode, 'cover_desc', ""))) ; 
                    // $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_DESC,$this->getParam($encode, 'cover_desc', "")) ; 

                    $mesg = "";
                    $document = $this->getParam($encode,'cover_document',"") ;
                    $temp_filename = $this->getParam($encode,'temp_filename',"") ;
                    if ($document != "") {
                        if (file_exists($document)) {
                            $pi = pathinfo(basename($document));
                            $ext = $pi['extension'];
                            $filename = "cover_page_".$this->getParamInt($encode, 'cover_page', 0).".".$ext ;
                        
                            $newPath = PATH_SALES_QUOTATION_OUTPUT. "cover_page/" .$quot_no. "/" ;
                            if (!file_exists($newPath)) {
                                mkdir($newPath, 0777, true);
                            }
                            $newfile = $newPath . $filename ;
                            if (file_exists($newfile)) {
                                unlink($newfile) ;
                            }
                            if (!copy($document, $newfile)) {
                                $mesg .= " Error in copying the file." ;
                            }
                            unlink($document) ;
                            
                            if($filename != "") {
                                $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_DOCUMENT,$filename);
                            }
                        } else {
                            $mesg .= " File not found in the upload directory." ;
                            $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_DOCUMENT,$temp_filename);
                        }
                    } else {                        
                        $datas[] = $this->db->fieldValue(SalesQuotationCoverTable::C_DOCUMENT,$temp_filename);
                    }

                    $cls->addRecord($datas) ; 
                    $line_no += 1;
                }
            }
            return;
        } catch(Exception $e){
            Log::write("[PortalSalesQuotationCover]" . $e->getMessage());
            return;
        }
    }

    private function processSalesQuotationUpdateView($params) {        
        ob_start() ;

        $id             = $params['id'];

        $clsInformation = new SalesQuotationAdditionalInformationClass($this->db);
        $rowsInfo = $clsInformation->getTable();

        $clsAttachment = new SalesQuotationAdditionalAttachmentClass($this->db);
        $rowsAttach = $clsAttachment->getAttachmentList($id);

        include (PATH_VIEWS . "portal/salesquotation/AddView.php") ;

        $datasReturn = array();
        $datasReturn["htmlContent"] =  str_replace("[index]",$params['index'], Util::minifyHtml(ob_get_clean())) ;
        if($this->type == Command::PortalSalesQuotationApprovalView)
            $datasReturn['headTitle']   =  "Sales Quotation Approval";
        else
            $datasReturn['headTitle']   =  "Edit Sales Quotation";

        $cls            = new SalesQuotationClass($this->db) ;
        $clsProject     = new SalesQuotationProjectPlanClass($this->db) ;
        $clsMaintenance = new SalesQuotationMaintenanceClass($this->db) ;
        $clsCurrency    = new CurrencyClass($this->db);
        
        $row            = $cls->getRecord($id);
        
        $datas = array();
        $datas['id']                    = $row[SalesQuotationTable::C_ID];
        $datas['bu_id']                 = $row[SalesQuotationTable::C_BU];
        $datas['type_id']               = $row[SalesQuotationTable::C_TYPE];
        $datas['quot_number']           = $row[SalesQuotationTable::C_NUMBER];
        $datas['cust_id']               = $row[SalesQuotationTable::C_CUSTOMER_ID];
        $datas['contact_id']            = $row[SalesQuotationTable::C_CONTACT_ID];
        $datas['contact_email']         = $row[SalesQuotationTable::C_CONTACT_EMAIL];
        $datas['contact_mobile']        = $row[SalesQuotationTable::C_CONTACT_MOBILE];
        $datas['contact_telephone']     = $row[SalesQuotationTable::C_CONTACT_TELEPHONE];
        $datas['currency']              = $row[SalesQuotationTable::C_CURRENCY];
        $currency                       = $clsCurrency->getRecord($row[SalesQuotationTable::C_CURRENCY])[CurrencyTable::C_REF];
        $datas['status']                = $row[SalesQuotationTable::C_STATUS];
        $datas['is_prospect']           = $row[SalesQuotationTable::C_PROSPECT];
        $datas['prospect_name']         = $row[SalesQuotationTable::C_PROSPECT_NAME];
        $datas['prospect_contact']      = $row[SalesQuotationTable::C_PROSPECT_CONTACT];
        $quotdate   = new DateTime($row[SalesQuotationTable::C_DATE]); 
        $datas['quot_date']             = $quotdate->format('d/m/Y');
        $issuedate   = new DateTime($row[SalesQuotationTable::C_ISSUE_DATE]); 
        $datas['issue_date']            = $issuedate->format('d/m/Y');
        $revisedate   = new DateTime($row[SalesQuotationTable::C_REVISE_DATE]); 
        $datas['revise_date']           = $revisedate->format('d/m/Y');
        $acceptdate   = new DateTime($row[SalesQuotationTable::C_ACCEPT_DATE]); 
        $datas['accept_date']           = $acceptdate->format('d/m/Y');
        $datas['revise_type']           = $row[SalesQuotationTable::C_REVISE_TYPE];
        $datas['revise_ver']            = $row[SalesQuotationTable::C_REVISE_VERSION];
        $datas['customer_ver']          = $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION];
        $datas['customer_quot_number']  = $row[SalesQuotationTable::C_CUSTOMER_NUMBER];
        $datas['footer']                = htmlspecialchars_decode($row[SalesQuotationTable::C_FOOTER]);
        $datas['issue']                 = htmlspecialchars_decode($row[SalesQuotationTable::C_ISSUE]);
        $datas['title']                 = $row[SalesQuotationTable::C_TITLE];
        $datas['add_contact']           = $row[SalesQuotationTable::C_ADDITIONAL_CONTACT];
        $datas['active']                = $row[SalesQuotationTable::C_ACTIVE];
        $datas['closed']                = $row[SalesQuotationTable::C_IS_CLOSED];
        $closeddate   = new DateTime($row[SalesQuotationTable::C_CLOSED_DATE]); 
        $datas['closed_date']           = $closeddate->format('d/m/Y');
        $preferreinvdate   = new DateTime($row[SalesQuotationTable::C_PREFERRED_INVOICE_DATE]); 
        $datas['preferred_inv_date']    = $preferreinvdate->format('Y-m-d');
        $expectedacceptdate   = new DateTime($row[SalesQuotationTable::C_EXPECTED_ACCEPT_DATE]); 
        if($expectedacceptdate->format('Y-m-d H:i:s') == NULL_DATE){
            $datas['exp_accept_date']       = "";
        }else{
            $datas['exp_accept_date']       = $expectedacceptdate->format('Y-m-d');
        }
        $expectedpaydate   = new DateTime($row[SalesQuotationTable::C_EXPECTED_PAY_DATE]); 
        if($expectedpaydate->format('Y-m-d H:i:s') == NULL_DATE){
            $datas['exp_pay_date']       = "";
        }else{
            $datas['exp_pay_date']          = $expectedpaydate->format('Y-m-d');
        }
        $datas['percentage_payment']    = number_format($row[SalesQuotationTable::C_PERCENTAGE_PAYMENT], 0);
        $datas['probability']                = $row[SalesQuotationTable::C_PROBABILITY];
        $datas['user_defined_1']        = $row[SalesQuotationTable::C_USER_DEFINED_1];
        $datas['user_defined_2']        = $row[SalesQuotationTable::C_USER_DEFINED_2];
        $datas['user_defined_3']        = $row[SalesQuotationTable::C_USER_DEFINED_3];
        $datas['user_defined_4']        = $row[SalesQuotationTable::C_USER_DEFINED_4];
        $datas['approver']              = $row[SalesQuotationTable::C_APPROVED_BY] == $_SESSION[SE_USERID] ? true : false;
        $datas['viewed']                = $row[SalesQuotationTable::C_VIEWED];
        $datas['viewed_date']           = date_create($row[SalesQuotationTable::C_VIEWED_DATE])->format('d/m/Y');

        $clsInvoice = new InvoiceHeaderClass($this->db);
        $rowInvoice = $clsInvoice->getRecord($id);
        if(!is_null($rowInvoice) && count($rowInvoice)>0) {
            $datas['invoice_number']        = $rowInvoice[InvoiceHeaderTable::C_INVOICE_NUMBER];
            $datas['generate_date']         = date_create($rowInvoice[InvoiceHeaderTable::C_CREATE_DATE])->format('d/m/Y');
            $datas['printed']               = $rowInvoice[InvoiceHeaderTable::C_PRINT];
            $datas['printed_date']          = date_create($rowInvoice[InvoiceHeaderTable::C_PRINT_DATE])->format('d/m/Y');
        } else {            
            $datas['invoice_number']        = "";
            $datas['generate_date']         = "";
            $datas['printed']               = 0;
            $datas['printed_date']          = "";
        }
        
        //print preview selection and sequence no
        $datas['issue_print']               = $row[SalesQuotationTable::C_ISSUE_PRINT] == 0 ? false:true;
        $datas['issue_print_page']          = $row[SalesQuotationTable::C_ISSUE_PRINT_PAGE] == 0 ? '':$row[SalesQuotationTable::C_ISSUE_PRINT_PAGE];
        $datas['items_print']               = $row[SalesQuotationTable::C_ITEMS_PRINT] == 0 ? false:true;
        $datas['items_print_page']          = $row[SalesQuotationTable::C_ITEMS_PRINT_PAGE] == 0 ? '':$row[SalesQuotationTable::C_ITEMS_PRINT_PAGE];
        $datas['maintenance_print']         = $row[SalesQuotationTable::C_MAINTENANCE_PRINT] == 0 ? false:true;
        $datas['maintenance_print_page']    = $row[SalesQuotationTable::C_MAINTENANCE_PRINT_PAGE] == 0 ? '':$row[SalesQuotationTable::C_MAINTENANCE_PRINT_PAGE];
        $datas['project_print']             = $row[SalesQuotationTable::C_PROJECT_PLAN_PRINT] == 0 ? false:true;
        $datas['project_print_page']        = $row[SalesQuotationTable::C_PROJECT_PLAN_PRINT_PAGE] == 0 ? '':$row[SalesQuotationTable::C_PROJECT_PLAN_PRINT_PAGE];
        $datas['cover_print']               = $row[SalesQuotationTable::C_COVER_PRINT] == 0 ? false:true;
        $datas['cover_print_page']          = $row[SalesQuotationTable::C_COVER_PRINT_PAGE] == 0 ? '':$row[SalesQuotationTable::C_COVER_PRINT_PAGE];
        $datas['footer_print']              = $row[SalesQuotationTable::C_FOOTER_PRINT] == 0 ? false:true;
        $datas['footer_print_page']         = $row[SalesQuotationTable::C_FOOTER_PRINT_PAGE] == 0 ? '':$row[SalesQuotationTable::C_FOOTER_PRINT_PAGE];
        $datas['appendix_print']            = $row[SalesQuotationTable::C_APPENDIX_PRINT] == 0 ? false:true;
        $datas['appendix_print_page']       = $row[SalesQuotationTable::C_APPENDIX_PRINT_PAGE] == 0 ? '':$row[SalesQuotationTable::C_APPENDIX_PRINT_PAGE];
        $datas['add_appendix']              = $row[SalesQuotationTable::C_ADDITIONAL_APPENDIX];

        $datas['grand_total']               = $cls->calculateGrandTotal($id);

        $datas['items']                     = $this->getSalesQuotationItems($id);
        $datas['appendix']                  = $this->getSalesQuotationAppendix($id);
        $datas['cover']                     = $this->getSalesQuotationCover($id);

        //project plan
        $row_projectplan = $clsProject->getRecord($id);
        if(!is_null($row_projectplan) && count($row_projectplan) > 0) {
            $datas['project_plan_id']       = $row_projectplan[SalesQuotationProjectPlanTable::C_ID];
            $datas['project_plan_currency'] = $row_projectplan[SalesQuotationProjectPlanTable::C_CURRENCY] == "" ? $currency:$row_projectplan[SalesQuotationProjectPlanTable::C_CURRENCY] ;
            $datas['project_plan_amount']   = number_format($row_projectplan[SalesQuotationProjectPlanTable::C_AMOUNT], 2, '.', '');
            $datas['project_plan']          = $this->getSalesQuotationProjectPlan($row_projectplan[SalesQuotationProjectPlanTable::C_ID], $id);            
        } else {
            $datas['project_plan_id']       = "";
            $datas['project_plan_currency'] = "";
            $datas['project_plan_amount']   = "0.00";
            $datas['project_plan']          = "[]";
        }

        //maintenance
        $row_maintenance = $clsMaintenance->getRecord($id);
        // log::write($row_maintenance);
        if(!is_null($row_maintenance) && count($row_maintenance) > 0) {
            $datas['maintenance_id']                = $row_maintenance[SalesQuotationMaintenanceTable::C_ID];
            $datas['maintenance_currency']          = $row_maintenance[SalesQuotationMaintenanceTable::C_CURRENCY] == "" ? $currency:$row_maintenance[SalesQuotationMaintenanceTable::C_CURRENCY] ;
            $datas['subtotal_maintenance']          = number_format($row_maintenance[SalesQuotationMaintenanceTable::C_SUBTOTAL], 2, '.', '');
            $datas['disc_type_maintenance']         = trim($row_maintenance[SalesQuotationMaintenanceTable::C_DISC_TYPE]);
            $datas['disc_percentage_maintenance']   = intval($row_maintenance[SalesQuotationMaintenanceTable::C_DISC_PERCENTAGE]);
            $datas['disc_total_maintenance']        = number_format($row_maintenance[SalesQuotationMaintenanceTable::C_DISC_TOTAL], 2, '.', '');
            $datas['gst_percentage_maintenance']    = intval($row_maintenance[SalesQuotationMaintenanceTable::C_GST_PERCENTAGE]);
            $datas['gst_total_maintenance']         = number_format($row_maintenance[SalesQuotationMaintenanceTable::C_GST_TOTAL], 2, '.', '');
            $datas['grand_total_maintenance']       = number_format($row_maintenance[SalesQuotationMaintenanceTable::C_GRAND_TOTAL], 2, '.', '');

            $datas['maintenance']          = $this->getSalesQuotationMaintenance($row_maintenance[SalesQuotationMaintenanceTable::C_ID], $id);            
        } else {
            $datas['maintenance_id']                = "";
            $datas['maintenance_currency']          = "";
            $datas['subtotal_maintenance']          = "0.00";
            $datas['disc_type_maintenance']         = "";
            $datas['disc_percentage_maintenance']   = "0";
            $datas['disc_total_maintenance']        = "0.00";
            $datas['gst_percentage_maintenance']    = "0";
            $datas['gst_total_maintenance']         = "0.00";
            $datas['grand_total_maintenance']       = "0.00";
            $datas['maintenance']                   = "[]";
        }

        $params['cust_id'] = $row[SalesQuotationTable::C_CUSTOMER_ID];
        $datas['contact_opt']           = $this->getCustomerContact($params);
        // $datas['currency_opt']          = $this->getCurrencyOption();

        $datasReturn["headerData"] =  $datas ;
       
        $this->sendJsonResponse(Status::Ok,"Sales Quotation Edit Content",$datasReturn,$this->type);
        unset($cls);
        unset($row);
    }

    private function getSalesQuotationItems($id) {
        $clsItems       = new SalesQuotationItemsClass($this->db) ;
        $clsDetail = new SalesQuotationItemsDetailClass($this->db) ;

        $rows = $clsItems->getRecordByQuotationId($id) ;

        $datas = array();
        if (!is_null($rows) && count($rows) > 0) {
            foreach($rows as $row) {
                $data                       = array() ;
                $data['items_id']           = $row[SalesQuotationItemsTable::C_ITEMS_ID];
                $data['sub_total']          = number_format($row[SalesQuotationItemsTable::C_SUBTOTAL], 2, '.', '');
                $data['disc_type']          = $row[SalesQuotationItemsTable::C_DISC_TYPE];
                $data['disc_percentage']    = number_format($row[SalesQuotationItemsTable::C_DISC_PERCENTAGE], 0);
                $data['disc_total']         = number_format($row[SalesQuotationItemsTable::C_DISC], 2, '.', '');
                $data['gst_percentage']     = number_format($row[SalesQuotationItemsTable::C_GST_PERCENTAGE], 0);
                $data['gst_total']          = number_format($row[SalesQuotationItemsTable::C_GST], 2, '.', '');
                $data['grand_total']        = number_format($row[SalesQuotationItemsTable::C_GRAND_TOTAL], 2, '.', '');
                $data['qty_total']          = number_format($row[SalesQuotationItemsTable::C_QTY_TOTAL], 2, '.', '');

                $details = $clsDetail->getRecordItemsDetail($id, $row[SalesQuotationItemsTable::C_ITEMS_ID]);
                
                $item_detail = array();
                if (!is_null($details) && count($details) > 0) {
                    foreach ($details as $detail) {
                        $data_detail                    = array() ;
                        $data_detail['line_no']         = $detail[SalesQuotationItemsDetailTable::C_LINE_NO];
                        $data_detail['line_desc']       = $detail[SalesQuotationItemsDetailTable::C_LINE_DESC];
                        $data_detail['line_comment']    = $detail[SalesQuotationItemsDetailTable::C_LINE_COMMENT];
                        $data_detail['line_amount']     = number_format($detail[SalesQuotationItemsDetailTable::C_LINE_AMOUNT], 2, '.', '');
                        $data_detail['line_disc']       = number_format($detail[SalesQuotationItemsDetailTable::C_LINE_DISC], 2, '.', '');
                        $data_detail['line_disc_desc']  = $detail[SalesQuotationItemsDetailTable::C_LINE_DISC_DESC];
                        $data_detail['line_unit_price'] = number_format($detail[SalesQuotationItemsDetailTable::C_LINE_UNIT_PRICE], 2, '.', '');
                        $data_detail['line_qty']        = number_format($detail[SalesQuotationItemsDetailTable::C_LINE_QTY], 2, '.', '');
                        $data_detail['line_phase']      = $detail[SalesQuotationItemsDetailTable::C_LINE_PHASE];
                        $data_detail['line_additional'] = $detail[SalesQuotationItemsDetailTable::C_LINE_ADDITIONAL];

                        array_push($item_detail,$data_detail);
                    }

                    $data['detail'] = $item_detail;
                } else {
                    $data['detail'] = [];
                }

                array_push($datas,$data);
            }
        }
        $json_array = json_encode($datas,true);
        // log::write($json_array);
        
        return $json_array;
        unset($clsItems);
        unset($clsDetail);
    }

    private function getSalesQuotationAppendix($id) {
        $cls = new SalesQuotationAppendixClass($this->db);

        $rows = $cls->getSalesQuotationAppendix($id) ;

        $datas = array();
        if (!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {

                $data               = array();
                $data['id']         = $row[SalesQuotationAppendixTable::C_APPENDIX_ID];
                $data['section']    = $row[SalesQuotationAppendixTable::C_SECTION];
                $data['subject']    = htmlspecialchars_decode($row[SalesQuotationAppendixTable::C_SUBJECT]);
                $data['desc']       = htmlspecialchars_decode($row[SalesQuotationAppendixTable::C_DESC]);

                array_push($datas,$data);
            }
        }

        $json_array = json_encode($datas,true);

        return $json_array;
    }

    private function getSalesQuotationProjectPlan($id, $quotId) {
        $cls       = new SalesQuotationProjectPlanClass($this->db);
        $clsDetail = new SalesQuotationProjectPlanDetailClass($this->db);

        $rows = $clsDetail->getSalesQuotationProjectPlan($id, $quotId) ;
        
        $datas = array();
        if (!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $data               = array();
                $data['id']         = $row[SalesQuotationProjectPlanDetailTable::C_DETAIL_ID];
                $data['phase']      = htmlspecialchars_decode($row[SalesQuotationProjectPlanDetailTable::C_PHASE]);
                $data['desc']       = htmlspecialchars_decode($row[SalesQuotationProjectPlanDetailTable::C_DESC]);
                $data['days']       = number_format($row[SalesQuotationProjectPlanDetailTable::C_DAYS], 2);

                array_push($datas,$data);
            }
        }

        $json_array = json_encode($datas,true);
        // log::write($json_array);
        return $json_array;
    }

    private function getSalesQuotationMaintenance($id, $quotId) {
        $cls       = new SalesQuotationMaintenanceClass($this->db);
        $clsDetail = new SalesQuotationMaintenanceDetailClass($this->db);

        $rows = $clsDetail->getSalesQuotationMaintenance($id, $quotId) ;
        
        $datas = array();
        if (!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $data               = array();
                $data['id']         = $row[SalesQuotationMaintenanceDetailTable::C_DETAIL_ID];
                $data['desc']       = htmlspecialchars_decode($row[SalesQuotationMaintenanceDetailTable::C_DESC]);
                $data['comment']    = htmlspecialchars_decode($row[SalesQuotationMaintenanceDetailTable::C_COMMENT]);
                $data['amount']     = number_format($row[SalesQuotationMaintenanceDetailTable::C_AMOUNT], 2, '.', '');

                array_push($datas,$data);
            }
        }

        $json_array = json_encode($datas,true);

        return $json_array;
    }

    private function getSalesQuotationCover($id) {
        $clsCover      = new SalesQuotationCoverClass($this->db) ;

        $rows = $clsCover->getRecordByQuotationId($id) ;

        $datas = array();
        if (!is_null($rows) && count($rows) > 0) {
            foreach($rows as $row) {
                $data                       = array() ;
                $data['cover_id']           = $row[SalesQuotationCoverTable::C_ID];
                $data['cover_line_no']      = $row[SalesQuotationCoverTable::C_LINE_NO];
                $data['cover_page']         = $row[SalesQuotationCoverTable::C_PAGE];
                $data['cover_page_line']    = $row[SalesQuotationCoverTable::C_PAGE_LINE];
                $data['cover_document']     = $row[SalesQuotationCoverTable::C_DOCUMENT];
                $data['cover_desc']         = $row[SalesQuotationCoverTable::C_DESC];

                array_push($datas,$data);
            }
        }
        $json_array = json_encode($datas,true);
        // log::write($json_array);
        
        return $json_array;
        unset($clsCover);
    }

    private function processSalesQuotationUpdate($params) {
        // log::write(print_r($params,true));die();
        if (isset($params['id'])) {
            $id = $params['id'] ;
            
            $cls                = new SalesQuotationClass($this->db) ;

            $clsAppendix        = new SalesQuotationAppendixClass($this->db) ;
            $clsAppendixTemp    = new SalesQuotationAppendixTemplateClass($this->db) ;

            $clsProjectPlan     = new SalesQuotationProjectPlanClass($this->db) ;
            $clsProjectPlanDtl  = new SalesQuotationProjectPlanDetailClass($this->db) ;

            $clsMaintenance     = new SalesQuotationMaintenanceClass($this->db) ;
            $clsMaintenanceDtl  = new SalesQuotationMaintenanceDetailClass($this->db) ;

            $clsCover           = new SalesQuotationCoverClass($this->db) ;

            $datas      = array() ;
            $orgid      = $_SESSION[SE_ORGID] ;
            $modifyby   = $_SESSION[SE_USERID] ;
            $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
            $dte        = date_create('now')->format('Y-m-d') ;
            $ws         = $_SESSION[SE_REMOTE_IP];
            
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_BU,$this->getParamInt($params,'bu_id',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_TYPE,$this->getParamInt($params,'type_id',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CUSTOMER_ID,$this->getParamInt($params,'cust_id',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PROSPECT,$this->getParamInt($params,'is_prospect',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PROSPECT_NAME,$this->getParam($params,'prospect_name',"")) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PROSPECT_CONTACT,$this->getParam($params,'prospect_contact',"")) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CONTACT_ID,$this->getParamInt($params,'contact_id',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CONTACT_EMAIL,$this->getParam($params,'contact_email',"")) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CONTACT_MOBILE,$this->getParam($params,'contact_mobile',"")) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CONTACT_TELEPHONE,$this->getParam($params,'contact_phone',"")) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CURRENCY,$this->getParamInt($params,'curr_id',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_FOOTER,htmlspecialchars($this->getParam($params,'footer',""))) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ISSUE,htmlspecialchars($this->getParam($params,'issue',""))) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_TITLE,$this->getParam($params,'title',"")) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ADDITIONAL_CONTACT,$this->getParam($params,'add_contact',"")) ;
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_IS_CLOSED,0) ; 
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_CLOSED_DATE,NULL_DATE) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PREFERRED_INVOICE_DATE,$this->getParam($params,'preferred_inv_date',NULL_DATE)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_EXPECTED_ACCEPT_DATE,$this->getParam($params,'exp_accept_date',NULL_DATE)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_EXPECTED_PAY_DATE,$this->getParam($params,'exp_pay_date',NULL_DATE)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PERCENTAGE_PAYMENT,$this->getParamInt($params,'percentage_payment',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PROBABILITY,$this->getParamInt($params,'probability',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_USER_DEFINED_1,$this->getParam($params,'user_defined_1',"")) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_USER_DEFINED_2,$this->getParam($params,'user_defined_2',"")) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_USER_DEFINED_3,$this->getParam($params,'user_defined_3',"")) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_USER_DEFINED_4,$this->getParam($params,'user_defined_4',"")) ;

            //print preview selection and sequence no
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ISSUE_PRINT,$this->getParamInt($params,'issue_print',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ISSUE_PRINT_PAGE,$this->getParamInt($params,'issue_print_page',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ITEMS_PRINT,$this->getParamInt($params,'items_print',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ITEMS_PRINT_PAGE,$this->getParamInt($params,'items_print_page',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_MAINTENANCE_PRINT,$this->getParamInt($params,'maintenance_print',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_MAINTENANCE_PRINT_PAGE,$this->getParamInt($params,'maintenance_print_page',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PROJECT_PLAN_PRINT,$this->getParamInt($params,'project_print',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_PROJECT_PLAN_PRINT_PAGE,$this->getParamInt($params,'project_print_page',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_COVER_PRINT,$this->getParamInt($params,'cover_print',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_COVER_PRINT_PAGE,$this->getParamInt($params,'cover_print_page',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_FOOTER_PRINT,$this->getParamInt($params,'footer_print',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_FOOTER_PRINT_PAGE,$this->getParamInt($params,'footer_print_page',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_APPENDIX_PRINT,$this->getParamInt($params,'appendix_print',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_APPENDIX_PRINT_PAGE,$this->getParamInt($params,'appendix_print_page',0)) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_ADDITIONAL_APPENDIX,$this->getParam($params,'add_appendix',"")) ;

            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_WS_ID,$ws) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_BY,$modifyby) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_DATE,$modifydate) ;
            
            try {
                $cls->updateRecord($id, $datas) ;
                $dataReturn['id'] = $id;
                //items
                $dataReturn['items_id'] = $this->processSalesQuotationUpdateItems($params);

                //appendix
                // $clsAppendixTemp->deleteTask($id);
                $clsAppendix->deleteRecord($id) ;
                $this->addSalesQuotationAppendix($id, $params["appendix"]);

                //project plan
                $clsProjectPlan->deleteRecord($id) ;
                $clsProjectPlanDtl->deleteRecord($id) ;
                $this->addSalesQuotationProjectPlan($params, $id, $params["project_plan"]) ;

                //maintenance & support
                $clsMaintenance->deleteRecord($id) ;
                $clsMaintenanceDtl->deleteRecord($id) ;
                $this->addSalesQuotationMaintenance($params, $id, $params["maintenance"]) ;

                //cover
                $clsCover->deleteRecordByQuotationId($id);
                $directory = PATH_SALES_QUOTATION_OUTPUT. "cover_page/" .$this->getParam($params,'quot_number',""). "/";
                if(file_exists($directory)){
                    $this->recursiveRemoveDirectory($directory);
                } 
                $this->processSalesQuotationAddCover($id,  $this->getParam($params,'quot_number',""), $this->getParam($params,'cover',""));                

                $this->sendJsonResponse(Status::Ok,"Sales Quotation successfully updated to the system.",$dataReturn,$this->type);
            } catch (Exception $e) {
                Log::write('[SalesQuotation]' . $e->getMessage());
                $this->sendJsonResponse(Status::Error,"Sorry, there is a error in database operation.","",$this->type) ;
            }
            unset($cls) ;
        }else {
            $this->sendJsonResponse(Status::Error,"You must supply the Sales Quotation id you wish to update. Please try again.","",$this->type);
        }
    }

    //new revision
    private function processSalesQuotationUpdateRevise($params) {
        // log::write(print_r($params,true));die();
        if (isset($params['id'])) {
            $id = $params['id'] ;
            // $quot_number = $params['quot_number'];
            $revise_type = $params['revise_type'];
            
            $cls                = new SalesQuotationClass($this->db) ;
            $clsItems           = new SalesQuotationItemsClass($this->db) ;
            $clsItemsDetail     = new SalesQuotationItemsDetailClass($this->db) ;

            $clsAppendix        = new SalesQuotationAppendixClass($this->db) ;

            $clsProjectPlan     = new SalesQuotationProjectPlanClass($this->db) ;
            $clsProjectPlanDtl  = new SalesQuotationProjectPlanDetailClass($this->db) ;

            $clsMaintenance     = new SalesQuotationMaintenanceClass($this->db) ;
            $clsMaintenanceDtl  = new SalesQuotationMaintenanceDetailClass($this->db) ;

            $clsCover           = new SalesQuotationCoverClass($this->db) ;

            $clsAttachment      = new SalesQuotationAttachmentClass($this->db) ;

            $clsCompany     = new CompanyClass($this->db);
            $opt 		    = new CompanyOptions() ;

            $datas      = array() ;
            $dataReturn = array();
            $orgid      = $_SESSION[SE_ORGID] ;
            $modifyby   = $_SESSION[SE_USERID] ;
            $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
            $dte        = date_create('now')->format('Y-m-d') ;
            $ws         = $_SESSION[SE_REMOTE_IP];
                
            try {
                $row = $cls->getRecord($id);

                $rowCompany = $clsCompany->getRecord($row[SalesQuotationTable::C_BU]);
                $opt->loadXml($rowCompany[CompanyTable::C_OPTIONS]) ;
                $op = $opt->getOption() ;
                $internal_prefix = trim($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_INTERNAL_PREFIX]);

                $quot_number = trim($row[SalesQuotationTable::C_NUMBER]);
                $customer_quot_number = trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]);

                $customer_revise_number = "";
                $revision_number = "";

                //internal revision
                $revision_number = $cls->getMaxReviseNumber($id);                
            
                $new_quot_number = str_replace($internal_prefix, "", $quot_number);
                if(strpos($new_quot_number, "-") > 0) {
                    $new_quot_number = substr($new_quot_number, 0, strpos($new_quot_number, "-"))."-".$revision_number;
                } else {
                    $new_quot_number = $new_quot_number."-".$revision_number;
                }
                $new_quot_number = $internal_prefix.$new_quot_number;

                $dataReturn['revise_type'] = $revise_type;
                if($revise_type == 1) { //customer revision
                    //get customer revision number
                    $customer_revise_number = $cls->getCustomerMaxReviseNumber($id);

                    $customer_quot_number = str_replace($internal_prefix, "", $quot_number);
                    if(strpos($customer_quot_number, "-") > 0) {
                        $customer_quot_number = substr($customer_quot_number, 0, strpos($customer_quot_number, "-"))."-".$customer_revise_number;
                    } else {
                        $customer_quot_number = $customer_quot_number."-".$customer_revise_number;
                    }
                } else {
                    if($row[SalesQuotationTable::C_STATUS] == SalesQuotationStatus::Issued || $row[SalesQuotationTable::C_STATUS] == SalesQuotationStatus::Revised) {
                        $customer_revise_number = $cls->getCustomerMaxReviseNumber($id);

                        $customer_quot_number = str_replace($internal_prefix, "", $quot_number);
                        if(strpos($customer_quot_number, "-") > 0) {
                            $customer_quot_number = substr($customer_quot_number, 0, strpos($customer_quot_number, "-"))."-".$customer_revise_number;
                        } else {
                            $customer_quot_number = $customer_quot_number."-".$customer_revise_number;
                        }
                    }
                }
                
                log::write($new_quot_number);
                log::write($customer_quot_number);

                //copy current record
                $new_quot_id = $cls->copySalesQuotation($id, $revision_number, $new_quot_number, $customer_revise_number, $customer_quot_number, $revise_type);

                // $cls->updateRecord($id, $datas) ;
                $dataReturn['id'] = $new_quot_id;

                // if($revise_type == 1) {
                //     $date = date_create('now')->format('Y-m-d H:i:s');
            
                //     $value = array();
                //     $value[] = $this->db->fieldValue(SalesQuotationTable::C_CUSTOMER_REVISE_VERSION,$customer_revise_number) ;
                //     $value[] = $this->db->fieldValue(SalesQuotationTable::C_CUSTOMER_NUMBER,$customer_quot_number) ;
                //     $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_BY,$_SESSION[SE_USERID]) ; 
                //     $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_DATE,$date) ;
                    
                //     $cls->updateRecord($new_quot_id, $value);
                // }
                
                //items
                $new_items_id = $clsItems->copySalesQuotation($id, $new_quot_id);
                if($new_items_id != 0)
                    $clsItemsDetail->copySalesQuotation($id, $new_quot_id, $new_items_id);
                $dataReturn['items_id'] = $new_items_id;

                //appendix
                $clsAppendix->copySalesQuotation($id, $new_quot_id);

                //project plan
                $new_project_id = $clsProjectPlan->copySalesQuotation($id, $new_quot_id);
                if($new_project_id != 0)
                    $clsProjectPlanDtl->copySalesQuotation($id, $new_quot_id, $new_project_id);

                //maintenance & support
                $new_maintenance_id = $clsMaintenance->copySalesQuotation($id, $new_quot_id);
                if($new_maintenance_id != 0)
                    $clsMaintenanceDtl->copySalesQuotation($id, $new_quot_id, $new_maintenance_id);

                //cover
                $clsCover->copySalesQuotation($id, $new_quot_id);                
                
                //attachment
                $clsAttachment->copySalesQuotation($id, $new_quot_id);

                $remove_filename = str_replace($internal_prefix, "", trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]));
                $remove_filename = substr($remove_filename, 0, strpos($remove_filename, "-"));
                $this->processSalesQuotationCopyAttachmentFile($id, $new_quot_id, $remove_filename);

                $this->sendJsonResponse(Status::Ok,"Sales Quotation successfully updated to the system.",$dataReturn,$this->type);
            } catch (Exception $e) {
                Log::write('[SalesQuotation]' . $e->getMessage());
                $this->sendJsonResponse(Status::Error,"Sorry, there is a error in database operation.","",$this->type) ;
            }
            unset($cls) ;
        }else {
            $this->sendJsonResponse(Status::Error,"You must supply the Sales Quotation id you wish to update. Please try again.","",$this->type);
        }
    }

    private function processSalesQuotationUpdateItems($params) {
        if(isset($params['id'])) {
            $id = $params['id'];
            $items_id = $params['items_id'];
            
            $cls            = new SalesQuotationClass($this->db) ;
            $clsItems       = new SalesQuotationItemsClass($this->db) ;
            $clsDetail      = new SalesQuotationItemsDetailClass($this->db) ;

            $datas      = array() ;
            $orgid      = $_SESSION[SE_ORGID] ;
            $modifyby   = $_SESSION[SE_USERID] ;
            $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
            $dte        = date_create('now')->format('Y-m-d') ;
            $ws         = $_SESSION[SE_REMOTE_IP];
            
            try {
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_SUBTOTAL,$this->getParam($params,'sub_total',"0.0000")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_DISC_TYPE,$this->getParam($params,'disc_type',"")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_DISC_PERCENTAGE,$this->getParam($params,'disc_percentage',"0.00")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_DISC,$this->getParam($params,'disc_total',"0.0000")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_GST_PERCENTAGE,$this->getParam($params,'gst_percentage',"0.00")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_GST,$this->getParam($params,'gst_total',"0.0000")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_GRAND_TOTAL,$this->getParam($params,'grand_total',"0.0000")) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_QTY_TOTAL,$this->getParam($params,'qty_total',"0")) ;

                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_WS_ID,$ws) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_MODIFY_BY,$modifyby) ;
                $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_MODIFY_DATE,$modifydate) ;

                if($items_id == -1) {
                    $datas[] = $this->db->fieldValue(SalesQuotationItemsTable::C_ID,$id) ;
                    $items_id = $clsItems->addRecord($datas) ;
                } else {                    
                    $clsItems->updateRecord($items_id, $datas) ;
                }

                $params['items_id'] = $items_id;

                $cls->updateItemsTotal($id, $this->getParam($params,'grand_total',"0.0000"), $this->getParam($params,'gst_total',"0.0000"));

                $clsDetail->deleteRecordByQuotationId($id);
                if(isset($params['items'])) {
                    $this->processSalesQuotationAddItemsDetail($params);
                }
            } catch (Exception $e) {
                Log::write('[SalesQuotation]' . $e->getMessage());
            }
            unset($cls) ;
            unset($clsItems) ;
            unset($clsDetail) ;
            
            return $items_id;
        }
    }

    private function processSalesQuotationDelete($params) {
        if (isset($params['id'])) {
            $id = $params['id'] ;

            $cls                = new SalesQuotationClass($this->db) ;
            $clsItems           = new SalesQuotationItemsClass($this->db) ;
            $clsDetail          = new SalesQuotationItemsDetailClass($this->db) ;
            $clsAppendix        = new SalesQuotationAppendixClass($this->db) ;
            $clsProjectPlan     = new SalesQuotationProjectPlanClass($this->db) ;
            $clsProjectDetail   = new SalesQuotationProjectPlanDetailClass($this->db) ;
            $clsMaintenance     = new SalesQuotationMaintenanceClass($this->db) ;
            $clsMaintenanceDetail  = new SalesQuotationMaintenanceDetailClass($this->db) ;
            $clsCover           = new SalesQuotationCoverClass($this->db) ;;
            $clsAttachment      = new SalesQuotationAttachmentClass($this->db) ;
            
            try {
                $row = $clsItems->getRecord($id);

                $clsDetail->deleteRecordByQuotationId($id) ;
                $clsItems->deleteRecordByQuotationId($id) ;

                $clsAppendix->deleteRecord($id) ;

                $clsProjectPlan->deleteRecord($id) ;
                $clsProjectDetail->deleteRecord($id) ;

                $clsMaintenance->deleteRecord($id) ;
                $clsMaintenanceDetail->deleteRecord($id) ;

                $clsCover->deleteRecordByQuotationId($id) ;

                $clsAttachment->deleteRecordByQuotationId($id) ;
                $dir = PATH_SALES_QUOTATION_OUTPUT . $id . "/";
                $this->deleteDir($dir);

                $cls->deleteRecord($id) ;

                $this->sendJsonResponse(Status::Ok,"Sales Quotation successfully deleted from the system.",$id,$this->type);
            } catch (Exception $e) {
                Log::write('[SalesQuotation]' . $e->getMessage());
                $this->sendJsonResponse(Status::Error,"Sorry, there is a problem in deleting Sales Quotation record from the system.","",$this->type) ;
            }
            unset($cls) ;
            unset($clsItems) ;
            unset($clsDetail) ;
        } else {
            $this->sendJsonResponse(Status::Error,"You must supply the Sales Quotation id if you wish to delete. Please try again.","",$this->type);
        }
    }

    public static function deleteDir($dirPath) {
        if (! is_dir($dirPath)) {
            // throw new InvalidArgumentException("$dirPath must be a directory");
        }
        if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
            $dirPath .= '/';
        }
        $files = glob($dirPath . '*', GLOB_MARK);
        foreach ($files as $file) {
            if (is_dir($file)) {
                self::deleteDir($file);
            } else {
                unlink($file);
            }
        }
        rmdir($dirPath);
    }

    private function processSalesQuotationCopy($params) {
        // log::write(print_r($params,true));die();
        if (isset($params['id'])) {
            $id = $params['id'] ;
            
            $cls                = new SalesQuotationClass($this->db) ;
            $clsItems           = new SalesQuotationItemsClass($this->db) ;
            $clsItemsDetail     = new SalesQuotationItemsDetailClass($this->db) ;

            $clsAppendix        = new SalesQuotationAppendixClass($this->db) ;

            $clsProjectPlan     = new SalesQuotationProjectPlanClass($this->db) ;
            $clsProjectPlanDtl  = new SalesQuotationProjectPlanDetailClass($this->db) ;

            $clsMaintenance     = new SalesQuotationMaintenanceClass($this->db) ;
            $clsMaintenanceDtl  = new SalesQuotationMaintenanceDetailClass($this->db) ;

            $clsCover           = new SalesQuotationCoverClass($this->db) ;

            $clsAttachment      = new SalesQuotationAttachmentClass($this->db) ;

            $datas      = array() ;
            $dataReturn = array();
            $orgid      = $_SESSION[SE_ORGID] ;
            $modifyby   = $_SESSION[SE_USERID] ;
            $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
            $dte        = date_create('now')->format('Y-m-d') ;
            $ws         = $_SESSION[SE_REMOTE_IP];

            $row = $cls->getRecord($id);

            //running number
            $companyCls = new CompanyClass($this->db) ;
            $row_com    = $companyCls->getRecord($row[SalesQuotationTable::C_BU]) ;
            $opt        = new CompanyOptions() ;
            $opt->loadXml($row_com[CompanyTable::C_OPTIONS]) ;
            $op         = $opt->getOption() ;
            // $max_code   = $cls->getMaxSalesQuotationNumber($row[SalesQuotationTable::C_BU]);
            // $new_quot_number = $op[CompanyOptions::C_SETTING][CompanyOptions::C_SET_CODE].date_create('now')->format('ym').$max_code;
            $max_code   = intval($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_CODE_RN]);
            $key_code =  date_create('now')->format('ym') . str_pad($max_code, intval($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_CODE_LENGTH]), "0", STR_PAD_LEFT);
            $internal_prefix = $op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_INTERNAL_PREFIX];
            $new_quot_number =  $internal_prefix . $op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_CODE_PREFIX] . $key_code;
            $new_customer_quot_number = $op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_CODE_PREFIX] . $key_code;
            // log::write($new_quot_number);
                
            try {
                //copy current record
                $new_quot_id = $cls->copySalesQuotationNew($id, $new_quot_number, $new_customer_quot_number, $key_code);
                $dataReturn['id'] = $new_quot_id;

                //running number
                $max_code += 1;
                $op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_CODE_RN] = $max_code;
                $opt->setOption($op) ;
                // log::write($opt->getXml());

                $data_coy       = array() ;
                $data_coy[]     = $this->db->fieldValue(CompanyTable::C_OPTIONS,$opt->getXml());
                $companyCls->updateRecord($row[SalesQuotationTable::C_BU],$data_coy) ;
                //==== 
                
                //items
                $new_items_id = $clsItems->copySalesQuotation($id, $new_quot_id);
                if($new_items_id != 0)
                    $clsItemsDetail->copySalesQuotation($id, $new_quot_id, $new_items_id);
                $dataReturn['items_id'] = $new_items_id;

                //appendix
                $clsAppendix->copySalesQuotation($id, $new_quot_id);

                //project plan
                $new_project_id = $clsProjectPlan->copySalesQuotation($id, $new_quot_id);
                if($new_project_id != 0)
                    $clsProjectPlanDtl->copySalesQuotation($id, $new_quot_id, $new_project_id);

                //maintenance & support
                $new_maintenance_id = $clsMaintenance->copySalesQuotation($id, $new_quot_id);
                if($new_maintenance_id != 0)
                    $clsMaintenanceDtl->copySalesQuotation($id, $new_quot_id, $new_maintenance_id);

                //cover
                $clsCover->copySalesQuotation($id, $new_quot_id);

                //attachment
                $clsAttachment->copySalesQuotation($id, $new_quot_id);

                $remove_filename = str_replace($internal_prefix, "", $new_quot_number);
                $remove_filename = substr($remove_filename, 0, strpos($remove_filename, "-"));
                $this->processSalesQuotationCopyAttachmentFile($id, $new_quot_id, $remove_filename);

                $this->sendJsonResponse(Status::Ok,"Sales Quotation successfully copied to the system.",$dataReturn,$this->type);
            } catch (Exception $e) {
                Log::write('[SalesQuotation]' . $e->getMessage());
                $this->sendJsonResponse(Status::Error,"Sorry, there is a error in database operation.","",$this->type) ;
            }
            unset($cls) ;
        }else {
            $this->sendJsonResponse(Status::Error,"You must supply the Sales Quotation id you wish to copy. Please try again.","",$this->type);
        }
    }

    private function processSalesQuotationCopyAttachmentFile($id, $new_quot_id, $remove_filename) {
        $dir = PATH_SALES_QUOTATION_OUTPUT . $id . "/";
        $newDir = PATH_SALES_QUOTATION_OUTPUT . $new_quot_id . "/";
        
        if (is_dir($dir)) {
            $this->recurse_copy($dir, $newDir);

            $filename = $newDir."*".$remove_filename."*";
            foreach (glob($filename) as $filefound) {
                log::write($filefound ." size " . filesize($filefound));
                unlink($filefound);
            }
        }
    }

    private function recurse_copy($src,$dst) {
        $dir = opendir($src);
        if (!file_exists($dst)) {
            mkdir($dst, 0777, true);
        }
        while(false !== ( $file = readdir($dir)) ) { 
            if (( $file != '.' ) && ( $file != '..' )) { 
                if ( is_dir($src . '/' . $file) ) { 
                    $this->recurse_copy($src . '/' . $file,$dst . '/' . $file); 
                } 
                else { 
                    copy($src . '/' . $file,$dst . '/' . $file); 
                } 
            } 
        } 
        closedir($dir); 
    } 

    //sales quotation preview
    //=============================================================================//
    private function processSalesQuotationPrintPreview($params) {
        // log::write(print_r($params,true));

        require_once(PATH_PDF . 'tcpdf.php');
        require_once(PATH_LIB . 'RequestPdfF.php');

        // create new PDF document
        $pdf = new RequestPdf('P', PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

        $pdf->setPrintHeader(false);

        // set header and footer fonts
        $pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
        $pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));

        // set default monospaced font
        $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);

        // set margins
        $pdf->SetMargins(PDF_MARGIN_LEFT, 10, PDF_MARGIN_RIGHT);
        $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
        $pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

        // set auto page breaks
        $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);

        // set image scale factor
        $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);

        // set some language-dependent strings (optional)
        if (@file_exists(dirname(__FILE__).'/lang/eng.php')) {
            require_once(dirname(__FILE__).'/lang/eng.php');
            $pdf->setLanguageArray($l);
        }

        // ---------------------------------------------------------

        // set font
        //$pdf->SetFont('helvetica', '', 11);

        // set cell padding
        $pdf->setCellPaddings(1, 1, 1, 1);

        // set cell margins
        //$pdf->setCellMargins(1, 1, 1, 1);

        // set color for background
        $pdf->SetFillColor(255, 255, 255);

        $clsQuotation   = new SalesQuotationClass($this->db) ;
        $clsCompany     = new CompanyClass($this->db) ;
        $clsUser        = new UserClass($this->db) ;
        $clsCustomer    = new CustomerClass($this->db) ;
        $clsContact     = new CustomerContactClass($this->db) ;
        $clsCurrency    = new CurrencyClass($this->db);
        
        $id = $params['id'];
        // $quot_type = $params['quot_type'];
        $rowQuotation   = $clsQuotation->getRecord($id);
        
        $companyId      = $rowQuotation[SalesQuotationTable::C_BU];
        $rowCompany     = $clsCompany->getRecord($companyId) ;
        $opt            = new CompanyOptions() ;
        $opt->loadXml($rowCompany[CompanyTable::C_OPTIONS]) ;
        $op             = $opt->getOption() ;

        $quot_title = $rowQuotation[SalesQuotationTable::C_TITLE];
        $quot_no    = $rowQuotation[SalesQuotationTable::C_NUMBER];
        $customer_quot_number = $rowQuotation[SalesQuotationTable::C_CUSTOMER_NUMBER];

        $quotnumber = $customer_quot_number;
        
        if(trim($rowQuotation[SalesQuotationTable::C_CUSTOMER_NUMBER]) == "") {
            if($rowQuotation[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "" || $rowQuotation[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "0") {
                if(strpos($rowQuotation[SalesQuotationTable::C_NUMBER], "-") > 0)
                    $quot_no     = substr($rowQuotation[SalesQuotationTable::C_NUMBER], 0, strpos($rowQuotation[SalesQuotationTable::C_NUMBER], "-"));
                else 
                    $quot_no     = $rowQuotation[SalesQuotationTable::C_NUMBER];
            } else {
                $quot_no     = substr($rowQuotation[SalesQuotationTable::C_NUMBER], 0, strpos($rowQuotation[SalesQuotationTable::C_NUMBER], "-")) . "-" . $rowQuotation[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION];
            }
            $customer_quot_number = $quot_no;
        } else {
            $customer_quot_number    = trim($rowQuotation[SalesQuotationTable::C_CUSTOMER_NUMBER]);
        }
        
        $internal_prefix = trim($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_INTERNAL_PREFIX]);
        $customer_quot_number = str_replace($internal_prefix, "", $customer_quot_number);

        $pdf_filename = $quot_title." - ".$customer_quot_number . ".pdf";
        log::write("processSalesQuotationPrintPreview = ".  $pdf_filename);

        if($rowQuotation[SalesQuotationTable::C_REVISE_TYPE] == 1) {
            $quotnumber = $customer_quot_number;
        }

        $outputType = "preview";
        if (isset($params['outputType'])){
            $outputType = $params['outputType'];
        }

        $selects = array();
        if(isset($params["select"])) {
            $selects = json_decode($params["select"], true);
        } else {
            if($rowQuotation[SalesQuotationTable::C_ISSUE_PRINT] == 1) {
                $selects[] = array("select"=>"issue", "sequence"=>$rowQuotation[SalesQuotationTable::C_ISSUE_PRINT_PAGE]);
            }
            if($rowQuotation[SalesQuotationTable::C_ITEMS_PRINT] == 1) {
                $selects[] = array("select"=>"items", "sequence"=>$rowQuotation[SalesQuotationTable::C_ITEMS_PRINT_PAGE]);
            }
            if($rowQuotation[SalesQuotationTable::C_MAINTENANCE_PRINT] == 1) {
                $selects[] = array("select"=>"maintenance", "sequence"=>$rowQuotation[SalesQuotationTable::C_MAINTENANCE_PRINT_PAGE]);
            }
            if($rowQuotation[SalesQuotationTable::C_PROJECT_PLAN_PRINT] == 1) {
                $selects[] = array("select"=>"project", "sequence"=>$rowQuotation[SalesQuotationTable::C_PROJECT_PLAN_PRINT_PAGE]);
            }
            if($rowQuotation[SalesQuotationTable::C_COVER_PRINT] == 1) {
                $selects[] = array("select"=>"cover", "sequence"=>$rowQuotation[SalesQuotationTable::C_COVER_PRINT_PAGE]);
            }
            if($rowQuotation[SalesQuotationTable::C_FOOTER_PRINT] == 1) {
                $selects[] = array("select"=>"footer", "sequence"=>$rowQuotation[SalesQuotationTable::C_FOOTER_PRINT_PAGE]);
            }
            if($rowQuotation[SalesQuotationTable::C_APPENDIX_PRINT] == 1) {
                $selects[] = array("select"=>"appendix", "sequence"=>$rowQuotation[SalesQuotationTable::C_APPENDIX_PRINT_PAGE]);
            }
            // log::write(print_r($selects,true));
        }
        if(!is_null($selects) && count($selects) > 0) {
            usort($selects, function($a, $b) {
                return $a['sequence'] - $b['sequence'];
            });
        }
        // log::write(print_r($selects,true));

        $logopath = Util::getCompanyLogoFile(PATH_PICTURE, $companyId);
        if ($logopath != ""){
            $logopath = "../web/picture/company-" . $companyId . "/" . $logopath;
        }
        $coverPath = "../web/sales_quotation_output/cover_page/";

        $coydesc = $rowCompany[CompanyTable::C_DESC];

        $coy_name = $rowCompany[CompanyTable::C_DESC];
        $coy_name = str_replace("Pte Ltd", "", $coy_name);
        $coy_name = str_replace("Sdn Bhd", "", $coy_name);
        $pdf->setCoyName($coy_name);

        // add a page
        $pdf->AddPage();
        $this->totalPages = 1;

        $contact_name = "";
        if($rowQuotation[SalesQuotationTable::C_PROSPECT]) {
            //Header
            $pdf = $this->printReportHeaderSalesQuotation($pdf, $logopath, $rowCompany[CompanyTable::C_DESC], $op, $rowQuotation,
                                                            $rowQuotation[SalesQuotationTable::C_PROSPECT_NAME], $rowQuotation[SalesQuotationTable::C_PROSPECT_CONTACT], $quotnumber);
            
            $contact_name = $rowQuotation[SalesQuotationTable::C_PROSPECT_CONTACT];
        } else {
            $rowCustomer        = $clsCustomer->getRecord($rowQuotation[SalesQuotationTable::C_CUSTOMER_ID]);
            $rowContact         = $clsContact->getRecord($rowQuotation[SalesQuotationTable::C_CONTACT_ID]);

            $contact_name = $rowContact[CustomerContactTable::C_NAME];
            
            //Header
            $pdf = $this->printReportHeaderSalesQuotation($pdf, $logopath, $rowCompany[CompanyTable::C_DESC], $op, $rowQuotation, 
                                                            $rowCustomer, $rowContact, $quotnumber);
        }
        // log::write("page header = ".$pdf->GetY());
        
        $columnSize = array(13.5, 92, 22, 17, 22, 8);

        $pdf->SetFont('helvetica', '', 11);
        $bottomHeight = $pdf->getPageHeight() - 40;
        $rowHeight = 6.409722;

        $header = "";
        $counter = 0;
        $subTotal = 0;
        $discPercentage = 0;
        $discTotal = 0;
        $gstPercentage = 0;
        $gstTotal = 0;
        $grandTotal = 0;

        $selectPage = 0;
        $totalAmountInvest = 0;
        
        $currency = $clsCurrency->getRecord($rowQuotation[SalesQuotationTable::C_CURRENCY])[CurrencyTable::C_REF];
        
        if(!is_null($selects) && count($selects) > 0) {
            $counterSelect = 0;
            foreach($selects as $select) {
                // log::write(print_r($select,true));
                switch($select['select']) {
                    case "issue":
                        $counterSelect++;
                        $estimated_height = $pdf->getNumLines(htmlspecialchars_decode($rowQuotation[SalesQuotationTable::C_ISSUE]), 175);
                        if((($estimated_height * $rowHeight) + $pdf->GetY()) > $bottomHeight){
                            $resStr = $this->getCutPrintStr($pdf, 175, $rowHeight, $bottomHeight, htmlspecialchars_decode($rowQuotation[SalesQuotationTable::C_ISSUE]));
                            // log::write(print_r($resStr,true));
                            $leftoverStr = $resStr[0];
                            $newpage = true;
                            if(trim($resStr[1]) == "")
                                $newpage=false;

                            if($newpage) {
                                //set font
                                $pdf->SetFont('helvetica', '', 10);

                                $pdf->MultiCell(175, 5, $resStr[0], "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                
                                // add a page
                                $pdf->AddPage();
                                $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);
                                $this->totalPages += 1;
                                $counter = 0;
                                
                                //set font
                                $pdf->SetFont('helvetica', '', 10);

                                $pdf->MultiCell(175, 5, $resStr[1], "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                            } else {
                                $leftoverStr = htmlspecialchars_decode($rowQuotation[SalesQuotationTable::C_ISSUE]);

                                //set font
                                $pdf->SetFont('helvetica', '', 10);

                                $pdf->MultiCell(175, 5, $leftoverStr, "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                            }
                        } else {
                            //set font
                            $pdf->SetFont('helvetica', '', 10);

                            $pdf->MultiCell(175, 5, htmlspecialchars_decode($rowQuotation[SalesQuotationTable::C_ISSUE]), "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                        }
                        // log::write("issue = ".$pdf->GetY());
                        break;
                    case "items":
                        $counterSelect++;
                        $clsItems       = new SalesQuotationItemsClass($this->db) ;
                        $clsDetail      = new SalesQuotationItemsDetailClass($this->db) ;
                        
                        $rowsItems      = $clsItems->getRecordByQuotationId($id);
                        if(!is_null($rowsItems) && count($rowsItems) > 0) {
                            $discType       = $rowsItems[0][SalesQuotationItemsTable::C_DISC_TYPE];
                            $discPercentage = $rowsItems[0][SalesQuotationItemsTable::C_DISC_PERCENTAGE];
                            $discTotal      = $rowsItems[0][SalesQuotationItemsTable::C_DISC];
                            $gstPercentage  = $rowsItems[0][SalesQuotationItemsTable::C_GST_PERCENTAGE];
                            $gstTotal       = $rowsItems[0][SalesQuotationItemsTable::C_GST];
                            $qty_total      = $rowsItems[0][SalesQuotationItemsTable::C_QTY_TOTAL];
                            $subTotal       = $rowsItems[0][SalesQuotationItemsTable::C_SUBTOTAL];
                            $grandTotal     = $rowsItems[0][SalesQuotationItemsTable::C_GRAND_TOTAL];

                            $totalAmountInvest = $grandTotal;

                            $rowsDetail     = $clsDetail->getRecordItemsDetail($id, $rowsItems[0][SalesQuotationItemsTable::C_ITEMS_ID]);                            

                            //Detail
                            if(!is_null($rowsDetail) && count($rowsDetail) > 0){
                                $first = true;                                
                                $totalAmount = 0;
                                $totalDiscount = 0;
                                $counter = 0;

                                // log::write("item createHeaderSalesQuotation " . $pdf->getY());
                                if($pdf->getY() > 240) {
                                    // add a page
                                    $pdf->AddPage();
                                    $pdf = $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);
                                    $this->totalPages += 1;
                                    $counter = 0;
                                }

                                $pdf = $this->createHeaderSalesQuotation($pdf, $columnSize, $rowHeight, $currency, $qty_total);
        
                                $count = 0;
                                $tempPhase = "";
                                $tempPhaseDesc = "";
                                $sectionSubTotal = 0;
                                foreach($rowsDetail as $rowDetail){
                                    
                                    if(trim($rowDetail[SalesQuotationItemsDetailTable::C_LINE_PHASE]) != ""){
                                        if($tempPhase == "") {
                                            $tempPhase = $rowDetail[SalesQuotationItemsDetailTable::C_LINE_PHASE];
                                            $tempPhaseDesc = $rowDetail[SalesQuotationItemsDetailTable::C_LINE_DESC];
                                        }

                                        if($tempPhase != $rowDetail[SalesQuotationItemsDetailTable::C_LINE_PHASE]) {
                                            $pdf = $this->createFooterSectionSalesQuotation($pdf, $columnSize, $rowHeight, $tempPhase, $tempPhaseDesc, $sectionSubTotal, $discTotal);

                                            $tempPhase = $rowDetail[SalesQuotationItemsDetailTable::C_LINE_PHASE];
                                            $tempPhaseDesc = $rowDetail[SalesQuotationItemsDetailTable::C_LINE_DESC];
                                        }

                                        $sectionSubTotal = 0;

                                        $pdf = $this->createHeaderSectionSalesQuotation($pdf, $columnSize, $rowHeight, $rowDetail[SalesQuotationItemsDetailTable::C_LINE_PHASE], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_DESC]);
                                        $counter = 0;
                                    } else {
                                        $sectionSubTotal += floatVal($rowDetail[SalesQuotationItemsDetailTable::C_LINE_AMOUNT]);
                                        $sectionSubTotal -= floatVal($rowDetail[SalesQuotationItemsDetailTable::C_LINE_DISC]);
    
                                        $counter++;
                                        if($rowQuotation[SalesQuotationTable::C_PROSPECT]) {
                                            $pdf = $this->processStringLineSalesQuotation($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency,  $this->currentPage,
                                                                                            $logopath, $rowCompany[CompanyTable::C_DESC], $op, $rowQuotation, $rowQuotation[SalesQuotationTable::C_PROSPECT_NAME], $rowQuotation[SalesQuotationTable::C_PROSPECT_CONTACT],
                                                                                            $counter, $rowDetail[SalesQuotationItemsDetailTable::C_LINE_NO], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_DESC], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_COMMENT], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_AMOUNT], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_DISC], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_DISC_DESC], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_UNIT_PRICE], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_QTY], $qty_total);
                                        } else {
                                            $rowCustomer        = $clsCustomer->getRecord($rowQuotation[SalesQuotationTable::C_CUSTOMER_ID]);
                                            $rowContact         = $clsContact->getRecord($rowQuotation[SalesQuotationTable::C_CONTACT_ID]);
                                            
                                            $pdf = $this->processStringLineSalesQuotation($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency,  $this->currentPage,
                                                                                            $logopath, $rowCompany[CompanyTable::C_DESC], $op, $rowQuotation, $rowCustomer, $rowContact,
                                                                                            $counter, $rowDetail[SalesQuotationItemsDetailTable::C_LINE_NO], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_DESC], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_COMMENT], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_AMOUNT], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_DISC], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_DISC_DESC], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_UNIT_PRICE], $rowDetail[SalesQuotationItemsDetailTable::C_LINE_QTY], $qty_total);
                                        }
                                    }
                                    $totalAmount += floatVal($rowDetail[SalesQuotationItemsDetailTable::C_LINE_AMOUNT]);
                                    $totalDiscount += floatVal($rowDetail[SalesQuotationItemsDetailTable::C_LINE_DISC]);
        
                                    $count++;
                                    // $first = false;
                                }                                
                                    
                                if($count == count($rowsDetail)) {
                                    $pdf = $this->createFooterSectionSalesQuotation($pdf, $columnSize, $rowHeight, $tempPhase, $tempPhaseDesc, $sectionSubTotal, $discTotal);
                                }

                            }
                        
                            $pdf = $this->printSubReportFooterSalesQuotation($pdf, $columnSize, $bottomHeight, $logopath, $coydesc, $op, $rowQuotation, $select['select'], $gstPercentage, $totalAmountInvest, $currency, $discType, $discPercentage, $discTotal);
                        }
                        // log::write("items = ".$pdf->GetY());
                        break;
                    case "maintenance":
                        $counterSelect++;
                        $clsMaintenance = new SalesQuotationMaintenanceClass($this->db) ;
                        $clsDetail      = new SalesQuotationMaintenanceDetailClass($this->db) ;
                        
                        $rowsMaintenance    = $clsMaintenance->getRecord($id);

                        if(!is_null($rowsMaintenance) && count($rowsMaintenance) > 0) {
                            $discType           = $rowsMaintenance[SalesQuotationMaintenanceTable::C_DISC_TYPE];
                            $discPercentage     = $rowsMaintenance[SalesQuotationMaintenanceTable::C_DISC_PERCENTAGE];
                            $discTotal          = $rowsMaintenance[SalesQuotationMaintenanceTable::C_DISC_TOTAL];
                            $gstPercentage      = $rowsMaintenance[SalesQuotationMaintenanceTable::C_GST_PERCENTAGE];
                            $gstTotal           = $rowsMaintenance[SalesQuotationMaintenanceTable::C_GST_TOTAL];
                            $maintenanceAmt     = $rowsMaintenance[SalesQuotationMaintenanceTable::C_GRAND_TOTAL];
                            
                            $totalAmountInvest = $maintenanceAmt;

                            $rowsDetail     = $clsDetail->getSalesQuotationMaintenance($rowsMaintenance[SalesQuotationMaintenanceTable::C_ID], $id);
                            
                            //Detail
                            if(!is_null($rowsDetail) && count($rowsDetail) > 0){
                                $first = true;                                
                                $totalAmount = 0;

                                $counter = 0;
                                // log::write("maintenance createHeaderSalesQuotation " . $pdf->getY());
                                if($pdf->getY() > 240) {
                                    // add a page
                                    $pdf->AddPage();
                                    $pdf = $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);
                                    $this->totalPages += 1;
                                    $counter = 0;
                                }
                                
                                $pdf = $this->createHeaderSalesQuotation($pdf, $columnSize, $rowHeight, $currency, 0);
        
                                foreach($rowsDetail as $rowDetail){                                    
                                    $counter++;
        
                                    if($rowQuotation[SalesQuotationTable::C_PROSPECT]) {
                                        $pdf = $this->processStringLineSalesQuotationMaintenance($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $this->currentPage,
                                                                                        $logopath, $rowCompany[CompanyTable::C_DESC], $op, $rowQuotation, $rowQuotation[SalesQuotationTable::C_PROSPECT_NAME], $rowQuotation[SalesQuotationTable::C_PROSPECT_CONTACT],
                                                                                        $counter, $rowDetail[SalesQuotationMaintenanceDetailTable::C_DESC], $rowDetail[SalesQuotationMaintenanceDetailTable::C_COMMENT], $rowDetail[SalesQuotationMaintenanceDetailTable::C_AMOUNT], $maintenanceAmt);
                                    } else {
                                        $rowCustomer        = $clsCustomer->getRecord($rowQuotation[SalesQuotationTable::C_CUSTOMER_ID]);
                                        $rowContact         = $clsContact->getRecord($rowQuotation[SalesQuotationTable::C_CONTACT_ID]);
                                        
                                        $pdf = $this->processStringLineSalesQuotationMaintenance($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $this->currentPage,
                                                                                        $logopath, $rowCompany[CompanyTable::C_DESC], $op, $rowQuotation, $rowCustomer, $rowContact,
                                                                                        $counter, $rowDetail[SalesQuotationMaintenanceDetailTable::C_DESC], $rowDetail[SalesQuotationMaintenanceDetailTable::C_COMMENT], $rowDetail[SalesQuotationMaintenanceDetailTable::C_AMOUNT], $maintenanceAmt);
                                    }
                                    
                                    $totalAmount += $rowDetail[SalesQuotationMaintenanceDetailTable::C_AMOUNT];
        
                                    // $first = false;
                                }
                            }
                            $pdf = $this->printSubReportFooterSalesQuotation($pdf, $columnSize, $bottomHeight, $logopath, $coydesc, $op, $rowQuotation, $select['select'], $gstPercentage, $totalAmountInvest, $currency, $discType, $discPercentage, $discTotal);
                        }
                        // log::write("maintenance = ".$pdf->GetY());
                        break;
                    case "project":
                        $counterSelect++;
                        $clsProject     = new SalesQuotationProjectPlanClass($this->db) ;
                        $clsDetail      = new SalesQuotationProjectPlanDetailClass($this->db) ;
                        
                        $rowsProject    = $clsProject->getRecord($id);

                        if(!is_null($rowsProject) && count($rowsProject) > 0) {
                            $projectCurr    = $rowsProject[SalesQuotationProjectPlanTable::C_CURRENCY];
                            $projectAmt     = $rowsProject[SalesQuotationProjectPlanTable::C_AMOUNT];
                            
                            $totalAmountInvest = $projectAmt;

                            $rowsDetail     = $clsDetail->getSalesQuotationProjectPlan($rowsProject[SalesQuotationProjectPlanTable::C_ID], $id);
                            
                            //Detail
                            if(!is_null($rowsDetail) && count($rowsDetail) > 0){
                                $first = true;                                
                                $totalDays = 0;

                                $counter = 0;
                                // log::write("project createHeaderSalesQuotation " . $pdf->getY());
                                if($pdf->getY() > 240) {
                                    // add a page
                                    $pdf->AddPage();
                                    $pdf = $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);
                                    $this->totalPages += 1;
                                    $counter = 0;
                                }

                                $this->createHeaderSalesQuotationProjectPlan($pdf, $columnSize);
        
                                foreach($rowsDetail as $rowDetail){                                    
                                    $counter++;
                                    
                                    $totalDays += $rowDetail[SalesQuotationProjectPlanDetailTable::C_DAYS];
        
                                    if($rowQuotation[SalesQuotationTable::C_PROSPECT]) {
                                        $pdf = $this->processStringLineSalesQuotationProjectPlan($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $this->currentPage,
                                                                                        $logopath, $rowCompany[CompanyTable::C_DESC], $op, $rowQuotation, $rowQuotation[SalesQuotationTable::C_PROSPECT_NAME], $rowQuotation[SalesQuotationTable::C_PROSPECT_CONTACT],
                                                                                        $counter, $rowDetail[SalesQuotationProjectPlanDetailTable::C_PHASE], $rowDetail[SalesQuotationProjectPlanDetailTable::C_DESC], "", $rowDetail[SalesQuotationProjectPlanDetailTable::C_DAYS], $totalDays, $projectAmt);
                                    } else {
                                        $rowCustomer        = $clsCustomer->getRecord($rowQuotation[SalesQuotationTable::C_CUSTOMER_ID]);
                                        $rowContact         = $clsContact->getRecord($rowQuotation[SalesQuotationTable::C_CONTACT_ID]);
                                        
                                        $pdf = $this->processStringLineSalesQuotationProjectPlan($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $this->currentPage,
                                                                                        $logopath, $rowCompany[CompanyTable::C_DESC], $op, $rowQuotation, $rowCustomer, $rowContact,
                                                                                        $counter, $rowDetail[SalesQuotationProjectPlanDetailTable::C_PHASE], $rowDetail[SalesQuotationProjectPlanDetailTable::C_DESC], "", $rowDetail[SalesQuotationProjectPlanDetailTable::C_DAYS], $totalDays, $projectAmt);
                                    }
        
                                    // $first = false;
                                }
                            }
                            $pdf = $this->printSubReportFooterSalesQuotation($pdf, $columnSize, $bottomHeight, $logopath, $coydesc, $op, $rowQuotation, $select['select'], 0, $totalDays, "");
                        }
                        // log::write("project = ".$pdf->GetY());
                        break;
                    case "cover":
                        $counterSelect++;
                        $clsCover = new SalesQuotationCoverClass($this->db);

                        $rowsCover = $clsCover->getRecordByQuotationId($id);
                        if(!is_null($rowsCover) && count($rowsCover) > 0) {
                            $counter  = 0;
                            foreach($rowsCover as $rowCover) {
                                $counter++;
                                // set font
                                $pdf->SetFont('helvetica', '', 10);

                                if(trim($rowCover[SalesQuotationCoverTable::C_DESC]) == "") {
                                } else {
                                    /* $estimated_height = $pdf->getStringHeight(175, htmlspecialchars_decode($rowCover[SalesQuotationCoverTable::C_DESC]));
                                    // $numLines = $pdf->getNumLines(htmlspecialchars_decode($rowQuotation[SalesQuotationTable::C_FOOTER]), 175);
                                    if(($estimated_height + $pdf->getY()) > $bottomHeight) {
                                    // if((($numLines * $rowHeight) + $pdf->getY()) > $bottomHeight) {
                                        $resStr = $this->getCutPrintStr($pdf, 175, $rowHeight, $bottomHeight, htmlspecialchars_decode($rowCover[SalesQuotationCoverTable::C_DESC]));
                                        // log::write(print_r($resStr,true));
                                        $leftoverStr = $resStr[0];
                                        $newpage = true;
                                        if(trim($resStr[1]) == "")
                                            $newpage=false;
            
                                        if($newpage) {
                                            //set font
                                            $pdf->SetFont('helvetica', '', 11);

                                            $arr_cover = explode("\n", $resStr[0]);

                                            foreach ($arr_cover as $str) {
                                                // log::write($str);

                                                if(strpos($str, "TOTAL INVESTMENT") > 0) {
                                                    $pdf->SetFont('helvetica', 'B', 11);
                                                    $pdf->MultiCell(175, 1, htmlspecialchars_decode($str), "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                                } else {
                                                    if($str == "") {
                                                        $pdf->MultiCell(1, 3, '', '', 'L', 1, 1, '', '', true);
                                                    } else {
                                                        $pdf->SetFont('helvetica', '', 11);
                                                        $pdf->MultiCell(175, 1, htmlspecialchars_decode($str), "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                                    }
                                                }
                                            }

                                            // add a page
                                            $pdf->AddPage();
                                            $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);
                                            $this->totalPages += 1;
                                            
                                            //set font
                                            $pdf->SetFont('helvetica', '', 11);                                           

                                            $arr_cover = explode("\n", $resStr[1]);

                                            foreach ($arr_cover as $str) {
                                                // log::write($str);

                                                if(strpos($str, "TOTAL INVESTMENT") > 0) {
                                                    $pdf->SetFont('helvetica', 'B', 11);
                                                    $pdf->MultiCell(175, 1, htmlspecialchars_decode($str), "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                                } else {
                                                    if($str == "") {
                                                        $pdf->MultiCell(1, 3, '', '', 'L', 1, 1, '', '', true);
                                                    } else {
                                                        $pdf->SetFont('helvetica', '', 11);
                                                        $pdf->MultiCell(175, 1, htmlspecialchars_decode($str), "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                                    }
                                                }
                                            }
                                        } else {
                                            //set font
                                            $pdf->SetFont('helvetica', '', 11);

                                            $arr_cover = explode("\n", $resStr[0]);

                                            foreach ($arr_cover as $str) {
                                                // log::write($str);

                                                if(strpos($str, "TOTAL INVESTMENT") > 0) {
                                                    $pdf->SetFont('helvetica', 'B', 11);
                                                    $pdf->MultiCell(175, 1, htmlspecialchars_decode($str), "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                                } else {
                                                    if($str == "") {
                                                        $pdf->MultiCell(1, 3, '', '', 'L', 1, 1, '', '', true);
                                                    } else {
                                                        $pdf->SetFont('helvetica', '', 11);
                                                        $pdf->MultiCell(175, 1, htmlspecialchars_decode($str), "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                                    }
                                                }
                                            }
                                        }
                                    } else {
                                        $leftoverStr = htmlspecialchars_decode($rowCover[SalesQuotationCoverTable::C_DESC]);
                                        //set font
                                        $pdf->SetFont('helvetica', '', 11);

                                        $arr_cover = explode("\n", $leftoverStr);

                                        foreach ($arr_cover as $str) {
                                            // log::write($str);

                                            if(strpos($str, "TOTAL INVESTMENT") > 0) {
                                                $pdf->SetFont('helvetica', 'B', 11);
                                                $pdf->MultiCell(175, 1, htmlspecialchars_decode($str), "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                            } else {
                                                if($str == "") {
                                                    $pdf->MultiCell(1, 3, '', '', 'L', 1, 1, '', '', true);
                                                } else {
                                                    $pdf->SetFont('helvetica', '', 11);
                                                    $pdf->MultiCell(175, 1, htmlspecialchars_decode($str), "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                                }
                                            }
                                        }
                                    }
                                    
                                    //space
                                    $pdf->MultiCell(1, 2, '', '', 'C', 1, 1, '', '', true); */

                                    $arr_cover = explode("\n", $rowCover[SalesQuotationCoverTable::C_DESC]);
                                    // log::write($arr_cover);
                                    foreach ($arr_cover as $str) {
                                        // log::write($str);
                                        
                                        // $estimate_height = $pdf->getStringHeight(175, htmlspecialchars_decode($str));
                                        // if(($estimate_height + $pdf->getY()) > $bottomHeight) {
                                        //     //add page
                                        //     $pdf->AddPage();
                                        //     $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);
                                        //     $this->totalPages += 1;
                                        // }

                                        if(strpos($str, "TOTAL INVESTMENT") > 0) {
                                            $pdf->SetFont('helvetica', 'B', 10);
                                            $pdf->MultiCell(175, 1, htmlspecialchars_decode($str), "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                        } else {
                                            if($str == "") {
                                                $pdf->MultiCell(1, 3, '', '', 'L', 1, 1, '', '', true);
                                            } else {
                                                $pdf->SetFont('helvetica', '', 10);
                                                $pdf->MultiCell(175, 1, htmlspecialchars_decode($str), "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                            }
                                        }
                                        // log::write(htmlspecialchars_decode($str));
                                        // log::write("cover = ".$pdf->GetY());
                                    }

                                    // $header = htmlspecialchars_decode($rowCover[SalesQuotationCoverTable::C_DESC]) ."\n";
                                    // $pdf->MultiCell(175, 5, $header, "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);

                                    // $numLines = $pdf->getNumLines(htmlspecialchars_decode($rowCover[SalesQuotationCoverTable::C_DESC]), 175);
                                    // if($numLines == ($rowCover[SalesQuotationCoverTable::C_PAGE_LINE]-1) || $numLines == ($rowCover[SalesQuotationCoverTable::C_PAGE_LINE])) {
                                    //     //add page
                                    //     $pdf->AddPage();
                                    //     $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);
                                    //     $this->totalPages += 1;
                                    // }
                                }
                            }
                        } else {
                            $header = "Dear " .$contact_name. ",\n\n". "Thank you for the invitation to submit a quotation. As per our understanding, below are the items required to support the proposed business solution:" ."\n\n";                            
                            $pdf->MultiCell(175, 5, $header, "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                        }

                        $totalAmountInvest = $rowQuotation[SalesQuotationTable::C_ITEMS_TOTAL];
                        // log::write("cover = ".$pdf->GetY());
                        break;
                    case "footer":
                        $counterSelect++;
                        // $estimated_height = $pdf->getStringHeight(175, htmlspecialchars_decode($rowQuotation[SalesQuotationTable::C_FOOTER]));
                        $numLines = $pdf->getNumLines(htmlspecialchars_decode($rowQuotation[SalesQuotationTable::C_FOOTER]), 175);
                        if((($numLines * $rowHeight) + $pdf->getY()) > $bottomHeight) {
                            $resStr = $this->getCutPrintStr($pdf, 175, $rowHeight, $bottomHeight, htmlspecialchars_decode($rowQuotation[SalesQuotationTable::C_FOOTER]));
                            $leftoverStr = $resStr[0];
                            $newpage = true;

                            if($newpage) {
                                if((($numLines * $rowHeight) + $pdf->getY()) > 275) {                                    
                                //     // add a page
                                    $pdf->AddPage();
                                    $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);
                                    $this->totalPages += 1;
                                }

                                //set font
                                $pdf->SetFont('helvetica', '', 10);

                                $pdf->MultiCell(175, 5, $resStr[0], "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                                                
                                if(trim($resStr[1]) != "") {
                                    if((($numLines * $rowHeight) + $pdf->getY()) > $bottomHeight) {                                    
                                        // add a page
                                        $pdf->AddPage();
                                        $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);
                                        $this->totalPages += 1;
                                    }
                                    
                                    //set font
                                    $pdf->SetFont('helvetica', '', 10);

                                    $pdf->MultiCell(175, 5, $resStr[1], "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                                }                                
                            } else {
                                //set font
                                $pdf->SetFont('helvetica', '', 10);

                                $pdf->MultiCell(175, 5, $resStr[0], "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                            }
                        } else {
                            $leftoverStr = htmlspecialchars_decode($rowQuotation[SalesQuotationTable::C_FOOTER]);
                            //set font
                            $pdf->SetFont('helvetica', '', 10);

                            $pdf->MultiCell(175, 5, $leftoverStr, "", 'L', 1, 1, PDF_MARGIN_LEFT+5, '', true);
                        }
                        
                        //space
                        $pdf->MultiCell(1, 2, '', '', 'C', 1, 1, '', '', true);
                        // log::write("footer = ".$pdf->GetY());
                        break;
                    case "appendix":
                        $counterSelect++;
                        if($select['sequence'] != 1) {
                            // add a page
                            $pdf->AddPage();
                            $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);
                            // $this->totalPages += 1;
                        }
        
                        //Appendix
                        $pdf = $this->printSalesQuotationAppendix($pdf, $rowHeight, $bottomHeight, $logopath, $coydesc, $rowQuotation[SalesQuotationTable::C_ID]);
                        $add_appendix = trim($rowQuotation[SalesQuotationTable::C_ADDITIONAL_APPENDIX]) == "" ? "" : " + ". trim($rowQuotation[SalesQuotationTable::C_ADDITIONAL_APPENDIX]);
                        $this->appendixPagesDesc = " + Appendix A". $add_appendix;
                        // log::write("appendix = ".$pdf->GetY());
                        break;
                }

                $this->currentPage = $pdf->getPage();
            }
        }

        // set font
        $pdf->SetFont('helvetica', '', 10);
        //print the total no of pages on the first page
        $pdf->setPage(1);
        $pdf->MultiCell(50, 5, $this->totalPages . $this->appendixPagesDesc, 0, 'L', 1, 1, $pdf->getPageWidth()-55, $this->totalPagesY, true);
        $pdf->Ln(1);
        // move pointer to last page
        $pdf->lastPage();

        // ---------------------------------------------------------
        
        //Close and output PDF document
        if ($outputType == 'save'){
            if ($id != 0){
                $path = PATH_SALES_QUOTATION_OUTPUT . $id;
                if(!file_exists($path)){
                    mkdir($path, 1777);
                }

                $path = PATH_SALES_QUOTATION_OUTPUT . $id. "/" .$pdf_filename;
                if(file_exists($path)){
                    unlink($path);
                }

                $pdf->Output($path, 'F');
            } else {
                $path = PATH_SALES_QUOTATION_OUTPUT . $id;
                if(!file_exists($path)){
                    mkdir($path, 1777);
                }

                $path = PATH_SALES_QUOTATION_OUTPUT . $id. "/" .$pdf_filename;
                if(file_exists($path)){
                    unlink($path);
                }

                $pdf->Output($path, 'F');
            }
        } else {
            $pdf->Output($pdf_filename, 'I');
        }

        //============================================================+
        // END OF FILE
        //============================================================+
    }

    private function printReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op, $quotation, $customer, $contact, $quotnumber) {
        $clsUser        = new UserClass($this->db) ;

        $customer_name = "";
        $customer_address = "";
        $contact_name = "";
        $fax_number = "";
        $box_start = 0;
        $box_height = 0;
        if($quotation[SalesQuotationTable::C_PROSPECT]) {
            $customer_name = $customer;
            $contact_name = $contact;
            $fax_number = "";
            // $box_height = 33;
        } else {
            $customer_name = $customer[CustomerTable::C_NAME];
            // $company_address = $customer[CustomerTable::C_ADDRESS_1]. " 2 " .$customer[CustomerTable::C_ADDRESS_2]. " 3 " .$customer[CustomerTable::C_ADDRESS_3]. " 4 " .$customer[CustomerTable::C_ADDRESS_4] ;
            // log::write($company_address);
            $customer_address = "";
            $customer_address_count = 1;
            if (trim($customer[CustomerTable::C_ADDRESS_1]) != '') {
                $customer_address .= trim($customer[CustomerTable::C_ADDRESS_1]);
                $customer_address_count++;
            }
            if (trim($customer[CustomerTable::C_ADDRESS_2]) != '') {
                $customer_address .= "\n" . trim($customer[CustomerTable::C_ADDRESS_2]);
                $customer_address_count++;
            }
            if (trim($customer[CustomerTable::C_ADDRESS_3]) != '') {
                $customer_address .= "\n" . trim($customer[CustomerTable::C_ADDRESS_3]);
                $customer_address_count++;
            }
            if (trim($customer[CustomerTable::C_ADDRESS_4]) != '') {
                $customer_address .= "\n" . trim($customer[CustomerTable::C_ADDRESS_4]);
                $customer_address_count++;
            }

            $contact_name = $contact[CustomerContactTable::C_NAME];
            $add_contact = trim($quotation[SalesQuotationTable::C_ADDITIONAL_CONTACT]) != "" ? ", ". $quotation[SalesQuotationTable::C_ADDITIONAL_CONTACT] : "";
            $contact_name = $contact_name . $add_contact;
            $fax_number = $customer[CustomerTable::C_FAX];
            // $box_height = 50;

            // if(trim($customer_address) != "") {
            //     $company = trim($company_name). "\n" .trim($customer_address) ;
            // }
        }

        $issuedate = date_create($quotation[SalesQuotationTable::C_ISSUE_DATE])->format('Y-m-d H:i:s');
        if($issuedate == NULL_DATE)
            $issuedate = date_create('now')->format('d F Y');
        else
            $issuedate = date_create($quotation[SalesQuotationTable::C_ISSUE_DATE])->format('d F Y');
        
        $revisedate = date_create($quotation[SalesQuotationTable::C_CUSTOMER_REVISE_DATE])->format('Y-m-d H:i:s');
        if($revisedate == NULL_DATE)
            $revisedate = "";
        else {
            $revisedate = date_create('now')->format('d F Y');
        }
        
        $preparer_name = $clsUser->getRecord($quotation[SalesQuotationTable::C_CREATE_BY])[UserTable::C_FULL_NAME];

        $y = $pdf->getY();

        $picHeight = 25;
        if($logopath != "")
            $pdf->Image($logopath, PDF_MARGIN_LEFT+10, 10, 0, $picHeight);
        
        $y += $picHeight;
        // $box_height += $picHeight;
        $pdf->SetY($y);

        // set font
        $pdf->SetFont('helvetica', 'B', 16);

        if(strpos($coydesc, "Sdn Bhd") > 0) {
            $pdf->MultiCell(125, 5, $coydesc, 0, 'C', 1, 1, $pdf->getPageWidth()-135, 10, true);
        } else {
            if(strlen($coydesc) > 22)
                $pdf->MultiCell(100, 5, $coydesc, 0, 'C', 1, 1, $pdf->getPageWidth()-125, 10, true);
            else
                $pdf->MultiCell(100, 5, $coydesc, 0, 'C', 1, 1, $pdf->getPageWidth()-115, 10, true);
        }
        $box_height += 10;
        
        // set font
        $pdf->SetFont('helvetica', 'B', 10);
        $companyAddress = "";
        if (trim($op['contact']['address1']) != '') $companyAddress .= trim($op['contact']['address1']);
        if(strpos($coydesc, "Sdn Bhd") > 0) {
            if (trim($op['contact']['address2']) != '') $companyAddress .= "\n" . trim($op['contact']['address2']);
        } else {
            if (trim($op['contact']['address2']) != '') $companyAddress .= " " . trim($op['contact']['address2']);
        }
        if (trim($op['contact']['address3']) != '') $companyAddress .= "\n" . trim($op['contact']['address3']);
        if (trim($op['contact']['address4']) != '') $companyAddress .= " " . trim($op['contact']['address4']);
        if (trim($op['contact']['address5']) != '') $companyAddress .= "\n" . trim($op['contact']['address5']);

        // if (trim($op['contact']['telno']) != '') $companyAddress .= "\nTel: " . trim($op['contact']['telno']);

        if(isset($op['iras']['taxid'])) {
            if (trim($op['iras']['taxid']) != '') $companyAddress .= "\n\nTel: " . trim($op['contact']['telno']) . "       Co. Reg: " . trim($op['iras']['taxid']);
        }
        
        if(strpos($coydesc, "Sdn Bhd") > 0) {
            $pdf->MultiCell(125, 5, $companyAddress, 0, 'C', 1, 1, $pdf->getPageWidth()-135, 18, true);
        } else {
        if(strlen($coydesc) > 22)
            $pdf->MultiCell(100, 5, $companyAddress, 0, 'C', 1, 1, $pdf->getPageWidth()-125, 18, true);
        else
            $pdf->MultiCell(100, 5, $companyAddress, 0, 'C', 1, 1, $pdf->getPageWidth()-115, 18, true);
        }

        $numLines = $pdf->getNumLines($companyAddress, 100);
        $y += 10;
        $box_start += $y + 8;

        // set font
        $pdf->SetFont('helvetica', 'B', 13);
        // $pdf->MultiCell(($pdf->getPageWidth() - PDF_MARGIN_LEFT - PDF_MARGIN_RIGHT), 5, 'Service Confirmation: ' .$quotation[SalesQuotationTable::C_NUMBER], 0, 'C', 1, 1, PDF_MARGIN_LEFT, $y, true);
        $pdf->MultiCell(($pdf->getPageWidth() - PDF_MARGIN_LEFT - PDF_MARGIN_RIGHT), 5, 'Service Quotation: ' .$quotnumber, 0, 'C', 1, 1, PDF_MARGIN_LEFT, $y, true);

        // set font
        $pdf->SetFont('helvetica', 'B', 10);
        $pdf->MultiCell(40, 5, 'Issue Date:', 0, 'L', 1, 0, PDF_MARGIN_LEFT+5, $y+10, true);
        $pdf->MultiCell(40, 5, $issuedate, 0, 'L', 1, 0, PDF_MARGIN_LEFT+40, $y+10, true);
        // set font
        $pdf->SetFont('helvetica', 'B', 10);
        $pdf->MultiCell(40, 5, 'Revise Date:', 0, 'L', 1, 0, $pdf->getPageWidth()-90, $y+10, true);
        $pdf->MultiCell(40, 5,  $revisedate, 0, 'L', 1, 1, $pdf->getPageWidth()-60, $y+10, true);
        $y += 10;
        $box_height += 10;

        // set font
        $pdf->SetFont('helvetica', 'B', 10);
        $pdf->MultiCell(40, 5, 'Company:', 0, 'L', 1, 1, PDF_MARGIN_LEFT+5, $y+7, true);
        $pdf->MultiCell(130, 5, $customer_name, 0, 'L', 1, 1, PDF_MARGIN_LEFT+40, $y+7, true);
        $y += 5;
        $box_height += 7;

        if($customer_address != "") {
            // set font
            $pdf->SetFont('helvetica', '', 10);
            $numLines = $pdf->getNumLines($customer_address, 150);
            $pdf->MultiCell(130, (3 * $customer_address_count), '' .$customer_address, 0, 'L', 1, 1, PDF_MARGIN_LEFT+40, $y+7, true);
            $y += (3 * $customer_address_count);
            $box_height += (($customer_address_count-2) * $customer_address_count);

            // set font
            $pdf->SetFont('helvetica', 'B', 10);
            $pdf->MultiCell(40, 5, 'Contact Person:', 0, 'L', 1, 0, PDF_MARGIN_LEFT+5, $y+(3 * $customer_address_count), true);
            $pdf->MultiCell(90, 5, $contact_name, 0, 'L', 1, 1, PDF_MARGIN_LEFT+40, $y+(3 * $customer_address_count), true);
            $y += (3 * $customer_address_count);
            // $box_height += 7;
        } else {
            $pdf->MultiCell(130, 5, '' .$customer_address, 0, 'L', 1, 1, PDF_MARGIN_LEFT+40, $y+7, true);
            $y += 7;
            // $box_height += 7;

            // set font
            $pdf->SetFont('helvetica', 'B', 10);
            $pdf->MultiCell(40, 5, 'Contact Person:', 0, 'L', 1, 0, PDF_MARGIN_LEFT+5, $y+7, true);
            $pdf->MultiCell(90, 5, $contact_name, 0, 'L', 1, 1, PDF_MARGIN_LEFT+40, $y+7, true);
            $y += 7;
            // $box_height += 7;
        }

        // set font
        $pdf->SetFont('helvetica', 'B', 10);
        $pdf->MultiCell(50, 5, 'Telephone Number:', 0, 'L', 1, 0, PDF_MARGIN_LEFT+5, $y+7, true);
        // set font
        $pdf->SetFont('helvetica', '', 10);
        $pdf->MultiCell(50, 5, $quotation[SalesQuotationTable::C_CONTACT_TELEPHONE], 0, 'L', 1, 0, PDF_MARGIN_LEFT+40, $y+7, true);
        // set font
        $pdf->SetFont('helvetica', 'B', 10);
        $pdf->MultiCell(50, 5, 'Fax Number:', 0, 'L', 1, 0, $pdf->getPageWidth()-90, $y+7, true);
        // set font
        $pdf->SetFont('helvetica', '', 10);
        $pdf->MultiCell(40, 5, $fax_number, 0, 'L', 1, 1, $pdf->getPageWidth()-60, $y+7, true);
        $y += 7;
        $box_height += 7;

        // set font
        $pdf->SetFont('helvetica', 'B', 10);
        $pdf->MultiCell(40, 5, 'From:', 0, 'L', 1, 0, PDF_MARGIN_LEFT+5, $y+7, true);
        // set font
        $pdf->SetFont('helvetica', '', 10);
        $pdf->MultiCell(40, 5, $preparer_name, 0, 'L', 1, 1, PDF_MARGIN_LEFT+40, $y+7, true);
        // set font
        $pdf->SetFont('helvetica', 'B', 10);
        $pdf->MultiCell(50, 5, 'Total No of Pages:', 0, 'L', 1, 0, $pdf->getPageWidth()-90, $y+7, true);
        // set font
        $pdf->SetFont('helvetica', '', 10);
        // $pdf->MultiCell(40, 5, $pdf->getNumPages() . " + 1 Appendix", 0, 'L', 1, 1, $pdf->getPageWidth()-50, $y+7, true);
        $pdf->MultiCell(40, 5, "", 0, 'L', 1, 1, $pdf->getPageWidth()-60, $y+7, true);
        $this->totalPagesY = $y+7;
        $y += 10;
        $box_height += 10;
        
        // set font
        $pdf->SetFont('helvetica', '', 10);

        // set line style
        $pdf->SetLineStyle(array("width" => 0.5, "cap" => "butt", "join" => "miter", "dash" => 0, "color" => array(0, 0, 0)));

        // set rounded rectangle
        $pdf->RoundedRect($pdf->getX(), $box_start, ($pdf->getPageWidth() - PDF_MARGIN_LEFT - PDF_MARGIN_RIGHT), $box_height, 3.5, "1111");

        $y += 7;
        $pdf->SetY($y);

        return $pdf;
    }

    private function printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op) {
        $y = $pdf->getY();

        $picHeight = 15;
        if($op[CompanyOptions::C_SETTING][CompanyOptions::C_SET_CODE] == "AOP")
            $picHeight = 10;
        
        if($logopath != "")
            $pdf->Image($logopath, PDF_MARGIN_LEFT+10, 10, 0, $picHeight);
        
        $y += $picHeight;
        $pdf->SetY($y);

        // set font
        $pdf->SetFont('helvetica', 'BI', 14);
        $pdf->MultiCell(100, 5, $coydesc, 0, 'C', 1, 1, $pdf->getPageWidth()-150, 12, true);
        
        $pdf->setY($y);
        
        $pdf->Ln(5);
        // log::write("sub header = ".$pdf->GetY());
        return $pdf;
    }

    private function printSubReportFooterSalesQuotation($pdf, $columnSize, $bottomHeight, $logopath, $coydesc, $op, $quotation, $selectType, $gstPercentage, $totalAmountInvest, $currency, $discType='', $discPercentage=0, $discountTotal=0) {
        if(($pdf->getPageHeight() - $pdf->getY()) < 55){
            // add a page
            $pdf->AddPage();
            $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);
            $this->totalPages += 1;
        }

        //set font
        $pdf->SetFont('helvetica', 'B', 10);

        if($discountTotal != 0) {
            $pdf->MultiCell($columnSize[0], 1, "", "", 'L', 1, 0, PDF_MARGIN_LEFT+9, '', true);
            if($discPercentage != 0) {
                $pdf->MultiCell($columnSize[1]+$columnSize[2]+$columnSize[3], 1, "Discount ".number_format($discPercentage, 0)."%", "", 'L', 1, 0, PDF_MARGIN_LEFT+5+$columnSize[0], '', true);
            } else {                
                $pdf->MultiCell($columnSize[1]+$columnSize[2]+$columnSize[3], 1, "Discount ", "", 'L', 1, 0, PDF_MARGIN_LEFT+5+$columnSize[0], '', true);
            }
            $pdf->MultiCell($columnSize[4]-1, 1, "(".number_format($discountTotal, 2).")", "", 'R', 1, 0, PDF_MARGIN_LEFT+7+$columnSize[0]+$columnSize[1]+$columnSize[2]+$columnSize[3], '', true);
            $pdf->MultiCell($columnSize[5], 1, "", "", 'L', 1, 1, '', '', true);
            //space
            $pdf->MultiCell(1, 1, '', '', 'C', 1, 1, '', '', true);
        }
        //space
        $pdf->MultiCell(1, 4, '', '', 'C', 1, 1, '', '', true);

        $pdf->MultiCell($columnSize[0], 15, "\n", "", 'C', 1, 0, PDF_MARGIN_LEFT+5, '', true, 0, false, true, 0, "M");  

        switch($selectType) {
            case "items":
            case "maintenance":
                if($gstPercentage == 0) {
                    $pdf->MultiCell($columnSize[1]+$columnSize[2], 15, "\nTotal Investment Amount (before GST)", "TB", 'L', 1, 0, '', '', true, 0, false, true, 0, "M");
                } else {
                    $pdf->MultiCell($columnSize[1]+$columnSize[2], 15, "\nTotal Investment Amount", "", 'L', 1, 0, '', '', true, 0, false, true, 0, "M");
                }
                $pdf->MultiCell($columnSize[3]+$columnSize[4], 15, "\n".$currency."   ".number_format($totalAmountInvest, 2), "", 'R', 1, 0, '', '', true, 0, false, true, 0, "M");
            break;
            case "project":
                $pdf->MultiCell($columnSize[1]+$columnSize[2], 15, "\nTotal No. of Days", "", 'L', 1, 0, '', '', true, 0, false, true, 0, "M");
                $pdf->MultiCell($columnSize[3]+$columnSize[4], 15, "\n ".number_format($totalAmountInvest, 2), "", 'R', 1, 0, '', '', true, 0, false, true, 0, "M");
            break;
            default:
                $pdf->MultiCell($columnSize[1]+$columnSize[2], 15, "\nTotal Investment Amount", "", 'L', 1, 0, '', '', true, 0, false, true, 0, "M");
                $pdf->MultiCell($columnSize[3]+$columnSize[4], 15, "\n".$currency."   ".number_format($totalAmountInvest, 2), "", 'R', 1, 0, '', '', true, 0, false, true, 0, "M");
            break;
        }
        $pdf->MultiCell($columnSize[5], 15, "\n", "", 'C', 1, 1, '', '', true, 0, false, true, 0, "M");
        $pdf->MultiCell(1, 1, '', '', 'C', 1, 1, '', '', true);
        
        // set rounded rectangle
        $pdf->RoundedRect($pdf->getX()+5, ($pdf->getY()-17), ($pdf->getPageWidth() - PDF_MARGIN_LEFT - PDF_MARGIN_RIGHT) -5, 15, 3.5, "1111");

        return $pdf;
    }

    private function createHeaderSectionSalesQuotation($pdf, $columnSize, $rowHeight, $sectionPhase, $sectionDesc){
        // set font
        $pdf->SetFont('helvetica', 'B', 10);

        $border = "";

        //space
        $pdf->MultiCell(1, 2, '', '', 'C', 1, 1, '', '', true);
        
        // $currency = trim($currency);
        $pdf->MultiCell($columnSize[0], 2, $sectionPhase, $border, 'L', 1, 0, PDF_MARGIN_LEFT+9, '', true);
        $pdf->MultiCell($columnSize[1]+$columnSize[2]+$columnSize[3]+$columnSize[4]+$columnSize[5], 2, $sectionDesc, $border, 'L', 1, 1, PDF_MARGIN_LEFT+5+$columnSize[0], '', true);
        
        //space
        // $pdf->MultiCell(1, 2, '', '', 'C', 1, 1, '', '', true);

        return $pdf;
    }

    private function createFooterSectionSalesQuotation($pdf, $columnSize, $rowHeight, $sectionPhase, $sectionDesc, $sectionSubTotal, $discountTotal){
        // set font
        $pdf->SetFont('helvetica', 'B', 10);

        $border = "";

        //space
        $pdf->MultiCell(1, 2, '', '', 'C', 1, 1, 'B', '', true);
        
        // $pdf->MultiCell($columnSize[0], 1, "", $border, 'L', 1, 0, PDF_MARGIN_LEFT+9, '', true);
        // $pdf->MultiCell($columnSize[1]+$columnSize[2]+$columnSize[3], 2, "" . "", $border, 'L', 1, 0, PDF_MARGIN_LEFT+5+$columnSize[0], '', true);
        // $pdf->MultiCell($columnSize[4]-3, 1, "", "B", 'R', 1, 0, PDF_MARGIN_LEFT+8+$columnSize[0]+$columnSize[1]+$columnSize[2]+$columnSize[3], '', true);
        // $pdf->MultiCell($columnSize[5], 1, "", $border, 'L', 1, 1, '', '', true);
        
        $pdf->MultiCell($columnSize[0], 2, "", $border, 'L', 1, 0, PDF_MARGIN_LEFT+9, '', true);
        $pdf->MultiCell($columnSize[1]+$columnSize[2]+$columnSize[3], 2, "Subtotal " . $sectionDesc, $border, 'L', 1, 0, PDF_MARGIN_LEFT+5+$columnSize[0], '', true);
        $pdf->MultiCell($columnSize[4]-2, 2, number_format($sectionSubTotal, 2), "T", 'R', 1, 0, PDF_MARGIN_LEFT+7+$columnSize[0]+$columnSize[1]+$columnSize[2]+$columnSize[3], '', true);
        $pdf->MultiCell($columnSize[5], 2, "", $border, 'L', 1, 1, '', '', true);
        
        if($discountTotal == 0) {
            //space
            $pdf->MultiCell(1, 5, '', '', 'C', 1, 1, '', '', true);
        }

        return $pdf;
    }

    private function createHeaderSalesQuotation($pdf, $columnSize, $rowHeight, $currency, $qty_total){
        // log::write(print_r($currency,true));
        // set font
        $pdf->SetFont('helvetica', 'UB', 10);

        // set line style
        $pdf->SetLineStyle(array("width" => 0, "cap" => "", "join" => "", "dash" => 0, "color" => array(0, 0, 0)));

        $border = "";
        
        // $currency = trim($currency);
        $pdf->MultiCell($columnSize[0], 2, 'S/No', $border, 'L', 1, 0, PDF_MARGIN_LEFT+7, '', true);
        $pdf->MultiCell($columnSize[1], 2, 'Description', $border, 'L', 1, 0, PDF_MARGIN_LEFT+5+$columnSize[0], '', true);
        if($qty_total != 0) {
            $pdf->MultiCell($columnSize[2], 2, 'Unit Price', $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[3], 2, 'Qty', $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[4], 2, 'Total ('.$currency.')', $border, 'R', 1, 0, '', '', true);
        } else {
            // set font
            $pdf->SetFont('helvetica', 'B', 10);
            $pdf->MultiCell($columnSize[2], 2, '', $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[3], 2, '', $border, 'R', 1, 0, '', '', true);

            // set font
            $pdf->SetFont('helvetica', 'UB', 10);
            $pdf->MultiCell($columnSize[4]+5, 2, 'Amount ('.$currency.')', $border, 'R', 1, 0, '', '', true);
        }

        // set font
        $pdf->SetFont('helvetica', 'B', 10);
        $pdf->MultiCell($columnSize[5], 2, "", $border, 'R', 1, 1, '', '', true);
        
        //space
        // $pdf->MultiCell(1, 2, '', '', 'C', 1, 1, '', '', true);
        // log::write("column header = ".$pdf->GetY());
        return $pdf;
    }

    private function processStringLineSalesQuotation($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $page,
                                                    $logopath, $coydesc, $op, $quotation, $customer, $contact, 
                                                    $counter, $itemLineNo, $itemLineDesc, $itemLineComment, $itemLineAmount, $itemLineDisc, $itemLineDiscDesc, $itemLineUnitPrice, $itemLineQty, $qty_total){

        $border = "";
        $resStr = null;
        $newpage=false;

        $estimated = $pdf->getNumLines(trim($itemLineDesc), $columnSize[1]);
        if((($estimated * $rowHeight) + $pdf->GetY()) > $bottomHeight){
            $newpage=true;
        }
        
        if ($newpage){
            $coy_desc = str_replace("Pte Ltd", "", $coydesc);
            $coy_desc = str_replace("Sdn Bhd", "", $coydesc);
            $pdf->setCoyName($coy_desc);
            

            $pdf->AddPage();
            $this->totalPages += 1;
            
            $pdf = $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);

            $pdf = $this->createHeaderSalesQuotation($pdf, $columnSize, $rowHeight, $currency, $qty_total); 
        
            $pdf = $this->processStringLineSalesQuotation($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $page,
                                                            $logopath, $coydesc, $op, $quotation, $customer, $contact, 
                                                            $counter, $itemLineNo, $itemLineDesc, $itemLineComment, $itemLineAmount, $itemLineDisc, $itemLineDiscDesc, $itemLineUnitPrice, $itemLineQty, $qty_total);
        }else{
             $pdf = $this->writeLinePDFSalesQuotationDesc($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                        $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                        $counter, $itemLineNo, $itemLineDesc, $itemLineComment, $itemLineAmount, $itemLineDisc, $itemLineDiscDesc, $itemLineUnitPrice, $itemLineQty, $qty_total);
        }

        // if(trim($itemLineComment) != "") {
            $estimated_comment = $pdf->getNumLines($itemLineComment, $columnSize[1]);
            if(((($estimated_comment) * $rowHeight) + $pdf->getY()) > ($bottomHeight)) {
                $resStr = $this->getCutPrintStr($pdf, $columnSize[1], $rowHeight, $bottomHeight, $itemLineComment);
                $leftoverStr = $resStr[0];
                $newpage = true;
            } else {
                $leftoverStr = $itemLineComment;
            }
            
            if ($newpage){
                $coy_desc = str_replace("Pte Ltd", "", $coydesc);
                $coy_desc = str_replace("Sdn Bhd", "", $coydesc);
                $pdf->setCoyName($coy_desc);

                if(count($resStr) > 0) {
                    if(((($estimated_comment) * $rowHeight) + $pdf->getY()) > ($bottomHeight)) {
                        $pdf->AddPage();
                        $this->totalPages += 1;
                    
                        $pdf = $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);
        
                        $pdf = $this->createHeaderSalesQuotation($pdf, $columnSize, $rowHeight, $currency, $qty_total); 
                    }

                    $pdf = $this->writeLinePDFSalesQuotation($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                                $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                                $counter, $itemLineNo, $itemLineDesc, $resStr[0], $itemLineAmount, $itemLineDisc, $itemLineDiscDesc, $itemLineUnitPrice, $itemLineQty, $qty_total);
                    $counter++;
                    $first = false;
                }
                
                if($resStr[1] == "") {
                } else {
                    // if(((($estimated_comment) * $rowHeight) + $pdf->getY()) > ($bottomHeight)) {
                        $pdf->AddPage();
                        $this->totalPages += 1;
                        
                        $pdf = $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);

                        $pdf = $this->createHeaderSalesQuotation($pdf, $columnSize, $rowHeight, $currency, $qty_total); 
                    
                        $pdf = $this->processStringLineSalesQuotation($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $page,
                                                                        $logopath, $coydesc, $op, $quotation, $customer, $contact, 
                                                                        $counter, $itemLineNo, $itemLineDesc, $resStr[1], $itemLineAmount, $itemLineDisc, $itemLineDiscDesc, $itemLineUnitPrice, $itemLineQty, $qty_total);
                    // }
                }
            }else{
                $pdf = $this->writeLinePDFSalesQuotation($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                            $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                            $counter, $itemLineNo, $itemLineDesc, $leftoverStr, $itemLineAmount, $itemLineDisc, $itemLineDiscDesc, $itemLineUnitPrice, $itemLineQty, $qty_total);
            }
        // } else {
        //     //space
        //     $pdf->MultiCell(1, 2, '', '', 'C', 1, 1, '', '', true);
        // }
                
        return $pdf;
    }

    private function writeLinePDFSalesQuotationDesc($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                $counter, $itemLineNo, $itemLineDesc, $itemLineComment, $itemLineAmount, $itemLineDisc, $itemLineDiscDesc, $itemLineUnitPrice, $itemLineQty, $qty_total){
        
        // set font
        $pdf->SetFont('helvetica', '', 10);

        $border = "";
        $estimated = 0;
        $str = "";
        $amount = "";
        $unit_price = "";
        $new_unit_price = "";
        $qty = 0;

        // if($page == $pdf->getPage()) {
            if($itemLineQty != 0) {
                $unit_price = number_format($itemLineUnitPrice, 2);
                $bracket = substr($unit_price, 0, 1) == "-" ? true : false;
                $new_unit_price = $bracket == true ? "(". substr($unit_price, 1) .")" : $unit_price;
                $qty = $itemLineQty;
            }
        // }

        if(!$first) {
            $itemLineDesc = "";
        }
        
        $rowHeightHeader = 0;
        if(trim($itemLineDesc) != "") {
            $estimated = $pdf->getStringHeight($columnSize[1],trim($itemLineDesc));
            if($rowHeight < $estimated) {
                $rowHeightHeader = $estimated;
            }

            // if($page == $pdf->getPage()) {
                $amount = number_format($itemLineAmount, 2);
                $bracket = substr($amount, 0, 1) == "-" ? true : false;
                $new_amount = $bracket == true ? "(". substr($amount, 1) .")" : $amount;
            // }

            $pdf->MultiCell($columnSize[0], $rowHeightHeader, $counter.".", $border, 'C', 1, 0, PDF_MARGIN_LEFT+5, '', true);
            $pdf->MultiCell($columnSize[1], $rowHeightHeader, htmlspecialchars_decode(trim($itemLineDesc)), $border, 'L', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[2], $rowHeightHeader, $new_unit_price, $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[3], $rowHeightHeader, number_format($qty, 2, '.', ','), $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[4], $rowHeightHeader, $new_amount, $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[5], $rowHeightHeader, "", $border, 'R', 1, 1, '', '', true);
        }

        return $pdf;
    }

    private function writeLinePDFSalesQuotation($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                $counter, $itemLineNo, $itemLineDesc, $itemLineComment, $itemLineAmount, $itemLineDisc, $itemLineDiscDesc, $itemLineUnitPrice, $itemLineQty, $qty_total){
        
        // set font
        $pdf->SetFont('helvetica', '', 10);

        $border = "";

        // set font
        $pdf->SetFont('helvetica', '', 9);
        if(trim($itemLineComment) == "") {
        //     //space
            $pdf->MultiCell(1, 1, '', '', 'C', 1, 1, '', '', true);
        } else {
            $estimated_comment = $pdf->getStringHeight($columnSize[1],$itemLineComment);

            $rowHeightComment = 3.409722; 
            $pdf->MultiCell($columnSize[0], $estimated_comment, "", $border, 'C', 1, 0, PDF_MARGIN_LEFT+5, '', true);
            $pdf->MultiCell($columnSize[1]+$columnSize[2], $estimated_comment, htmlspecialchars_decode($itemLineComment), $border, 'L', 1, 0, '', '', true);
            // $pdf->MultiCell($columnSize[2], $estimated_comment, "", $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[3], $estimated_comment, "", $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[4], $estimated_comment, "", $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[5], $estimated_comment, "", $border, 'R', 1, 1, '', '', true);
        }

        // set font
        $pdf->SetFont('helvetica', '', 9);
        if(trim($itemLineDiscDesc) != "") {
            $estimated_linedisc = $pdf->getStringHeight($columnSize[1],trim($itemLineDiscDesc));        
            // if($estimated < $estimated_linedisc) {
            //     $estimated = $estimated_linedisc;
            // }

            // if(!$newpage) {
                $pdf->MultiCell($columnSize[0], $estimated_linedisc, "", $border, 'C', 1, 0, PDF_MARGIN_LEFT+5, '', true);
                $pdf->MultiCell($columnSize[1]+$columnSize[2], $estimated_linedisc, htmlspecialchars_decode(trim($itemLineDiscDesc)), $border, 'L', 1, 0, '', '', true);
                // $pdf->MultiCell($columnSize[2], $estimated_linedisc, "", $border, 'R', 1, 0, '', '', true);
                $pdf->MultiCell($columnSize[3], $estimated_linedisc, "", $border, 'R', 1, 0, '', '', true);
                $pdf->MultiCell($columnSize[4], $estimated_linedisc, "(". number_format($itemLineDisc, 2) .")", $border, 'R', 1, 0, '', '', true);
                $pdf->MultiCell($columnSize[5], $estimated_linedisc, "", $border, 'R', 1, 1, '', '', true);
            // }

            //space
            $pdf->MultiCell(1, 2, '', '', 'C', 1, 1, '', '', true);
        }

        return $pdf;
    }

    private function processStringLineSalesQuotationMaintenance($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $page,
                                                    $logopath, $coydesc, $op, $quotation, $customer, $contact, 
                                                    $counter, $desc, $comment, $amount, $totalAmount){

        $border = "";
        $resStr = null;
        $newpage=false;

        $estimated = $pdf->getNumLines(trim($desc), $columnSize[1]+$columnSize[2]+$columnSize[3]);
        if((($estimated * $rowHeight) + $pdf->GetY()) > $bottomHeight){
            $newpage=true;
        }
        
        if ($newpage){
            $coy_desc = str_replace("Pte Ltd", "", $coydesc);
            $coy_desc = str_replace("Sdn Bhd", "", $coydesc);
            $pdf->setCoyName($coy_desc);
            
            $pdf->AddPage();
            $this->totalPages += 1;

            $pdf = $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);

            $pdf = $this->createHeaderSalesQuotation($pdf, $columnSize, $rowHeight, $currency, 0); 
                                                
            $pdf = $this->processStringLineSalesQuotationMaintenance($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $page,
                                                        $logopath, $coydesc, $op, $quotation, $customer, $contact, 
                                                        $counter, $desc, $comment, $amount, $totalAmount);
        }else{
            $pdf = $this->writeLinePDFSalesQuotationMaintenanceDesc($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                       $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                       $counter, $desc, $comment, $amount, $totalAmount);
        }

        $estimated = $pdf->getNumLines($comment, $columnSize[1]+$columnSize[2]+$columnSize[3]);
        // log::write($estimated);
        // log::write($pdf->GetY());
        if((($estimated * $rowHeight) + $pdf->GetY()) > $bottomHeight){
            $resStr = $this->getCutPrintStr($pdf, $columnSize[1]+$columnSize[2]+$columnSize[3], $rowHeight, $bottomHeight, $comment);
            // log::write($resStr);
            $leftoverStr = $resStr[0];
            $newpage=true;
            // if(trim($resStr[1]) == "")
            //     $newpage=false;
        } else {
            $leftoverStr = $comment;
        }
        
        if ($newpage){
            $coy_desc = str_replace("Pte Ltd", "", $coydesc);
            $coy_desc = str_replace("Sdn Bhd", "", $coydesc);
            $pdf->setCoyName($coy_desc);

            if(count($resStr) > 0) {
                $pdf = $this->writeLinePDFSalesQuotationMaintenance($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                            $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                            $counter, $desc, $resStr[0], $amount, $totalAmount);
                $counter++;
                $first = false;
            }

            if($resStr[1] == "") {
            } else {
                $pdf->AddPage();
                $this->totalPages += 1;

                $pdf = $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);

                $pdf = $this->createHeaderSalesQuotation($pdf, $columnSize, $rowHeight, $currency, 0); 
                                                    
                $pdf = $this->processStringLineSalesQuotationMaintenance($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $page,
                                                            $logopath, $coydesc, $op, $quotation, $customer, $contact, 
                                                            $counter, $desc, $resStr[1], $amount, $totalAmount);
            }
        }else{
             $pdf = $this->writeLinePDFSalesQuotationMaintenance($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                        $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                        $counter, $desc, $leftoverStr, $amount, $totalAmount);
        }
                
        return $pdf;
    }

    private function writeLinePDFSalesQuotationMaintenanceDesc($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                $counter, $desc, $comment, $amount, $totalAmount){
        
        // set font
        $pdf->SetFont('helvetica', '', 10);

        $border = "";
        $estimated = 0;

        if(!$first) {
            $desc = "";
        }

        if(trim($desc) != "") {
            $estimated = $pdf->getStringHeight($columnSize[1]+$columnSize[2]+$columnSize[3],trim($desc));

            $str = htmlspecialchars_decode(trim($desc));// ."\n". htmlspecialchars_decode($comment);
            
            $amount = number_format($amount, 2);
            $bracket = substr($amount, 0, 1) == "-" ? true : false;
            $new_amount = $bracket == true ? "(". substr($amount, 1) .")" : $amount;

            $pdf->MultiCell($columnSize[0], $estimated, $counter.".", $border, 'C', 1, 0, PDF_MARGIN_LEFT+5, '', true);
            $pdf->MultiCell($columnSize[1]+$columnSize[2]+$columnSize[3], $estimated, $str, $border, 'L', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[4], $estimated, $new_amount, $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[5], $estimated, "", $border, 'R', 1, 1, '', '', true);

            //space
            // $pdf->MultiCell(1, 5, '', '', 'C', 1, 1, '', '', true);
        }
        // log::write($desc);
        // log::write($pdf->GetY());

        return $pdf;
    }

    private function writeLinePDFSalesQuotationMaintenance($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                $counter, $desc, $comment, $amount, $totalAmount){
        
        // set font
        $pdf->SetFont('helvetica', '', 10);

        $border = "";
        $estimated = 0;

        if(!$first) {
            $desc = "";
        }

        if($comment != "") {
            $estimated_comment = $pdf->getStringHeight($columnSize[1]+$columnSize[2]+$columnSize[3],$comment);
            
            $pdf->MultiCell($columnSize[0], $estimated_comment, "", $border, 'C', 1, 0, PDF_MARGIN_LEFT+5, '', true);
            $pdf->MultiCell($columnSize[1]+$columnSize[2]+$columnSize[3], $estimated_comment, htmlspecialchars_decode($comment), $border, 'L', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[4], $estimated_comment, "", $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[5], $estimated_comment, "", $border, 'R', 1, 1, '', '', true);
        }
        // log::write($comment);
        // log::write($pdf->GetY());
        
            //space
            $pdf->MultiCell(1, 1, '', '', 'C', 1, 1, '', '', true);

        return $pdf;
    }

    private function createHeaderSalesQuotationProjectPlan($pdf, $columnSize){
        // set font
        $pdf->SetFont('helvetica', 'UB', 10);

        // set line style
        $pdf->SetLineStyle(array("width" => 0, "cap" => "", "join" => "", "dash" => 0, "color" => array(0, 0, 0)));

        $border = "";
        
        // $currency = trim($currency);
        $pdf->MultiCell($columnSize[0], 2, 'Phase', $border, 'L', 1, 0, PDF_MARGIN_LEFT+5, '', true);
        $pdf->MultiCell($columnSize[1]+$columnSize[2]+$columnSize[3], 2, 'Description', $border, 'L', 1, 0, '', '', true);
        $pdf->MultiCell($columnSize[4], 2, 'No. of Days', $border, 'R', 1, 0, '', '', true);

        // set font
        $pdf->SetFont('helvetica', 'B', 10);
        $pdf->MultiCell($columnSize[5], 2, "", $border, 'L', 1, 1, '', '', true);
        
        //space
        $pdf->MultiCell(1, 2, '', '', 'C', 1, 1, '', '', true);

        return $pdf;
    }

    private function processStringLineSalesQuotationProjectPlan($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $page,
                                                    $logopath, $coydesc, $op, $quotation, $customer, $contact, 
                                                    $counter, $phase, $desc, $comment, $days, $totalDays, $totalAmount){

        $border = "";
        $resStr = null;
        $newpage=false;

        $estimated = $pdf->getNumLines($desc, $columnSize[1]+$columnSize[2]+$columnSize[3]);
        // print_r($estimated."</br>");
        // if((($estimated * $rowHeight) + $pdf->GetY()) > $bottomHeight){
        //     $newpage=true;
        // }

        if((($estimated * $rowHeight) + $pdf->GetY()) > $bottomHeight){
            //print_r((($estimated * $rowHeight) + $pdf->GetY()) .">". $bottomHeight);
            $resStr = $this->getCutPrintStr($pdf, $columnSize[1]+$columnSize[2]+$columnSize[3], $rowHeight, $bottomHeight, $desc);
            $leftoverStr = $resStr[0];
            $newpage=true;
            // if(trim($resStr[1]) == "")
            //     $newpage=false;
        } else {
            $leftoverStr = $desc;
        }

        if ($newpage){
            $coy_desc = str_replace("Pte Ltd", "", $coydesc);
            $coy_desc = str_replace("Sdn Bhd", "", $coydesc);
            $pdf->setCoyName($coy_desc);

            // if(count($resStr) > 0) {
            //     $pdf = $this->writeLinePDFSalesQuotationProjectPlan($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
            //                                                 $logopath, $coydesc, $op, $quotation, $customer, $contact,
            //                                                 $counter, $phase, $desc, $comment, $days, $totalDays, $totalAmount);
            //     $counter++;
            //     $first = false;
            // }

            $pdf->AddPage();
            $this->totalPages += 1;

            $this->printSubReportHeaderSalesQuotation($pdf, $logopath, $coydesc, $op);

            $this->createHeaderSalesQuotationProjectPlan($pdf, $columnSize);
                                                
            $pdf = $this->processStringLineSalesQuotationProjectPlan($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $page,
                                                            $logopath, $coydesc, $op, $quotation, $customer, $contact, 
                                                            $counter, $phase, $leftoverStr, $comment, $days, $totalDays, $totalAmount);
            if(trim($resStr[1]) != ""){
                $this->writeLinePDFSalesQuotationProjectPlan($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                            $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                            $counter, $phase, $resStr[1], $comment, $days, $totalDays, $totalAmount);
            }
        }else{
             $this->writeLinePDFSalesQuotationProjectPlan($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                        $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                        $counter, $phase, $leftoverStr, $comment, $days, $totalDays, $totalAmount);
        }
                
        return $pdf;
    }

    private function writeLinePDFSalesQuotationProjectPlan($pdf, $columnSize, $rowHeight, $bottomHeight, $first, $currency, $newpage, $page,
                                                $logopath, $coydesc, $op, $quotation, $customer, $contact,
                                                $counter, $phase, $desc, $comment, $days, $totalDays, $totalAmount){
        
        // set font
        $pdf->SetFont('helvetica', '', 10);

        $border = "";
        $estimated = 0;

        $estimated_desc = $pdf->getStringHeight($columnSize[1]+$columnSize[2]+$columnSize[3],trim($desc));
        if($rowHeight < $estimated_desc)
            $estimated = $estimated_desc;

        $pdf->MultiCell($columnSize[0], $rowHeight+$estimated, $phase, $border, 'L', 1, 0, PDF_MARGIN_LEFT+5, '', true);
        $pdf->MultiCell($columnSize[1]+$columnSize[2]+$columnSize[3], $rowHeight+$estimated, htmlspecialchars_decode(trim($desc)), $border, 'L', 1, 0, '', '', true);
        $pdf->MultiCell($columnSize[4], $rowHeight+$estimated, number_format($days, 2), $border, 'R', 1, 0, '', '', true);
        $pdf->MultiCell($columnSize[5], $rowHeight+$estimated, "", $border, 'R', 1, 1, PDF_MARGIN_RIGHT-5, '', true);

        // if(trim($comment) != "") {
        //     $estimated_comment = $pdf->getStringHeight($columnSize[1]+$columnSize[2]+$columnSize[3],trim($comment));
        //     if($rowHeight < $estimated_comment)
        //         $estimated = $estimated_comment;
        //     else
        //         $estimated = 0;
            
        //     $pdf->MultiCell($columnSize[0], $rowHeight+$estimated, "", $border, 'C', 1, 0, '', '', true);
        //     $pdf->MultiCell($columnSize[1]+$columnSize[2]+$columnSize[3], $rowHeight+$estimated, trim($comment), $border, 'L', 1, 0, '', '', true);
        //     $pdf->MultiCell($columnSize[4], $rowHeight+$estimated, "", $border, 'R', 1, 0, '', '', true);
        //     $pdf->MultiCell($columnSize[5], $rowHeight+$estimated, "", $border, 'R', 1, 1, '', '', true);
        // }
        
        //space
        $pdf->MultiCell(1, 5, '', '', 'C', 1, 1, '', '', true);

        // return $pdf;
    }

    private function printSalesQuotationAppendix($pdf, $rowHeight, $bottomHeight, $logopath, $coydesc, $quot_id) {        
        $clsAppendix        = new SalesQuotationAppendixClass($this->db) ;

        $columnSize = array(50, 130);
        
        $border = "";
        // set font
        $pdf->SetFont('helvetica', 'B', 10);
        $pdf->MultiCell($columnSize[0]+$columnSize[1], 5, "APPENDIX A", $border, 'R', 1, 1, '', '', true);

        $border = "TBLR";
        
        $rows = $clsAppendix->getSalesQuotationAppendixBySection($quot_id, SalesQuotationSection::DeliveryTerms);
        if(!is_null($rows) && count($rows) > 0) {
            // set font
            $pdf->SetFont('helvetica', 'B', 10);
            $pdf->MultiCell($columnSize[0]+$columnSize[1], $rowHeight, "DELIVERY TERMS", $border, 'C', 1, 1, '', '', true);

            // set font
            $pdf->SetFont('helvetica', '', 10);
            
            foreach($rows as $row) {
                $this->processStringLineSalesQuotationAppendix($pdf, $columnSize, $rowHeight, $bottomHeight, $logopath, $coydesc, $quot_id, $row[SalesQuotationAppendixTable::C_SECTION], $row[SalesQuotationAppendixTable::C_SUBJECT], $row[SalesQuotationAppendixTable::C_DESC]);
            }
        }

        $rows = $clsAppendix->getSalesQuotationAppendixBySection($quot_id, SalesQuotationSection::PaymentTerms);
        if(!is_null($rows) && count($rows) > 0) {
            // set font
            $pdf->SetFont('helvetica', 'B', 10);
            $pdf->MultiCell($columnSize[0]+$columnSize[1], $rowHeight, "PAYMENT TERMS", $border, 'C', 1, 1, '', '', true);

            foreach($rows as $row) {
                $this->processStringLineSalesQuotationAppendix($pdf, $columnSize, $rowHeight, $bottomHeight, $logopath, $coydesc, $quot_id, $row[SalesQuotationAppendixTable::C_SECTION], $row[SalesQuotationAppendixTable::C_SUBJECT], $row[SalesQuotationAppendixTable::C_DESC]);
            }
        }

        $rows = $clsAppendix->getSalesQuotationAppendixBySection($quot_id, SalesQuotationSection::ConsultingTermsCondition);
        if(!is_null($rows) && count($rows) > 0) {
            // set font
            $pdf->SetFont('helvetica', 'B', 10);
            $pdf->MultiCell($columnSize[0]+$columnSize[1], $rowHeight, "CONSULTING TERMS AND CONDITIONS", $border, 'C', 1, 1, '', '', true);
    
            foreach($rows as $row) {
                $this->processStringLineSalesQuotationAppendix($pdf, $columnSize, $rowHeight, $bottomHeight, $logopath, $coydesc, $quot_id, $row[SalesQuotationAppendixTable::C_SECTION], $row[SalesQuotationAppendixTable::C_SUBJECT], $row[SalesQuotationAppendixTable::C_DESC]);
            }
        }

        $rows = $clsAppendix->getSalesQuotationAppendixBySection($quot_id, SalesQuotationSection::TravellingCondition);
        if(!is_null($rows) && count($rows) > 0) {
            // set font
            $pdf->SetFont('helvetica', 'B', 10);
            $pdf->MultiCell($columnSize[0]+$columnSize[1], $rowHeight, "TRAVELLING CONDITIONS", $border, 'C', 1, 1, '', '', true);
    
            foreach($rows as $row) {
                $this->processStringLineSalesQuotationAppendix($pdf, $columnSize, $rowHeight, $bottomHeight, $logopath, $coydesc, $quot_id, $row[SalesQuotationAppendixTable::C_SECTION], $row[SalesQuotationAppendixTable::C_SUBJECT], $row[SalesQuotationAppendixTable::C_DESC]);
            }
        }

        $rows = $clsAppendix->getSalesQuotationAppendixBySection($quot_id, SalesQuotationSection::TrainingRoomCondition);
        if(!is_null($rows) && count($rows) > 0) {
            // set font
            $pdf->SetFont('helvetica', 'B', 10);
            $pdf->MultiCell($columnSize[0]+$columnSize[1], $rowHeight, "TRAINING ROOM CONDITIONS", $border, 'C', 1, 1, '', '', true);
    
            foreach($rows as $row) {
                $this->processStringLineSalesQuotationAppendix($pdf, $columnSize, $rowHeight, $bottomHeight, $logopath, $coydesc, $quot_id, $row[SalesQuotationAppendixTable::C_SECTION], $row[SalesQuotationAppendixTable::C_SUBJECT], $row[SalesQuotationAppendixTable::C_DESC]);
            }
        }

        $rows = $clsAppendix->getSalesQuotationAppendixBySection($quot_id, SalesQuotationSection::GeneralTermsCondition);
        if(!is_null($rows) && count($rows) > 0) {
            // set font
            $pdf->SetFont('helvetica', 'B', 10);
            $pdf->MultiCell($columnSize[0]+$columnSize[1], $rowHeight, "GENERAL TERMS AND CONDITIONS", $border, 'C', 1, 1, '', '', true);
    
            foreach($rows as $row) {
                $this->processStringLineSalesQuotationAppendix($pdf, $columnSize, $rowHeight, $bottomHeight, $logopath, $coydesc, $quot_id, $row[SalesQuotationAppendixTable::C_SECTION], $row[SalesQuotationAppendixTable::C_SUBJECT], $row[SalesQuotationAppendixTable::C_DESC]);
            }
        }

        return $pdf;
    }

    private function processStringLineSalesQuotationAppendix($pdf, $columnSize, $rowHeight, $bottomHeight, $logopath, $coydesc, $quot_id, $appendixSection, $appendixSubject, $appendixDesc) {
        $newpage=false;

        $estimated = $pdf->getNumLines(trim($appendixDesc), $columnSize[1]);

        // if((($estimated * $rowHeight) + $pdf->GetY()) > $bottomHeight){
        if((($estimated * $rowHeight)) > $bottomHeight){
            $newpage=true;
        }

        if ($newpage){
            $pdf->AddPage();
            $this->totalPages += 1;

            $pdf = $this->processStringLineSalesQuotationAppendix($pdf, $columnSize, $rowHeight, $bottomHeight, 
                                                                    $logopath, $coydesc, $quot_id, $appendixSection, $appendixSubject, $appendixDesc);

            // $pdf = $this->writeLinePDFSalesQuotationAppendix($pdf, $columnSize, $rowHeight, $bottomHeight, 
                                                            // $logopath, $coydesc, $appendixSection, $appendixSubject, $appendixDesc);            
        } else {
            $pdf = $this->writeLinePDFSalesQuotationAppendix($pdf, $columnSize, $rowHeight, $bottomHeight, 
                                                            $logopath, $coydesc, $appendixSection, $appendixSubject, $appendixDesc);
        }

        return $pdf;
    }

    private function writeLinePDFSalesQuotationAppendix($pdf, $columnSize, $rowHeight, $bottomHeight, $logopath, $coydesc, $appendixSection, $appendixSubject, $appendixDesc) {
        // set font
        $pdf->SetFont('helvetica', '', 10);

        $border = "TBLR";
        $estimated = $pdf->getStringHeight($columnSize[0],trim($appendixSubject));
        $estimated_desc = $pdf->getStringHeight($columnSize[1],trim($appendixDesc));

        if($estimated < $estimated_desc) {
            $estimated = $estimated_desc;
        }
        
        if(trim($appendixSubject) == "") {
            $pdf->MultiCell($columnSize[0]+$columnSize[1], $estimated, htmlspecialchars_decode($appendixDesc), $border, 'L', 1, 1, '', '', true);
        } else {
            $pdf->MultiCell($columnSize[0], $estimated, htmlspecialchars_decode($appendixSubject), $border, 'L', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[1], $estimated, htmlspecialchars_decode(trim($appendixDesc)), $border, 'L', 1, 1, '', '', true);
        }
        
        return $pdf;
    }

    private function getCutPrintStr($pdf, $columnSize, $rowHeight, $bottomHeight, $str, $divider = "\n"){
        
        $strArray = explode($divider, $str);
        
        $oriCount = count($strArray);
        
        $bottomHeight = $bottomHeight + 45;
        
        $counter = ($oriCount > 500 ? $oriCount - 500 : 0);
        $strArrayNew = array_slice($strArray, 0, $oriCount - $counter);
        $strNew = implode($divider, $strArrayNew);
        $estimated = $pdf->getNumLines($strNew, $columnSize);
        //Log::write($estimated . " - " . $rowHeight . " - " . ($estimated * $rowHeight) . " - " . $pdf->GetY() . " - " . (($estimated * $rowHeight) + $pdf->GetY()) . ' - ' . $bottomHeight);
        
        while((($estimated * $rowHeight) + $pdf->GetY()) > $bottomHeight && $counter < $oriCount){
            $counter++;
            $strArrayNew = array_slice($strArray, 0, $oriCount - $counter);
            $strNew = implode($divider, $strArrayNew);
            //Log::write($strNew);
            $estimated = $pdf->getNumLines($strNew, $columnSize);
            //Log::write($estimated . " - " . $rowHeight . " - " . ($estimated * $rowHeight) . " - " . $pdf->GetY() . " - " . (($estimated * $rowHeight) + $pdf->GetY()) . ' - ' . $bottomHeight);
        }
        
        
        $result = array();
        if($counter >= $oriCount){
            $result = $this->getCutPrintStr($pdf, $columnSize, $rowHeight, $bottomHeight, $str, " ");
        } else {
            $strArrayNew = array_slice($strArray, 0, $oriCount - $counter);
            $result[] = implode($divider, $strArrayNew);
            $strArrayNew = array_slice($strArray, $oriCount - $counter);
            $result[] = implode($divider, $strArrayNew);
        }
        
        return $result;
    }
    //=============================================================================//

    //TEMPLATE APPENDIX
    private function saveAppendixTemplate($params) {
        $cls     = new SalesQuotationTemplateClass($this->db);
        $clsTask = new SalesQuotationAppendixTemplateClass($this->db);
        
        $salesquotation_appendix      = $params['data'];
        $option                       = $params['option_template'];
        $template_id                  = $params['template_id'];

        $datas      = array() ;
        $orgid      = $_SESSION[SE_ORGID] ;
        $modifyby   = $_SESSION[SE_USERID] ;
        $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
        $dte        = date_create('now')->format('Y-m-d') ;
        $ws         = $_SESSION[SE_REMOTE_IP];

        if($option==0) {
            //UPDATE TEMPLATE
            // $tempate_name   = $this->getParam($params,'new_name','');
     
            //do not update name if new name is empty
            // if( $tempate_name != '' ){
            //     $check_name = $cls->checkName($tempate_name);
    
            //     if($check_name){
            //         $this->sendJsonResponse(Status::Error,"Template name is already in use","",$this->type);
            //         return;
            //     }

            //     $datas[]    = $this->db->fieldValue(SalesQuotationTemplateTable::C_TEMP_NAME,$params['new_name']);
            //     $cls->updateRecord($template_id,$datas) ;

            // }

            try {
                $clsTask->deleteTask($template_id);

                $encodes = json_decode($salesquotation_appendix,true);

                $line_id        = 1;

                if(!is_null($encodes) && count($encodes)>0){

                    foreach ($encodes as $encode) {

                        $datas=[];

                        
                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_DETAIL_ID,$line_id) ;

                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_ORG_ID,$orgid) ;

                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_WS_ID,$ws) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_MODIFY_BY,$modifyby) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_CREATE_BY,$modifyby) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_MODIFY_DATE,$modifydate) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_CREATE_DATE,$modifydate) ;

                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_SECTION,$encode['section']) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_SUBJECT,htmlspecialchars($encode['subject'])) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_DESC,htmlspecialchars($encode['desc'])) ;
                    
                        $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_ID,$template_id) ;
                                                
                        $line_id ++;
                    
                        $clsTask->addRecord($datas) ;                        
                        
                    }
        
                }

                $this->sendJsonResponse(Status::Ok,"Template Name successfully updated to the system.",$datas,$this->type) ;
                return;
            } catch (Exception $e) {
                Log::write('[Sales Quotation Appendix Template]' . $e->getMessage());
                $this->sendJsonResponse(Status::Error,"Sorry, there is a error in updating Template Name to the system.","",$this->type) ;
                return;
            }
        } else {
            //SAVE TEMPLATE
            $tempate_name   = $this->getParam($params,'name','');
            $line_id        = 1;
    
            $check_name = $cls->checkName($tempate_name);
    
            if($check_name){
                $this->sendJsonResponse(Status::Error,"Template name is already in use","",$this->type);
                return;
            }

            $datas[] = $this->db->fieldValue(SalesQuotationTemplateTable::C_TEMP_NAME,$tempate_name) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTemplateTable::C_ORG_ID,$orgid) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTemplateTable::C_WS_ID,$ws) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTemplateTable::C_MODIFY_BY,$modifyby) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTemplateTable::C_CREATE_BY,$modifyby) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTemplateTable::C_MODIFY_DATE,$modifydate) ;
            $datas[] = $this->db->fieldValue(SalesQuotationTemplateTable::C_CREATE_DATE,$modifydate) ;

            try {

               $id = $cls->addRecord($datas) ;
             
                if ($id > 0) {
                
                    $encodes = json_decode($salesquotation_appendix,true);

                    if(!is_null($encodes) && count($encodes)>0){

                        foreach ($encodes as $encode) {

                            $datas=[];

                            
                            $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_DETAIL_ID,$line_id) ;

                            $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_ORG_ID,$orgid) ;

                            $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_WS_ID,$ws) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_MODIFY_BY,$modifyby) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_CREATE_BY,$modifyby) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_MODIFY_DATE,$modifydate) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_CREATE_DATE,$modifydate) ;

                            $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_SECTION,$encode['section']) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_SUBJECT,htmlspecialchars($encode['subject'])) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_DESC,htmlspecialchars($encode['desc'])) ;

                            $datas[] = $this->db->fieldValue(SalesQuotationAppendixTemplateTable::C_ID,$id) ;
                                                  
                            $line_id ++;
                     
                            $clsTask->addRecord($datas) ;                        
                            
                        }
            
                    }

                    $this->sendJsonResponse(Status::Ok,"Success","",$this->type);

                    return;
                    
                }else{

                    $this->sendJsonResponse(Status::Error,"Failed to do database operation","",$this->type);
                    return;

                }
                

            } catch(Exception $e){

                Log::write("[Sales Quotation Appendix Template]" . $e->getMessage());

                $this->sendJsonResponse(Status::Error,"Failed to do database operation","",$this->type);

                return;
            }
        }
    }

    private function loadViewAppendixTemplate($params) {
        $cls = new SalesQuotationTemplateClass($this->db);

        $rows = $cls->getAllTemplate();

        $vls   = array() ;
        $vls[] = array ('code'=>"0",'desc'=>"--- Select Template ---") ;
        
        if(!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $vls[] = array ('code'=>$row[SalesQuotationTemplateTable::C_ID],'desc'=>$row[SalesQuotationTemplateTable::C_TEMP_NAME]) ;
            }           
        }
        $data = [];
        $data['load_option'] = Util::createOptionValue($vls) ;

        $this->sendJsonResponse(Status::Ok,"Success",$data,$this->type);
    }

    private function loadViewAppendixTemplateList($params) {
        $cls = new SalesQuotationTemplateClass($this->db);

        $rows = $cls->getAllTemplate();

        $vls   = array() ;
        $vls[] = array ('code'=>"0",'desc'=>"--- Select Template ---") ;
        
        if(!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $vls[] = array ('code'=>$row[SalesQuotationTemplateTable::C_ID],'desc'=>$row[SalesQuotationTemplateTable::C_TEMP_NAME]) ;
            }           
        }
        $data = [];
        $data['load_option'] = Util::createOptionValue($vls) ;

        $this->sendJsonResponse(Status::Ok,"Success",$data,$this->type);
    }

    private function loadAppendixTemplate($params) {
        $cls = new SalesQuotationAppendixTemplateClass($this->db);

        $id = $this->getParamInt($params,'template_id',0);

        $rows = $cls->getSalesQuotationAppendixTemplate($id) ;
        $datas = [];
        if (!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {

                $data           = [] ;

                $data['id']         = $row[SalesQuotationAppendixTemplateTable::C_DETAIL_ID];
                $data['section']    = $row[SalesQuotationAppendixTemplateTable::C_SECTION];
                $data['subject']    = htmlspecialchars_decode($row[SalesQuotationAppendixTemplateTable::C_SUBJECT]);
                $data['desc']       = htmlspecialchars_decode($row[SalesQuotationAppendixTemplateTable::C_DESC]);

                array_push($datas,$data);
            }
        }

        $json_array = json_encode($datas,true);

        $vls =[];
        $vls['salesquotation_appendix'] = $json_array;

        $this->sendJsonResponse(Status::Ok,"Success",$vls,$this->type);
    }

    private function deleteAppendixTemplate($params) {
        $cls     = new SalesQuotationTemplateClass($this->db);
        $clsTask = new SalesQuotationAppendixTemplateClass($this->db);

        $id = $this->getParamInt($params,'template_id',0);

        if($id == 0){
            $this->sendJsonResponse(Status::Error,"Please provide id before deleting","",$this->type);
            return;
        }

        try{
            $clsTask->deleteTask($id);
            $cls->deleteRecord($id);

            $this->sendJsonResponse(Status::Ok,"Template is deleted","",$this->type);

            return;
        }catch(Exception $e){

            Log::write("[Sales Quotation Appendix Template]" . $e->getMessage());

            $this->sendJsonResponse(Status::Error,"Failed to do database operation","",$this->type);

            return;
        }
    }
    //==============================================================================

     //TEMPLATE PROJECT PLAN
    private function saveProjectPlanTemplate($params) {

        $cls         = new SalesQuotationProjectPlanTemplateClass($this->db);
        $clsTask     = new SalesQuotationProjectPlanHeaderTemplateClass($this->db);
        $clsTaskDtl  = new SalesQuotationProjectPlanDetailTemplateClass($this->db);
        
        $projectplan                    = $params['data'];
        $project_plan_id                = $params['project_plan_id'];
        $project_plan_amount            = $params['project_plan_amount'];
        $project_plan_currency          = $params['project_plan_currency'];

        $option                         = $params['option_template'];
        $template_id                    = $params['template_id'];

        $datas      = array() ;
        $orgid      = $_SESSION[SE_ORGID] ;
        $modifyby   = $_SESSION[SE_USERID] ;
        $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
        $dte        = date_create('now')->format('Y-m-d') ;
        $ws         = $_SESSION[SE_REMOTE_IP];

        if($option==0) {
            //UPDATE TEMPLATE
            // $tempate_name   = $this->getParam($params,'new_name','');
     
            //do not update name if new name is empty
            // if( $tempate_name != '' ){
            //     $check_name = $cls->checkName($tempate_name);
    
            //     if($check_name){
            //         $this->sendJsonResponse(Status::Error,"Template name is already in use","",$this->type);
            //         return;
            //     }

            //     $datas[]    = $this->db->fieldValue(SalesQuotationProjectPlanTemplateTable::C_TEMP_NAME,$params['new_name']);

            //     $cls->updateRecord($template_id,$datas) ;

            // }

            try {
                $clsTask->deleteRecord($template_id);
                $clsTaskDtl->deleteTask($template_id);

                //header
                $datas=[];

                $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_ORG_ID,$orgid) ;
                $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_WS_ID,$ws) ;
                $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_MODIFY_BY,$modifyby) ;
                $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_CREATE_BY,$modifyby) ;
                $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_MODIFY_DATE,$modifydate) ;
                $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_CREATE_DATE,$modifydate) ;
                
                $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_ID,$project_plan_id) ;
                $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_QUOTATION_ID,$template_id) ;
                $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_CURRENCY,$project_plan_currency) ;
                $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_AMOUNT,floatval(str_replace(',', '', $project_plan_amount))) ;

                $clsTask->addRecord($datas) ; 

                //detail
                $encodes = json_decode($projectplan,true);
                $line_id        = 1;
                if(!is_null($encodes) && count($encodes)>0){

                    foreach ($encodes as $encode) {

                        $datas=[];

                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_ORG_ID,$orgid) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_WS_ID,$ws) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_MODIFY_BY,$modifyby) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_CREATE_BY,$modifyby) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_MODIFY_DATE,$modifydate) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_CREATE_DATE,$modifydate) ;

                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_DETAIL_ID,$line_id) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_ID,$project_plan_id) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_QUOTATION_ID,$template_id) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_PHASE,$encode['phase']) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_DESC,htmlspecialchars($encode['desc'])) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_DAYS,$encode['days']) ;
                                
                        $line_id ++;
                    
                        $clsTaskDtl->addRecord($datas) ;
                    }
                }

                $this->sendJsonResponse(Status::Ok,"Template Name successfully updated to the system.",$datas,$this->type) ;
                return;
            } catch (Exception $e) {
                Log::write('[Sales Quotation Appendix Template]' . $e->getMessage());
                $this->sendJsonResponse(Status::Error,"Sorry, there is a error in updating Template Name to the system.","",$this->type) ;
                return;
            }
        } else {
            //SAVE TEMPLATE
            $tempate_name   = $this->getParam($params,'name','');
            $line_id        = 1;
    
            $check_name = $cls->checkName($tempate_name);
    
            if($check_name){
                $this->sendJsonResponse(Status::Error,"Template name is already in use","",$this->type);
                return;
            }

            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTemplateTable::C_TEMP_NAME,$tempate_name) ;
            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTemplateTable::C_ORG_ID,$orgid) ;
            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTemplateTable::C_WS_ID,$ws) ;
            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTemplateTable::C_MODIFY_BY,$modifyby) ;
            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTemplateTable::C_CREATE_BY,$modifyby) ;
            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTemplateTable::C_MODIFY_DATE,$modifydate) ;
            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanTemplateTable::C_CREATE_DATE,$modifydate) ;

            try {
               $id = $cls->addRecord($datas) ;
             
                if ($id > 0) {

                    //header
                    $datas=[];

                    $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_ORG_ID,$orgid) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_WS_ID,$ws) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_MODIFY_BY,$modifyby) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_CREATE_BY,$modifyby) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_MODIFY_DATE,$modifydate) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_CREATE_DATE,$modifydate) ;
                    
                    $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_ID,$project_plan_id) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_QUOTATION_ID,$id) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_CURRENCY,$project_plan_currency) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanHeaderTemplateTable::C_AMOUNT,floatval(str_replace(',', '', $project_plan_amount))) ;
                                            // Log::write(print_r($datas,true));die();
                    $clsTask->addRecord($datas) ; 

                    //detail
                    $encodes = json_decode($projectplan,true);
                    if(!is_null($encodes) && count($encodes)>0){
                        foreach ($encodes as $encode) {

                            $datas=[];

                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_ORG_ID,$orgid) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_WS_ID,$ws) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_MODIFY_BY,$modifyby) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_CREATE_BY,$modifyby) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_MODIFY_DATE,$modifydate) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_CREATE_DATE,$modifydate) ;

                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_DETAIL_ID,$line_id) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_ID,$project_plan_id) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_QUOTATION_ID,$id) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_PHASE,$encode['phase']) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_DESC,htmlspecialchars($encode['desc'])) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationProjectPlanDetailTemplateTable::C_DAYS,$encode['days']) ;
           
                            $line_id ++;
                     
                            $clsTaskDtl->addRecord($datas) ;                        
                        }
                    }

                    $this->sendJsonResponse(Status::Ok,"Success","",$this->type);
                    return;
                }else{
                    $this->sendJsonResponse(Status::Error,"Failed to do database operation","",$this->type);
                    return;
                }
                

            } catch(Exception $e){

                Log::write("[Sales Quotation Appendix Template]" . $e->getMessage());

                $this->sendJsonResponse(Status::Error,"Failed to do database operation","",$this->type);

                return;
            }
        }
    }

    private function loadViewProjectPlanTemplate($params) {
        $cls = new SalesQuotationProjectPlanTemplateClass($this->db);

        $rows = $cls->getAllTemplate();

        $vls   = array() ;
        $vls[] = array ('code'=>"0",'desc'=>"--- Select Template ---") ;
        
        if(!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $vls[] = array ('code'=>$row[SalesQuotationProjectPlanTemplateTable::C_ID],'desc'=>$row[SalesQuotationProjectPlanTemplateTable::C_TEMP_NAME]) ;
            }           
        }
        $data = [];
        $data['load_option'] = Util::createOptionValue($vls) ;

        $this->sendJsonResponse(Status::Ok,"Success",$data,$this->type);
    }

    private function loadViewProjectPlanTemplateList($params) {
        $cls = new SalesQuotationProjectPlanTemplateClass($this->db);

        $rows = $cls->getAllTemplate();
        $vls   = array() ;
        $vls[] = array ('code'=>"0",'desc'=>"--- Select Template ---") ;
        
        if(!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $vls[] = array ('code'=>$row[SalesQuotationProjectPlanTemplateTable::C_ID],'desc'=>$row[SalesQuotationProjectPlanTemplateTable::C_TEMP_NAME]) ;
            }           
        }
        $data = [];
        $data['load_option'] = Util::createOptionValue($vls) ;

        $this->sendJsonResponse(Status::Ok,"Success",$data,$this->type);
    }

    private function loadProjectPlanTemplate($params) {
        $cls = new SalesQuotationProjectPlanHeaderTemplateClass($this->db);
        $clsDtl = new SalesQuotationProjectPlanDetailTemplateClass($this->db);

        $id = $this->getParamInt($params,'template_id',0);

        $rowHeader = $cls->getRecord($id) ;

        $rows = $clsDtl->getSalesQuotationProjectPlanDetailTemplate($id) ;
        $datas = [];
        if (!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {

                $data           = [] ;

                $data['id']         = $row[SalesQuotationProjectPlanDetailTemplateTable::C_DETAIL_ID];
                $data['phase']      = $row[SalesQuotationProjectPlanDetailTemplateTable::C_PHASE];
                $data['desc']       = htmlspecialchars_decode($row[SalesQuotationProjectPlanDetailTemplateTable::C_DESC]);
                $data['days']       = $row[SalesQuotationProjectPlanDetailTemplateTable::C_DAYS];

                array_push($datas,$data);
            }
        }

        $json_array = json_encode($datas,true);

        $vls =[];
        $vls['salesquotation_project_plan'] = $json_array;
        $vls['project_plan_id']             = $rowHeader[SalesQuotationProjectPlanHeaderTemplateTable::C_ID];
        $vls['project_plan_currency']       = $rowHeader[SalesQuotationProjectPlanHeaderTemplateTable::C_CURRENCY];
        $vls['project_plan_amount']         = number_format($rowHeader[SalesQuotationProjectPlanHeaderTemplateTable::C_AMOUNT], 2);

        $this->sendJsonResponse(Status::Ok,"Success",$vls,$this->type);
    }

    private function deleteProjectPlanTemplate($params) {
        $cls                = new SalesQuotationProjectPlanTemplateClass($this->db);
        $clsProjectPlan     = new SalesQuotationProjectPlanHeaderTemplateClass($this->db);
        $clsProjectPlanDtl  = new SalesQuotationProjectPlanDetailTemplateClass($this->db);

        $id = $this->getParamInt($params,'template_id',0);

        if($id == 0){
            $this->sendJsonResponse(Status::Error,"Please provide id before deleting","",$this->type);
            return;
        }

        try{
            $clsProjectPlan->deleteRecord($id);
            $clsProjectPlanDtl->deleteTask($id);
            $cls->deleteRecord($id);

            $this->sendJsonResponse(Status::Ok,"Template is deleted","",$this->type);

            return;
        }catch(Exception $e){
            Log::write("[Sales Quotation Appendix Template]" . $e->getMessage());
            $this->sendJsonResponse(Status::Error,"Failed to do database operation","",$this->type);

            return;
        }
    }

    //==============================================================================
     //TEMPLATE MAINTENANCE
    private function saveMaintenanceTemplate($params) {

        $cls         = new SalesQuotationMaintenanceTemplateClass($this->db);
        $clsTask     = new SalesQuotationMaintenanceHeaderTemplateClass($this->db);
        $clsTaskDtl  = new SalesQuotationMaintenanceDetailTemplateClass($this->db);
        
        $maintenance                   = $params['data'];
        $maintenance_id                = $params['maintenance_id'];
        $maintenance_currency          = $params['maintenance_currency'];
        $subtotal_maintenance          = $params['subtotal_maintenance'];
        $disc_type_maintenance         = $params['disc_type_maintenance'];
        $disc_percentage_maintenance   = $params['disc_percentage_maintenance'];
        $disc_total_maintenance        = $params['disc_total_maintenance'];
        $gst_percentage_maintenance    = $params['gst_percentage_maintenance'];
        $gst_total_maintenance         = $params['gst_total_maintenance'];
        $grand_total_maintenance       = $params['grand_total_maintenance'];

        $option                         = $params['option_template'];
        $template_id                    = $params['template_id'];

        $datas      = array() ;
        $orgid      = $_SESSION[SE_ORGID] ;
        $modifyby   = $_SESSION[SE_USERID] ;
        $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
        $dte        = date_create('now')->format('Y-m-d') ;
        $ws         = $_SESSION[SE_REMOTE_IP];

        if($option==0) {
            //UPDATE TEMPLATE
            // $tempate_name   = $this->getParam($params,'new_name','');
     
            //do not update name if new name is empty
            // if( $tempate_name != '' ){
            //     $check_name = $cls->checkName($tempate_name);
    
            //     if($check_name){
            //         $this->sendJsonResponse(Status::Error,"Template name is already in use","",$this->type);
            //         return;
            //     }

            //     $datas[]    = $this->db->fieldValue(SalesQuotationMaintenanceTemplateTable::C_TEMP_NAME,$params['new_name']);

            //     $cls->updateRecord($template_id,$datas) ;

            // }

            try {
                $clsTask->deleteRecord($template_id);
                $clsTaskDtl->deleteTask($template_id);

                //header
                $datas=[];

                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_ORG_ID,$orgid) ;
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_WS_ID,$ws) ;
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_MODIFY_BY,$modifyby) ;
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_CREATE_BY,$modifyby) ;
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_MODIFY_DATE,$modifydate) ;
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_CREATE_DATE,$modifydate) ;
                
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_ID,$maintenance_id) ;
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_QUOTATION_ID,$template_id) ;
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_CURRENCY,$maintenance_currency) ;
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_SUBTOTAL,$this->getParam($params,'subtotal_maintenance',"0.0000"));
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_DISC_TYPE,$this->getParam($params,'disc_type_maintenance',""));
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_DISC_PERCENTAGE,$this->getParam($params,'disc_percentage_maintenance',"0.00"));
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_DISC_TOTAL,$this->getParam($params,'disc_total_maintenance',"0.0000"));
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_GST_PERCENTAGE,$this->getParam($params,'gst_percentage_maintenance',"0.00"));
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_GST_TOTAL,$this->getParam($params,'gst_total_maintenance',"0.0000"));
                $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_GRAND_TOTAL,$this->getParam($params,'grand_total_maintenance',"0.0000"));

                $clsTask->addRecord($datas) ; 

                //detail
                $encodes = json_decode($maintenance,true);
                $line_id        = 1;
                if(!is_null($encodes) && count($encodes)>0){

                    foreach ($encodes as $encode) {

                        $datas=[];

                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_ORG_ID,$orgid) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_WS_ID,$ws) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_MODIFY_BY,$modifyby) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_CREATE_BY,$modifyby) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_MODIFY_DATE,$modifydate) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_CREATE_DATE,$modifydate) ;

                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_DETAIL_ID,$line_id) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_ID,$maintenance_id) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_QUOTATION_ID,$template_id) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_DESC,htmlspecialchars($encode['desc'])) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_COMMENT,htmlspecialchars($encode['comment'])) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_AMOUNT,floatval(str_replace(',', '', $encode['amount']))) ;
                                
                        $line_id ++;
                    
                        $clsTaskDtl->addRecord($datas) ;
                    }
                }

                $this->sendJsonResponse(Status::Ok,"Template Name successfully updated to the system.",$datas,$this->type) ;
                return;
            } catch (Exception $e) {
                Log::write('[Sales Quotation Maintenance Template]' . $e->getMessage());
                $this->sendJsonResponse(Status::Error,"Sorry, there is a error in updating Template Name to the system.","",$this->type) ;
                return;
            }
        } else {
            //SAVE TEMPLATE
            $tempate_name   = $this->getParam($params,'name','');
            $line_id        = 1;
    
            $check_name = $cls->checkName($tempate_name);
    
            if($check_name){
                $this->sendJsonResponse(Status::Error,"Template name is already in use","",$this->type);
                return;
            }

            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTemplateTable::C_TEMP_NAME,$tempate_name) ;
            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTemplateTable::C_ORG_ID,$orgid) ;
            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTemplateTable::C_WS_ID,$ws) ;
            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTemplateTable::C_MODIFY_BY,$modifyby) ;
            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTemplateTable::C_CREATE_BY,$modifyby) ;
            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTemplateTable::C_MODIFY_DATE,$modifydate) ;
            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceTemplateTable::C_CREATE_DATE,$modifydate) ;

            try {
               $id = $cls->addRecord($datas) ;
             
                if ($id > 0) {

                    //header
                    $datas=[];

                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_ORG_ID,$orgid) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_WS_ID,$ws) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_MODIFY_BY,$modifyby) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_CREATE_BY,$modifyby) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_MODIFY_DATE,$modifydate) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_CREATE_DATE,$modifydate) ;
                    
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_ID,$maintenance_id) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_QUOTATION_ID,$id) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_CURRENCY,$maintenance_currency) ;
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_SUBTOTAL,$this->getParam($params,'subtotal_maintenance',"0.0000"));
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_DISC_TYPE,$this->getParam($params,'disc_type_maintenance',""));
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_DISC_PERCENTAGE,$this->getParam($params,'disc_percentage_maintenance',"0.00"));
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_DISC_TOTAL,$this->getParam($params,'disc_total_maintenance',"0.0000"));
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_GST_PERCENTAGE,$this->getParam($params,'gst_percentage_maintenance',"0.00"));
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_GST_TOTAL,$this->getParam($params,'gst_total_maintenance',"0.0000"));
                    $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceHeaderTemplateTable::C_GRAND_TOTAL,$this->getParam($params,'grand_total_maintenance',"0.0000"));

                    $clsTask->addRecord($datas) ; 

                    //detail
                    $encodes = json_decode($maintenance,true);
                    if(!is_null($encodes) && count($encodes)>0){
                        foreach ($encodes as $encode) {

                            $datas=[];

                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_ORG_ID,$orgid) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_WS_ID,$ws) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_MODIFY_BY,$modifyby) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_CREATE_BY,$modifyby) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_MODIFY_DATE,$modifydate) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_CREATE_DATE,$modifydate) ;

                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_DETAIL_ID,$line_id) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_ID,$maintenance_id) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_QUOTATION_ID,$id) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_DESC,htmlspecialchars($encode['desc'])) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_COMMENT,htmlspecialchars($encode['comment'])) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationMaintenanceDetailTemplateTable::C_AMOUNT,floatval(str_replace(',', '', $encode['amount']))) ;
           
                            $line_id ++;
                     
                            $clsTaskDtl->addRecord($datas) ;                        
                        }
                    }

                    $this->sendJsonResponse(Status::Ok,"Success","",$this->type);
                    return;
                }else{
                    $this->sendJsonResponse(Status::Error,"Failed to do database operation","",$this->type);
                    return;
                }
                

            } catch(Exception $e){

                Log::write("[Sales Quotation Maintenance Template]" . $e->getMessage());

                $this->sendJsonResponse(Status::Error,"Failed to do database operation","",$this->type);

                return;
            }
        }
    }

    private function loadViewMaintenanceTemplate($params) {
        $cls = new SalesQuotationMaintenanceTemplateClass($this->db);

        $rows = $cls->getAllTemplate();

        $vls   = array() ;
        $vls[] = array ('code'=>"0",'desc'=>"--- Select Template ---") ;
        
        if(!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $vls[] = array ('code'=>$row[SalesQuotationMaintenanceTemplateTable::C_ID],'desc'=>$row[SalesQuotationMaintenanceTemplateTable::C_TEMP_NAME]) ;
            }           
        }
        $data = [];
        $data['load_option'] = Util::createOptionValue($vls) ;

        $this->sendJsonResponse(Status::Ok,"Success",$data,$this->type);
    }

    private function loadViewMaintenanceTemplateList($params) {
        $cls = new SalesQuotationMaintenanceTemplateClass($this->db);

        $rows = $cls->getAllTemplate();
        $vls   = array() ;
        $vls[] = array ('code'=>"0",'desc'=>"--- Select Template ---") ;
        
        if(!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $vls[] = array ('code'=>$row[SalesQuotationMaintenanceTemplateTable::C_ID],'desc'=>$row[SalesQuotationMaintenanceTemplateTable::C_TEMP_NAME]) ;
            }           
        }
        $data = [];
        $data['load_option'] = Util::createOptionValue($vls) ;

        $this->sendJsonResponse(Status::Ok,"Success",$data,$this->type);
    }

    private function loadMaintenanceTemplate($params) {
        $cls = new SalesQuotationMaintenanceHeaderTemplateClass($this->db);
        $clsDtl = new SalesQuotationMaintenanceDetailTemplateClass($this->db);

        $id = $this->getParamInt($params,'template_id',0);

        $rowHeader = $cls->getRecord($id) ;

        $rows = $clsDtl->getSalesQuotationMaintenanceDetailTemplate($id) ;
        $datas = [];
        if (!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $data               = [] ;
                $data['id']         = $row[SalesQuotationMaintenanceDetailTemplateTable::C_DETAIL_ID];
                $data['desc']       = htmlspecialchars_decode($row[SalesQuotationMaintenanceDetailTemplateTable::C_DESC]);
                $data['comment']    = htmlspecialchars_decode($row[SalesQuotationMaintenanceDetailTemplateTable::C_COMMENT]);
                $data['amount']     = number_format($row[SalesQuotationMaintenanceDetailTemplateTable::C_AMOUNT], 2);

                array_push($datas,$data);
            }
        }

        $json_array = json_encode($datas,true);

        $vls =[];
        $vls['salesquotation_maintenance']  = $json_array;
        $vls['maintenance_id']              = $rowHeader[SalesQuotationMaintenanceHeaderTemplateTable::C_ID];
        $vls['maintenance_currency']        = $rowHeader[SalesQuotationMaintenanceHeaderTemplateTable::C_CURRENCY];
        $vls['subtotal_maintenance']        = number_format($rowHeader[SalesQuotationMaintenanceHeaderTemplateTable::C_SUBTOTAL], 2);
        $vls['disc_type_maintenance']       = trim($rowHeader[SalesQuotationMaintenanceHeaderTemplateTable::C_DISC_TYPE]);
        $vls['disc_percentage_maintenance'] = number_format($rowHeader[SalesQuotationMaintenanceHeaderTemplateTable::C_DISC_PERCENTAGE], 0);
        $vls['disc_total_maintenance']      = number_format($rowHeader[SalesQuotationMaintenanceHeaderTemplateTable::C_DISC_TOTAL], 2);
        $vls['gst_percentage_maintenance']  = number_format($rowHeader[SalesQuotationMaintenanceHeaderTemplateTable::C_GST_PERCENTAGE], 0);
        $vls['gst_total_maintenance']       = number_format($rowHeader[SalesQuotationMaintenanceHeaderTemplateTable::C_GST_TOTAL], 2);
        $vls['grand_total_maintenance']     = number_format($rowHeader[SalesQuotationMaintenanceHeaderTemplateTable::C_GRAND_TOTAL], 2);

        $this->sendJsonResponse(Status::Ok,"Success",$vls,$this->type);
    }

    private function deleteMaintenanceTemplate($params) {
        $cls                = new SalesQuotationMaintenanceTemplateClass($this->db);
        $clsMaintenance     = new SalesQuotationMaintenanceHeaderTemplateClass($this->db);
        $clsMaintenanceDtl  = new SalesQuotationMaintenanceDetailTemplateClass($this->db);

        $id = $this->getParamInt($params,'template_id',0);

        if($id == 0){
            $this->sendJsonResponse(Status::Error,"Please provide id before deleting","",$this->type);
            return;
        }

        try{
            $clsMaintenance->deleteRecord($id);
            $clsMaintenanceDtl->deleteTask($id);
            $cls->deleteRecord($id);

            $this->sendJsonResponse(Status::Ok,"Template is deleted","",$this->type);

            return;
        }catch(Exception $e){
            Log::write("[Sales Quotation Maintenance Template]" . $e->getMessage());
            $this->sendJsonResponse(Status::Error,"Failed to do database operation","",$this->type);

            return;
        }
    }

    //=============================================================================//

    //TEMPLATE COVER
    private function saveCoverTemplate($params) {
        $cls     = new SalesQuotationCoverTemplateClass($this->db);
        $clsTask = new SalesQuotationCoverDetailTemplateClass($this->db);
        
        $salesquotation_cover      = $params['data'];
        $option                       = $params['option_template'];
        $template_id                  = $params['template_id'];

        $datas      = array() ;
        $orgid      = $_SESSION[SE_ORGID] ;
        $modifyby   = $_SESSION[SE_USERID] ;
        $modifydate = date_create('now')->format('Y-m-d H:i:s') ;
        $dte        = date_create('now')->format('Y-m-d') ;
        $ws         = $_SESSION[SE_REMOTE_IP];
     
        if($option==0) {
            //UPDATE TEMPLATE
            // $tempate_name   = $this->getParam($params,'new_name','');
     
            //do not update name if new name is empty
            // if( $tempate_name != '' ){
            //     $check_name = $cls->checkName($tempate_name);
    
            //     if($check_name){
            //         $this->sendJsonResponse(Status::Error,"Template name is already in use","",$this->type);
            //         return;
            //     }

            //     $datas[]    = $this->db->fieldValue(SalesQuotationCoverTemplateTable::C_TEMP_NAME,$params['new_name']);
            //     $cls->updateRecord($template_id,$datas) ;

            // }

            try {
                $clsTask->deleteTask($template_id);

                $encodes = json_decode($salesquotation_cover,true);

                if(!is_null($encodes) && count($encodes)>0){
                    $line_no = 1000;
                    foreach ($encodes as $encode) {

                        $datas=[];

                        

                        $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_ORG_ID,$orgid) ;

                        $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_WS_ID,$ws) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_MODIFY_BY,$modifyby) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_CREATE_BY,$modifyby) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_MODIFY_DATE,$modifydate) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_CREATE_DATE,$modifydate) ;

                        $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_LINE_NO, $line_no) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_PAGE,$encode['cover_page']) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_PAGE_LINE,$encode['cover_page_line']) ;
                        $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_DESC,htmlspecialchars($encode['cover_desc'])) ; 
                    
                        $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_ID,$template_id) ;
                        
                        $mesg = "";
                        if(isset($encode['cover_document'])) {
                            $document =  $encode['cover_document'];

                        } else {
                            $document = null;
                        }

                        if(isset($encode['temp_filename'])) {
                            $temp_filename =  $encode['temp_filename'];

                        } else {
                            $temp_filename = "";
                        }

                        if ($document != null) {
                            $pi = pathinfo(basename($document));
                            $ext = $pi['extension'];

                            if(isset($encode['cover_page'])) {
                                $coverpage =  $encode['cover_page'];
                            } else {
                                $coverpage = "";
                            }
                            $filename = "cover_page_".$coverpage.".".$ext ;
                                
                            
                            if (file_exists($document)) {
                                $newPath = PATH_SALES_QUOTATION_TEMPLATE_OUTPUT. "cover_page/" .$template_id. "/" ;
                                if (!file_exists($newPath)) {
                                    mkdir($newPath, 0777, true);
                                }
                                $newfile = $newPath . $filename ;
                                if (file_exists($newfile)) {
                                    unlink($newfile) ;
                                }
                                if (!copy($document, $newfile)) {
                                    $mesg .= " Error in copying the file." ;
                                }
                                unlink($document) ;
                            } else {
                                $mesg .= " File not found in the upload directory." ;
                            }

                            if($filename != "") {
                                $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_DOCUMENT,$filename);
                            }
                        }               
                    
                        $clsTask->addRecord($datas) ;     
                        $line_no += 1;
                    }
        
                }

                $this->sendJsonResponse(Status::Ok,"Template Name successfully updated to the system.",$datas,$this->type) ;
                return;
            } catch (Exception $e) {
                Log::write('[Sales Quotation Cover Template]' . $e->getMessage());
                $this->sendJsonResponse(Status::Error,"Sorry, there is a error in updating Template Name to the system.","",$this->type) ;
                return;
            }
        } else {
            //SAVE TEMPLATE
            $tempate_name   = $this->getParam($params,'name','');
    
            $check_name = $cls->checkName($tempate_name);
    
            if($check_name){
                $this->sendJsonResponse(Status::Error,"Template name is already in use","",$this->type);
                return;
            }

            $datas[] = $this->db->fieldValue(SalesQuotationCoverTemplateTable::C_TEMP_NAME,$tempate_name) ;
            $datas[] = $this->db->fieldValue(SalesQuotationCoverTemplateTable::C_ORG_ID,$orgid) ;
            $datas[] = $this->db->fieldValue(SalesQuotationCoverTemplateTable::C_WS_ID,$ws) ;
            $datas[] = $this->db->fieldValue(SalesQuotationCoverTemplateTable::C_MODIFY_BY,$modifyby) ;
            $datas[] = $this->db->fieldValue(SalesQuotationCoverTemplateTable::C_CREATE_BY,$modifyby) ;
            $datas[] = $this->db->fieldValue(SalesQuotationCoverTemplateTable::C_MODIFY_DATE,$modifydate) ;
            $datas[] = $this->db->fieldValue(SalesQuotationCoverTemplateTable::C_CREATE_DATE,$modifydate) ;

            try {

               $id = $cls->addRecord($datas) ;
             
                if ($id > 0) {
                
                    $encodes = json_decode($salesquotation_cover,true);

                    if(!is_null($encodes) && count($encodes)>0){
                        $line_no = 1000;
                        foreach ($encodes as $encode) {

                            $datas=[];

                            $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_ORG_ID,$orgid) ;

                            $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_WS_ID,$ws) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_MODIFY_BY,$modifyby) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_CREATE_BY,$modifyby) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_MODIFY_DATE,$modifydate) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_CREATE_DATE,$modifydate) ;

                            $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_LINE_NO, $line_no) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_PAGE,$encode['cover_page']) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_PAGE_LINE,$encode['cover_page_line']) ;
                            $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_DESC,htmlspecialchars($encode['cover_desc'])) ; 
                    
                            $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_ID,$id) ;
                                          
                            $mesg = "";

                            if(isset($encode['cover_document'])) {
                                $document =  $encode['cover_document'];

                            } else {
                                $document = null;
                            }

                            if(isset($encode['temp_filename'])) {
                                $temp_filename =  $encode['temp_filename'];

                            } else {
                                $temp_filename = "";
                            }

                            if ($document != null) {
                                $pi = pathinfo(basename($document));
                                $ext = $pi['extension'];

                                if(isset($encode['cover_page'])) {
                                    $coverpage =  $encode['cover_page'];
                                } else {
                                    $coverpage = "";
                                }
                                $filename = "cover_page_".$coverpage.".".$ext ;
                                
                                if (file_exists($document)) {
                                    $newPath = PATH_SALES_QUOTATION_TEMPLATE_OUTPUT. "cover_page/" .$id. "/" ;
                                    if (!file_exists($newPath)) {
                                        mkdir($newPath, 0777, true);
                                    }
                                    $newfile = $newPath . $filename ;
                                    if (file_exists($newfile)) {
                                        unlink($newfile) ;
                                    }
                                    if (!copy($document, $newfile)) {
                                        $mesg .= " Error in copying the file." ;
                                    }
                                    unlink($document) ;
                                } else {
                                    $mesg .= " File not found in the upload directory." ;
                                }

                                if($filename != "") {
                                    $datas[] = $this->db->fieldValue(SalesQuotationCoverDetailTemplateTable::C_DOCUMENT,$filename);
                                }
                            }

                            $clsTask->addRecord($datas) ;                        
                            $line_no += 1;
                        }
            
                    }

                    $this->sendJsonResponse(Status::Ok,"Success","",$this->type);

                    return;
                    
                }else{

                    $this->sendJsonResponse(Status::Error,"Failed to do database operation","",$this->type);
                    return;

                }
                

            } catch(Exception $e){

                Log::write("[Sales Quotation Cover Template]" . $e->getMessage());

                $this->sendJsonResponse(Status::Error,"Failed to do database operation","",$this->type);

                return;
            }
        }
    }

    private function loadViewCoverTemplate($params) {
        $cls = new SalesQuotationCoverTemplateClass($this->db);

        $rows = $cls->getAllTemplate();

        $vls   = array() ;
        $vls[] = array ('code'=>"0",'desc'=>"--- Select Template ---") ;
        
        if(!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $vls[] = array ('code'=>$row[SalesQuotationCoverTemplateTable::C_ID],'desc'=>$row[SalesQuotationCoverTemplateTable::C_TEMP_NAME]) ;
            }           
        }
        $data = [];
        $data['load_option'] = Util::createOptionValue($vls) ;

        $this->sendJsonResponse(Status::Ok,"Success",$data,$this->type);
    }

    private function loadViewCoverTemplateList($params) {
        $cls = new SalesQuotationCoverTemplateClass($this->db);

        $rows = $cls->getAllTemplate();

        $vls   = array() ;
        $vls[] = array ('code'=>"0",'desc'=>"--- Select Template ---") ;
        
        if(!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $vls[] = array ('code'=>$row[SalesQuotationCoverTemplateTable::C_ID],'desc'=>$row[SalesQuotationCoverTemplateTable::C_TEMP_NAME]) ;
            }           
        }
        $data = [];
        $data['load_option'] = Util::createOptionValue($vls) ;

        $this->sendJsonResponse(Status::Ok,"Success",$data,$this->type);
    }

    private function loadCoverTemplate($params) {
        $cls = new SalesQuotationCoverDetailTemplateClass($this->db);

        $id = $this->getParamInt($params,'template_id',0);

        $rows = $cls->getSalesQuotationCoverTemplate($id) ;
        $datas = [];
        if (!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {

                $data           = [] ;

                $data['cover_id']           = $row[SalesQuotationCoverDetailTemplateTable::C_DETAIL_ID];
                $data['cover_line_no']      = $row[SalesQuotationCoverDetailTemplateTable::C_LINE_NO];
                $data['cover_page']         = $row[SalesQuotationCoverDetailTemplateTable::C_PAGE];
                $data['cover_page_line']    = $row[SalesQuotationCoverDetailTemplateTable::C_PAGE_LINE];
                $data['cover_document']     = $row[SalesQuotationCoverDetailTemplateTable::C_DOCUMENT];
                $data['cover_desc']         = $row[SalesQuotationCoverDetailTemplateTable::C_DESC];

                array_push($datas,$data);
            }
        }

        $json_array = json_encode($datas,true);

        $vls =[];
        $vls['salesquotation_cover'] = $json_array;

        $this->sendJsonResponse(Status::Ok,"Success",$vls,$this->type);
    }

    private function deleteCoverTemplate($params) {
        $cls     = new SalesQuotationCoverTemplateClass($this->db);
        $clsTask = new SalesQuotationCoverDetailTemplateClass($this->db);

        $id = $this->getParamInt($params,'template_id',0);

        if($id == 0){
            $this->sendJsonResponse(Status::Error,"Please provide id before deleting","",$this->type);
            return;
        }

        try{
            $clsTask->deleteTask($id);
            $cls->deleteRecord($id);

            $directory = PATH_SALES_QUOTATION_TEMPLATE_OUTPUT. "cover_page/" .$id. "/";
            if(file_exists($directory)){
                $this->recursiveRemoveDirectory($directory);
            }

            $this->sendJsonResponse(Status::Ok,"Template is deleted","",$this->type);

            return;
        }catch(Exception $e){

            Log::write("[Sales Quotation Cover Template]" . $e->getMessage());

            $this->sendJsonResponse(Status::Error,"Failed to do database operation","",$this->type);

            return;
        }
    }

    //=================================================================================================================

    private function processSalesQuotationSubmit($params){
        $cls            = new SalesQuotationClass($this->db);
        $companyCls     = new CompanyClass($this->db);

        $url = $this->getBaseURL();

        $id = $this->getParamInt($params,'id',0);
        $approver = $this->getParamInt($params,'approver',0);

        if($id == 0){
            $this->sendJsonResponse(Status::Error,"Email engine is not ready, please draft your Sales Quotation first.","",$this->type) ;
            return;
        }

        $result = false;
        
        try{
            $row           = $cls->getRecord($id);

            $company_id     = $row[SalesQuotationTable::C_BU];
            $row_com        = $companyCls->getRecord($company_id) ;
            $opt            = new CompanyOptions() ;
            $opt->loadXml($row_com[CompanyTable::C_OPTIONS]) ;
            $op             = $opt->getOption() ;

            $quot_title     = $row[SalesQuotationTable::C_TITLE];
            $customer_quot_number = $row[SalesQuotationTable::C_CUSTOMER_NUMBER];
         
            if(trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]) == "") {
                if($row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "" || $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "0") {
                    if(strpos($row[SalesQuotationTable::C_NUMBER], "-") > 0)
                        $quot_no     = substr($row[SalesQuotationTable::C_NUMBER], 0, strpos($row[SalesQuotationTable::C_NUMBER], "-"));
                    else 
                        $quot_no     = $row[SalesQuotationTable::C_NUMBER];
                } else {
                    $quot_no     = substr($row[SalesQuotationTable::C_NUMBER], 0, strpos($row[SalesQuotationTable::C_NUMBER], "-")) . "-" . $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION];
                }
                $customer_quot_number = $quot_no;
            } else {
                $customer_quot_number = trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]);
            }
            
            $internal_prefix = trim($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_INTERNAL_PREFIX]);
            $customer_quot_number = str_replace($internal_prefix, "", $customer_quot_number);

            $pdf_filename = $quot_title." - ".$customer_quot_number . ".pdf";
            log::write("processSalesQuotationSubmit = ". $pdf_filename);
         
            $dir = PATH_SALES_QUOTATION_OUTPUT . $id. "/";
            $path = $dir .$pdf_filename;
            if(file_exists($path)) {
                unlink($path);
            }

            $fromEmail = $op[CompanyOptions::C_EMAIL_SETTING][CompanyOptions::C_EMAIL_SETTING_SENDER];
            $custEmail      = $this->getParam($params,'to_email',"");
            $ccEmail        = $this->getParam($params,'cc_email',"");
            $contactName    = $this->getParam($params,'contact',"");
            $mail_remarks   = $this->getParam($params,'remarks',"");

            $fromEmailStr = $fromEmail;
            $fromEmails   = explode(";", $fromEmailStr);
            
            $params['outputType'] = 'save';
            // $params['quot_type'] = 0;
            $this->processSalesQuotationPrintPreview($params);

            //attachment
            $attachmentList = array();
            $attachmentList[] = $path;

            $attachments = json_decode($this->getParam($params,'attachments',""), true);
            if(!is_null($attachments) && count($attachments)>0) {
                foreach($attachments as $attachment) {
                    array_push($attachmentList, $dir . $attachment);
                }
            }

            $page = Util::convertLink("PortalSalesQuotation");
            $link = $url.'/portal/index.pzx?c='.$page.'&cmd='.Command::PortalSalesQuotationApprovalListView;

            $email_body = file_get_contents(PATH_LIB . "email_sales_quotation.txt");
        
            // $email_body = str_replace("{CONTACT_NAMES}", trim($contactName), $email_body);
            $email_body = str_replace("{REMARKS_BODY}", nl2br($mail_remarks), $email_body);
            $email_body = str_replace("{WEB_URL}", $link, $email_body);
            $email_body = str_replace("{IMAGE}", $this->getLogo($company_id), $email_body);
            $email_body = str_replace("{TITLE}", nl2br($quot_title), $email_body);
            
            $result =  $this->sendEmail("Quotation Approval for " . $quot_title, 
                                    $email_body,
                                    $fromEmails, 
                                    explode(";",$custEmail), 
                                    $ccEmail != "" ? explode(";",$ccEmail) : null,
                                    $attachmentList,
                                    $company_id,
                                    AppType::SalesQuotation,
                                    $id);           
            
            if($result){
                EmailLog::write("Email sent to --> ".$custEmail);
                
                $date = date_create('now')->format('Y-m-d H:i:s');
                
                $value = array();
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_STATUS,SalesQuotationStatus::Submitted) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_SUBMIT_DATE,$date) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_APPROVED_BY,$approver) ;
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_APPROVED_DATE,NULL_DATE) ;
                // $value[] = $this->db->fieldValue(SalesQuotationTable::C_REVISE_DATE,$date) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_BY,$_SESSION[SE_USERID]) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_DATE,$date) ;
                
                $cls->updateRecord($id, $value);
                
                $this->sendJsonResponse(Status::Ok,"Sales Quotation successfully submitted for approval.","", $this->type);
            } else {
                $this->sendJsonResponse(Status::Error,"There is an error in sending email.", "", $this->type);
            }
        } catch(Exception $e){
            Log::write("[SendEmailSalesSubmitApproval]" . $e->getMessage());
            $this->sendJsonResponse(Status::Error,"Application Error","",$this->type) ;
        }
    }

    private function processSalesQuotationIssue($params){
        $cls            = new SalesQuotationClass($this->db);
        $companyCls     = new CompanyClass($this->db);

        $id = $this->getParamInt($params,'id',0);

        if($id == 0){
            $this->sendJsonResponse(Status::Error,"Email engine is not ready, please draft your Sales Quotation first.","",$this->type) ;
            return;
        }

        $result = false;
        
        try{
            $row       = $cls->getRecord($id);

            $company_id     = $row[SalesQuotationTable::C_BU];
            $row_com        = $companyCls->getRecord($company_id) ;
            $opt            = new CompanyOptions() ;
            $opt->loadXml($row_com[CompanyTable::C_OPTIONS]) ;
            $op             = $opt->getOption() ;

            $quot_title = $row[SalesQuotationTable::C_TITLE];
            $quot_no    = $row[SalesQuotationTable::C_NUMBER];
            $customer_quot_number = $row[SalesQuotationTable::C_CUSTOMER_NUMBER];

            if(trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]) == "") {
                if($row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "" || $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "0") {
                    if(strpos($row[SalesQuotationTable::C_NUMBER], "-") > 0)
                        $quot_no     = substr($row[SalesQuotationTable::C_NUMBER], 0, strpos($row[SalesQuotationTable::C_NUMBER], "-"));
                    else 
                        $quot_no     = $row[SalesQuotationTable::C_NUMBER];
                } else {
                    $quot_no     = substr($row[SalesQuotationTable::C_NUMBER], 0, strpos($row[SalesQuotationTable::C_NUMBER], "-")) . "-" . $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION];
                }
                $customer_quot_number = $quot_no;
            } else {
                $customer_quot_number = trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]);
            }
            
            $internal_prefix = trim($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_INTERNAL_PREFIX]);
            $customer_quot_number = str_replace($internal_prefix, "", $customer_quot_number);

            $pdf_filename = $quot_title." - ".$customer_quot_number . ".pdf";
            log::write("processSalesQuotationIssue = ". $pdf_filename);
         
            $pdf_filename   = $customer_quot_number;
            $path           = PATH_SALES_QUOTATION_OUTPUT . $id. "/" .$pdf_filename;
            if(file_exists($path)) {
                unlink($path);
            }

            $fromEmail = $op[CompanyOptions::C_EMAIL_SETTING][CompanyOptions::C_EMAIL_SETTING_SENDER];
            $custEmail      = $this->getParam($params,'to_email',"");
            $ccEmail        = $this->getParam($params,'cc_email',"");
            $contactName    = $this->getParam($params,'contact',"");
            $mail_remarks   = $this->getParam($params,'remarks',"");

            $fromEmailStr = $fromEmail;
            $fromEmails   = explode(";", $fromEmailStr);

            $quot_no = $row[SalesQuotationTable::C_NUMBER];
            $quot_title = $row[SalesQuotationTable::C_TITLE];
            
            $params['outputType'] = 'save';            
            // $params['quot_type'] = 1;
            $this->processSalesQuotationPrintPreview($params);

            //attachment
            $attachmentList = $this->getDirContents(PATH_SALES_QUOTATION_OUTPUT . $id . "/");

            $email_body = file_get_contents(PATH_LIB . "email_sales_quotation_issue.txt");
        
            $email_body = str_replace("{CONTACT_NAMES}", trim($contactName), $email_body);
            $email_body = str_replace("{REMARKS_BODY}", nl2br($mail_remarks), $email_body);
            $email_body = str_replace("{IMAGE}", $this->getLogo($company_id), $email_body);
            $email_body = str_replace("{TITLE}", nl2br($quot_title), $email_body);

            $result =  $this->sendEmail("Quotation for " . $quot_title, 
                                    $email_body,
                                    $fromEmails, 
                                    explode(";",$custEmail), 
                                    explode(";",$ccEmail),
                                    $attachmentList,
                                    $company_id,
                                    AppType::SalesQuotation,
                                    $id);           
            
            if($result){
                EmailLog::write("Email sent to --> ".$custEmail);

                $date = date_create('now')->format('Y-m-d H:i:s');

                $value = array();
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_CUSTOMER_NUMBER,$customer_quot_number) ;  //first time set customer quotation number
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_STATUS,SalesQuotationStatus::Issued) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_ISSUE_DATE,$date) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_IS_CLOSED,0) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_CLOSED_DATE,NULL_DATE) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_BY,$_SESSION[SE_USERID]) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_DATE,$date) ;  
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_ACTIVE,0) ; 
                
                $cls->updateRecord($id, $value);

                $this->sendJsonResponse(Status::Ok,"Email has been sent to customer email address.","", $this->type);
            } else {
                $this->sendJsonResponse(Status::Error,"There is an error in sending email", "", $this->type);
            }
        } catch(Exception $e){
            Log::write("[SendEmailSalesIssue]" . $e->getMessage());
            $this->sendJsonResponse(Status::Error,"Application Error","",$this->type) ;
        }
    }
    
    //send revise quotation to customer
    private function processSalesQuotationRevise($params){
        $cls            = new SalesQuotationClass($this->db);
        $companyCls     = new CompanyClass($this->db);

        $id             = $this->getParamInt($params,'id',0);
        // $quot_number    = $this->getParam($params,'quot_number',"");
        // $quot_type      = $this->getParamInt($params,'quot_type',0);

        if($id == 0){
            $this->sendJsonResponse(Status::Error,"Email engine is not ready, please draft your Sales Quotation first.","",$this->type) ;
            return;
        }

        $result = false;
        
        try{            
            $row = $cls->getRecord($id);

            $company_id     = $row[SalesQuotationTable::C_BU];
            $row_com        = $companyCls->getRecord($company_id) ;
            $opt            = new CompanyOptions() ;
            $opt->loadXml($row_com[CompanyTable::C_OPTIONS]) ;
            $op             = $opt->getOption() ;

            $quot_title = $row[SalesQuotationTable::C_TITLE];
            $quot_no    = $row[SalesQuotationTable::C_NUMBER];
            $customer_quot_number = $row[SalesQuotationTable::C_CUSTOMER_NUMBER];

            if(trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]) == "") {
                if($row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "" || $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "0") {
                    if(strpos($row[SalesQuotationTable::C_NUMBER], "-") > 0)
                        $quot_no     = substr($row[SalesQuotationTable::C_NUMBER], 0, strpos($row[SalesQuotationTable::C_NUMBER], "-"));
                    else 
                        $quot_no     = $row[SalesQuotationTable::C_NUMBER];
                } else {
                    $quot_no     = substr($row[SalesQuotationTable::C_NUMBER], 0, strpos($row[SalesQuotationTable::C_NUMBER], "-")) . "-" . $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION];
                }
                $customer_quot_number = $quot_no;
            } else {
                $customer_quot_number = trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]);
            }
            
            $internal_prefix = trim($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_INTERNAL_PREFIX]);
            $customer_quot_number = str_replace($internal_prefix, "", $customer_quot_number);

            $pdf_filename = $quot_title." - ".$customer_quot_number . ".pdf";
            log::write("processSalesQuotationRevise = ". $pdf_filename);
         
            $pdf_filename   = $customer_quot_number;
            $path           = PATH_SALES_QUOTATION_OUTPUT . $id. "/" .$pdf_filename;
            if(file_exists($path)) {
                unlink($path);
            }

            $value = array();
            $date = date_create('now')->format('Y-m-d H:i:s');            
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_CUSTOMER_REVISE_DATE,$date) ;
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_IS_CLOSED,0) ;  
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_CLOSED_DATE,NULL_DATE) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_BY,$_SESSION[SE_USERID]) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_DATE,$date) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_ACTIVE,0) ; 
            
            $cls->updateRecord($id, $value);

            $fromEmail = $op[CompanyOptions::C_EMAIL_SETTING][CompanyOptions::C_EMAIL_SETTING_SENDER];
            $custEmail      = $this->getParam($params,'to_email',"");
            $ccEmail        = $this->getParam($params,'cc_email',"");
            $contactName    = $this->getParam($params,'contact',"");
            $mail_remarks   = $this->getParam($params,'remarks',"");

            $fromEmailStr = $fromEmail;
            $fromEmails   = explode(";", $fromEmailStr);

            $params['outputType'] = 'save';
            // $params['quot_type'] = 1;
            $this->processSalesQuotationPrintPreview($params);

            //attachment
            $attachmentList = $this->getDirContents(PATH_SALES_QUOTATION_OUTPUT . $id . "/");
            
            $email_body = file_get_contents(PATH_LIB . "email_sales_quotation_revise.txt");
        
            $email_body = str_replace("{CONTACT_NAMES}", trim($contactName), $email_body);
            $email_body = str_replace("{REMARKS_BODY}", nl2br($mail_remarks), $email_body);
            $email_body = str_replace("{IMAGE}", $this->getLogo($company_id), $email_body);
            $email_body = str_replace("{TITLE}", nl2br($quot_title), $email_body);

            $result =  $this->sendEmail("Quotation for " . $quot_title, 
                                    $email_body,
                                    $fromEmails, 
                                    explode(";",$custEmail), 
                                    explode(";",$ccEmail),
                                    $attachmentList,
                                    $company_id,
                                    AppType::SalesQuotation,
                                    $id);
           
            
            if($result){
                EmailLog::write("Email sent to --> ".$custEmail);

                $value = array();
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_STATUS,SalesQuotationStatus::Revised) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_REVISE_DATE,$date) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_BY,$_SESSION[SE_USERID]) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_DATE,$date) ; 
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_ACTIVE,0) ; 

                $cls->updateRecord($id, $value);

                $this->sendJsonResponse(Status::Ok,"Email has been sent to customer email address.","", $this->type);
            } else {
                $this->sendJsonResponse(Status::Error,"There is an error in sending email", "", $this->type);
            }
        } catch(Exception $e){
            Log::write("[SendEmailSalesRevise]" . $e->getMessage());
            $this->sendJsonResponse(Status::Error,"Application Error","",$this->type) ;
        }
    }
    
    private function processSalesQuotationUpdateExpected($params){
        $cls = new SalesQuotationClass($this->db);

        $id = $params['id'];

        try{
            $date = date_create('now')->format('Y-m-d H:i:s') ;

            $value = array();
            if($params['exp_accept_date'] != ""){
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_EXPECTED_ACCEPT_DATE,$this->getParam($params, 'exp_accept_date', NULL_DATE)) ;
            }
            if($params['exp_pay_date'] != ""){
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_EXPECTED_PAY_DATE,$this->getParam($params, 'exp_pay_date', NULL_DATE)) ;
                $value[] = $this->db->fieldValue(SalesQuotationTable::C_PERCENTAGE_PAYMENT,$this->getParam($params, 'percentage_payment', 0)) ;
            }
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_BY,$_SESSION[SE_USERID]) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_DATE,$date) ;
            
            $cls->updateRecord($id, $value);

            $this->sendJsonResponse(Status::Ok,"Sales Quotation successfully saved.","", $this->type);
        } catch(Exception $e){
            Log::write("[SalesExpected]" . $e->getMessage());
            $this->sendJsonResponse(Status::Error,"There is an error in accept Sales Quotation","",$this->type) ;
        }
    }

    //customer accept the quotation
    private function processSalesQuotationAccept($params){
        $cls = new SalesQuotationClass($this->db);

        $id = $params['id'];

        try{
            $date = date_create('now')->format('Y-m-d H:i:s') ;

            $value = array();
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_STATUS,SalesQuotationStatus::Accepted) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_ACCEPT_DATE,$date) ;
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_IS_CLOSED,0) ;  
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_CLOSED_DATE,NULL_DATE) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_BY,$_SESSION[SE_USERID]) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_DATE,$date) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_ACTIVE,0) ; 
            
            $cls->updateRecord($id, $value);

            $this->sendJsonResponse(Status::Ok,"Sales Quotation successfully accepted.","", $this->type);
        } catch(Exception $e){
            Log::write("[SalesAccept]" . $e->getMessage());
            $this->sendJsonResponse(Status::Error,"There is an error in accept Sales Quotation","",$this->type) ;
        }
    }

    //close quotation
    private function processSalesQuotationClosed($params){
        $cls = new SalesQuotationClass($this->db);

        $id = $params['id'];

        try{
            $date = date_create('now')->format('Y-m-d H:i:s') ;

            $value = array();
            // $value[] = $this->db->fieldValue(SalesQuotationTable::C_STATUS,SalesQuotationStatus::Closed) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_IS_CLOSED,1) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_CLOSED_DATE,$date) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_CLOSED_BY,$_SESSION[SE_USERID]) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_BY,$_SESSION[SE_USERID]) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_DATE,$date) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_ACTIVE,0) ;
            
            $cls->updateRecord($id, $value);

            $this->sendJsonResponse(Status::Ok,"Sales Quotation successfully closed.","", $this->type);
        } catch(Exception $e){
            Log::write("[processSalesQuotationClosed]" . $e->getMessage());
            $this->sendJsonResponse(Status::Error,"Sorry, there is an error in closing the Sales Quotation","",$this->type) ;
        }
    }

    //=====================================================================================
    //DOCUMENT
    private function processViewSalesQuotationAddUpload($id) {
        ob_start() ;
        
        $cls    = new SalesQuotationClass($this->db) ;
        $companyCls     = new CompanyClass($this->db);

        $row    = $cls->getRecord($id);
        $Idx    = $cls->getMaxID();
        
        $clDoc  = new SalesQuotationAttachmentClass($this->db);
        $docs   = $clDoc->getDocs($id);

        $row       = $cls->getRecord($id);

        $company_id     = $row[SalesQuotationTable::C_BU];
        $row_com        = $companyCls->getRecord($company_id) ;
        $opt            = new CompanyOptions() ;
        $opt->loadXml($row_com[CompanyTable::C_OPTIONS]) ;
        $op             = $opt->getOption() ;

        $quot_title = $row[SalesQuotationTable::C_TITLE];
        $quot_no    = $row[SalesQuotationTable::C_NUMBER];
        $customer_quot_number = $row[SalesQuotationTable::C_CUSTOMER_NUMBER];

        if(trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]) == "") {
            if($row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "" || $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "0") {
                if(strpos($row[SalesQuotationTable::C_NUMBER], "-") > 0)
                    $quot_no     = substr($row[SalesQuotationTable::C_NUMBER], 0, strpos($row[SalesQuotationTable::C_NUMBER], "-"));
                else 
                    $quot_no     = $row[SalesQuotationTable::C_NUMBER];
            } else {
                $quot_no     = substr($row[SalesQuotationTable::C_NUMBER], 0, strpos($row[SalesQuotationTable::C_NUMBER], "-")) . "-" . $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION];
            }
            $customer_quot_number = $quot_no;
        } else {
            $customer_quot_number     = trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]);
        }

        $internal_prefix = trim($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_INTERNAL_PREFIX]);
        $customer_quot_number = str_replace($internal_prefix, "", $customer_quot_number);

        $pdf_filename = $quot_title." - ".$customer_quot_number . ".pdf";
        log::write("processViewSalesQuotationAddUpload = ". $pdf_filename);
        
        include (PATH_VIEWS . "portal/salesquotation/SalesQuotationAddUploadView.php") ;
        $uploadDocContent =  Util::minifyHtml(ob_get_clean()) ;
        
        $dataReturn = array();
        $dataReturn['content'] = $uploadDocContent;
        
        $this->sendJsonResponse(Status::Ok,"Upload View",$dataReturn,$this->type);
        unset($cls);
        unset($row);
    }

    private function generateAddUploadDocViewSalesQuotationRows($docs){
        $resultRows = "";
        if (isset($docs)) {
            foreach($docs as $doc) {
                $resultRows .= "<tr id='trdocs" . $doc[SalesQuotationAttachmentTable::C_ATTACH_ID] . "'>";
                $resultRows .= "<td>".$doc[SalesQuotationAttachmentTable::C_DESC]."</td>";
                // $resultRows .= "<td> <input name='txtDescs' type='text' value='" .$doc[SalesQuotationAttachmentTable::C_REF]. "' ></td>";
                $resultRows .= "<td style='width:40px;text-align:center;'><a class='fa fa-search' title='Preview' style='color:green; margin-top: 5px;' href='javascript:' onclick='downloadSalesQuotationFile(\"" . $doc[SalesQuotationAttachmentTable::C_ID] . "\", \"" . $doc[SalesQuotationAttachmentTable::C_DOC_NAME] . "\")'></a>";
                $resultRows .= "&nbsp;&nbsp;&nbsp;<a class='fa fa-trash' title='Delete' style='color:red; margin-top: 5px;' href='javascript:' onclick='removeSalesQuotationFile(" . $doc[SalesQuotationAttachmentTable::C_ATTACH_ID] . ")'></a></td>";
                $resultRows .= "<input type='hidden' name='lblIds' value='". $doc[SalesQuotationAttachmentTable::C_ATTACH_ID]. "'>";
                $resultRows .= "</tr>";
            }
        }
        return $resultRows;
    }

    private function addUploadDoc($params) {
        
        $cls            = new SalesQuotationAttachmentClass($this->db) ;
        $clsHeader      = new SalesQuotationClass($this->db);
        $id             = $_REQUEST["salesquotation_id"];
        $attach_type    = isset($_REQUEST["attach_type"]) ? $_REQUEST["attach_type"] : 0;
        
        $docNo      = $cls->getMaxFieldBySalesQuotationId($id, SalesQuotationAttachmentTable::C_ATTACH_ID) + 1;
        
        $attach_field   = isset($_REQUEST["attach_field"]) ? $_REQUEST["attach_field"] : "";
        $attach_idx     = isset($_REQUEST["attach_idx"]) ? $_REQUEST["attach_idx"] : $docNo;
        if($attach_type == 1) {
            $docNo = $attach_idx;
        }
        $result     = true;
        $err        = "";
        $centreDocReturn  = "";

        $sizeConfigured       = $this->getSizeConfig();
        
        $limitFilesize  = $sizeConfigured * 1024;   //5000kb
        $limitSideSize  = 500;
        
        if (!isset($_FILES)) {
            $err_temp = "No upload file found." ;
            echo Status::Error . "|" . $_REQUEST['type'] . "|" . $err_temp ;
            return ;
        }   
            
        $fileNames = "";
        if($attach_type == 1) {
            $fileNames = $_FILES[$attach_field.$attach_idx]["name"]; 
        } else {
            $fileNames = $_FILES["uploadFile"]["name"]; 
        }

        for($i = 0; $i < count($fileNames); $i++) {
            $resultTemp = true;

            $size = 0;
            if($attach_type == 1) {
                $size       = $_FILES[$attach_field.$attach_idx]['size']; 
            } else {
                $size       = $_FILES["uploadFile"]['size'][$i]; 
            }
            
            //check size
            if($size <= 0) {
                $err .= ", missing upload file.";
                $result &=false;
                continue;
            }
            
            $docfile = "" ;
            if($attach_type == 1) {
                $docfile       = basename($fileNames); 
            } else {
                $docfile       = basename($fileNames[$i]); 
            }

            $pi      = pathinfo($docfile);
            $ext     = $pi['extension'];
            $exts    = array("png","jpg","jpeg","doc","docx","xls","xlsx","xlsb","pdf") ;
            if (Util::validFileExt($ext,$exts) == false) {
                $err .= ", unsupported upload file type" ;
                $result &=false;
                continue;
            }
            
            $imgExts = array("png","jpg","jpeg");
            $docExts = array("doc","docx","xls","xlsx","xlsb","pdf");
            if (Util::validFileExt($ext,$docExts) && $size > $limitFilesize) {
                $err .= ", upload file over limit. Upload file size must be less than 5000KB." ;
                $result &=false;
                continue;
            } 
            
            $docfile =  ""; 
            if($attach_type == 1) {
                $docfile =  basename($_FILES[$attach_field.$attach_idx]['name']); 
            }  else {
                $docfile =  basename($_FILES["uploadFile"]['name'][$i]); 
            }
            $pi = pathinfo($docfile);
            
            $directory = PATH_SALES_QUOTATION_OUTPUT . $id. "/";
            $newName   = "salesquotation_doc_" . time() . "_" . $docNo . "." . $ext;
            $newfile   = $directory . $newName;

            $fileUpload= "";
            if($attach_type == 1) {
                $fileUpload= $_FILES[$attach_field.$attach_idx]['tmp_name']; 
            }  else {
                $fileUpload= $_FILES["uploadFile"]['tmp_name'][$i]; 
            }
            if (!file_exists($directory)) {
                mkdir($directory, 1777);
            }
            
            $uploadResult = true;
            $temp_name = "";
            //resize image if image is too big
            if (Util::validFileExt($ext,$imgExts)) {
                $imageTemp      = "";  
                if($attach_type == 1) {
                    $imageTemp      = $_FILES[$attach_field.$attach_idx]['tmp_name'];
                }  else {
                    $imageTemp      = $_FILES['uploadFile']['tmp_name'][$i];  
                }
                $temp_name = $imageTemp;

                $imageSizeInfo    = getimagesize($imageTemp); 
                
                if($imageSizeInfo == false){
                    $err .= ", make sure image file is valid!." ;
                    $result &=false;
                    continue;
                }
                
                $image_width  = $imageSizeInfo[0]; 
                $image_height = $imageSizeInfo[1]; 
                $image_type   = $imageSizeInfo['mime'];
                $image_res    = ImageResize::createImageResource($image_type, $imageTemp);
                
                if($image_res == null){
                    $err .= ", can not create image resource." ;
                    $result &=false;
                    continue;
                }
                
                $uploadResult = ImageResize::normalResizeImage($image_res, $newfile, $image_type, $limitFilesize, $image_width, $image_height);
            } else {
                $uploadResult = move_uploaded_file($fileUpload, $newfile);
            }
            
            if ($uploadResult) {
                //save Sales Quotation Document here
                $datas = array() ;
                $datas[] = $this->db->fieldValue(SalesQuotationAttachmentTable::C_ID ,$id);
                $datas[] = $this->db->fieldValue(SalesQuotationAttachmentTable::C_ATTACH_ID , $docNo);
                $datas[] = $this->db->fieldValue(SalesQuotationAttachmentTable::C_TYPE , $attach_type);
                // $datas[] = $this->db->fieldValue(SalesQuotationAttachmentTable::C_REF , $_REQUEST['txtDesc'][$i]);
                $datas[] = $this->db->fieldValue(SalesQuotationAttachmentTable::C_DOC_NAME , $newName );
                $datas[] = $this->db->fieldValue(SalesQuotationAttachmentTable::C_ORG_ID , $_SESSION[SE_ORGID] );
                $datas[] = $this->db->fieldValue(SalesQuotationAttachmentTable::C_COY_ID , 0);

                $filename_desc = "";
                if($attach_type == 1) {
                    $filename_desc = $_FILES[$attach_field.$attach_idx]["name"];
                } else {
                    $filename_desc = $_FILES["uploadFile"]["name"][$i];
                }
                $datas[] = $this->db->fieldValue(SalesQuotationAttachmentTable::C_DESC , $filename_desc);
                    
                $cls->addRecord($datas) ;
                if($i != 0)
                    $centreDocReturn .= "~";
                    
                // $centreDocReturn .= $_FILES["uploadFile"]["name"][$i] . "|" . $newName . "|" . $_REQUEST['txtDesc'][$i] ."|". $docNo . "|" . $id;
                
                if($attach_type == 1) {
                    $centreDocReturn .= $_FILES[$attach_field.$attach_idx]["name"] . "|" . $newName ."|". $docNo . "|" . $id;
                } else {
                    $centreDocReturn .= $_FILES["uploadFile"]["name"][$i] . "|" . $newName ."|". $docNo . "|" . $id;
                }
                    
                $resultTemp = true ;
                $docNo++;
            } else {
                $resultTemp = false ;
                $err .= ", error in processing uploaded file" ;
            }
            
            $result &=$resultTemp;
        }
        
        unset($cls);
        unset($clsHeader);
        
        if($result){
            $statusSend =  Status::Ok . "*" . $centreDocReturn . "*";
        }else{
            $statusSend =  Status::Error . "*" . $centreDocReturn . "*" . $err;
            Log::write("[PortalSalesQuotationDocument]" . $err);
        }
        echo $statusSend;
    }

    private function saveDocument($params) {
        $result     = true;
        $id         = $params["salesQuotationId"];
        
        // if(isset($params["docIds"]) && isset($params["descList"])) {
        if(isset($params["docIds"])) {
            $docIds     = $params["docIds"];
            // $descList   = $params["descList"];
        } else {
            $this->sendJsonResponse(Status::Error,"No record found for updating",$id, $this->type) ;
            return;
        }
        
        $cls        = new SalesQuotationAttachmentClass($this->db);
        $allDocs    = $cls->getDocs($id);
    
        // if(count($allDocs) == 0 || count($docIds) == 0 || count($descList) == 0 ) {
        if(count($allDocs) == 0 || count($docIds) == 0) {
            $this->sendJsonResponse(Status::Error,"Sorry, there is a error in updating Sales Quotation Document to the system.",$id, $this->type) ;
            return;
        }
        
        $this->db->beginTran() ;
        try {
            foreach ($allDocs as $doc) {
                $dbDocId    = $doc[JobCentreAttachmentTable::C_ATTACH_ID];
                for($i = 0; $i < count($docIds); $i++) {
                    
                    $docId  = $docIds[$i];
                    if($docId != $dbDocId)
                        continue;
                    // $datas   = array();
                    // $datas[] = $this->db->fieldValue(JobCentreAttachmentTable::C_REF , $descList[$i]);
                    
                    // $result &= $cls->updateRecord($id, $datas, $docId);
                }
            }       
        } catch (Exception $e) {
            $this->db->rollbackTran();
            Log::write('[SalesQuotation]' . $e->getMessage());
            $this->sendJsonResponse(Status::Error,"Sorry, we are unable to process your request as there is a error in database operation.","",$this->type) ;
        }
        
        if($result) {
            $this->db->commitTran();
            $this->sendJsonResponse(Status::Ok,"Sales Quotation Document successfully updated to the system.",$id,$this->type);
        }
        else {
            $this->db->rollbackTran();
            $this->sendJsonResponse(Status::Error,"Sorry, we are unable to process your request as there is a error in database operation.","",$this->type) ;
        }
        
        unset($cls) ;
    }

    private function processDownloadFile($params) {
        $expfile = $this->getParam($params,"fn","") ;
        $id = $this->getParam($params,'id',"") ;
        // Log::write(print_r($params,true));
        
        $dir = PATH_SALES_QUOTATION_OUTPUT . $id . "/";
        $fn = $expfile;
        if ($expfile != "") {
            $docfile = $dir . $fn;

            if (file_exists($docfile)) {
                $filename = basename($expfile);
                $file_extension = strtolower(substr(strrchr($filename,"."),1));
                switch( $file_extension ) {
                    case "gif": 
                        header('Content-type: image/gif'); 
                        break;
                    case "png": 
                        header('Content-type: image/png'); 
                        break;
                    case "jpeg":
                    case "jpg": 
                        header('Content-type: image/jpeg'); 
                        break;
                    case "pdf": 
                        header('Content-type: application/pdf'); 
                        break;
                    default:
                        header('Content-disposition: attachment; filename='. $expfile);
                        header('Content-type: application/octet-stream'); 
                        break;
                }
                
                header('Content-Description: View File');
                header('Content-Transfer-Encoding: binary');
                header('Expires: 0');
                header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
                header('Pragma: public');
                header('Content-Length: ' . filesize($docfile));

                ob_clean();
                flush();
                readfile($docfile);
                exit;

            } else {
                echo "<tr><td colspan='12'>Document file not found.</td></tr>" ;
                return;
            }
        } else {
            echo "<tr><td colspan='12'>Missing document file info.</td></tr>" ;
            return;
        }
    }

    private function deleteDocument($params) {
        $id         = $params["salesquotation_id"];
        $doc_id     = $params["doc_id"];
        $attach_type = isset($params["attach_type"]) ? $params["attach_type"] : 0;

        $cls        = new SalesQuotationAttachmentClass($this->db) ;
        
        try{
            // $docItem    = $cls->getRecord($id, $doc_id);
            $filter = SalesQuotationAttachmentTable::C_ID." = ".$id." and ".SalesQuotationAttachmentTable::C_ATTACH_ID." = ".$doc_id;
            $docsItem    = $cls->getTable($filter);

            if(!is_null($docsItem) && count($docsItem)>0) {
                foreach($docsItem as $docItem) {
                    if(trim($docItem[SalesQuotationAttachmentTable::C_DOC_NAME]) != "") {
                        $directory   = PATH_SALES_QUOTATION_OUTPUT . $id. "/";
                        
                        $filePath   = $directory.$docItem[SalesQuotationAttachmentTable::C_DOC_NAME];
                        if(file_exists($filePath))
                            unlink($filePath);
                    }
                    $cls->deleteDoc($id, $doc_id);
                }
            }

            $datasReturn = array();
            $datasReturn['doc_id'] = $doc_id;
            $datasReturn['attach_type'] = $attach_type;
            
            $this->sendJsonResponse(Status::Ok,"Sales Quotation Doc successfully deleted to the system.",$datasReturn,$this->type);
        } catch (Exception $ex) {
            $this->sendJsonResponse(Status::Error,"Sorry, there is a error in deleting new Sales Quotation Document to the system.","", $this->type) ;
        }
    }

    //REVISED
    private function processViewSalesQuotationReviseAddUpload($id) {
        ob_start() ;
        
        $cls    = new SalesQuotationClass($this->db) ;
        $companyCls     = new CompanyClass($this->db);

        $row    = $cls->getRecord($id);
        $Idx    = $cls->getMaxID();
        
        $clDoc  = new SalesQuotationAttachmentClass($this->db);
        $docs   = $clDoc->getDocs($id);

        $company_id     = $row[SalesQuotationTable::C_BU];
        $row_com        = $companyCls->getRecord($company_id) ;
        $opt            = new CompanyOptions() ;
        $opt->loadXml($row_com[CompanyTable::C_OPTIONS]) ;
        $op             = $opt->getOption() ;

        $quot_title = $row[SalesQuotationTable::C_TITLE];
        $quot_no    = $row[SalesQuotationTable::C_NUMBER];
        $customer_quot_number = $row[SalesQuotationTable::C_CUSTOMER_NUMBER];

        if(trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]) == "") {
            if($row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "" || $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "0") {
                // if(strpos($row[SalesQuotationTable::C_NUMBER], "-") > 0)
                //     $quot_no     = substr($row[SalesQuotationTable::C_NUMBER], 0, strpos($row[SalesQuotationTable::C_NUMBER], "-"));
                // else
                    $quot_no     = $row[SalesQuotationTable::C_NUMBER];
            } else {
                $quot_no     = substr($row[SalesQuotationTable::C_NUMBER], 0, strpos($row[SalesQuotationTable::C_NUMBER], "-")) . "-" . $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION];
            }
            $customer_quot_number = $quot_no;
        } else {
            $customer_quot_number     = $row[SalesQuotationTable::C_CUSTOMER_NUMBER];
        }

        $internal_prefix = trim($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_INTERNAL_PREFIX]);
        $customer_quot_number = str_replace($internal_prefix, "", $customer_quot_number);

        $pdf_filename = $quot_title." - ".$customer_quot_number . ".pdf";
        log::write("processViewSalesQuotationReviseAddUpload = ". $pdf_filename);

        include (PATH_VIEWS . "portal/salesquotation/SalesQuotationReviseAddUploadView.php") ;
        $uploadDocContent =  Util::minifyHtml(ob_get_clean()) ;
        
        $dataReturn = array();
        $dataReturn['content'] = $uploadDocContent;
        
        $this->sendJsonResponse(Status::Ok,"Upload View",$dataReturn,$this->type);
        unset($cls);
        unset($row);
    }

    private function generateAddUploadReviseDocViewSalesQuotationRows($docs){
        $resultRows = "";
        if (isset($docs)) {
            foreach($docs as $doc) {
                $resultRows .= "<tr id='trdocs" . $doc[SalesQuotationAttachmentTable::C_ATTACH_ID] . "'>";
                $resultRows .= "<td>".$doc[SalesQuotationAttachmentTable::C_DESC]."</td>";
                // $resultRows .= "<td> <input name='txtDescs' type='text' value='" .$doc[SalesQuotationAttachmentTable::C_REF]. "' ></td>";
                $resultRows .= "<td style='width:40px;text-align:center;'><a class='fa fa-search' title='Preview' style='color:green; margin-top: 5px;' href='javascript:' onclick='downloadSalesQuotationFile(\"" . $doc[SalesQuotationAttachmentTable::C_ID] . "\", \"" . $doc[SalesQuotationAttachmentTable::C_DOC_NAME] . "\")'></a>";
                $resultRows .= "&nbsp;&nbsp;&nbsp;<a class='fa fa-trash' title='Delete' style='color:red; margin-top: 5px;' href='javascript:' onclick='removeSalesQuotationFile(" . $doc[SalesQuotationAttachmentTable::C_ATTACH_ID] . ")'></a></td>";
                $resultRows .= "<input type='hidden' name='lblIds' value='". $doc[SalesQuotationAttachmentTable::C_ATTACH_ID]. "'>";
                $resultRows .= "</tr>";
            }
        }
        return $resultRows;
    }

    //Submit
    private function processSalesQuotationSubmitApprovalAttachView($id) {
        ob_start() ;
        
        $cls    = new SalesQuotationClass($this->db) ;
        $companyCls     = new CompanyClass($this->db);

        $row    = $cls->getRecord($id);
        $Idx    = $cls->getMaxID();
        
        $clDoc  = new SalesQuotationAttachmentClass($this->db);
        $attachments   = $clDoc->getDocs($id, 1);

        $company_id     = $row[SalesQuotationTable::C_BU];
        $row_com        = $companyCls->getRecord($company_id) ;
        $opt            = new CompanyOptions() ;
        $opt->loadXml($row_com[CompanyTable::C_OPTIONS]) ;
        $op             = $opt->getOption() ;

        $quot_title = $row[SalesQuotationTable::C_TITLE];
        $quot_no    = $row[SalesQuotationTable::C_NUMBER];
        $customer_quot_number = $row[SalesQuotationTable::C_CUSTOMER_NUMBER];

        if(trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]) == "") {
            if($row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "" || $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "0") {
                // if(strpos($row[SalesQuotationTable::C_NUMBER], "-") > 0)
                //     $quot_no     = substr($row[SalesQuotationTable::C_NUMBER], 0, strpos($row[SalesQuotationTable::C_NUMBER], "-"));
                // else
                    $quot_no     = $row[SalesQuotationTable::C_NUMBER];
            } else {
                $quot_no     = substr($row[SalesQuotationTable::C_NUMBER], 0, strpos($row[SalesQuotationTable::C_NUMBER], "-")) . "-" . $row[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION];
            }
            $customer_quot_number = $quot_no;
        } else {
            $customer_quot_number     = $row[SalesQuotationTable::C_CUSTOMER_NUMBER];
        }

        $internal_prefix = trim($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_INTERNAL_PREFIX]);
        $customer_quot_number = str_replace($internal_prefix, "", $customer_quot_number);

        $pdf_filename = $quot_title." - ".$customer_quot_number . ".pdf";
        log::write("processSalesQuotationSubmitApprovalAttachView = ". $pdf_filename);

        include (PATH_VIEWS . "portal/salesquotation/SalesQuotationSubmitApprovalView.php") ;
        $uploadDocContent =  Util::minifyHtml(ob_get_clean()) ;
        
        $dataReturn = array();
        $dataReturn['content'] = $uploadDocContent;
        
        $this->sendJsonResponse(Status::Ok,"Upload View",$dataReturn,$this->type);
        unset($cls);
        unset($row);
    }

    private function generateAttachmentSalesQuotationSubmitApproval($attachments){
        $resultRows = "";
        if (isset($attachments)) {
            $count = 0;
            foreach($attachments as $attachment) {
                $resultRows .= "<tr id='trattachment" . $attachment[SalesQuotationAttachmentTable::C_ATTACH_ID] . "'>";
                $resultRows .= "<td style='display:none;' id='attach_name".$count."'>".$attachment[SalesQuotationAttachmentTable::C_DOC_NAME]."</td>";
                $resultRows .= "<td width='60%'>".$attachment[SalesQuotationAttachmentTable::C_DESC]."</td>";
                $resultRows .= "<td width='10%' style='width:40px;text-align:center;'><a class='fa fa-search' title='Preview' style='color:green; margin-top: 5px;' href='javascript:' onclick='downloadSalesQuotationFile(\"" . $attachment[SalesQuotationAttachmentTable::C_ID] . "\", \"" . $attachment[SalesQuotationAttachmentTable::C_DOC_NAME] . "\")'></a>";
                $resultRows .= "<input type='hidden' name='lblIds' value='". $attachment[SalesQuotationAttachmentTable::C_ATTACH_ID]. "'>";
                $resultRows .= "</tr>";
                $count++;
            }
        }
        return $resultRows;
    }

    private function processSalesQuotationApprovalListView($params) {
        ob_start() ;        
        include (PATH_VIEWS . "portal/salesquotation/ApprovalListView.php") ;
        
		$var_screen = str_replace("[index]",$params['index'], Util::minifyHtml(ob_get_clean())) ;
        $datas=[];
        $datas['htmlContent'] = $var_screen;
        $datas['headTitle']  = "Sales Quotation Approval List";
        
        $this->sendJsonResponse(Status::Ok,"Load Sales Quotation Approval List",$datas,$this->type);
    }

    private function processSalesQuotationApprovalList($params) {
        // log::write($params);
        $cls            = new SalesQuotationClass($this->db);
        $clsCompany     = new CompanyClass($this->db);
        $opt 		    = new CompanyOptions() ;
        $clsCustomer    = new CustomerClass($this->db);
        $clsContact     = new CustomerContactClass($this->db);
        $clsCurrency    = new CurrencyClass($this->db);
                
        $btnStr = "";
        $htmlStr = "";

        $rows_approval  = $cls->getApprovalList($_SESSION[SE_USERID]);
        $rows_pending   = $cls->getPendingApprovalList($_SESSION[SE_USERID]);

        $rows = array_merge($rows_approval, $rows_pending);

        if(!is_null($rows) && count($rows) > 0){
            foreach ($rows as $row) {
                $rowCompany = $clsCompany->getRecord($row[SalesQuotationTable::C_BU]);
                $opt->loadXml($rowCompany[CompanyTable::C_OPTIONS]) ;
                $op = $opt->getOption() ;                

                if($row[SalesQuotationTable::C_PROSPECT]) {
                    $company = $row[SalesQuotationTable::C_PROSPECT_NAME];
                    $contact = $row[SalesQuotationTable::C_PROSPECT_CONTACT];
                } else {
                    $rowCustomer = $clsCustomer->getRecord($row[SalesQuotationTable::C_CUSTOMER_ID]);
                    $company = $rowCustomer[CustomerTable::C_NAME] . " (" . $rowCustomer[CustomerTable::C_CODE] . ")" ;                    
                    $contact = $clsContact->getRecord($row[SalesQuotationTable::C_CONTACT_ID])[CustomerContactTable::C_NAME];
                }

                $quot_type = "";
                switch($row[SalesQuotationTable::C_TYPE]) {
                    case SalesQuotationType::Service:
                        $quot_type = "Service";
                        break;
                    case SalesQuotationType::Project:
                        $quot_type = "Project";
                        break;
                    case SalesQuotationType::Contract:
                        $quot_type = "Contract";
                        break;
                    case SalesQuotationType::Item:
                        $quot_type = "Item";
                        break;
                    case SalesQuotationType::License:
                        $quot_type = "Re-Sub";
                        break;
                    case SalesQuotationType::NewSub:
                        $quot_type = "New-Sub";
                        break;
                    default:
                        $quot_type = "";
                        break;
                }

                $quot_status = "";
                switch($row[SalesQuotationTable::C_STATUS]) {
                    case SalesQuotationStatus::Open:
                        $quot_status = "Open";
                        break;
                    case SalesQuotationStatus::Issued:
                        $quot_status = "Issued";
                        break;
                    case SalesQuotationStatus::Revised:
                        $quot_status = "Revised";
                        break;
                    case SalesQuotationStatus::Accepted:
                        $quot_status = "Accepted";
                        break;
                    case SalesQuotationStatus::Closed:
                        $quot_status = "Closed";
                        break;
                    case SalesQuotationStatus::Submitted:
                        $quot_status = "Pending Approval";
                        break;
                    case SalesQuotationStatus::Approved:
                        $quot_status = "Approved";
                        break;
                    case SalesQuotationStatus::Rejected:
                        $quot_status = "Rejected";
                        break;
                    default:
                        $quot_status = "";
                        break;
                }

                $btnStr  = "<td class=\"kt-datatable__cell\"><button type=\"button\"  class=\"btn btn-icon btn-success btn-sm btn-icon btn-icon-md\" title=\"Edit\" onclick='viewApprovalSalesQuotation(\"".$row[SalesQuotationTable::C_ID]."\");'><i class=\"fa fa-edit\"></i></button></td>";

                if($row[SalesQuotationTable::C_STATUS] != SalesQuotationStatus::Approved && $row[SalesQuotationTable::C_STATUS] != SalesQuotationStatus::Rejected) {
                    $btnStr  .= "<td class=\"kt-datatable__cell\"><button type=\"button\"  class=\"btn btn-icon btn-brand btn-sm btn-icon btn-icon-md\" title=\"Approval\" onclick='openApprovalModal(".$row[SalesQuotationTable::C_ID].", \"".$row[SalesQuotationTable::C_CUSTOMER_NUMBER]."\");'><i class=\"fa fa-check-circle\"></i></button></td>";
                }

                $htmlStr .= '<tr data-row="sales-quotation-rows-'.$row[SalesQuotationTable::C_ID].'" class="kt-datatable__row" style="left: 0px;">'.
                            '<td class="kt-datatable__cell" style="display:none;">'.$row[SalesQuotationTable::C_ID].'</td>'.
                            '<td class="kt-datatable__cell">'.$op[CompanyOptions::C_SETTING][CompanyOptions::C_SET_CODE].'</td>'.
                            '<td class="kt-datatable__cell">'.trim($row[SalesQuotationTable::C_NUMBER]).'</td>'.
                            '<td class="kt-datatable__cell">'.$quot_type.'</td>'.
                            '<td class="kt-datatable__cell">'.$company.'</td>'.
                            '<td class="kt-datatable__cell">'.$contact.'</td>'.
                            '<td class="kt-datatable__cell">'.trim($row[SalesQuotationTable::C_TITLE]).'</td>'.
                            '<td class="kt-datatable__cell">'.$clsCurrency->getRecord($row[SalesQuotationTable::C_CURRENCY])[CurrencyTable::C_REF].'</td>'.
                            '<td class="kt-datatable__cell">'.$quot_status.'</td>';

                $htmlStr .= $btnStr.'</tr>';
            }
        }
        
        $datasReturn = array();
        $datasReturn['htmlStr'] = $htmlStr;
        
        $this->sendJsonResponse(Status::Ok,"",$datasReturn,$this->type);
    }

    private function processSalesQuotationApprovalConfirm($params){
        $cls = new SalesQuotationClass($this->db);

        $id = $params['id'];

        try{
            $date = date_create('now')->format('Y-m-d H:i:s') ;

            $value = array();
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_STATUS,$this->getParam($params, "approval_status", 6)) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_APPROVED_DATE,$date) ;
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_REJECT_REASON,$this->getParam($params, "approval_reason", "")) ;
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_BY,$_SESSION[SE_USERID]) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_MODIFY_DATE,$date) ; 
            $value[] = $this->db->fieldValue(SalesQuotationTable::C_ACTIVE,0) ;
            
            $cls->updateRecord($id, $value);

            $totalApproval = intVal(count($cls->getApprovalList($_SESSION[SE_USERID]))) + intVal(count($cls->getPendingApprovalList($_SESSION[SE_USERID]))) ;

            $this->sendJsonResponse(Status::Ok,"Sales Quotation approval successfully updated into the system.",$totalApproval, $this->type);
        } catch(Exception $e){
            Log::write("[processSalesQuotationClosed]" . $e->getMessage());
            $this->sendJsonResponse(Status::Error,"Sorry, there is an error in approving the Sales Quotation","",$this->type) ;
        }
    }
    //=====================================================================================

    //proforma invoice generate
    //=====================================================================================
    private function generateInvoiceNumber($params) {
        $clsQuotation   = new SalesQuotationClass($this->db) ;

        $id = $params['id'];

        try {
            //generate
            $companyCls = new CompanyClass($this->db) ;
            $row_com    = $companyCls->getRecord($params['bu']) ;
            $opt        = new CompanyOptions() ;
            $opt->loadXml($row_com[CompanyTable::C_OPTIONS]) ;
            $op         = $opt->getOption() ;
            $max_code   = intval($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_PROFORMA_INVOICE_CODE_RN]);
            $result_code = $op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_PROFORMA_INVOICE_CODE_PREFIX] . str_pad($max_code, intval($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_PROFORMA_INVOICE_CODE_LENGTH]), "0", STR_PAD_LEFT);
            
            $datasReturn = array();
            $datasReturn['invoice_running_number'] = $max_code;
            $datasReturn['invoice_number'] = $result_code;
            
            $this->sendJsonResponse(Status::Ok,"Invoice number successfully generated.",$datasReturn, $this->type);
        } catch(Exception $e) {
            Log::write("[processSalesQuotationClosed]" . $e->getMessage());
            $this->sendJsonResponse(Status::Error,"Sorry, there is an error in generating the invoice number.","",$this->type) ;
        }
    }

    private function updateInvoiceDetail($params) {
        try {
            $cls        = new SalesQuotationClass($this->db) ;
            $clsInvoice = new InvoiceHeaderClass($this->db) ;
            
            $id                 = $this->getParamInt($params, 'id', 0);
            $bu                 = $this->getParamInt($params, 'bu', 0);

            $running_number     = 0;
            $invoice_number     = "";
            $invoice_title      = "";
            $invoice_override   = 0;
            $invoice_type       = 0;
            $invoice_value      = 0;
            $invoice_amount     = 0;
            $customer_reference = "";
            $payment_terms      = 0;
            $invoice_remarks    = "";
            $grand_total        = 0;
            
            $invoice = json_decode($this->getParam($params, 'invoice_detail', ""), true);
            if(!is_null($invoice) && count($invoice)>0) {
                $running_number     = $this->getParamInt($invoice, 'running_number', 0);
                $invoice_number     = $this->getParam($invoice, 'invoice_number', "");
                $invoice_title      = $this->getParam($invoice, 'invoice_title', "");
                $invoice_override   = $this->getParamInt($invoice, 'invoice_override', 0);
                $invoice_type       = $this->getParam($invoice, 'invoice_type', "");
                $invoice_value      = floatval(str_replace(",", "", $this->getParam($invoice, 'invoice_value', 0)));
                $customer_reference = $this->getParam($invoice, 'customer_ref', "");
                $payment_terms      = $this->getParamInt($invoice, 'payment_terms', 0);
                $invoice_remarks    = $this->getParam($invoice, 'invoice_remarks', "");
                // $grand_total        = floatval(str_replace(",", "", $this->getParam($invoice, 'grand_total', 0)));
                
                $grand_total = $cls->calculateGrandTotal($id);

                if($invoice_type == 'P') {
                    $invoice_amount = $grand_total * ($invoice_value / 100);
                } else {
                    $invoice_amount = $invoice_value;
                }
            }

            if($invoice_override==0) {
                //update running number
                $companyCls = new CompanyClass($this->db) ;
                $row_com    = $companyCls->getRecord($bu) ;
                $opt        = new CompanyOptions() ;
                $opt->loadXml($row_com[CompanyTable::C_OPTIONS]) ;
                $op         = $opt->getOption() ;

                if($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_PROFORMA_INVOICE_CODE_RN] > $running_number) {
                    $running_number = intVal($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_PROFORMA_INVOICE_CODE_RN]);
                    $invoice_number = $op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_PROFORMA_INVOICE_CODE_PREFIX] . str_pad($running_number, intval($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_PROFORMA_INVOICE_CODE_LENGTH]), "0", STR_PAD_LEFT);
                }
                $running_number += 1;
                $op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_PROFORMA_INVOICE_CODE_RN] = $running_number;
                $opt->setOption($op) ;

                $data_coy= array() ;
                $data_coy[]    = $this->db->fieldValue(CompanyTable::C_OPTIONS,$opt->getXml());
                $companyCls->updateRecord($bu,$data_coy) ;
                //==== 
            }
            
            $modifydate = date_create('now')->format('Y-m-d H:i:s') ;

            $datas = array();
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_ID,$id) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_INVOICE_NUMBER,$invoice_number) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_INVOICE_OVERRIDE,$invoice_override) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_INVOICE_TITLE,$invoice_title) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_INVOICE_TYPE,$invoice_type) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_INVOICE_VALUE,$invoice_value) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_INVOICE_AMOUNT,$invoice_amount) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_CUSTOMER_REFERENCE,$customer_reference) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_PAYMENT_TERMS,$payment_terms) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_INVOICE_REMARKS,$invoice_remarks) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_PRINT,1) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_PRINT_DATE,$modifydate) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_MODIFY_BY,$_SESSION[SE_USERID]) ; 
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_MODIFY_DATE,$modifydate) ;
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_CREATE_BY,$_SESSION[SE_USERID]) ; 
            $datas[] = $this->db->fieldValue(InvoiceHeaderTable::C_CREATE_DATE,$modifydate) ;
            $clsInvoice->addRecord($datas);
            unset($cls);
            unset($clsInvoice);

            return true;
        } catch(Exception $e) {
            Log::write("[updateInvoiceDetail]" . $e->getMessage());
            return false;
        }
    }

    private function retrieveInvoiceDetail($params) {
        try {
            $id     = $this->getParamInt($params, 'id', 0);
            $cls    = new InvoiceHeaderClass($this->db) ;
            $row   = $cls->getRecord($id);
            
            $invoice_type = $row[InvoiceHeaderTable::C_INVOICE_TYPE];
            $invoice_value = 0;
            if($invoice_type == 'P') {
                $invoice_value = number_format($row[InvoiceHeaderTable::C_INVOICE_VALUE], 0);
            } else {
                $invoice_value = number_format($row[InvoiceHeaderTable::C_INVOICE_VALUE], 2, '.', ',');
            }

            $datasReturn = array();
            $datasReturn['invoice_number']      = $row[InvoiceHeaderTable::C_INVOICE_NUMBER];
            $datasReturn['invoice_date']        = date_create($row[InvoiceHeaderTable::C_CREATE_DATE])->format('d/m/Y');
            $datasReturn['invoice_override']    = $row[InvoiceHeaderTable::C_INVOICE_OVERRIDE];
            $datasReturn['invoice_type']        = $invoice_type;
            $datasReturn['invoice_value']       = $invoice_value;
            $datasReturn['customer_reference']  = $row[InvoiceHeaderTable::C_CUSTOMER_REFERENCE];
            $datasReturn['payment_terms']       = $row[InvoiceHeaderTable::C_PAYMENT_TERMS];
            $datasReturn['invoice_remarks']     = $row[InvoiceHeaderTable::C_INVOICE_REMARKS];
            $datasReturn['invoice_title']       = $row[InvoiceHeaderTable::C_INVOICE_TITLE];

            $this->sendJsonResponse(Status::Ok,"Invoice number successfully generated.",$datasReturn, $this->type);
        } catch(Exception $e) {
            Log::write("[getInvoiceDetail]" . $e->getMessage());
            $this->sendJsonResponse(Status::Error,"Sorry, there is an error in retrieving the invoice detail.","",$this->type) ;
        }
    }
    //=====================================================================================

    //proforma invoice preview
    //=============================================================================//
    private function processInvoicePrintPreview($params) {
        $clsQuotation   = new SalesQuotationClass($this->db) ;

        $id                 = $this->getParamInt($params, 'id', 0);
        $bu                 = $this->getParamInt($params, 'bu', 0);

        $running_number     = 0;
        $invoice_number     = "";
        $invoice_title      = "";
        $invoice_override   = 0;
        $invoice_type       = 0;
        $invoice_value      = 0;
        $customer_reference = "";
        $payment_terms      = 0;
        $invoice_remarks    = "";
        $invoice_date       = date('d/m/Y');
        
        $invoice = json_decode($this->getParam($params, 'invoice_detail', ""), true);
        if(!is_null($invoice) && count($invoice)>0) {
            $running_number     = $this->getParamInt($invoice, 'running_number', -1);
            $invoice_number     = $this->getParam($invoice, 'invoice_number', "");
            $invoice_title      = $this->getParam($invoice, 'invoice_title', "");
            $invoice_override   = $this->getParamInt($invoice, 'invoice_override', 0);
            $invoice_type       = $this->getParam($invoice, 'invoice_type', "");
            $invoice_value      = floatval(str_replace(",", "", $this->getParam($invoice, 'invoice_value', 0)));
            $customer_reference = $this->getParam($invoice, 'customer_ref', "");
            $payment_terms      = $this->getParamInt($invoice, 'payment_terms', 0);
            $invoice_remarks    = $this->getParam($invoice, 'invoice_remarks', "");
        }        
        
        $invoice_updated = false;
        if($running_number != -1)
            $invoice_updated = $this->updateInvoiceDetail($params);
        
        require_once(PATH_PDF . 'tcpdf.php');
		require_once(PATH_LIB . 'RequestPdfInvoiceFooter.php');

        // create new PDF document
        $pdf = new RequestPdf(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

        // set default header data
        //$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 005', PDF_HEADER_STRING);
        
        $pdf->setPrintHeader(false);
        
        // set header and footer fonts
        $pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
        $pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));

        // set default monospaced font
        $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);

        // set margins
        $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
        $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
        // $pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

        // set auto page breaks
        // $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
        $pdf->SetAutoPageBreak(TRUE);

        // set image scale factor
        $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);

        // set some language-dependent strings (optional)
        if (@file_exists(dirname(__FILE__).'/lang/eng.php')) {
            require_once(dirname(__FILE__).'/lang/eng.php');
            $pdf->setLanguageArray($l);
        }

        // ---------------------------------------------------------

        // set font
        $pdf->SetFont('helvetica', '', 10);

        // add a page
        $pdf->AddPage();
        $totalPages = 1;

        // set cell padding
        $pdf->setCellPaddings(1, 1, 1, 1);

        // set cell margins
        //$pdf->setCellMargins(1, 1, 1, 1);

        // set color for background
        $pdf->SetFillColor(255, 255, 255);

        $outputType = "preview";
        if (isset($params['outputType'])){
            $outputType = $params['outputType'];
        }
        
        $clsCompany     = new CompanyClass($this->db) ;
        $clsUser        = new UserClass($this->db) ;
        $clsCurrency    = new CurrencyClass($this->db);
        
        $id = $params['id'];
        // $quot_type = $params['quot_type'];
        $rowQuotation   = $clsQuotation->getRecord($id);
        
        $currency = $clsCurrency->getRecord($rowQuotation[SalesQuotationTable::C_CURRENCY])[CurrencyTable::C_REF];
        
        $companyId      = $rowQuotation[SalesQuotationTable::C_BU];
        $rowCompany     = $clsCompany->getRecord($companyId) ;
        $opt            = new CompanyOptions() ;
        $opt->loadXml($rowCompany[CompanyTable::C_OPTIONS]) ;
        $op             = $opt->getOption() ;

        $quot_title = $rowQuotation[SalesQuotationTable::C_TITLE];
        $quot_no    = $rowQuotation[SalesQuotationTable::C_NUMBER];
        $customer_quot_number = $rowQuotation[SalesQuotationTable::C_CUSTOMER_NUMBER];

        $quotnumber = $quot_no;
        
        if(trim($rowQuotation[SalesQuotationTable::C_CUSTOMER_NUMBER]) == "") {
            if($rowQuotation[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "" || $rowQuotation[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION] == "0") {
                if(strpos($rowQuotation[SalesQuotationTable::C_NUMBER], "-") > 0)
                    $quot_no     = substr($rowQuotation[SalesQuotationTable::C_NUMBER], 0, strpos($rowQuotation[SalesQuotationTable::C_NUMBER], "-"));
                else 
                    $quot_no     = $rowQuotation[SalesQuotationTable::C_NUMBER];
            } else {
                $quot_no     = substr($rowQuotation[SalesQuotationTable::C_NUMBER], 0, strpos($rowQuotation[SalesQuotationTable::C_NUMBER], "-")) . "-" . $rowQuotation[SalesQuotationTable::C_CUSTOMER_REVISE_VERSION];
            }
            $customer_quot_number = $quot_no;
        } else {
            $customer_quot_number    = trim($rowQuotation[SalesQuotationTable::C_CUSTOMER_NUMBER]);
        }
        
        $internal_prefix = trim($op[CompanyOptions::C_WORKFLOW][CompanyOptions::C_SALES_QUOTATION_INTERNAL_PREFIX]);
        $customer_quot_number = str_replace($internal_prefix, "", $customer_quot_number);

        $pdf_filename = $quot_title." - ".$invoice_number . ".pdf";
        // log::write("processSalesQuotationInvoicePrintPreview = ".  $pdf_filename);

        if($rowQuotation[SalesQuotationTable::C_REVISE_TYPE] == 1) {
            $quotnumber = $customer_quot_number;
        }

        $selects = array();
        if(isset($params["select"])) {
            $selects = json_decode($params["select"], true);
        } else {
            if($rowQuotation[SalesQuotationTable::C_ISSUE_PRINT] == 1) {
                $selects[] = array("select"=>"issue", "sequence"=>$rowQuotation[SalesQuotationTable::C_ISSUE_PRINT_PAGE]);
            }
            if($rowQuotation[SalesQuotationTable::C_ITEMS_PRINT] == 1) {
                $selects[] = array("select"=>"items", "sequence"=>$rowQuotation[SalesQuotationTable::C_ITEMS_PRINT_PAGE]);
            }
            if($rowQuotation[SalesQuotationTable::C_MAINTENANCE_PRINT] == 1) {
                $selects[] = array("select"=>"maintenance", "sequence"=>$rowQuotation[SalesQuotationTable::C_MAINTENANCE_PRINT_PAGE]);
            }
            if($rowQuotation[SalesQuotationTable::C_PROJECT_PLAN_PRINT] == 1) {
                $selects[] = array("select"=>"project", "sequence"=>$rowQuotation[SalesQuotationTable::C_PROJECT_PLAN_PRINT_PAGE]);
            }
            // if($rowQuotation[SalesQuotationTable::C_COVER_PRINT] == 1) {
            //     $selects[] = array("select"=>"cover", "sequence"=>$rowQuotation[SalesQuotationTable::C_COVER_PRINT_PAGE]);
            // }
            // if($rowQuotation[SalesQuotationTable::C_FOOTER_PRINT] == 1) {
            //     $selects[] = array("select"=>"footer", "sequence"=>$rowQuotation[SalesQuotationTable::C_FOOTER_PRINT_PAGE]);
            // }
            // if($rowQuotation[SalesQuotationTable::C_APPENDIX_PRINT] == 1) {
            //     $selects[] = array("select"=>"appendix", "sequence"=>$rowQuotation[SalesQuotationTable::C_APPENDIX_PRINT_PAGE]);
            // }
            // log::write(print_r($selects,true));
        }
        if(!is_null($selects) && count($selects) > 0) {
            usort($selects, function($a, $b) {
                return $a['sequence'] - $b['sequence'];
            });
        }
        
        $logopath = Util::getCompanyLogoFile(PATH_PICTURE, $companyId);
        if ($logopath != ""){
            $logopath = "../web/picture/company-" . $companyId . "/" . $logopath;
        }
        $paynowqrpath = Util::getCompanyPayNowQRFile(PATH_PICTURE, $companyId);
        if ($paynowqrpath != ""){
            $paynowqrpath = "../web/picture/company-" . $companyId . "/" . $paynowqrpath;
        }
        
        $pdf->setCoyName($rowCompany[CompanyTable::C_DESC]);

        $companyAddress = "";
        if (trim($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_ADDR1]) != '') $companyAddress .= strtoupper($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_ADDR1]);
        if (trim($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_ADDR2]) != '') $companyAddress .= strtoupper($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_ADDR2]);
        if (trim($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_ADDR3]) != '') $companyAddress .= strtoupper($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_ADDR3]);
        if (trim($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_ADDR4]) != '') $companyAddress .= strtoupper($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_ADDR4]);
        if (trim($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_ADDR5]) != '') $companyAddress .= strtoupper($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_ADDR5]);
        if (trim($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_TEL]) != '') $companyAddress .= "  Tel:".strtoupper($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_TEL]);
        if (trim($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_FAX]) != '') $companyAddress .= "  Fax:".strtoupper($op[CompanyOptions::C_CONTACT][CompanyOptions::C_CONT_FAX]);

        $pdf->setCoyAddress($companyAddress);

        //REPORT HEADER
        $pdf = $this->createReportHeaderInvoicePreview($pdf, $logopath, $rowCompany[CompanyTable::C_DESC], $op, $rowQuotation, $currency, 
                                                        $invoice_title, $invoice_number, $invoice_date, $payment_terms, $customer_reference);

        //COLUMN HEADER
        $columnSize = array(15, 85, 30, 27, 27);
        // log::write("page height = ".$pdf->getPageHeight());
        $pdf->SetFont('helvetica', '', 9);
        $bottomHeight = $pdf->getPageHeight() - 40;
        // log::write("bottomHeight = ".$bottomHeight);
        $rowHeight = 6.409722;

        $subTotal = 0;
        $discPercentage = 0;
        $discTotal = 0;
        $gstPercentage = 0;
        $gstTotal = 0;
        $grandTotal = 0;

        $page_content = "";
        $counter = 0;

        if(!is_null($selects) && count($selects) > 0) {
            foreach($selects as $select) {
                $page_content = $select['select'];
                switch($select['select']) {
                    case "items":
                        //COLUMN HEADER
                        $pdf = $this->createLineHeaderInvoicePreview($pdf, $columnSize, $rowHeight, $currency, $page_content);
                        
                        $clsItems       = new SalesQuotationItemsClass($this->db) ;
                        $clsDetail      = new SalesQuotationItemsDetailClass($this->db) ;
                        
                        $rowsItems      = $clsItems->getRecordByQuotationId($id);
                        if(!is_null($rowsItems) && count($rowsItems) > 0) {
                            $discPercentage = $rowsItems[0][SalesQuotationItemsTable::C_DISC_PERCENTAGE];
                            $discTotal      = $rowsItems[0][SalesQuotationItemsTable::C_DISC];
                            $gstPercentage  = $rowsItems[0][SalesQuotationItemsTable::C_GST_PERCENTAGE];
                            $gstTotal       = $rowsItems[0][SalesQuotationItemsTable::C_GST];
                            $qty_total       = $rowsItems[0][SalesQuotationItemsTable::C_QTY_TOTAL];
                            $subTotal       = $rowsItems[0][SalesQuotationItemsTable::C_SUBTOTAL];
                            $grandTotal     = $rowsItems[0][SalesQuotationItemsTable::C_GRAND_TOTAL];

                            $rowsDetail     = $clsDetail->getRecordItemsDetail($id, $rowsItems[0][SalesQuotationItemsTable::C_ITEMS_ID]);                            

                            // //Detail
                            if(!is_null($rowsDetail) && count($rowsDetail) > 0){
                                $first = true;
                                $page = 1;
                                $counter = 0;
                                foreach($rowsDetail as $rowDetail){
                                    if ($page != $pdf->getPage()){
                                        $page = $pdf->getPage();
                                    }
                                    
                                    $counter++;                                    
                                    if($rowDetail[SalesQuotationItemsDetailTable::C_LINE_PHASE] == "") {
                                        $str = $rowDetail[SalesQuotationItemsDetailTable::C_LINE_DESC];
                                        if (strlen(trim($rowDetail[SalesQuotationItemsDetailTable::C_LINE_COMMENT])) > 0)
                                            $str .= "\n" . $rowDetail[SalesQuotationItemsDetailTable::C_LINE_COMMENT];
                                    } else {
                                        $str .= $rowDetail[SalesQuotationItemsDetailTable::C_LINE_PHASE] ." ". $rowDetail[SalesQuotationItemsDetailTable::C_LINE_DESC];
                                    }
                                    $pdf = $this->processStringLineInvoicePreview($pdf, $columnSize, $rowHeight, $bottomHeight, 
                                                                                $logopath, $rowCompany[CompanyTable::C_DESC], $op, 
                                                                                $currency, $str,
                                                                                number_format($rowDetail[SalesQuotationItemsDetailTable::C_LINE_QTY]), "UNIT", number_format($rowDetail[SalesQuotationItemsDetailTable::C_LINE_UNIT_PRICE], 2), number_format($rowDetail[SalesQuotationItemsDetailTable::C_LINE_DISC], 2), $rowDetail[SalesQuotationItemsDetailTable::C_LINE_DISC_DESC], number_format($rowDetail[SalesQuotationItemsDetailTable::C_LINE_AMOUNT], 2), $rowQuotation, $invoice_title, $invoice_number, $invoice_date, $payment_terms, $customer_reference, $invoice_remarks, $page_content, $counter);
                                                                                
                                    $first = false;
                                }
                            }
                        }
                        break;
                    case "maintenance":
                        //COLUMN HEADER
                        $pdf = $this->createLineHeaderInvoicePreview($pdf, $columnSize, $rowHeight, $currency, $page_content);
                        
                        $clsMaintenance = new SalesQuotationMaintenanceClass($this->db) ;
                        $clsDetail      = new SalesQuotationMaintenanceDetailClass($this->db) ;
                        
                        $rowsMaintenance    = $clsMaintenance->getRecord($id);

                        if(!is_null($rowsMaintenance) && count($rowsMaintenance) > 0) {
                            $subTotal      = $rowsMaintenance[SalesQuotationMaintenanceTable::C_SUBTOTAL];
                            $discPercentage = $rowsMaintenance[SalesQuotationMaintenanceTable::C_DISC_PERCENTAGE];
                            $discTotal     = $rowsMaintenance[SalesQuotationMaintenanceTable::C_DISC_TOTAL];
                            $gstPercentage = $rowsMaintenance[SalesQuotationMaintenanceTable::C_GST_PERCENTAGE];
                            $gstTotal      = $rowsMaintenance[SalesQuotationMaintenanceTable::C_GST_TOTAL];
                            $grandTotal    = $rowsMaintenance[SalesQuotationMaintenanceTable::C_GRAND_TOTAL];

                            $rowsDetail     = $clsDetail->getSalesQuotationMaintenance($rowsMaintenance[SalesQuotationMaintenanceTable::C_ID], $id);
                            
                            //Detail
                            if(!is_null($rowsDetail) && count($rowsDetail) > 0){
                                $first = true;
                                $counter = 0;
                                $page = 1;
                                foreach($rowsDetail as $rowDetail){
                                    if ($page != $pdf->getPage()){
                                        $page = $pdf->getPage();
                                    }
                                    
                                    $counter++;
                                    $str = $rowDetail[SalesQuotationMaintenanceDetailTable::C_DESC];
                                    if (strlen(trim($rowDetail[SalesQuotationMaintenanceDetailTable::C_COMMENT])) > 0)
                                        $str .= "\n" . $rowDetail[SalesQuotationMaintenanceDetailTable::C_COMMENT];
                                    $pdf = $this->processStringLineInvoicePreview($pdf, $columnSize, $rowHeight, $bottomHeight, 
                                                                                $logopath, $rowCompany[CompanyTable::C_DESC], $op, 
                                                                                $currency, $str,
                                                                                1, "UNIT", 0, 0, "", number_format($rowDetail[SalesQuotationMaintenanceDetailTable::C_AMOUNT], 2), $rowQuotation, $invoice_title, $invoice_number, $invoice_date, $payment_terms, $customer_reference, $invoice_remarks, $page_content, $counter); 
                                    $first = false;
                                }
                            }
                        }
                        break;
                    case "project":
                        //COLUMN HEADER
                        $pdf = $this->createLineHeaderInvoicePreview($pdf, $columnSize, $rowHeight, $currency, $page_content);

                        $clsProject     = new SalesQuotationProjectPlanClass($this->db) ;
                        $clsDetail      = new SalesQuotationProjectPlanDetailClass($this->db) ;
                        
                        $rowsProject    = $clsProject->getRecord($id);

                        if(!is_null($rowsProject) && count($rowsProject) > 0) {
                            $subTotal     = $rowsProject[SalesQuotationProjectPlanTable::C_AMOUNT];
                            $grandTotal     = $rowsProject[SalesQuotationProjectPlanTable::C_AMOUNT];

                            $rowsDetail     = $clsDetail->getSalesQuotationProjectPlan($rowsProject[SalesQuotationProjectPlanTable::C_ID], $id);
                            
                            //Detail
                            if(!is_null($rowsDetail) && count($rowsDetail) > 0){
                                $first = true;
                                $counter = 0;
                                foreach($rowsDetail as $rowDetail){                                    
                                    $counter++;
                                    $str = $rowDetail[SalesQuotationProjectPlanDetailTable::C_DESC];
                                    $pdf = $this->processStringLineInvoicePreview($pdf, $columnSize, $rowHeight, $bottomHeight, 
                                                                                $logopath, $rowCompany[CompanyTable::C_DESC], $op, 
                                                                                $currency, $str,
                                                                                0, "DAYS", $rowDetail[SalesQuotationProjectPlanDetailTable::C_PHASE], 0, "", $rowDetail[SalesQuotationProjectPlanDetailTable::C_DAYS], $rowQuotation, $invoice_title, $invoice_number, $invoice_date, $payment_terms, $customer_reference, $invoice_remarks, $page_content, $counter);        
                                    $first = false;
                                }
                            }
                        }
                        break;
                }
            }
        } else {
            //COLUMN HEADER
            $pdf = $this->createLineHeaderInvoicePreview($pdf, $columnSize, $rowHeight, $currency, $page_content);
        }


        $pdf->MultiCell($columnSize[0]+$columnSize[1]+$columnSize[2]+$columnSize[3]+$columnSize[4], $rowHeight, '- End Of Transaction -', '', 'C', 1, 1, '', '', true);
        
        if($pdf->GetY() > ($pdf->getPageHeight() - 90)) {
            $pdf->AddPage();
            //REPORT HEADER
            $pdf = $this->createReportHeaderInvoicePreview($pdf, $logopath, $rowCompany[CompanyTable::C_DESC], $op, $rowQuotation, $currency, 
                                                            $invoice_title, $invoice_number, $invoice_date, $payment_terms, $customer_reference);
            //ITEM HEADER
            $pdf = $this->createLineHeaderInvoicePreview($pdf, $columnSize, $rowHeight, $currency, $page_content);
            
            if(trim($invoice_remarks) != "") {
                $pdf->Ln(1);

                $pdf->MultiCell($columnSize[0], $rowHeight, "", '', 'L', 1, 0, '', '', true);
                $pdf->MultiCell($columnSize[1]+$columnSize[2]+$columnSize[3]+$columnSize[4], $rowHeight, "Remarks:\n".$invoice_remarks, '', 'L', 1, 1, '', '', true);
            }
            
            $bottomHeight = $pdf->getPageHeight() - 90;
        } else {
            if(trim($invoice_remarks) != "") {
                $pdf->Ln(1);

                $pdf->MultiCell($columnSize[0], $rowHeight, "", '', 'L', 1, 0, '', '', true);
                $pdf->MultiCell($columnSize[1]+$columnSize[2]+$columnSize[3]+$columnSize[4], $rowHeight, "Remarks:\n".$invoice_remarks, '', 'L', 1, 1, '', '', true);
            }

            $bottomHeight = $pdf->getPageHeight() - 90;
        }

        $border = "";
        while($pdf->GetY() < $bottomHeight){
            if ($pdf->GetY() + $rowHeight >= $bottomHeight)
                $border = "B";
                $pdf->MultiCell($columnSize[0], $rowHeight       , '', '', 'L', 1, 0, '', '', true);
                $pdf->MultiCell($columnSize[1], $rowHeight       , '', '', 'C', 1, 0, '', '', true);
                $pdf->MultiCell($columnSize[2], $rowHeight       , '', '', 'R', 1, 0, '', '', true);
                $pdf->MultiCell($columnSize[3], $rowHeight       , '', '', 'R', 1, 0, '', '', true);
                $pdf->MultiCell($columnSize[4], $rowHeight       , '', '', 'R', 1, 1, '', '', true);
        }

        $pdf = $this->printReportFooterInvoicePreview($pdf, $columnSize, $rowHeight, $bottomHeight, $paynowqrpath, $op, $rowCompany, $currency,
                                                        $invoice_updated, $invoice_type, $invoice_value, 
                                                        $subTotal, $discTotal, $gstPercentage, $gstTotal, $grandTotal);

        // $pdf->Ln(4);

        // move pointer to last page
        $pdf->lastPage();

        // // ---------------------------------------------------------

        $pdf_filename = $invoice_number;

        //Close and output PDF document
        if ($outputType == 'save'){
            if ($soId != 0){
                $path = PATH_PROFORMA_INVOICE . $id;
                if (!file_exists($path)) {
                    mkdir($path, 0777, true);
                }
                // if(!file_exists($path)){
                //     mkdir($path, 1777);
                // }
                $path .= "/" . $pdf_filename . ".pdf";
                $pdf->Output($path, 'F');
            } else {
                $path = PATH_PROFORMA_INVOICE . $id;
                if (!file_exists($path)) {
                    mkdir($path, 0777, true);
                }
                // if(!file_exists($path)){
                //     mkdir($path, 1777);
                // }

                $path = PATH_PROFORMA_INVOICE . $id. "/" .$pdf_filename. ".pdf";
                if(file_exists($path)){
                    unlink($path);
                }

                $pdf->Output($path, 'F');
            }
        } else {
            $pdf->Output($pdf_filename.'.pdf', 'I');
        }

        //============================================================+
        // END OF FILE
        //============================================================+
    }
    private function createReportHeaderInvoicePreview($pdf, $logopath, $companyname, $op, $rowQuotation, $currency, 
                                                        $invoiceTitle, $invoiceNumber, $invoiceDate, $paymentTerms, $customerRef){        
        $clsCustomer    = new CustomerClass($this->db) ;
        $clsContact     = new CustomerContactClass($this->db) ;
        $clsTerms       = new PaymentTermsClass($this->db) ;

        $service_confirmation_number = trim($rowQuotation[SalesQuotationTable::C_CUSTOMER_NUMBER]) != "" ? $rowQuotation[SalesQuotationTable::C_CUSTOMER_NUMBER] : $rowQuotation[SalesQuotationTable::C_NUMBER];

        if($rowQuotation[SalesQuotationTable::C_PROSPECT]) {
            //Header            
            $pdf = $this->printReportHeaderInvoicePreview($pdf, $logopath, 
                                                $companyname, $op, 
                                                $invoiceNumber, $invoiceDate,
                                                $customerRef, $service_confirmation_number, 
                                                $clsTerms->getDescription($paymentTerms),  $currency,
                                                $rowQuotation[SalesQuotationTable::C_PROSPECT_NAME], "", 
                                                $rowQuotation[SalesQuotationTable::C_PROSPECT_CONTACT], $rowQuotation[SalesQuotationTable::C_CONTACT_EMAIL], 
                                                $rowQuotation[SalesQuotationTable::C_CONTACT_MOBILE], $rowQuotation[SalesQuotationTable::C_CONTACT_TELEPHONE], $invoiceTitle);
        } else {
            $rowCustomer        = $clsCustomer->getRecord($rowQuotation[SalesQuotationTable::C_CUSTOMER_ID]);
            $rowContact         = $clsContact->getRecord($rowQuotation[SalesQuotationTable::C_CONTACT_ID]);
            
            $custAddress = array();
            if (trim($rowCustomer[CustomerTable::C_ADDRESS_1]) != '') $custAddress[] = trim($rowCustomer[CustomerTable::C_ADDRESS_1]);
            if (trim($rowCustomer[CustomerTable::C_ADDRESS_2]) != '') $custAddress[] = trim($rowCustomer[CustomerTable::C_ADDRESS_2]);
            if (trim($rowCustomer[CustomerTable::C_ADDRESS_3]) != '') $custAddress[] = trim($rowCustomer[CustomerTable::C_ADDRESS_3]);
            if (trim($rowCustomer[CustomerTable::C_ADDRESS_4]) != '') $custAddress[] = trim($rowCustomer[CustomerTable::C_ADDRESS_4]);
            if (trim($rowCustomer[CustomerTable::C_ADDRESS_5]) != '') $custAddress[] = trim($rowCustomer[CustomerTable::C_ADDRESS_5]);
            
            //Header
            $pdf = $this->printReportHeaderInvoicePreview($pdf, $logopath, 
                                                $companyname, $op, 
                                                $invoiceNumber, $invoiceDate,
                                                $customerRef, $service_confirmation_number, 
                                                $clsTerms->getDescription($paymentTerms),  $currency,
                                                $rowCustomer[CustomerTable::C_NAME], $custAddress, 
                                                $rowContact[CustomerContactTable::C_NAME], $rowQuotation[SalesQuotationTable::C_CONTACT_EMAIL], 
                                                $rowQuotation[SalesQuotationTable::C_CONTACT_MOBILE], $rowQuotation[SalesQuotationTable::C_CONTACT_TELEPHONE], $invoiceTitle);
        }
        
        return $pdf;
    }
    private function printReportHeaderInvoicePreview($pdf, $logopath, 
                                                    $companyName, $op,
                                                    $invoiceNumber, $invoiceDate,
                                                    $customerRef, $serviceConfirmationNo,
                                                    $paymentTerms, $currency,
                                                    $customerName, $billingAddress,
                                                    $contactName, $contactEmail,
                                                    $contactMobile, $contactFax, $invoiceTitle){
        
        
        // set font
        $pdf->SetFont('helvetica', 'B', 15);
        $pdf->MultiCell(85, 5, strtoupper($invoiceTitle), 0, 'L', 1, 1, PDF_MARGIN_LEFT + 100, 10, true);
        
        $picHeight = 32;
        if ($logopath != ""){
            $pdf->Image($logopath, PDF_MARGIN_LEFT+5, 13, 0, $picHeight);
        }
        
        $pdf->SetFont('helvetica', 'B', 9);
        $pdf->MultiCell(45, 5, "Invoice Number", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 100, 20, true);
        $pdf->MultiCell(25, 5, ":", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 140, 20, true);
        $pdf->MultiCell(40, 5, $invoiceNumber, 0, 'L', 1, 1, PDF_MARGIN_LEFT + 145, 20, true);
        $pdf->MultiCell(40, 5, "Order Date", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 100, 25, true);
        $pdf->MultiCell(25, 5, ":", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 140, 25, true);
        $pdf->MultiCell(40, 5, $invoiceDate, 0, 'L', 1, 1, PDF_MARGIN_LEFT + 145, 25, true);
        $pdf->MultiCell(40, 5, "Payment Terms", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 100, 30, true);
        $pdf->MultiCell(25, 5, ":", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 140, 30, true);
        $pdf->MultiCell(40, 5, $paymentTerms, 0, 'L', 1, 1, PDF_MARGIN_LEFT + 145, 30, true);
        $pdf->MultiCell(40, 5, "Customer Reference", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 100, 35, true);
        $pdf->MultiCell(25, 5, ":", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 140, 35, true);
        $pdf->MultiCell(40, 5, $customerRef, 0, 'L', 1, 1, PDF_MARGIN_LEFT + 145, 35, true);
        $pdf->MultiCell(45, 5, "Service Confirmation No.", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 100, 40, true);
        $pdf->MultiCell(25, 5, ":", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 140, 40,  true);
        $pdf->MultiCell(40, 5, $serviceConfirmationNo, 0, 'L', 1, 1, PDF_MARGIN_LEFT + 145, 40, true);
        $pdf->MultiCell(40, 5, "Company/GST Reg. ", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 100, 45, true);
        $pdf->MultiCell(25, 5, ":", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 140, 45,  true);
        $pdf->MultiCell(40, 5, $op[CompanyOptions::C_IRAS][CompanyOptions::C_IRAS_TAX_ID], 0, 'L', 1, 1, PDF_MARGIN_LEFT + 145, 45, true);

        $pdf->MultiCell(40, 5, "Page", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 100, 55, true);
        $pdf->MultiCell(25, 5, ":", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 140, 55,  true);
        $pdf->MultiCell(40, 5, "", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 145, 55, true);
        
        $pdf->SetFont('helvetica', 'B', 9);  
        $counterPosY = 35;
        
        $pdf->MultiCell(90, 5, "Bill To : ", 0, 'L', 1, 0, PDF_MARGIN_LEFT+5, $picHeight + $counterPosY, true);
        $pdf->MultiCell(90, 5, "Ship To : ", 0, 'L', 1, 1, PDF_MARGIN_LEFT + 100, $picHeight + $counterPosY, true);
        $counterPosY += 5;

        $pdf->MultiCell(90, 5, strtoupper($customerName), 0, 'L', 1, 0, PDF_MARGIN_LEFT+5, $picHeight + $counterPosY, true);
        $pdf->MultiCell(90, 5, strtoupper($customerName), 0, 'L', 1, 1, PDF_MARGIN_LEFT + 100, $picHeight + $counterPosY, true);
        $counterPosY += 5;
        
        $pdf->SetFont('helvetica', '', 9);
        $posY = $counterPosY;
        $counterBillingAddress = 0;
        if(!is_null($billingAddress) && count($billingAddress) > 0){
            foreach($billingAddress as $line){
                $pdf->MultiCell(90, 5, strtoupper($line), 0, 'L', 1, 0, PDF_MARGIN_LEFT+5, $picHeight + $counterPosY, true);
                $counterPosY += 5;
                $counterBillingAddress += 5;
            }
        }
        
        $counterBillingAddress = 0;
        if(!is_null($billingAddress) && count($billingAddress) > 0){
            foreach($billingAddress as $line){
                $pdf->MultiCell(90, 5, strtoupper($line), 0, 'L', 1, 0, PDF_MARGIN_LEFT + 100, $picHeight + $posY, true);
                $posY += 5;
                $counterBillingAddress += 5;
            }
        }
        $counterPosY += 3;

        // $pdf->SetFont('helvetica', 'B', 9);
        // $pdf->MultiCell(85, 5, "Attn : ", 0, 'L', 1, 0, PDF_MARGIN_LEFT+5, $picHeight + $counterPosY, true);
        $pdf->SetFont('helvetica', '', 9);
		$pdf->MultiCell(75, 5, $contactName, 0, 'L', 1, 0, PDF_MARGIN_LEFT+5, $picHeight + $counterPosY, true); 
        // $pdf->SetFont('helvetica', 'B', 9);
        // $pdf->MultiCell(85, 5, "Attn : ", 0, 'L', 1, 0, PDF_MARGIN_LEFT + 100, $picHeight + $counterPosY, true);
        $pdf->SetFont('helvetica', '', 9);
		$pdf->MultiCell(75, 5, $contactName, 0, 'L', 1, 1, PDF_MARGIN_LEFT + 100, $picHeight + $counterPosY, true); 
        $counterPosY += 8; 

        $pdf->SetFont('helvetica', 'B', 9);
        $pdf->MultiCell(30, 5, "Tel : ", 0, 'L', 1, 0, PDF_MARGIN_LEFT+5, $picHeight + $counterPosY, true);
        $pdf->SetFont('helvetica', '', 9);
        $pdf->MultiCell(30, 5, $contactMobile, 0, 'L', 1, 0, PDF_MARGIN_LEFT + 20, $picHeight + $counterPosY, true);
        $pdf->SetFont('helvetica', 'B', 9);
        $pdf->MultiCell(30, 5, "Tel : ", 0, 'L', 1, 0, PDF_MARGIN_LEFT + 100, $picHeight + $counterPosY, true);
        $pdf->SetFont('helvetica', '', 9);
        $pdf->MultiCell(30, 5, $contactMobile, 0, 'L', 1, 1, PDF_MARGIN_LEFT + 115, $picHeight + $counterPosY, true);

        $pdf->SetFont('helvetica', 'B', 9);
        $pdf->MultiCell(30, 5, "Fax : ", 0, 'L', 1, 0, PDF_MARGIN_LEFT + 40, $picHeight + $counterPosY, true);
        $pdf->SetFont('helvetica', '', 9);
        $pdf->MultiCell(30, 5, $contactFax, 0, 'L', 1, 0, PDF_MARGIN_LEFT + 50, $picHeight + $counterPosY, true);
        $pdf->SetFont('helvetica', 'B', 9);
        $pdf->MultiCell(30, 5, "Fax : ", 0, 'L', 1, 0, PDF_MARGIN_LEFT + 140, $picHeight + $counterPosY, true);
        $pdf->SetFont('helvetica', '', 9);
        $pdf->MultiCell(30, 5, $contactFax, 0, 'L', 1, 1, PDF_MARGIN_LEFT + 150, $picHeight + $counterPosY, true);
        $counterPosY += 5;

        $pdf->SetFont('helvetica', 'B', 9);
        $pdf->MultiCell(30, 5, "Email : ", 0, 'L', 1, 0, PDF_MARGIN_LEFT+5, $picHeight + $counterPosY, true);
        $pdf->SetFont('helvetica', '', 9);
		$pdf->MultiCell(75, 5, $contactEmail, 0, 'L', 1, 0, PDF_MARGIN_LEFT + 20, $picHeight + $counterPosY, true); 
        $pdf->SetFont('helvetica', 'B', 9);
        $pdf->MultiCell(30, 5, "Email : ", 0, 'L', 1, 0, PDF_MARGIN_LEFT + 100, $picHeight + $counterPosY, true);
        $pdf->SetFont('helvetica', '', 9);
		$pdf->MultiCell(75, 5, $contactEmail, 0, 'L', 1, 0, PDF_MARGIN_LEFT + 115, $picHeight + $counterPosY, true); 
        $counterPosY += 5; 

        $pdf->SetY($picHeight + $counterPosY + 5);

        return $pdf;
    }

    private function createLineHeaderInvoicePreview($pdf, $columnSize, $rowHeight, $currency, $pageContent) {      
        $border = "TB";  
        $pdf->SetFont('helvetica', 'B', 9);
        if($pageContent == "project") {
            $pdf->MultiCell($columnSize[0], 10, "Phase", $border, 'L', 1, 0, '', '', true);
        } else {
            $pdf->MultiCell($columnSize[0], 10, "S/No.", $border, 'L', 1, 0, '', '', true);
        }
        $pdf->MultiCell($columnSize[1], 10, "Description", $border, 'L', 1, 0, '', '', true);
        if($pageContent == "maintenance") {
            $pdf->MultiCell($columnSize[2], 10, '', $border, 'C', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[3], 10, '', $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[4], 10, 'Amount'."\n".$currency, $border, 'R', 1, 1, '', '', true);
        } else if($pageContent == "project") {
            $pdf->MultiCell($columnSize[2], 10, '', $border, 'C', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[3], 10, '', $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[4], 10, 'No. of Days', $border, 'R', 1, 1, '', '', true);
        } else {            
            $pdf->MultiCell($columnSize[2], 10, 'Qty', $border, 'C', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[3], 10, 'Unit Price', $border, 'R', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[4], 10, 'Amount'."\n".$currency, $border, 'R', 1, 1, '', '', true);
        }

        return $pdf;
    }
    private function processStringLineInvoicePreview($pdf, $columnSize, $rowHeight, $bottomHeight, $logopath, $companyName, $op,
                                                $currency, $str, $qty, $uom, $unitPrice, $disc, $discDesc, $amount, $quotation, 
                                                $invoiceTitle, $invoiceNumber, $invoiceDate, $paymentTerms, $customerRef, $invoiceRemarks, 
                                                $pageContent, $counter){
        
        $leftoverStr = "";
        $border = "";
        $resStr = null;

        $estimated = $pdf->getNumLines($str, $columnSize[1]);
        
        if((($estimated * $rowHeight) + $pdf->GetY()) > $bottomHeight+40){
            // log::write(($estimated * $rowHeight) + $pdf->GetY());
            // log::write($bottomHeight + 40);
            $resStr = $this->getCutPrintString($pdf, $columnSize, $rowHeight, $bottomHeight, $str);
            $leftoverStr = $resStr[0];
        } else {
            $leftoverStr = $str;
        }
        // log::write($resStr);
        
        // $pdf = $this->writeLineInvoicePreview($pdf, $columnSize, $rowHeight, $leftoverStr, $border, $qty, $uom, $unitPrice, $disc, $discDesc, $amount, $pageContent, $counter);

        if (count($resStr)>0){
            $pdf = $this->printBottomBorderInvoicePreview($pdf, $columnSize, $rowHeight);

            $pdf->AddPage();

            //REPORT HEADER
            $pdf = $this->createReportHeaderInvoicePreview($pdf, $logopath, $companyName, $op, $quotation, $currency, 
                                                            $invoiceTitle, $invoiceNumber, $invoiceDate, $paymentTerms, $customerRef);

            //ITEM HEADER
            $pdf = $this->createLineHeaderInvoicePreview($pdf, $columnSize, $rowHeight, $currency, "");
            
            $pdf = $this->writeLineInvoicePreview($pdf, $columnSize, $rowHeight, $leftoverStr, $border, $qty, $uom, $unitPrice, $disc, $discDesc, $amount, $pageContent, $counter);
            
            if(trim($resStr[1]!="")) {
                $pdf = $this->processStringLineInvoicePreview($pdf, $columnSize, $rowHeight, $bottomHeight, $logopath, $companyName, $op,
                                                                $currency, $resStr[1], $qty, $uom, $unitPrice, $disc, $discDesc, "", $quotation, 
                                                                $invoiceTitle, $invoiceNumber, $invoiceDate, $paymentTerms, $customerRef, $invoiceRemarks, 
                                                                $pageContent, "");
            }
        }
         else {
            $pdf = $this->writeLineInvoicePreview($pdf, $columnSize, $rowHeight, $leftoverStr, $border, $qty, $uom, $unitPrice, $disc, $discDesc, $amount, $pageContent, $counter);
        }
                
        return $pdf;
    }   
    private function writeLineInvoicePreview($pdf, $columnSize, $rowHeight, $str, $border, $qty, $uom, $unitPrice, $disc, $discDesc, $amount, $pageContent, $counter){
        $pdf->SetFont('helvetica', '', 9);

        $strCounter = $counter == "" ? "" : ".";

        if($pageContent == "project") {
            $pdf->MultiCell($columnSize[0], $rowHeight, $unitPrice, $border, 'L', 1, 0, '', '', true);
        } else {            
            $pdf->MultiCell($columnSize[0], $rowHeight, $counter.$strCounter, $border, 'L', 1, 0, '', '', true);
        }
        $pdf->MultiCell($columnSize[1], $rowHeight, htmlspecialchars_decode($str), $border, 'L', 1, 0, '', '', true);

        $descH = $pdf->getLastH();

        if($pageContent == "items") {
            if($qty == 0)
                $str = "";
            else
                $str = $qty . " " . $uom;
            $pdf->MultiCell($columnSize[2], $descH, $str, $border, 'C', 1, 0, '', '', true);

            if($qty == 0)
                $str = "";
            else
                $str = $unitPrice;
            $pdf->MultiCell($columnSize[3], $descH, $str, $border, 'R', 1, 0, '', '', true);
        }else{
            $pdf->MultiCell($columnSize[2], $descH, "", $border, 'C', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[3], $descH, "", $border, 'R', 1, 0, '', '', true);
        }

        $bracket = substr($amount, 0, 1) == "-" ? true : false;
        $str = $bracket == true ? "(". substr($amount, 1) .")" : $amount;
        
        $pdf->MultiCell($columnSize[4], $descH, $str, $border, 'R', 1, 1, '', '', true);

        if($disc > 0 || $discDesc != "") {
            $pdf->MultiCell($columnSize[0], $rowHeight, "", $border, 'L', 1, 0, '', '', true);
            $pdf->MultiCell($columnSize[1], $rowHeight, htmlspecialchars_decode($discDesc), $border, 'L', 1, 0, '', '', true);

            $descH = $pdf->getLastH();

            $pdf->MultiCell($columnSize[2], $descH, "", $border, 'C', 1, 0, '', '', true);

            $pdf->MultiCell($columnSize[3], $descH, "", $border, 'R', 1, 0, '', '', true);

            $str = "(".$disc.")";
            $pdf->MultiCell($columnSize[4], $descH, $str, $border, 'R', 1, 1, '', '', true);
        }
        
        return $pdf;
    }
    private function printBottomBorderInvoicePreview($pdf, $columnSize, $rowHeight){     
        $border = "";

        $pdf->MultiCell($columnSize[0], $rowHeight       , '', $border, 'L', 1, 0, '', '', true);
        $pdf->MultiCell($columnSize[1], $rowHeight       , '', $border, 'L', 1, 0, '', '', true);
        $pdf->MultiCell($columnSize[2], $rowHeight       , '', $border, 'C', 1, 0, '', '', true);
        $pdf->MultiCell($columnSize[3], $rowHeight       , '', $border, 'R', 1, 0, '', '', true);
        $pdf->MultiCell($columnSize[4], $rowHeight       , '', $border, 'R', 1, 1, '', '', true);
        
        return $pdf;
    }    
    private function printReportFooterInvoicePreview($pdf, $columnSize, $rowHeight, $bottomHeight, $paynowqrpath, $op, $rowCompany, $currency,
                                                    $invoice_updated, $invoice_type, $invoice_value, 
                                                    $subTotal, $discTotal, $gstPercentage, $gstTotal, $grandTotal){

        $total_amount_payable = 0;
        // if($invoice_updated) {
            switch($invoice_type) {
                case InvoiceType::Percentage:
                    $total_amount_payable = ($grandTotal * ($invoice_value / 100));
                    break;
                case InvoiceType::Amount:
                    $total_amount_payable = $invoice_value;
                    break;
            }
        // }

        // $pdf->SetY($bottomHeight + 5);
        
        // $pdf->MultiCell($columnSize[0]+$columnSize[1]+$columnSize[2]+$columnSize[3]+$columnSize[4], $rowHeight, '', 'B', 'C', 1, 1, '', '', true);

        $pdf->SetFont('helvetica', '', 9);
        $pdf->MultiCell(90, 1, "Goods sold are not returnable. No claim for the shortage or damaged will be accepted unless notification is made to us immediately. The goods under this invoice / delivery remain the property of our company until full payment has been received. A flat rate of 1.5% per month will be imposed on overdue payment.", 'T', 'L', 1, 0, PDF_MARGIN_LEFT, $pdf->getY()+1, true);

        $pdf->MultiCell(90, 1, "", 'T', 'L', 1, 0, PDF_MARGIN_LEFT+90, $pdf->getY(), true);

        //total
        $pdf->SetFont('helvetica', 'B', 9);
        $pdf->MultiCell(45, 1, "SUBTOTAL", 'T', 'L', 1, 0, PDF_MARGIN_LEFT+105, $pdf->getY(), true);
        $pdf->MultiCell(15, 1, ":", 'T', 'C', 1, 0, PDF_MARGIN_LEFT+145, $pdf->getY(), true);
        $pdf->MultiCell(35, 1, number_format($subTotal, 2, '.', ','), 'T', 'R', 1, 1, PDF_MARGIN_LEFT+150, $pdf->getY(), true);

        $pdf->MultiCell(45, 1, "LESS DISCOUNT", '', 'L', 1, 0, PDF_MARGIN_LEFT+105, $pdf->getY()-1, true);
        $pdf->MultiCell(15, 1, ":", '', 'C', 1, 0, PDF_MARGIN_LEFT+145, $pdf->getY(), true);
        $pdf->MultiCell(35, 1, number_format($discTotal, 2, '.', ','), '', 'R', 1, 1, PDF_MARGIN_LEFT+150, $pdf->getY(), true);

        $pdf->MultiCell(45, 1, "AFTER DISCOUNT", '', 'L', 1, 0, PDF_MARGIN_LEFT+105, $pdf->getY()-1, true);
        $pdf->MultiCell(15, 1, ":", '', 'C', 1, 0, PDF_MARGIN_LEFT+145, $pdf->getY(), true);
        $pdf->MultiCell(35, 1, number_format(($subTotal - $discTotal), 2, '.', ','), '', 'R', 1, 1, PDF_MARGIN_LEFT+150, $pdf->getY(), true);

        $pdf->MultiCell(45, 1, "GST ".number_format($gstPercentage, 0, '', '')."%", '', 'L', 1, 0, PDF_MARGIN_LEFT+105, $pdf->getY()-1, true);
        $pdf->MultiCell(15, 1, ":", '', 'C', 1, 0, PDF_MARGIN_LEFT+145, $pdf->getY(), true);
        $pdf->MultiCell(35, 1, number_format($gstTotal, 2, '.', ','), '', 'R', 1, 1, PDF_MARGIN_LEFT+150, $pdf->getY(), true);

        $pdf->MultiCell(45, 1, "GRAND TOTAL", '', 'L', 1, 0, PDF_MARGIN_LEFT+105, $pdf->getY()-1, true); 
        $pdf->MultiCell(15, 1, ":", '', 'C', 1, 0, PDF_MARGIN_LEFT+145, $pdf->getY(), true);       
        $pdf->MultiCell(35, 1, number_format($grandTotal, 2, '.', ','), '', 'R', 1, 1, PDF_MARGIN_LEFT+150, $pdf->getY(), true);

        $pdf->MultiCell(45, 10, "AMOUNT PAYABLE FOR THIS INVOICE", '', 'L', 1, 0, PDF_MARGIN_LEFT+105, $pdf->getY()-1, true); 
        $pdf->MultiCell(15, 10, "\n:", '', 'C', 1, 0, PDF_MARGIN_LEFT+145, $pdf->getY(), true);       
        $pdf->MultiCell(35, 10, "\n".number_format($total_amount_payable, 2, '.', ','), '', 'R', 1, 1, PDF_MARGIN_LEFT+150, $pdf->getY(), true);
        
        //remarks
        $pdf->SetFont('helvetica', '', 9);

        $paynowX = 0;
        $paynowY = 2;
        if($paynowqrpath != "") {
            $paynowX = 30;
            $paynowY = 0;
            $pdf->MultiCell(30, 1, "PayNow", 'T', 'C', 1, 0, PDF_MARGIN_LEFT, $pdf->getY(), true);
        }
        $pdf->MultiCell(120, 1, "Payment by Cheque should be crossed and payable to :", 'T', 'L', 1, 0, PDF_MARGIN_LEFT+$paynowX, $pdf->getY(), true);
        $pdf->MultiCell(75, 1, "For and on behalf of ", 'T', 'C', 1, 1, PDF_MARGIN_LEFT+110, $pdf->getY(), true);

        $pdf->SetFont('helvetica', '', 9);
        if($paynowqrpath != "") {
            $pdf->MultiCell(30, 1, "QR Code", '', 'C', 1, 0, PDF_MARGIN_LEFT, $pdf->getY()-2, true);
        }
        $pdf->SetFont('helvetica', 'B', 9);
        $pdf->MultiCell(120, 1, strtoupper($rowCompany[CompanyTable::C_DESC]), '', 'L', 1, 0, PDF_MARGIN_LEFT+$paynowX, $pdf->getY()-$paynowY, true);
        $pdf->MultiCell(75, 1, strtoupper($rowCompany[CompanyTable::C_DESC]), '', 'C', 1, 1, PDF_MARGIN_LEFT+110, $pdf->getY(), true);
        
        $picHeight = 25;
        if ($paynowqrpath != ""){
            $pdf->Image($paynowqrpath, PDF_MARGIN_LEFT, $pdf->getY(), 0, $picHeight);
        }

        $pdf->SetFont('helvetica', '', 9);
        $pdf->MultiCell(30, 1, "Name of Bank", '', 'L', 1, 0, PDF_MARGIN_LEFT+$paynowX, $pdf->getY()-1, true);
        $pdf->MultiCell(10, 1, ":", '', 'C', 1, 0, PDF_MARGIN_LEFT+25+$paynowX, $pdf->getY(), true);
        $pdf->MultiCell(50, 1, $op[CompanyOptions::C_BANK_DETAIL][CompanyOptions::C_BANK_DETAIL_NAME], '', 'L', 1, 1, PDF_MARGIN_LEFT+30+$paynowX, $pdf->getY(), true);

        $pdf->MultiCell(35, 1, "Account Name", '', 'L', 1, 0, PDF_MARGIN_LEFT+$paynowX, $pdf->getY()-2, true);
        $pdf->MultiCell(10, 1, ":", '', 'C', 1, 0, PDF_MARGIN_LEFT+25+$paynowX, $pdf->getY(), true);
        $pdf->MultiCell(50, 1, $op[CompanyOptions::C_BANK_DETAIL][CompanyOptions::C_BANK_DETAIL_ACCOUNT_NAME], '', 'L', 1, 1, PDF_MARGIN_LEFT+30+$paynowX, $pdf->getY(), true);

        $pdf->MultiCell(35, 1, "Account No.", '', 'L', 1, 0, PDF_MARGIN_LEFT+$paynowX, $pdf->getY()-2, true);
        $pdf->MultiCell(10, 1, ":", '', 'C', 1, 0, PDF_MARGIN_LEFT+25+$paynowX, $pdf->getY(), true);
        $pdf->MultiCell(50, 1, $op[CompanyOptions::C_BANK_DETAIL][CompanyOptions::C_BANK_DETAIL_ACCOUNT_NUMBER]." (".$currency.")", '', 'L', 1, 1, PDF_MARGIN_LEFT+30+$paynowX, $pdf->getY(), true);

        $pdf->MultiCell(35, 1, "Bank Code", '', 'L', 1, 0, PDF_MARGIN_LEFT+$paynowX, $pdf->getY()-2, true);
        $pdf->MultiCell(10, 1, ":", '', 'C', 1, 0, PDF_MARGIN_LEFT+25+$paynowX, $pdf->getY(), true);
        $pdf->MultiCell(50, 1, $op[CompanyOptions::C_BANK_DETAIL][CompanyOptions::C_BANK_DETAIL_CODE], '', 'L', 1, 1, PDF_MARGIN_LEFT+30+$paynowX, $pdf->getY(), true);

        $pdf->MultiCell(35, 1, "Branch Code", '', 'L', 1, 0, PDF_MARGIN_LEFT+$paynowX, $pdf->getY()-2, true);
        $pdf->MultiCell(10, 1, ":", '', 'C', 1, 0, PDF_MARGIN_LEFT+25+$paynowX, $pdf->getY(), true);
        $pdf->MultiCell(50, 1, $op[CompanyOptions::C_BANK_DETAIL][CompanyOptions::C_BANK_DETAIL_BRANCH_CODE], '', 'L', 1, 0, PDF_MARGIN_LEFT+30+$paynowX, $pdf->getY(), true);
        $pdf->MultiCell(65, 1, "", '', 'C', 1, 1, PDF_MARGIN_LEFT+120, $pdf->getY(), true);

        $pdf->MultiCell(35, 1, "Swift Code", '', 'L', 1, 0, PDF_MARGIN_LEFT+$paynowX, $pdf->getY()-2, true);
        $pdf->MultiCell(10, 1, ":", '', 'C', 1, 0, PDF_MARGIN_LEFT+25+$paynowX, $pdf->getY(), true);
        $pdf->MultiCell(50, 1, $op[CompanyOptions::C_BANK_DETAIL][CompanyOptions::C_BANK_DETAIL_SWIFT_CODE], '', 'L', 1, 0, PDF_MARGIN_LEFT+30+$paynowX, $pdf->getY(), true);
        $pdf->MultiCell(75, 1, "Authorised Signature", 'T', 'C', 1, 1, PDF_MARGIN_LEFT+110, $pdf->getY(), true);
        
        return $pdf;
    }
    public function getCutPrintString($pdf, $columnSize, $rowHeight, $bottomHeight, $str, $divider = "\n"){

        $strArray = explode($divider, $str);
        
        $oriCount = count($strArray);
        
        $bottomHeight = $bottomHeight + 45;
        
        $counter = ($oriCount > 500 ? $oriCount - 500 : 0);
        $strArrayNew = array_slice($strArray, 0, $oriCount - $counter);
        $strNew = implode($divider, $strArrayNew);
        $estimated = $pdf->getNumLines($strNew, $columnSize[1]);
        //Log::write($estimated . " - " . $rowHeight . " - " . ($estimated * $rowHeight) . " - " . $pdf->GetY() . " - " . (($estimated * $rowHeight) + $pdf->GetY()) . ' - ' . $bottomHeight);
        
        while((($estimated * $rowHeight) + $pdf->GetY()) > $bottomHeight && $counter < $oriCount){
            $counter++;
            $strArrayNew = array_slice($strArray, 0, $oriCount - $counter);
            $strNew = implode($divider, $strArrayNew);
            //Log::write($strNew);
            $estimated = $pdf->getNumLines($strNew, $columnSize[1]);
            //Log::write($estimated . " - " . $rowHeight . " - " . ($estimated * $rowHeight) . " - " . $pdf->GetY() . " - " . (($estimated * $rowHeight) + $pdf->GetY()) . ' - ' . $bottomHeight);
        }        
        
        $result = array();
        if($counter >= $oriCount){
            $result = $this->getCutPrintStr($pdf, $columnSize, $rowHeight, $bottomHeight, $str, " ");
        } else {
            $strArrayNew = array_slice($strArray, 0, $oriCount - $counter);
            $result[] = implode($divider, $strArrayNew);
            $strArrayNew = array_slice($strArray, $oriCount - $counter);
            $result[] = implode($divider, $strArrayNew);
        }
        
        return $result;
    }
    //=====================================================================================

    //Export Invoice
    //=====================================================================================
    private function filterExportInvoice($params) {
        $cls            = new SalesQuotationClass($this->db);
        $clsInvoice     = new InvoiceHeaderClass($this->db);
        $clsCompany     = new CompanyClass($this->db);
        $opt 		    = new CompanyOptions() ;
        $clsCustomer    = new CustomerClass($this->db);
        $clsCurrency    = new CurrencyClass($this->db);

        $htmlStr = "";

        $fromdte    = str_replace('/', '-', $params['from_date'] );
        $from_date   = date_create($fromdte)->format('Y-m-d');
        $todte      = str_replace('/', '-', $params['to_date'] );
        $to_date     = date_create($todte)->format('Y-m-d');

        $rows       = $clsInvoice->getExportInvoiceList($from_date, $to_date);

        if(!is_null($rows) && count($rows) > 0){
            foreach ($rows as $row) {
                $rowCompany = $clsCompany->getRecord($row[SalesQuotationTable::C_BU]);
                $opt->loadXml($rowCompany[CompanyTable::C_OPTIONS]) ;
                $op = $opt->getOption() ;

                $name = "";
                if($row[SalesQuotationTable::C_PROSPECT]) {
                    $company = $row[SalesQuotationTable::C_PROSPECT_NAME];
                } else {
                    $rowCustomer = $clsCustomer->getRecord($row[SalesQuotationTable::C_CUSTOMER_ID]);
                    $company = $rowCustomer[CustomerTable::C_NAME] . " (" . $rowCustomer[CustomerTable::C_CODE] . ")" ;
                }

                $grand_total = $cls->calculateGrandTotal($row[SalesQuotationTable::C_ID]);
                $invoice_amount = 0;
                if($row[InvoiceHeaderTable::C_INVOICE_AMOUNT] == 0){
                    if($row[InvoiceHeaderTable::C_INVOICE_TYPE] == 'P') {
                        $invoice_amount = $grand_total * ($row[InvoiceHeaderTable::C_INVOICE_VALUE]  / 100);
                    } else {
                        $invoice_amount = $row[InvoiceHeaderTable::C_INVOICE_VALUE];
                    }
                }

                $htmlStr .= '<tr data-row="sales-quotation-rows-'.$row[SalesQuotationTable::C_ID].'" class="kt-datatable__row" style="left: 0px;">'.
                            '<td class="kt-datatable__cell" style="display:none;">'.$row[SalesQuotationTable::C_ID].'</td>'.
                            '<td class="kt-datatable__cell">'.$op[CompanyOptions::C_SETTING][CompanyOptions::C_SET_CODE].'</td>'.
                            '<td class="kt-datatable__cell">'.$company.'</td>'.
                            '<td class="kt-datatable__cell">'.$row[SalesQuotationTable::C_CUSTOMER_NUMBER].'</td>'.
                            '<td class="kt-datatable__cell" style="text-align: center;">'.$clsCurrency->getRecord($row[SalesQuotationTable::C_CURRENCY])[CurrencyTable::C_REF].'</td>'.
                            '<td class="kt-datatable__cell" style="text-align: right;">'.number_format($grand_total, 2,'.',',').'</td>'.
                            '<td class="kt-datatable__cell" style="text-align: right;">'.number_format($invoice_amount, 2,'.',',').'</td>'.
                            '</tr>';
            }
        }
        
        $this->sendJsonResponse(Status::Ok,"",$htmlStr,$this->type);
    }

    private function exportInvoiceToExcel($params) {
        require_once(PATH_EXCEL . 'PHPExcel.php');
        
        $cls 		    = new SalesQuotationClass($this->db);
        $clsInvoice     = new InvoiceHeaderClass($this->db);
        $clsCompany     = new CompanyClass($this->db);
        $opt 		    = new CompanyOptions() ;
        $clsCustomer    = new CustomerClass($this->db);
        $clsCurrency    = new CurrencyClass($this->db);
       
        $style_title = array(
            'font'          => array('bold' => false, 'size'=>14),
            'alignment'     => array('horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_LEFT,)
        );
        $style_date = array(
            'alignment'     => array('horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_RIGHT,)
        ); 
        $style_header = array(
            'font'          => array('bold' => true),
            'alignment'     => array('horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,),
            'fill'          => array('type' => PHPExcel_Style_Fill::FILL_SOLID,'color' => array('rgb' => 'C8C8C8'))
        );
        $style_table = array(
            'alignment'     => array('wrap' => true, 'vertical' => PHPExcel_Style_Alignment::VERTICAL_TOP)
        );
        $style_total = array(
            'font'          => array('bold' => true),
            'alignment'     => array('horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_RIGHT,)
        );

        $excel = new PHPExcel();

        if (!file_exists(PATH_PROFORMA_INVOICE_EXPORT)) {
            mkdir(PATH_PROFORMA_INVOICE_EXPORT, 0777, true);
        }

        $filename = PATH_PROFORMA_INVOICE_EXPORT."Export Invoice ". date_create('now')->format('YmdHis').".xlsx";
        $excel->setActiveSheetIndex(0);
        
        $columnHeader = array ("S/No.","BU","Customer/Prospect","Quotation #","Currency","Total Amount","Payable Amount");
        
        $idx = 1;
        $excel->getActiveSheet()->getStyle(chr(65) . $idx)->applyFromArray($style_title);
        $excel->setActiveSheetIndex(0)->setCellValue(chr(65) . $idx, "Export Invoice");

        $idx += 1;
        $excel->getActiveSheet()->getStyle(chr(65) . $idx)->applyFromArray($style_date);
        $excel->setActiveSheetIndex(0)->setCellValue(chr(65) . $idx, "As at " . date("d/m/Y"));

        $idx += 2;
        for($i=0;$i<count($columnHeader);$i++){
            $excel->setActiveSheetIndex(0)->setCellValue(chr(65+$i) . $idx, $columnHeader[$i]);
        }
        $excel->setActiveSheetIndex(0)->getStyle(chr(65) . $idx . ":" . chr(65+count($columnHeader)-1) . $idx)->applyFromArray($style_header);
        $excel->getActiveSheet()->getStyle(chr(65) . $idx . ":" . chr(65+count($columnHeader)-1) . $idx)->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THICK);
        
        $fromdte    = str_replace('/', '-', $params['from_date'] );
        $from_date   = date_create($fromdte)->format('Y-m-d');
        $todte      = str_replace('/', '-', $params['to_date'] );
        $to_date     = date_create($todte)->format('Y-m-d');

        $rows = $clsInvoice->getExportInvoiceList($from_date, $to_date);

        $idx += 1;
        $counter = 0;
        if(!is_null($rows) && count($rows) > 0){
            foreach ($rows as $row) {
                $counter++;
                $rowCompany = $clsCompany->getRecord($row[SalesQuotationTable::C_BU]);
                $opt->loadXml($rowCompany[CompanyTable::C_OPTIONS]) ;
                $op = $opt->getOption() ;                

                $name = "";
                if($row[SalesQuotationTable::C_PROSPECT]) {
                    $company = $row[SalesQuotationTable::C_PROSPECT_NAME];
                } else {
                    $rowCustomer = $clsCustomer->getRecord($row[SalesQuotationTable::C_CUSTOMER_ID]);
                    $company = $rowCustomer[CustomerTable::C_NAME] . " (" . $rowCustomer[CustomerTable::C_CODE] . ")" ;
                }

                $currency = $clsCurrency->getRecord($row[SalesQuotationTable::C_CURRENCY])[CurrencyTable::C_REF];

                $grand_total = $cls->calculateGrandTotal($row[SalesQuotationTable::C_ID]);
                $invoice_amount = $row[InvoiceHeaderTable::C_INVOICE_AMOUNT];
                if($row[InvoiceHeaderTable::C_INVOICE_AMOUNT] == 0){
                    if($row[InvoiceHeaderTable::C_INVOICE_TYPE] == 'P') {
                        $invoice_amount = $grand_total * ($row[InvoiceHeaderTable::C_INVOICE_VALUE]  / 100);
                    } else {
                        $invoice_amount = $row[InvoiceHeaderTable::C_INVOICE_VALUE];
                    }
                }

                $columnContent = array (
                    $counter,
                    $op[CompanyOptions::C_SETTING][CompanyOptions::C_SET_CODE],
                    $company,
                    trim($row[SalesQuotationTable::C_CUSTOMER_NUMBER]),
                    $currency,
                    number_format($grand_total, 2, '.', ','),
                    number_format($invoice_amount, 2, '.', ','),
                );

                for($i=0;$i<count($columnContent);$i++){
                    $excel->setActiveSheetIndex(0)->getStyle(chr(65 + $i) . $idx, $columnContent[$i])->applyFromArray($style_table)->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
                    $excel->setActiveSheetIndex(0)->setCellValue(chr(65 + $i) . $idx, $columnContent[$i]);
                }

                $idx += 1;
            }
        }

        $objWriter = new PHPExcel_Writer_Excel2007($excel);
        $objWriter->save($filename);

        header('Content-Description: File Transfer');
        header('Content-Type: application/force-download');
        header('Content-Disposition: attachement; filename="' . basename($filename) . '"');
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($filename));
        ob_clean();
        flush();
        readfile($filename);
    }

    function getDirContents($dir, &$results = array()) {
        $files = scandir($dir);

        foreach ($files as $key => $value) {
            $path = realpath($dir . DIRECTORY_SEPARATOR . $value);
            if (!is_dir($path)) {
                $results[] = $path;
            } else if ($value != "." && $value != "..") {
                $this->getDirContents($path, $results);
                $results[] = $path;
            }
        }

        return $results;
    }

    private function getLogo($coyid) {
        $userCls  = new UserClass($this->db);

        $fn = Util::getLogoFile(PATH_PICTURE, "company-".$coyid) ;
        if ($fn == "") {
            return "" ;
        } else  {
            if (get_magic_quotes_gpc()) {
                $image = stripslashes('<img align="center" alt="Alternate text" border="0" class="center fixedwidth " src="http://'.$_SERVER['SERVER_NAME'].'/web/picture/company-' . $coyid . '/' . $fn. '" style="text-decoration: none; -ms-interpolation-mode: bicubic; height: auto; border: 0; width: 100%; max-width: 175px; display: block;" title="Alternate text" width="175"/>');
            }
            else {
                $image = '<img align="center" alt="Alternate text" border="0" class="center fixedwidth " src="http://'.$_SERVER['SERVER_NAME'].'/web/picture/company-' . $coyid . '/' . $fn. '" style="text-decoration: none; -ms-interpolation-mode: bicubic; height: auto; border: 0; width: 100%; max-width: 175px; display: block;" title="Alternate text" width="175"/>';
            }
            return $image;
        }

    }

    private function getCustomerContact($params) {
        $datas = array() ;

        $sql = "SELECT * FROM " . CustomerContactTable::C_TABLE.
                " WHERE " . CustomerContactTable::C_ID . " = " . $params['cust_id'].
                " ORDER BY " . CustomerContactTable::C_NAME ;
        
        $rows = $this->db->getTable($sql);
        
        $vls  = array() ;
        $vls[] = array ('code'=>"0",'desc'=>"-- Select a Name --") ;
        if(!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $vls[] = array ('code'=>$row[CustomerContactTable::C_CONTACT_ID],'desc'=>$row[CustomerContactTable::C_NAME]) ;
            }           
        }

        if($this->type == "_CUSTOMER_CONTACT")
            $this->sendJsonResponse(Status::Ok,"", Util::createOptionValue($vls),$this->type);
        else
            return Util::createOptionValue($vls);
    }

    private function getContactDetail($params) {
        $datas = array() ;

        $sql = "SELECT * FROM " .CustomerContactTable::C_TABLE.
                " WHERE " .CustomerContactTable::C_ID. " = " .$params['cust_id']. 
                " AND " .CustomerContactTable::C_CONTACT_ID. "=" .$params['contact_id'];
        
        $rows = $this->db->getTable($sql);
        
        $datasReturn = array();
        if(!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $datasReturn['contact_name'] = trim($row[CustomerContactTable::C_NAME]);
                $datasReturn['contact_email'] = trim($row[CustomerContactTable::C_EMAIL]);
                $datasReturn['contact_mobile'] = trim($row[CustomerContactTable::C_MOBILE]);
                $datasReturn['contact_telephone'] = trim($row[CustomerContactTable::C_TELEPHONE]);
            }           
        }

        $this->sendJsonResponse(Status::Ok,"", $datasReturn,$this->type);
    }

    private function getSectionOption(){
        $arr = array() ;
        $arr[] = array ('code'=>0,'desc'=>"-- Select a Subject --" );
        $arr[] = array ('code'=>1,'desc'=>"Delivery Terms" );
        $arr[] = array ('code'=>2,'desc'=>"Payment Terms" );
        $arr[] = array ('code'=>3,'desc'=>"Consulting Terms and Conditions" );
        $arr[] = array ('code'=>4,'desc'=>"Travelling Conditions" );
        $arr[] = array ('code'=>5,'desc'=>"Training Room Coniditons" );
        $arr[] = array ('code'=>6,'desc'=>"General Terms and Conditions" );
        return Util::createOptionValue($arr) ; 
    }

    private function getCoverPageOption(){
        $arr = array() ;
        // $arr[] = array ('code'=>0,'desc'=>"-- Select a Cover --" );
        $arr[] = array ('code'=>"1|20",'desc'=>"Cover Page 1");
        $arr[] = array ('code'=>"2|30",'desc'=>"Cover Page 2");
        $arr[] = array ('code'=>"3|30",'desc'=>"Cover Page 3");
        return Util::createOptionValue($arr) ; 
    }

    private function getCustomerOptionFilter(){
        $cls = new CustomerClass($this->db);
        
        $rows = $cls->getTable();
        
        $vls   = array() ;
        $vls[] = array ('code'=>"0",'desc'=>"-- All Company --") ;
        
        if(!is_null($rows) && count($rows) > 0) {
            foreach ($rows as $row) {
                $vls[] = array ('code'=>$row[CustomerTable::C_ID],'desc'=>$row[CustomerTable::C_CODE] ." - ". $row[CustomerTable::C_NAME]) ;
            }

            array_multisort(array_map(function($element) {
                return strtolower( $element['desc'] );
            }, $vls), SORT_ASC, $vls);           
        }
        
        return Util::createOptionValue($vls) ;
    }

    private function getReviseListSalesQuotation($params){
        try {
            $cls            = new SalesQuotationClass($this->db);
            $clsCompany     = new CompanyClass($this->db);
            $opt 		    = new CompanyOptions() ;
            
            $rows = $cls->getTable(SalesQuotationTable::C_REF_ID."='".$params['id']."'", SalesQuotationTable::C_ID);
            rsort($rows);
            
            $vls   = array() ;
            if(!is_null($rows) || count($rows) > 0) {
                foreach ($rows as $row) {
                    if($row[SalesQuotationTable::C_REVISE_TYPE] == SalesQuotationReviseType::Internal) {
                        $vls[] = array ('code'=>$row[SalesQuotationTable::C_ID]."|".$row[SalesQuotationTable::C_REVISE_TYPE],'desc'=>$row[SalesQuotationTable::C_NUMBER]) ;
                    } else {
                        $vls[] = array ('code'=>$row[SalesQuotationTable::C_ID]."|".$row[SalesQuotationTable::C_REVISE_TYPE],'desc'=>$row[SalesQuotationTable::C_CUSTOMER_NUMBER]) ;
                    }
                }
            }
  
            $datasReturn = array();
            $datasReturn['list'] = Util::createOptionValue($vls);
            $datasReturn['status'] = $params['status'];
            if($params['approver'] == $_SESSION[SE_USERID]) {
                $datasReturn['approver'] = true;
            }else{
                $datasReturn['approver'] = false;
            }
            
            $this->sendJsonResponse(Status::Ok,"", $datasReturn,$this->type);
        } catch (Exception $e) {
            Log::write("[getReviseListSalesQuotation] ".$e->getMessage());
            $this->sendJsonResponse(Status::Error,"Sorr, there is an error in retrieving the list.", "",$this->type);
        }
    }

    private function getAdditionalItemOption(){
        $arr = array() ;
        $arr[] = array ('code'=>0,'desc'=>"-- Select Item --" );
        $arr[] = array ('code'=>1,'desc'=>"Manpower" );
        $arr[] = array ('code'=>2,'desc'=>"Extended Warranty" );
        return Util::createOptionValue($arr) ; 
    }
}
?>