"vtiger_purchaseorder", "SalesOrder" => "vtiger_salesorder", "Quotes" => "vtiger_quotes", "Invoice" => "vtiger_invoice", "Issuecards" => "vtiger_issuecards", "Receiptcards" => "vtiger_receiptcards", "Creditnote" => "vtiger_creditnote", "StornoInvoice" => "vtiger_stornoinvoice"); private static $inventory_id_array = array("PurchaseOrder" => "purchaseorderid", "SalesOrder" => "salesorderid", "Quotes" => "quoteid", "Invoice" => "invoiceid", "Issuecards" => "issuecardid", "Receiptcards" => "receiptcardid", "Creditnote" => "creditnote_id", "StornoInvoice" => "stornoinvoice_id"); private static $org_colsOLD = array("organizationname" => "NAME", "address" => "ADDRESS", "city" => "CITY", "state" => "STATE", "code" => "ZIP", "country" => "COUNTRY", "phone" => "PHONE", "fax" => "FAX", "website" => "WEBSITE", "logo" => "LOGO"); private static $relBlockModules = array(); /** @var PDFMaker_PDFMaker_Model */ public $PDFMaker; /** @var PDFMaker_Module_Model */ public $moduleModel; public $skipPageBreaks = false; /** * @param int $l_templateid * @param string $l_module * @param object $l_focus * @param string $l_language */ public function __construct($l_templateid, $l_module, $l_focus, $l_language) { if (!defined('LOGO_PATH')) { define('LOGO_PATH', 'test/logo/'); } PDFMaker_Debugger_Model::GetInstance()->Init(); self::$db = PearDatabase::getInstance(); self::$def_charset = vglobal('default_charset'); $this->retrievePDFMakerModel(); $this->retrieveModuleModel(); $this->setLanguage($l_language); $this->setTemplateId($l_templateid); self::$module = $l_module; self::$focus = $l_focus; $this->retrieveModStrings(); $this->getTemplateData(); $this->getIgnoredPicklistValues(); self::$bridge2mpdf['record'] = self::$focus->id; self::$bridge2mpdf['templateid'] = self::$templateid; self::$rowbreak = ''; self::$is_inventory_module[self::$module] = $this->isInventoryModule(self::$module); } /** * @param int $templateId * @param string $moduleName * @param object $focus * @param string $language * @return PDFMaker_PDFContent_Model */ public static function getInstance($templateId, $moduleName, $focus, $language) { return new self($templateId, $moduleName, $focus, $language); } public function retrieveModStrings() { $mod_strings_array = Vtiger_Language_Handler::getModuleStringsFromFile(self::$language, self::$module); self::$mod_strings = $mod_strings_array['languageStrings']; } public function setTemplateId($value) { self::$templateid = $value; vglobal('PDFMaker_template_id', $value); } public function setLanguage($value) { self::$language = $value; $current_user = Users_Record_Model::getCurrentUserModel(); $current_user->set('language', $value); } public function retrievePDFMakerModel() { $this->PDFMaker = new PDFMaker_PDFMaker_Model(); } public function retrieveModuleModel() { $this->moduleModel = Vtiger_Module_Model::getInstance('PDFMaker'); } public function getPDFMakerModel() { if (!$this->PDFMaker) { $this->retrievePDFMakerModel(); } return $this->PDFMaker; } public function getModuleModel() { if (!$this->moduleModel) { $this->retrieveModuleModel(); } return $this->moduleModel; } private function getTemplateData() { self::$site_url = trim(vglobal('site_URL'), "/"); $result = self::$db->pquery("SELECT vtiger_pdfmaker.*, vtiger_pdfmaker_settings.* FROM vtiger_pdfmaker LEFT JOIN vtiger_pdfmaker_settings ON vtiger_pdfmaker_settings.templateid = vtiger_pdfmaker.templateid WHERE vtiger_pdfmaker.templateid=?", array(self::$templateid)); $data = self::$db->fetch_array($result); self::$decimal_point = html_entity_decode($data["decimal_point"], ENT_QUOTES); self::$thousands_separator = html_entity_decode(($data["thousands_separator"] != "sp" ? $data["thousands_separator"] : " "), ENT_QUOTES); self::$decimals = $data["decimals"]; self::$truncate_zero = $data['truncate_zero']; self::$disable_export_edit = $data['disable_export_edit']; foreach (array("header", "footer") as $stype) { if (!empty($data[$stype . 'id']) && $data[$stype . 'id'] != "0") { $data[$stype] = $this->moduleModel->getTemplateBlockContent($data[$stype . 'id']); } } self::$header = $data["header"]; self::$footer = $data["footer"]; self::$body = $data["body"]; self::$filename = $data["file_name"]; self::$pdf_password = $data["pdf_password"]; self::$watermark_text = $data["watermark_text"]; self::$templatename = $data["filename"]; $this->retrievePageBreak($data); } public function getPageBreakFormat($data) { $formatPB = $data['format']; if (0 < strpos($formatPB, ';')) { $tmpArr = explode(';', $formatPB); $formatPB = $tmpArr[0] . 'mm ' . $tmpArr[1] . 'mm'; } elseif ($data['orientation'] == 'landscape') { $formatPB .= "-L"; } return $formatPB; } private function getIgnoredPicklistValues() { $result = self::$db->pquery("SELECT value FROM vtiger_pdfmaker_ignorepicklistvalues", array()); while ($row = self::$db->fetchByAssoc($result)) { self::$ignored_picklist_values[] = $row["value"]; } } public function replaceDates() { $currentUser = Users_Record_Model::getCurrentUserModel(); $hour = '24' == $currentUser->get('hour_format') ? date('H') : date('h'); self::$rep['##DD-MM-YYYY##'] = date('d-m-Y'); self::$rep['##DD.MM.YYYY##'] = date('d.m.Y'); self::$rep['##MM-DD-YYYY##'] = date('m-d-Y'); self::$rep['##YYYY-MM-DD##'] = date('Y-m-d'); self::$rep['##HH:II:SS##'] = $hour . date(':i:s'); self::$rep['##HH:II##'] = $hour . date(':i'); self::$rep["##YYYY##"] = date('Y'); self::$rep["##MM##"] = date('m'); self::$rep["##DD##"] = date('d'); self::$rep["##HH##"] = $hour; self::$rep["##II##"] = date('i'); self::$rep["##SS##"] = date('s'); } public function getContent() { PDFMaker_PDFMaker_Model::getSimpleHtmlDomFile(); $img_root = vglobal('img_root_directory'); if (self::$module == 'Calendar') { self::$rep = array(); } self::$content = self::$body; self::$content = self::$header . self::$section_sep; self::$content .= self::$body . self::$section_sep; self::$content .= self::$footer; self::$rep['$siteurl$'] = self::$site_url; self::$rep[' '] = ' '; self::$rep['##PAGE##'] = '{PAGENO}'; self::$rep['##PAGES##'] = '{nb}'; $this->replaceDates(); self::$rep["src='"] = "src='" . $img_root; self::$rep["$" . strtoupper(self::$module) . "_CRMID$"] = self::$focus->id; self::$rep["%" . strtoupper(self::$module) . "_CRMID%"] = "CRMID"; $createdtime = new DateTimeField(self::$focus->column_fields['createdtime']); $displayValueCreated = $createdtime->getDisplayDateTimeValue(); $modifiedtime = new DateTimeField(self::$focus->column_fields['modifiedtime']); $displayValueModified = $modifiedtime->getDisplayDateTimeValue(); self::$rep["$" . strtoupper(self::$module) . "_CREATEDTIME_DATETIME$"] = $displayValueCreated; self::$rep["$" . strtoupper(self::$module) . "_MODIFIEDTIME_DATETIME$"] = $displayValueModified; $this->convertEntityImages(); $this->replaceContent(); self::$content = html_entity_decode(self::$content, ENT_QUOTES, self::$def_charset); $html = str_get_html(self::$content); $page_break_after = $html->find("div[style^=page-break-after]"); if (is_array($page_break_after)) { foreach ($page_break_after as $div_page_break) { $div_page_break->outertext = self::$pagebreak; self::$content = $html->save(); } } $page_break_after2 = $html->find("div[style^=PAGE-BREAK-AFTER]"); if (is_array($page_break_after2)) { foreach ($page_break_after2 as $div_page_break) { $div_page_break->outertext = self::$pagebreak; self::$content = $html->save(); } } $this->convertRelatedModule(); $this->convertRelatedBlocks(); $this->replaceFieldsToContent(self::$module, self::$focus); if (self::$module == "Calendar") { $this->replaceFieldsToContent("Events", self::$focus); } $this->convertInventoryModules(); $this->retrieveAssignedUser(); self::$content = $this->convertListViewBlock(self::$content); $this->handleRowbreak(); $this->replaceUserCompanyFields(); $this->replaceLabels(); self::$content = $this->replaceBarcode(self::$content); self::$content = $this->fixImg(self::$content); if (strtoupper(self::$def_charset) != "UTF-8") { self::$content = iconv(self::$def_charset, "UTF-8//TRANSLIT", self::$content); } $this->convertHideTR('BEFORE'); $this->replaceCustomFunctions(); $this->convertHideTR(); $this->replaceSignature(); $this->replacePageBreak(); $PDF_content = array(); list($PDF_content["header"], $PDF_content["body"], $PDF_content["footer"]) = explode( self::$section_sep, self::$content ); return $PDF_content; } public function retrieveAssignedUser() { if (empty(self::$focus->column_fields['assigned_user_id'])) { $result = self::$db->pquery('SELECT smownerid FROM vtiger_crmentity WHERE crmid=?', array(self::$focus->id)); self::$focus->column_fields['assigned_user_id'] = self::$db->query_result($result, 0, 'smownerid'); } } public function replacePageBreak() { if ($this->strContain(self::$content, PDFMaker_PageBreak_Model::PAGE_BREAK_TAG)) { $pageBreak = PDFMaker_PageBreak_Model::getInstance(self::$content); if (!$this->skipPageBreaks) { $pageBreak->setPageBreak($this->getPageBreak()); } else { $pageBreak->setPageBreak($pageBreak::PAGE_BREAK_TAG); } $pageBreak->updateContent(); self::$content = $pageBreak->getContent(); } } /** * @param string $value * @param string $search * @return bool */ public function strContain($value, $search) { return false !== stripos($value, $search); } /** * @return string */ public function getSignature() { $signHtml = vglobal('ITS4YouSignatureHTML'); if ($signHtml) { return $signHtml; } $settings = $this->getSettings(); $signatureImage = vglobal('ITS4YouSignatureImage'); $image = !empty($signatureImage) ? $signatureImage : $this->getEmptySignature(); return $this->getSignatureImage($image, $settings['signature_width'], $settings['signature_height']); } public function getEmptySignature() { return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/3PfWwAJWgOlFi1RWAAAAABJRU5ErkJggg=='; } public function getSignatureImage($src, $width, $height) { $width = empty($width) ? 150 : (int)$width; $height = empty($height) ? 60 : (int)$height; return $src ? 'Signature' : 'The Signature is missing or has been deleted'; } public function retrieveConfirmSignatures() { /** * confirm 1 = replace with images * confirm 2 = replace with placeholder * confirm 3 = edit */ $confirm = (int)vglobal('ITS4YouSignatureConfirm'); if (3 !== $confirm) { $string = self::$body; $regex = '/\$PDF\_SIGNATURE\_([A-Z]*)\_([0-9]*)\$/m'; preg_match_all($regex, $string, $matches, PREG_SET_ORDER, 0); foreach ($matches as $match) { list($variable, $type, $record) = $match; $recordModel = PDFMaker_Signatures_Model::getInstanceById($record); $image = 1 === $confirm ? $recordModel->getImage() : $this->getEmptySignature(); self::$rep[$variable] = $this->getSignatureImage($image, $recordModel->get('width'), $recordModel->get('height')); } } } public function setBody($value) { self::$body = $value; } public function replaceSignature() { self::$rep['$PDF_SIGNATURE$'] = $this->getSignature(); $this->retrieveConfirmSignatures(); $this->replaceContent(); } private function convertEntityImages() { switch (self::$module) { case "Contacts": self::$rep["$" . "CONTACTS_IMAGENAME$"] = $this->getContactImage(self::$focus->id, self::$site_url); break; case "Products": self::$rep['$PRODUCTS_IMAGENAME$'] = $this->getProductImage(self::$focus->id, self::$site_url); self::$rep['$PRODUCT_IMAGE$'] = self::$rep['$PRODUCTS_IMAGENAME$']; break; } } private function replaceContent() { if (!empty(self::$rep)) { self::$content = str_replace(array_keys(self::$rep), self::$rep, self::$content); self::$filename = str_replace(array_keys(self::$rep), self::$rep, self::$filename); self::$pdf_password = str_replace(array_keys(self::$rep), self::$rep, self::$pdf_password); self::$watermark_text = str_replace(array_keys(self::$rep), self::$rep, self::$watermark_text); self::$rep = array(); } } private function convertRelatedModule() { $v = "vtiger_current_version"; $vcv = vglobal($v); $field_inf = "_fieldinfo_cache"; $module_tabid = getTabId(self::$module); $Query_Parr = array('3', '64', $module_tabid); $sql = "SELECT fieldid, fieldname, uitype, columnname FROM vtiger_field WHERE (displaytype != ? OR fieldid = ?) AND tabid"; if (self::$module == "Calendar") { $Query_Parr[] = getTabId("Events"); $sql .= " IN ( ?, ? ) GROUP BY fieldname"; } else { $sql .= " = ?"; } $result = self::$db->pquery($sql, $Query_Parr); $num_rows = self::$db->num_rows($result); if ($num_rows > 0) { while ($row = self::$db->fetch_array($result)) { $fieldModel = Vtiger_Field_Model::getInstance($row["fieldid"]); $columnname = $row["columnname"]; $fk_record = self::$focus->column_fields[$row["fieldname"]]; $related_module = $this->getUITypeRelatedModule($row["uitype"], $fk_record); if ($fieldModel) { $references = array_merge(array($related_module), $fieldModel->getReferenceList()); if (!empty($references)) { foreach ($references as $related_module) { if (!PDFMaker_Module_Model::isModuleActive($related_module)) { continue; } $displayValueModified = $displayValueCreated = $related_module_id = ""; $tabid = getTabId($related_module); $temp = &VTCacheUtils::$$field_inf; unset($temp[$tabid]); $focus2 = CRMEntity::getInstance($related_module); if ($fk_record != "" && $fk_record != "0") { if ($related_module == "Users") { $control_sql = "vtiger_users WHERE id="; } else { $control_sql = "vtiger_crmentity WHERE crmid="; } $result_delete = self::$db->pquery("SELECT deleted FROM " . $control_sql . "? AND deleted=0", array($fk_record)); if (self::$db->num_rows($result_delete) > 0) { $focus2->retrieve_entity_info($fk_record, $related_module); $related_module_id = $focus2->id = $fk_record; if ($vcv == '5.2.1') { $displayValueCreated = getDisplayDate($focus2->column_fields['createdtime']); $displayValueModified = getDisplayDate($focus2->column_fields['modifiedtime']); } else { if (!empty($focus2->column_fields['createdtime'])) { $createdtime = new DateTimeField($focus2->column_fields['createdtime']); $displayValueCreated = $createdtime->getDisplayDateTimeValue(); } if (!empty($focus2->column_fields['modifiedtime'])) { $modifiedtime = new DateTimeField($focus2->column_fields['modifiedtime']); $displayValueModified = $modifiedtime->getDisplayDateTimeValue(); } } } } self::$rep["$" . "R_" . strtoupper($columnname) . "_CRMID$"] = $related_module_id; self::$rep["$" . "R_" . strtoupper($columnname) . "_CREATEDTIME_DATETIME$"] = $displayValueCreated; self::$rep["$" . "R_" . strtoupper($columnname) . "_MODIFIEDTIME_DATETIME$"] = $displayValueModified; if ($related_module != "Users") { self::$rep["$" . "R_" . strtoupper($related_module) . "_CRMID$"] = $related_module_id; self::$rep["$" . "R_" . strtoupper($related_module) . "_CREATEDTIME_DATETIME$"] = $displayValueCreated; self::$rep["$" . "R_" . strtoupper($related_module) . "_MODIFIEDTIME_DATETIME$"] = $displayValueModified; } if (isset($related_module)) { $entityImg = ""; switch ($related_module) { case "Contacts": $entityImg = $this->getContactImage($related_module_id, self::$site_url); break; case "Products": $entityImg = $this->getProductImage($related_module_id, self::$site_url); break; } if ($related_module != "Users") { self::$rep["$" . "R_" . strtoupper($related_module) . "_IMAGENAME$"] = $entityImg; } self::$rep["$" . "R_" . strtoupper($columnname) . "_IMAGENAME$"] = $entityImg; } $this->replaceContent(); if ($related_module != "Users") { $this->replaceFieldsToContent($related_module, $focus2, true); } $this->replaceFieldsToContent($related_module, $focus2, $columnname); $this->replaceInventoryDetailsBlock($related_module, $focus2, $columnname); unset($focus2); } } } $fieldModRel = $this->GetFieldModuleRel(); if ($row["uitype"] == "68") { $fieldModRel[$row["fieldid"]][] = "Contacts"; $fieldModRel[$row["fieldid"]][] = "Accounts"; } if (isset($fieldModRel[$row["fieldid"]])) { foreach ($fieldModRel[$row["fieldid"]] as $idx => $relMod) { if (!PDFMaker_Module_Model::isModuleActive($relMod) || $relMod == $related_module) { continue; } $tmpTabId = getTabId($relMod); $temp = &VTCacheUtils::$$field_inf; unset($temp[$tmpTabId]); if (file_exists("modules/" . $relMod . "/" . $relMod . ".php")) { $tmpFocus = CRMEntity::getInstance($relMod); if ($related_module != "Users") { self::$rep["$" . "R_" . strtoupper($relMod) . "_CRMID$"] = ""; self::$rep["$" . "R_" . strtoupper($relMod) . "_CREATEDTIME_DATETIME$"] = ""; self::$rep["$" . "R_" . strtoupper($relMod) . "_MODIFIEDTIME_DATETIME$"] = ""; $this->replaceFieldsToContent($relMod, $tmpFocus, true); } self::$rep["$" . "R_" . strtoupper($columnname) . "_CRMID$"] = ""; self::$rep["$" . "R_" . strtoupper($columnname) . "_CREATEDTIME_DATETIME$"] = ""; self::$rep["$" . "R_" . strtoupper($columnname) . "_MODIFIEDTIME_DATETIME$"] = ""; $this->replaceFieldsToContent($relMod, $tmpFocus, $columnname); $this->replaceInventoryDetailsBlock($relMod, $tmpFocus, $columnname); unset($tmpFocus); } } } } } } /** * @return bool */ public function isProductsBlockField($value) { $productBlockValues = [ 'received', 'balance', 'paid', 'paidamount', 'openamount', ]; return in_array($value, $productBlockValues); } protected $recordExists = array(); /** * @param bool $record * @return bool */ public function isRecordExists($record) { if (!isset($this->recordExists[$record])) { $this->recordExists[$record] = !empty($record) && isRecordExists($record); } return $this->recordExists[$record]; } protected $userExists = array(); public function isUserExists($record) { if (!isset($this->userExists[$record])) { $adb = PearDatabase::getInstance(); $result = $adb->pquery('SELECT user_name FROM vtiger_users WHERE id=? AND deleted=?', [$record, '0'] ); $this->userExists[$record] = !empty($record) && $adb->num_rows($result); } return $this->userExists[$record]; } protected $groupExists = array(); public function isGroupExists($record) { if (!isset($this->groupExists[$record])) { $adb = PearDatabase::getInstance(); $result = $adb->pquery('SELECT groupname FROM vtiger_groups WHERE groupid=?', [$record] ); $this->groupExists[$record] = !empty($record) && $adb->num_rows($result); } return $this->groupExists[$record]; } public function isRecordModelStructure($record, $module = '') { return $this->isRecordExists($record) || ('Users' === $module && $this->isUserExists($record)); } public function getFieldDisplayValue($field, $inventoryCurrency) { $fieldValue = $field->get('fieldvalue'); $fieldName = $field->get('name'); $fieldDataType = $field->getFieldDataType(); switch ($fieldDataType) { case 'owner': $fieldDisplayValue = getOwnerName($fieldValue); break; case 'reference': $fieldDisplayValue = $field->getEditViewDisplayValue($fieldValue); break; case 'double': case 'percentage': $fieldDisplayValue = $this->formatNumberToPDF($fieldValue); break; case 'currency': if (is_numeric($fieldValue) && !$this->isProductsBlockField($fieldName)) { if (!$inventoryCurrency) { $current_user = Users_Record_Model::getCurrentUserModel(); $user_currency_data = getCurrencySymbolandCRate($current_user->currency_id); $crate = $user_currency_data['rate']; } else { $crate = $inventoryCurrency['conversion_rate']; } $fieldValue = (float)$fieldValue * (float)$crate; } $fieldDisplayValue = $this->formatCurrencyToPDF($fieldValue); break; case 'url': $fieldDisplayValue = $fieldValue; break; case 'picklist': $fieldDisplayValue = !empty($fieldValue) ? $this->getTranslatedStringCustom($fieldValue, $field->getModuleName(), self::$language) : ''; break; case 'text': $fieldDisplayValue = decode_html($field->getDisplayValue($fieldValue)); break; default: $fieldDisplayValue = $field->getDisplayValue($fieldValue); break; } return $fieldDisplayValue; } /** * @param string $module * @param object $focus * @param bool|string $is_related * @param bool $inventory_currency * @param string $related * @return array|bool|void */ private function replaceFieldsToContent($module, $focus, $is_related = false, $inventory_currency = false, $related = 'R_') { $current_user = Users_Record_Model::getCurrentUserModel(); if (false !== $inventory_currency) { $inventory_content = array(); } $convEntity = 'Events' === $module ? 'Calendar' : $module; if (false === $is_related) { $related = ''; } elseif (true !== $is_related) { $convEntity = $is_related; } if ($this->isRecordModelStructure($focus->id, $module)) { $VtigerDetailViewModel = Vtiger_DetailView_Model::getInstance($module, $focus->id); $recordModel = $VtigerDetailViewModel->getRecord(); $recordStructure = Vtiger_RecordStructure_Model::getInstanceFromRecordModel($recordModel, ''); } else { $moduleModel = Vtiger_Module_Model::getInstance($module); $recordStructure = Vtiger_RecordStructure_Model::getInstanceForModule($moduleModel, ''); } foreach ($recordStructure->getStructure() as $blockFields) { foreach ($blockFields as $fieldModel) { $fieldName = $fieldModel->get('name'); $fieldLabel = $fieldModel->get('label'); $fieldDisplayValue = ''; if ($this->isRecordModelStructure($focus->id, $module)) { if ('Calendar' === $module) { $this->updateCalendarField($fieldModel, $recordModel); } $fieldDisplayValue = $this->getFieldDisplayValue($fieldModel, $inventory_currency); } self::$rep['%' . $related . strtoupper($convEntity . '_' . $fieldName) . '%'] = vtranslate($fieldLabel, $module); self::$rep['%M_' . $fieldLabel . '%'] = vtranslate($fieldLabel, $module); if ($inventory_currency !== false) { $inventory_content[strtoupper($module . '_' . $fieldName)] = $fieldDisplayValue; } else { self::$rep['$' . $related . strtoupper($convEntity . '_' . $fieldName) . '$'] = $fieldDisplayValue; } } } $this->retrieveDisabledFields($module, $related . $convEntity); if ($inventory_currency !== false) { return $inventory_content; } else { $this->replaceContent(); return true; } } public function retrieveDisabledFields($module, $prefix) { $result = self::$db->pquery( 'SELECT fieldname FROM vtiger_field WHERE presence=? AND tabid=?', [1, getTabid($module)] ); while ($row = self::$db->fetchByAssoc($result)) { self::$rep['$' . strtoupper($prefix . '_' . $row['fieldname']) . '$'] = ''; } } /** * @param string $value * @return string */ private function formatNumberToPDF($value) { $number = ''; if (is_numeric($value)) { $number = number_format($value, self::$decimals, self::$decimal_point, self::$thousands_separator); if (self::$truncate_zero) { $number = rtrim(rtrim($number, '0'), self::$decimal_point); } } return $number; } /** * @param string $value * @return string */ private function formatCurrencyToPDF($value) { $settings = $this->getSettings(); $number = ''; if(is_numeric($value)) { if($settings['is_currency']) { $thousands = 'sp' === $settings['currency_thousands'] ? ' ' : $settings['currency_thousands']; $point = 'sp' === $settings['currency_point'] ? ' ' : $settings['currency_point']; $number = number_format($value, $settings['currency'], $point, $thousands); } else { $number = $this->formatNumberToPDF($value); } } return $number; } private function replaceInventoryDetailsBlock($module, $focus, $is_related = false) { if (!isset(self::$inventory_table_array[$module])) { $this->fillInventoryData($module, $focus); } if (!isset(self::$inventory_table_array[$module])) { return array(); } $prefix = ""; if ($is_related !== false) { $prefix = "R_" . strtoupper($is_related) . "_"; } self::$rep["$" . $prefix . "SUBTOTAL$"] = $this->formatCurrencyToPDF($focus->column_fields["hdnSubTotal"]); self::$rep["$" . $prefix . "TOTAL$"] = $this->formatCurrencyToPDF($focus->column_fields["hdnGrandTotal"]); $currencytype = $this->getInventoryCurrencyInfoCustom($module, $focus); $currencytype["currency_symbol"] = str_replace("€", "€", $currencytype["currency_symbol"]); $currencytype["currency_symbol"] = str_replace("£", "£", $currencytype["currency_symbol"]); self::$rep["$" . $prefix . "CURRENCYNAME$"] = getTranslatedCurrencyString($currencytype["currency_name"]); self::$rep["$" . $prefix . "CURRENCYSYMBOL$"] = $currencytype["currency_symbol"]; self::$rep["$" . $prefix . "CURRENCYCODE$"] = $currencytype["currency_code"]; self::$rep["$" . $prefix . "ADJUSTMENT$"] = $this->formatCurrencyToPDF($focus->column_fields["txtAdjustment"]); $Products = $this->getInventoryProducts($module, $focus); self::$rep["$" . $prefix . "TOTALWITHOUTVAT$"] = $Products["TOTAL"]["TOTALWITHOUTVAT"]; self::$rep["$" . $prefix . "VAT$"] = $Products["TOTAL"]["TAXTOTAL"]; if('individual' === $Products['TOTAL']['TAXTYPE']) { self::$rep["$" . $prefix . "VATPERCENT$"] = '$VATPERCENT_INDIVIDUAL$'; } else { self::$rep["$" . $prefix . "VATPERCENT$"] = $Products["TOTAL"]["TAXTOTALPERCENT"]; } self::$rep["$" . $prefix . "TOTALWITHVAT$"] = $Products["TOTAL"]["TOTALWITHVAT"]; self::$rep["$" . $prefix . "SHTAXAMOUNT$"] = $Products["TOTAL"]["SHTAXAMOUNT"]; self::$rep["$" . $prefix . "SHTAXTOTAL$"] = $Products["TOTAL"]["SHTAXTOTAL"]; self::$rep["$" . $prefix . "DEDUCTEDTAXESTOTAL$"] = $Products["TOTAL"]["DEDUCTEDTAXESTOTAL"]; self::$rep["$" . $prefix . "TOTALDISCOUNT$"] = $Products["TOTAL"]["FINALDISCOUNT"]; self::$rep["$" . $prefix . "TOTALDISCOUNTPERCENT$"] = $Products["TOTAL"]["FINALDISCOUNTPERCENT"]; self::$rep["$" . $prefix . "TOTALAFTERDISCOUNT$"] = $Products["TOTAL"]["TOTALAFTERDISCOUNT"]; self::$rep["$" . $prefix . "NETTOTAL$"] = $Products["TOTAL"]["NETTOTAL"]; self::$rep["$" . $prefix . "TAXTOTAL$"] = $Products["TOTAL"]["TAXTOTAL"]; self::$rep["$" . $prefix . "FINALDISCOUNT$"] = $Products["TOTAL"]["FINALDISCOUNT"]; $this->replaceContent(); if ($is_related === false) { $blockTypes = array('VATBLOCK', 'DEDUCTEDTAXESBLOCK', 'CHARGESBLOCK'); foreach ($blockTypes as $blockType) { $vattable = ""; if (PDFMaker_Utils_Helper::count((array)$Products["TOTAL"][$blockType]) > 0) { $vattable = ''; $vattable .= ' '; if ($blockType == 'CHARGESBLOCK') { $vattable .= ''; } else { $vattable .= ''; } $vattable .= ''; foreach ($Products["TOTAL"][$blockType] as $keyW => $valueW) { if ($valueW["netto"] != 0 || ($blockType == 'CHARGESBLOCK' && !empty($valueW['value']))) { $vattable .= ''; if ($blockType == 'CHARGESBLOCK') { $vattable .= ''; } else { $vattable .= ''; } $vattable .= ''; } } $vattable .= "
' . vtranslate("LBL_CHARGESBLOCK_SUM", "PDFMaker") . '' . vtranslate("Name") . ' ' . vtranslate("LBL_VATBLOCK_VAT_PERCENT", "PDFMaker") . ' ' . vtranslate("LBL_VATBLOCK_SUM", "PDFMaker") . ' (' . $currencytype["currency_symbol"] . ') ' . vtranslate("LBL_VATBLOCK_VAT_VALUE", "PDFMaker") . ' (' . $currencytype["currency_symbol"] . ')
' . $valueW['label'] . ' ' . $this->formatNumberToPDF($valueW['value']) . '' . $valueW['label'] . ' ' . $this->formatNumberToPDF($valueW['value']) . ' % ' . $this->formatCurrencyToPDF($valueW['netto']) . ' ' . $this->formatCurrencyToPDF($valueW['vat']) . '
"; } self::$rep["$" . $blockType . "$"] = $vattable; $PDFMaker_Fields_Model = new PDFMaker_Fields_Model(); $MoreFields = $PDFMaker_Fields_Model->getMoreFields($module); foreach ($MoreFields as $f_name => $f_lang) { self::$rep["%" . $f_name . "%"] = $f_lang; } } $this->replaceContent(); $VProductParts = array(); foreach (['VAT', 'CHARGES'] as $blockType) { if (strpos(self::$content, '#' . $blockType . 'BLOCK_START#') !== false && strpos(self::$content, '#' . $blockType . 'BLOCK_END#') !== false) { self::$content = $this->convertBlock(self::$content, $blockType); $VExplodedPdf = []; $VExploded = explode('#' . $blockType . 'BLOCK_START#', self::$content); $VExplodedPdf[] = $VExploded[0]; for ($iterator = 1; $iterator < PDFMaker_Utils_Helper::count($VExploded); $iterator++) { $VSubExploded = explode('#' . $blockType . 'BLOCK_END#', $VExploded[$iterator]); foreach ($VSubExploded as $Vpart) { $VExplodedPdf[] = $Vpart; } $Vhighestpartid = $iterator * 2 - 1; $VProductParts[$Vhighestpartid] = $VExplodedPdf[$Vhighestpartid]; $VExplodedPdf[$Vhighestpartid] = ''; } if (PDFMaker_Utils_Helper::count($Products['TOTAL'][$blockType . 'BLOCK']) > 0) { foreach ($Products['TOTAL'][$blockType . 'BLOCK'] as $keyW => $valueW) { foreach ($VProductParts as $productpartid => $productparttext) { if ($valueW['netto'] != 0 || ($blockType == 'CHARGES' && !empty($valueW['value']))) { foreach ($valueW as $vColl => $vVal) { if (is_numeric($vVal)) { if('value' === $vColl) { $vVal = $this->formatNumberToPDF($vVal); } else { $vVal = $this->formatCurrencyToPDF($vVal); } } $productparttext = str_replace('$' . $blockType . 'BLOCK_' . strtoupper($vColl) . '$', $vVal, $productparttext); } $VExplodedPdf[$productpartid] .= $productparttext; } } } } self::$content = implode('', $VExplodedPdf); } } } return $Products; } private function fillInventoryData($module, $focus) { if (!isset(self::$is_inventory_module[$module])) { self::$is_inventory_module[$module] = $this->isInventoryModule($module); } if (self::$is_inventory_module[$module] || (isset($focus->column_fields["currency_id"]) && isset($focus->column_fields["conversion_rate"]) && isset($focus->column_fields["hdnGrandTotal"]))) { self::$inventory_table_array[$module] = $focus->table_name; self::$inventory_id_array[$module] = $focus->table_index; } } /** * @throws Exception * @var string $module * @var object $focus */ private function getInventoryCurrencyInfoCustom($module, $focus) { $record_id = ''; $inventory_table = self::$inventory_table_array[$module]; $inventory_id = self::$inventory_id_array[$module]; if (!empty($focus->id)) { $record_id = $focus->id; } return $this->getInventoryCurrencyInfoCustomArray($inventory_table, $inventory_id, $record_id); } /** * @param array $finalDetails * @return int|float */ public function getTotalWithVat($finalDetails) { if ('individual' === $finalDetails['taxtype']) { return $finalDetails['preTaxTotal']; } return $finalDetails['preTaxTotal'] + $finalDetails['tax_totalamount']; } public function retrieveProductsCurrencyFields(&$products, $finalDetails) { $currencyFieldsList = array( 'NETTOTAL' => 'hdnSubTotal', 'TAXTOTAL' => 'tax_totalamount', 'SHTAXTOTAL' => 'shtax_totalamount', 'TOTALAFTERDISCOUNT' => 'preTaxTotal', 'FINALDISCOUNT' => 'discountTotal_final', 'SHTAXAMOUNT' => 'shipping_handling_charge', 'DEDUCTEDTAXESTOTAL' => 'deductTaxesTotalAmount', ); foreach ($currencyFieldsList as $variableName => $fieldName) { $products['TOTAL'][$variableName] = $this->formatCurrencyToPDF($finalDetails[$fieldName]); } } protected function isAllowedNewLineToBr($value) { return strpos($value, '<br />') === false && strpos($value, '<br/>') === false && strpos($value, '<br>') === false && strpos($value, '<li>') === false && strpos($value, '
') === false && strpos($value, '
') === false && strpos($value, '
') === false && strpos($value, '
  • ') === false; } protected function getTaxPercentageFromFinalDetails($finalDetails) { $percentage = 0; foreach ((array)$finalDetails['taxes'] as $finalDetailTax) { if (!empty((float)$finalDetailTax['percentage'])) { $percentage += (float)$finalDetailTax['percentage']; } } return $percentage; } /** * @param string $module * @param object $focus * @return array * @throws Exception */ private function getInventoryProducts($module, $focus) { $vatBlock = $finalDetails = $mpdfSubtotalAble = array(); $taxType = 'group'; $usageUnit = ''; $totalVatSum = $totalAfterDiscountSubTotal = $totalSubTotal = $totalSumSubTotal = 0; if (!empty($focus->id)) { $recordModel = Inventory_Record_Model::getInstanceById($focus->id); if (!method_exists($recordModel, 'getProducts')) { return array(); } $relatedProducts = $recordModel->getProducts(); $finalDetails = $relatedProducts[1]['final_details']; $taxType = $finalDetails['taxtype']; $this->retrieveProductsCurrencyFields($Details, $finalDetails); $totalWithVat = $this->getTotalWithVat($finalDetails); $Details['TOTAL']['TOTALWITHVAT'] = $this->formatCurrencyToPDF($totalWithVat); $Details['TOTAL']['TAXTYPE'] = $taxType; $currencyType = $this->getInventoryCurrencyInfoCustom($module, $focus); foreach ($relatedProducts as $i => $PData) { $Details['P'][$i] = array( 'TAXTYPE' => $taxType, ); $sequence = $i; $productTitle = $productName = $PData['productName' . $sequence]; $entityType = $PData['entityType' . $sequence]; $productId = $psId = $PData['hdnProductId' . $sequence]; $productFocus = CRMEntity::getInstance('Products'); if ('Products' === $entityType && !empty($psId)) { $productFocus->id = $psId; $this->retrieve_entity_infoCustom($productFocus, $psId, $entityType); } $productInfo = $this->replaceFieldsToContent('Products', $productFocus, false, $currencyType); $Details['P'][$i] = array_merge($productInfo, $Details['P'][$i]); unset($productFocus); $serviceFocus = CRMEntity::getInstance('Services'); if ('Services' === $entityType && !empty($psId)) { $serviceFocus->id = $psId; $this->retrieve_entity_infoCustom($serviceFocus, $psId, $entityType); } $serviceInfo = $this->replaceFieldsToContent('Services', $serviceFocus, false, $currencyType); $Details['P'][$i] = array_merge($serviceInfo, $Details['P'][$i]); unset($serviceFocus); $Details['P'][$i]['PRODUCTS_CRMID'] = $Details['P'][$i]['SERVICES_CRMID'] = $qtyPerUnit = $module = ''; if ('Products' === $entityType) { $Details['P'][$i]['PRODUCTS_CRMID'] = $psId; $qtyPerUnit = $Details['P'][$i]['PRODUCTS_QTY_PER_UNIT']; $usageUnit = $Details['P'][$i]['PRODUCTS_USAGEUNIT']; } elseif ('Services' === $entityType) { $Details['P'][$i]['SERVICES_CRMID'] = $psId; $qtyPerUnit = $Details['P'][$i]['SERVICES_QTY_PER_UNIT']; $usageUnit = $Details['P'][$i]['SERVICES_SERVICE_USAGEUNIT']; } $psDescription = $Details['P'][$i][strtoupper($entityType) . '_DESCRIPTION']; $Details['P'][$i]['RECORD_ID'] = $Details['P'][$i]['PS_CRMID'] = $psId; $Details['P'][$i]['PS_NO'] = $PData['hdnProductcode' . $sequence]; if (PDFMaker_Utils_Helper::count((array)$PData['subprod_qty_list' . $sequence]) > 0) { $productName .= $this->getSubProductsForProductName($PData['subprod_qty_list' . $sequence]); } $comment = $PData['comment' . $sequence]; if (!empty($comment)) { if ($this->isAllowedNewLineToBr($comment)) { $comment = str_replace("\\n", "
    ", nl2br($comment)); } $comment = html_entity_decode($comment, ENT_QUOTES, self::$def_charset); $productName .= '
    ' . $comment . ''; } $Details['P'][$i]['PRODUCTNAME'] = $productName; if (!$this->isRecordExists($psId) && empty($productTitle)) { $productTitle = $this->translateString('LBL_ITEM_DELETED_FROM_SYSTEM', 'PDFMaker'); } $Details['P'][$i]['PRODUCTTITLE'] = $productTitle; $inventoryProductRelDescription = $psDescription; if ($this->isAllowedNewLineToBr($psDescription)) { $psDescription = str_replace("\\n", '
    ', nl2br($psDescription)); } $Details['P'][$i]['PRODUCTDESCRIPTION'] = html_entity_decode($psDescription, ENT_QUOTES, self::$def_charset); $Details['P'][$i]['PRODUCTEDITDESCRIPTION'] = $comment; if (false === strpos($inventoryProductRelDescription, '<br />') && false === strpos($inventoryProductRelDescription, '<br/>') && false === strpos($inventoryProductRelDescription, '<br>') ) { $inventoryProductRelDescription = str_replace("\\n", "
    ", nl2br($inventoryProductRelDescription) ); } $Details['P'][$i]['CRMNOWPRODUCTDESCRIPTION'] = html_entity_decode($inventoryProductRelDescription, ENT_QUOTES, self::$def_charset); $Details['P'][$i]['PRODUCTLISTPRICE'] = $this->formatCurrencyToPDF($PData['listPrice' . $sequence]); $Details['P'][$i]['PRODUCTTOTAL'] = $this->formatCurrencyToPDF($PData['productTotal' . $sequence]); $Details['P'][$i]['PRODUCTQUANTITY'] = $this->formatNumberToPDF($PData['qty' . $sequence]); $Details['P'][$i]['PRODUCTQINSTOCK'] = $this->formatNumberToPDF($PData['qtyInStock' . $sequence]); $Details['P'][$i]['PRODUCTPRICE'] = $this->formatCurrencyToPDF($PData['unitPrice' . $sequence]); $Details['P'][$i]['PRODUCTPOSITION'] = $sequence; $Details['P'][$i]['PRODUCTQTYPERUNIT'] = $this->formatNumberToPDF($qtyPerUnit); $Details['P'][$i]['PRODUCTUSAGEUNIT'] = $usageUnit; $Details['P'][$i]['PRODUCTDISCOUNT'] = $this->formatCurrencyToPDF($PData['discountTotal' . $sequence]); $Details['P'][$i]['PRODUCTDISCOUNTPERCENT'] = $this->formatNumberToPDF($PData['discount_percent' . $sequence]); $totalAfterDiscount = $PData['totalAfterDiscount' . $sequence]; $Details['P'][$i]['PRODUCTSTOTALAFTERDISCOUNTSUM'] = $totalAfterDiscount; $Details['P'][$i]['PRODUCTSTOTALAFTERDISCOUNT'] = $this->formatCurrencyToPDF($totalAfterDiscount); $netPrice = (float)$PData['netPrice' . $sequence]; if ('individual' !== $taxType) { $netPriceTax = $this->getTaxPercentageFromFinalDetails($finalDetails); $netPrice += $netPrice / 100 * $netPriceTax; } $Details['P'][$i]['PRODUCTTOTALSUM'] = $this->formatCurrencyToPDF($netPrice); $Details['P'][$i]['PRODUCT_LISTPRICEWITHTAX'] = $this->formatCurrencyToPDF($netPrice / $PData['qty' . $sequence]); $totalAfterDiscountSubTotal += $totalAfterDiscount; $totalSubTotal += $PData['productTotal' . $sequence]; $totalSumSubTotal += $netPrice; $Details['P'][$i]['PRODUCTSTOTALAFTERDISCOUNT_SUBTOTAL'] = $this->formatCurrencyToPDF($totalAfterDiscountSubTotal); $Details['P'][$i]['PRODUCTTOTAL_SUBTOTAL'] = $this->formatCurrencyToPDF($totalSubTotal); $Details['P'][$i]['PRODUCTTOTALSUM_SUBTOTAL'] = $this->formatCurrencyToPDF($totalSumSubTotal); $mpdfSubtotalAble[$i]['$TOTALAFTERDISCOUNT_SUBTOTAL$'] = $Details['P'][$i]['PRODUCTSTOTALAFTERDISCOUNT_SUBTOTAL']; $mpdfSubtotalAble[$i]['$TOTAL_SUBTOTAL$'] = $Details['P'][$i]['PRODUCTTOTAL_SUBTOTAL']; $mpdfSubtotalAble[$i]['$TOTALSUM_SUBTOTAL$'] = $Details['P'][$i]['PRODUCTTOTALSUM_SUBTOTAL']; $Details['P'][$i]['PRODUCTSEQUENCE'] = $sequence; $Details['P'][$i]['PRODUCTS_IMAGENAME'] = $this->getProductImage($focus->id, self::$site_url, $productId, $sequence); $Details['P'][$i]['PRODUCT_IMAGE'] = $Details['P'][$i]['PRODUCTS_IMAGENAME']; $taxTotal = $taxAvgValue = 0; if ('individual' === $taxType) { $lineItemId = $this->getItemIdBySequence($i, $focus->id); $taxDetails = getTaxDetailsForProduct($productId, 'all'); $taxValues = array(); $vatPercent = array(); $totalTaxValues = array(); foreach ($taxDetails as $taxDetail) { $taxName = $taxDetail['taxname']; $taxLabel = $taxDetail['taxlabel']; $taxValue = getInventoryProductTaxValue($focus->id, $productId, $taxName, $lineItemId); $individualTaxAmount = $totalAfterDiscount * $taxValue / 100; $taxTotal = $taxTotal + $individualTaxAmount; if ($taxName != '') { $taxKey = $taxName . '-' . $taxValue; $vatSum = round($individualTaxAmount, self::$decimals); $totalVatSum += $vatSum; $vatBlock[$taxKey]['label'] = $taxLabel; $vatBlock[$taxKey]['netto'] += $totalAfterDiscount; $vatBlock[$taxKey]['vat'] += $vatSum; $vatBlock[$taxKey]['value'] = $taxValue; array_push($taxValues, $taxValue); array_push($totalTaxValues, $taxValue); array_push($vatPercent, $this->formatNumberToPDF($taxValue)); } } if (PDFMaker_Utils_Helper::count($taxValues) > 0) { $taxAvgValue = array_sum($taxValues); } $vatPercentString = implode(', ', array_filter($vatPercent)); $Details['P'][$i]['VATPERCENT_INDIVIDUAL'] = $vatPercentString ?: '0'; $Details['TOTAL']['VATPERCENT_INDIVIDUAL'][] = $vatPercentString; } else { $taxAvgValue = $this->getTaxPercentageFromFinalDetails($finalDetails); $taxTotal = !empty($taxAvgValue) ? $totalAfterDiscount * $taxAvgValue / 100 : 0; } $Details['P'][$i]['PRODUCTVATPERCENT'] = $this->formatNumberToPDF($taxAvgValue); $Details['P'][$i]['PRODUCTVATSUM'] = $this->formatNumberToPDF($taxTotal); $result1 = self::$db->pquery('SELECT * FROM vtiger_inventoryproductrel WHERE id=? AND sequence_no=?', array(self::$focus->id, $sequence) ); $row1 = self::$db->fetchByAssoc($result1, 0); $result2 = self::$db->pquery('SELECT fieldname, fieldlabel, columnname, uitype, typeofdata FROM vtiger_field WHERE tablename = ? AND tabid = ?', array('vtiger_inventoryproductrel', getTabid(self::$module)) ); while ($row2 = self::$db->fetchByAssoc($result2)) { if (!isset($Details['P'][$i]['PRODUCT_' . strtoupper($row2['fieldname'])])) { $UITypes = array(); $value = $row1[$row2['columnname']]; if (!empty($value)) { $uiTypeName = $this->getUITypeName($row2['uitype'], $row2['typeofdata']); if (!empty($uiTypeName)) { $UITypes[$uiTypeName][] = $row2['fieldname']; } $value = $this->getFieldValue($focus, $module, $row2['fieldname'], $value, $UITypes); } $Details['P'][$i]['PRODUCT_' . strtoupper($row2['fieldname'])] = $value; } } } } $Details['TOTAL']['TOTALWITHOUTVAT'] = $this->formatCurrencyToPDF($totalAfterDiscountSubTotal); $totalVatPercentage = 0; if ('individual' === $taxType) { $Details['TOTAL']['TAXTOTAL'] = $this->formatCurrencyToPDF($totalVatSum); } else { $vatBlock = $this->getGroupVatBlock($finalDetails); $totalVatPercentage = $this->getTotalVatPercentage($finalDetails); } $Details['TOTAL']['TAXTOTALPERCENT'] = $this->formatNumberToPDF($totalVatPercentage); $Details['TOTAL']['VATBLOCK'] = $vatBlock; $Details['TOTAL']['CHARGESBLOCK'] = $this->getChargesBlock($finalDetails); $finalDiscountAmount = !empty($focus->column_fields['hdnDiscountAmount']) ? $focus->column_fields['hdnDiscountAmount'] : ''; $finalDiscountPercent = !empty($focus->column_fields['hdnDiscountPercent']) ? $focus->column_fields['hdnDiscountPercent'] : ''; $Details['TOTAL']['FINALDISCOUNTPERCENT'] = $this->formatNumberToPDF($finalDiscountPercent); $Details['TOTAL']['FINALDISCOUNTAMOUNT'] = $this->formatNumberToPDF($finalDiscountAmount); $Details['TOTAL']['DEDUCTEDTAXESBLOCK'] = $this->getDeductedTaxesBlock($finalDetails); return $Details; } public function getSubProductsForProductName($values) { $productName = ''; foreach ($values as $id => $data) { $name = $data['name']; if (0 < $data['qty']) { $name .= ' (' . $data['qty'] . ')'; } $productName .= '
    ' . $name . ''; } return $productName; } /** * @param array $finalDetails * @return array */ public function getGroupVatBlock($finalDetails) { if (empty($finalDetails['taxes'])) { return array(); } $vatBlock = array(); foreach ($finalDetails['taxes'] as $tax) { $taxName = $tax['taxname']; $vatBlock[$taxName]['netto'] = $finalDetails['totalAfterDiscount']; $vatBlock[$taxName]['label'] = $tax['taxlabel']; $vatBlock[$taxName]['value'] = $tax['percentage']; if (isset($vatBlock[$taxName]['vat'])) { $vatBlock[$taxName]['vat'] += $tax['amount']; } else { $vatBlock[$taxName]['vat'] = $tax['amount']; } } return $vatBlock; } /** * @param array $finalDetails * @return int|float */ public function getTotalVatPercentage($finalDetails) { if (empty($finalDetails['taxes'])) { return 0; } $percentage = 0; foreach ($finalDetails['taxes'] as $tax) { $percentage += $tax['percentage']; } return $percentage; } /** * @param array $finalDetails * @return array */ public function getChargesBlock($finalDetails) { if (empty($finalDetails['chargesAndItsTaxes'])) { return array(); } $chargesBlock = array(); $allCharges = getAllCharges(); $chargesAndItsTaxes = $finalDetails['chargesAndItsTaxes']; foreach ($chargesAndItsTaxes as $chargeId => $chargeData) { $name = $allCharges[$chargeId]['name']; $chargesBlock[] = array( 'label' => $name, 'value' => $chargeData['value'] ); } return $chargesBlock; } public function getDeductedTaxesBlock($finalDetails) { if (empty($finalDetails['deductTaxes'])) { return array(); } $deductTaxesBlock = array(); foreach ($finalDetails['deductTaxes'] as $deductTax) { $taxName = $deductTax['taxname']; $deductTaxesBlock[$taxName]['label'] = $deductTax['taxlabel']; $deductTaxesBlock[$taxName]['netto'] = $finalDetails['totalAfterDiscount']; $deductTaxesBlock[$taxName]['vat'] = $deductTax['amount']; $deductTaxesBlock[$taxName]['value'] = $deductTax['percentage']; } return $deductTaxesBlock; } /** * @throws Exception * @var object $focus * @var int $record * @var string $module */ private function retrieve_entity_infoCustom(&$focus, $record, $module) { $result = array(); foreach ($focus->tab_name_index as $table_name => $index) { $result[$table_name] = self::$db->pquery(sprintf('SELECT * FROM %s WHERE %s=?', $table_name, $index), array($record) ); } $tabId = getTabid($module); $result1 = self::$db->pquery('SELECT fieldname, fieldid, fieldlabel, columnname, tablename, uitype, typeofdata, presence FROM vtiger_field WHERE tabid=?', array($tabId)); if (self::$db->num_rows($result1)) { while ($row1 = self::$db->fetch_array($result1)) { $columnName = $row1['columnname']; $tableName = $row1['tablename']; $fieldName = $row1['fieldname']; $fieldValue = ''; if (isset($result[$tableName])) { $fieldValue = self::$db->query_result($result[$tableName], 0, $columnName); } $focus->column_fields[$fieldName] = $fieldValue; } } $focus->column_fields['record_id'] = $record; $focus->column_fields['record_module'] = $module; } /** * @param int $sequence * @param int $record * @return int * @throws Exception */ public function getItemIdBySequence($sequence, $record) { $result = self::$db->pquery('SELECT lineitem_id FROM vtiger_inventoryproductrel WHERE id=? AND sequence_no=?', [$record, $sequence]); return (int)self::$db->query_result($result, 0, 'lineitem_id'); } private function getFieldValue($efocus, $emodule, $fieldname, $value, $UITypes, $inventory_currency = false) { return $this->getFieldValueUtils($efocus, $emodule, $fieldname, $value, $UITypes, $inventory_currency, self::$ignored_picklist_values, self::$def_charset, self::$decimals, self::$decimal_point, self::$thousands_separator, self::$language, self::$focus->id); } /** * @throws Exception */ public function getRelatedBlockSecondaryModule($relatedBlockId) { $result = self::$db->pquery('SELECT secmodule FROM vtiger_pdfmaker_relblocks WHERE relblockid = ?', array($relatedBlockId)); return self::$db->query_result($result, 0, 'secmodule'); } /** * @throws Exception */ private function convertRelatedBlocks() { include_once("modules/PDFMaker/resources/RelBlockRun.php"); if (false !== strpos(self::$content, "#RELBLOCK")) { preg_match_all("|#RELBLOCK([0-9]+)_START#|U", self::$content, $relatedBlocks, PREG_PATTERN_ORDER); if (PDFMaker_Utils_Helper::count($relatedBlocks[1]) > 0) { $convertRelBlock = array(); $productParts = array(); foreach ($relatedBlocks[1] as $relatedBlockId) { if (!in_array($relatedBlockId, $convertRelBlock)) { $secondaryModule = $this->getRelatedBlockSecondaryModule($relatedBlockId); if (self::strContain(self::$content, '#RELBLOCK' . $relatedBlockId . '_START#') && self::strContain(self::$content, '#RELBLOCK' . $relatedBlockId . '_END#')) { $this->convertRelatedBlock($relatedBlockId); $relatedBlockRun = new RelBlockRun(self::$focus->id, $relatedBlockId, self::$module, $secondaryModule); $relatedBlockRun->SetPDFLanguage(self::$language); $relatedBlockData = $relatedBlockRun->GenerateReport(); $explodedPdf = array(); $exploded = explode('#RELBLOCK' . $relatedBlockId . '_START#', self::$content); $explodedPdf[] = $exploded[0]; for ($iterator = 1; $iterator < PDFMaker_Utils_Helper::count($exploded); $iterator++) { $subExploded = explode('#RELBLOCK' . $relatedBlockId . '_END#', $exploded[$iterator]); foreach ($subExploded as $subExplodedPart) { $explodedPdf[] = $subExplodedPart; } $highestPartId = $iterator * 2 - 1; $productParts[$highestPartId] = $explodedPdf[$highestPartId]; $explodedPdf[$highestPartId] = ''; } if (!in_array($secondaryModule, self::$relBlockModules)) { self::$relBlockModules[] = $secondaryModule; } if (PDFMaker_Utils_Helper::count($relatedBlockData) > 0) { $rowId = 0; foreach ($relatedBlockData as $relatedBlockDetail) { $rowId++; $relatedBlockDetail['ROW_ID'] = $rowId; foreach ($productParts as $productPartId => $productPartText) { $show_line = false; foreach ($relatedBlockDetail as $coll => $value) { if (trim($value) != "-" && $coll != "listprice") { $show_line = true; } $productPartText = str_ireplace("$" . $coll . "$", $value, $productPartText); } if ($show_line) { $explodedPdf[$productPartId] .= $productPartText; } } } } self::$content = implode('', $explodedPdf); } $convertRelBlock[] = $relatedBlockId; } } } } } private function convertRelatedBlock($relBlockId) { PDFMaker_PDFMaker_Model::getSimpleHtmlDomFile(); $html = str_get_html(self::$content); if (is_array($html->find("td"))) { foreach ($html->find("td") as $td) { if (trim($td->plaintext) == "#RELBLOCK" . $relBlockId . "_START#") { $td->parent->outertext = "#RELBLOCK" . $relBlockId . "_START#"; } if (trim($td->plaintext) == "#RELBLOCK" . $relBlockId . "_END#") { $td->parent->outertext = "#RELBLOCK" . $relBlockId . "_END#"; } } self::$content = $html->save(); } } private function convertInventoryModules() { $result = self::$db->pquery("select * from vtiger_inventoryproductrel where id=?", array(self::$focus->id)); $num_rows = self::$db->num_rows($result); if ($num_rows > 0) { $products = $this->replaceInventoryDetailsBlock(self::$module, self::$focus); $blockTypes = array('', 'PRODUCTS_', 'SERVICES_', 'UNIQUE_'); foreach ($blockTypes as $blockType) { if (strpos(self::$content, "#PRODUCTBLOC_" . $blockType . "START#") !== false && strpos(self::$content, "#PRODUCTBLOC_" . $blockType . "END#") !== false) { $tableTag = $this->convertProductBlock($blockType); $breakLinesData = $this->getInventoryBreaklines(self::$focus->id); $breakLineType = $this->getBreakLineType($breakLinesData, $tableTag); $this->replaceProducts($products, $blockType, $breakLinesData['products'], $breakLineType); } } self::$rep['$VATPERCENT_INDIVIDUAL$'] = implode(', ', array_filter((array)$products['TOTAL']['VATPERCENT_INDIVIDUAL'])); $this->replaceContent(); } } public function getBreakLineType($breakLinesData, $tableTag) { $breakLines = $breakLinesData['products']; $breakLineType = ''; if (PDFMaker_Utils_Helper::count($breakLines) > 0) { if ($tableTag !== false) { if (1 === $breakLinesData['show_subtotal']) { $breakLineType = $tableTag['subtotal']; } else { $breakLineType = $tableTag['footer']; } $breakLineType .= '' . PDFMaker_PageBreak_Model::PAGE_BREAK_TAG . $tableTag['tag']; if (1 === $breakLinesData['show_header']) { $breakLineType .= $tableTag['header']; } } else { $breakLineType = PDFMaker_PageBreak_Model::PAGE_BREAK_TAG; } } return $breakLineType; } /** * @param array $products * @param string $blockType * @param array $breakLines * @param string $breakLineType * @return void */ public function replaceProducts($products, $blockType = '', $breakLines = array(), $breakLineType = '') { $exploded = explode('#PRODUCTBLOC_' . $blockType . 'START#', self::$content); $explodedContent = [ $exploded[0] ]; for ($iterator = 1; $iterator < PDFMaker_Utils_Helper::count($exploded); $iterator++) { $subExploded = explode("#PRODUCTBLOC_" . $blockType . "END#", $exploded[$iterator]); foreach ($subExploded as $subExplode) { $explodedContent[] = $subExplode; } $highestPartId = $iterator * 2 - 1; $productParts[$highestPartId] = $explodedContent[$highestPartId]; $explodedContent[$highestPartId] = ''; } if (isset($products['P'])) { $userProductIds = []; foreach ($products['P'] as $productDetails) { $productId = $productDetails['RECORD_ID']; if (($blockType == 'PRODUCTS_' && empty($productDetails['PRODUCTS_CRMID'])) || ($blockType == 'SERVICES_' && empty($productDetails['SERVICES_CRMID']))) { continue; } foreach ($productParts as $productPartId => $productPartText) { if ('UNIQUE_' == $blockType && in_array($productId, $userProductIds)) { $productPartText = ''; } $userProductIds[] = $productId; if (!empty($breakLineType) && isset($breakLines[$productDetails['RECORD_ID'] . '_' . $productDetails['PRODUCTSEQUENCE']])) { $productPartText .= $breakLineType; } foreach ($productDetails as $column => $value) { $value = is_null($value) ? '' : $value; $productPartText = str_replace('$' . strtoupper($column) . '$', $value, $productPartText); } $explodedContent[$productPartId] .= $productPartText; } } } self::$content = implode('', $explodedContent); } private function convertProductBlock($block_type = '') { PDFMaker_PDFMaker_Model::getSimpleHtmlDomFile(); $html = str_get_html(self::$content); $tableDOM = false; if (is_array($html->find("td"))) { foreach ($html->find("td") as $td) { if (trim($td->plaintext) == "#PRODUCTBLOC_" . $block_type . "START#") { $td->parent->outertext = "#PRODUCTBLOC_" . $block_type . "START#"; $oParent = $td->parent; while ($oParent->tag != "table") { $oParent = $oParent->parent; } list($tag) = explode(">", $oParent->outertext, 2); $header = $oParent->first_child(); if ($header->tag != "tr") { $header = $header->children(0); } $header_style = ''; if (is_object($td->parent->prev_sibling()->children[0])) { $header_style = $td->parent->prev_sibling()->children[0]->getAttribute("style"); } $footer_tag = ""; if (isset($header_style)) { $StyleHeader = explode(";", $header_style); if (isset($StyleHeader)) { foreach ($StyleHeader as $style_header_tag) { if (strpos($style_header_tag, "border-top") == true) { $footer_tag .= " "; } } } } else { $footer_tag .= " "; } $footer_tag .= ""; $var = $td->parent->next_sibling()->last_child()->plaintext; $subtotal_tr = ""; if (strpos($var, "TOTAL") !== false) { if (is_object($td)) { $style_subtotal = $td->getAttribute("style"); } $style_subtotal_tag = $style_subtotal_endtag = ""; if (isset($td->innertext)) { list($style_subtotal_tag, $style_subtotal_endtag) = explode("#PRODUCTBLOC_" . $block_type . "START#", $td->innertext); } if (isset($style_subtotal)) { $StyleSubtotal = explode(";", $style_subtotal); if (isset($StyleSubtotal)) { foreach ($StyleSubtotal as $style_tag) { if (strpos($style_tag, "border-top") == true) { $tag .= " style='" . $style_tag . "'"; break; } } } } else { $style_subtotal = ""; } $subtotal_tr = ""; $preg_cond = '/\$([A-Z]*)\$/'; preg_match($preg_cond, $var, $var_array); $var_text = $var_array[1]; $var_split = preg_split($preg_cond, $var); $subtotal_tr .= "" . $style_subtotal_tag . "%G_Subtotal%" . $style_subtotal_endtag . ""; $subtotal_tr .= "" . $style_subtotal_tag . $var_split[0] . "$" . $var_text . "_SUBTOTAL$" . $var_split[1] . $style_subtotal_endtag . ""; $subtotal_tr .= ""; } $tag .= ">"; $tableDOM["tag"] = $tag; $tableDOM["header"] = $header->outertext; $tableDOM["footer"] = $footer_tag; $tableDOM["subtotal"] = $subtotal_tr; } if (trim($td->plaintext) == "#PRODUCTBLOC_" . $block_type . "END#") { $td->parent->outertext = "#PRODUCTBLOC_" . $block_type . "END#"; } } self::$content = $html->save(); } return $tableDOM; } private function handleRowbreak() { $html = str_get_html(self::$content); $toSkip = 0; if (is_array($html->find("rowbreak"))) { foreach ($html->find("rowbreak") as $pb) { if ($pb->outertext == self::$rowbreak) { $tmpPb = $pb; while ($tmpPb != null && $tmpPb->tag != "td") { $tmpPb = $tmpPb->parent(); } if ($tmpPb->tag == "td") { if ($toSkip > 0) { $toSkip--; continue; } $prev_sibling = $tmpPb->prev_sibling(); $prev_sibling_styles = array(); while ($prev_sibling != null) { $prev_sibling_styles[] = $this->getDOMElementAtts($prev_sibling); $prev_sibling = $prev_sibling->prev_sibling(); } $next_sibling = $tmpPb->next_sibling(); $next_sibling_styles = array(); while ($next_sibling != null) { $next_sibling_styles[] = $this->getDOMElementAtts($next_sibling); $next_sibling = $next_sibling->next_sibling(); } $partsArr = explode(self::$rowbreak, $tmpPb->innertext); for ($i = 0; $i < (count($partsArr) - 1); $i++) { $tmpPb->innertext = $partsArr[$i]; $addition = ''; for ($j = 0; $j < count($prev_sibling_styles); $j++) { $addition .= ' '; } $addition .= '' . $partsArr[$i + 1] . ''; for ($j = 0; $j < count($next_sibling_styles); $j++) { $addition .= ' '; } $addition .= ''; $tmpPb->parent()->outertext = $tmpPb->parent()->outertext . $addition; } $toSkip = count($partsArr) - 2; } } } self::$content = $html->save(); } } private function replaceUserCompanyFields() { $current_user = Users_Record_Model::getCurrentUserModel(); if (getTabId('ITS4YouMultiCompany') && PDFMaker_Module_Model::isModuleActive('ITS4YouMultiCompany')) { $CompanyDetailsRecord_Model = ITS4YouMultiCompany_Record_Model::getCompanyInstance(self::$focus->column_fields["assigned_user_id"]); $CompanyDetails_Model = $CompanyDetailsRecord_Model->getModule(); $CompanyDetails_Data = $CompanyDetailsRecord_Model->getData(); $ismulticompany = true; } else { $CompanyDetails_Model = Settings_Vtiger_CompanyDetails_Model::getInstance(); $CompanyDetails_Data = $CompanyDetails_Model->getData(); $ismulticompany = false; } $CompanyDetails_Fields = $CompanyDetails_Model->getFields(); foreach ($CompanyDetails_Fields as $field_name => $field_data) { $value = ""; if ($field_name == "organizationname" || $field_name == "companyname") { $coll = "name"; } elseif ($field_name == "street") { $coll = "address"; } elseif ($field_name == "code") { $coll = "zip"; } elseif ($field_name == "logoname") { continue; } else { $coll = $field_name; } if ('logo' === $coll && !empty($CompanyDetails_Data['logoname'])) { $value = ''; } elseif (($coll == "logo" || $coll == "stamp") && $ismulticompany && !empty($CompanyDetails_Data[$coll])) { $value = $this->getAttachmentImage($CompanyDetails_Data[$coll], self::$site_url); } elseif (isset($CompanyDetails_Data[$field_name])) { $value = $CompanyDetails_Data[$field_name]; } self::$rep["$" . "COMPANY_" . strtoupper($coll) . "$"] = $value; if ($ismulticompany) { $label = vtranslate($field_data->get("label"), "ITS4YouMultiCompany"); } else { $label = vtranslate($field_name, "Settings:Vtiger"); } self::$rep["%" . "COMPANY_" . strtoupper($coll) . "%"] = $label; } $result = self::$db->pquery("SELECT tandc FROM vtiger_inventory_tandc WHERE type = ?", array('Inventory')); $tandc = self::$db->query_result($result, 0, "tandc"); $tandc = is_null($tandc) ? '' : $tandc; if (strpos($tandc, '<br />') === false && strpos($tandc, '<br/>') === false && strpos($tandc, '<br>') === false) { self::$rep["$" . "TERMS_AND_CONDITIONS$"] = nl2br($tandc); } if (self::$focus->column_fields["assigned_user_id"] != "") { $user_res = self::$db->pquery("SELECT * FROM vtiger_users WHERE id = ?", array(self::$focus->column_fields["assigned_user_id"])); $user_row = self::$db->fetchByAssoc($user_res); $this->replaceUserData($user_row["id"], $user_row, "USER"); } else { $this->replaceUserData($current_user->id, $current_user, "USER"); } $this->replaceUserData($current_user->id, $current_user, "L_USER"); $focus_user = CRMEntity::getInstance("Users"); $focus_user->id = self::$focus->column_fields["assigned_user_id"]; $this->retrieve_entity_infoCustom($focus_user, $focus_user->id, "Users"); $this->replaceFieldsToContent("Users", $focus_user, false); $curr_user_focus = CRMEntity::getInstance("Users"); $curr_user_focus->id = $current_user->id; $this->retrieve_entity_infoCustom($curr_user_focus, $curr_user_focus->id, "Users"); $this->replaceFieldsToContent("Users", $curr_user_focus, true); self::$rep["$" . "USERS_CRMID$"] = $focus_user->id; self::$rep["$" . "R_USERS_CRMID$"] = $curr_user_focus->id; $modifiedby_user_res = self::$db->pquery("SELECT vtiger_users.* FROM vtiger_users INNER JOIN vtiger_crmentity ON vtiger_crmentity.modifiedby = vtiger_users.id WHERE vtiger_crmentity.crmid = ?", array(self::$focus->id)); $modifiedby_user_row = self::$db->fetchByAssoc($modifiedby_user_res); $this->replaceUserData($modifiedby_user_row["id"], $modifiedby_user_row, "M_USER"); $modifiedby_user_focus = CRMEntity::getInstance("Users"); $modifiedby_user_focus->id = $modifiedby_user_row["id"]; $this->retrieve_entity_infoCustom($modifiedby_user_focus, $modifiedby_user_focus->id, "Users"); $this->replaceFieldsToContent("Users", $modifiedby_user_focus, true, false, 'M_'); $smcreatorid_user_res = self::$db->pquery("SELECT vtiger_users.* FROM vtiger_users INNER JOIN vtiger_crmentity ON vtiger_crmentity.smcreatorid = vtiger_users.id WHERE vtiger_crmentity.crmid = ?", array(self::$focus->id)); $smcreatorid_user_row = self::$db->fetchByAssoc($smcreatorid_user_res); $this->replaceUserData($smcreatorid_user_row["id"], $smcreatorid_user_row, "C_USER"); $smcreatorid_user_focus = CRMEntity::getInstance("Users"); $smcreatorid_user_focus->id = $smcreatorid_user_row["id"]; $this->retrieve_entity_infoCustom($smcreatorid_user_focus, $smcreatorid_user_focus->id, "Users"); $this->replaceFieldsToContent("Users", $smcreatorid_user_focus, true, false, 'C_'); $this->replaceContent(); } private function replaceUserData($id, $data, $type) { $Fields = array( "FIRSTNAME" => "first_name", "LASTNAME" => "last_name", "EMAIL" => "email1", "TITLE" => "title", "FAX" => "phone_fax", "DEPARTMENT" => "department", "OTHER_EMAIL" => "email2", "PHONE" => "phone_work", "YAHOOID" => "yahoo_id", "MOBILE" => "phone_mobile", "HOME_PHONE" => "phone_home", "OTHER_PHONE" => "phone_other", "SIGHNATURE" => "signature", "NOTES" => "description", "ADDRESS" => "address_street", "COUNTRY" => "address_country", "CITY" => "address_city", "ZIP" => "address_postalcode", "STATE" => "address_state" ); foreach ($Fields as $n => $v) { self::$rep["$" . $type . "_" . $n . "$"] = $this->getUserValue($v, $data); } $currency_id = $this->getUserValue("currency_id", $data); $currency_info = $this->getInventoryCurrencyInfoCustomArray('', '', $currency_id); if ($type == "L_USER") { $type = "R_USER"; } self::$rep["$" . $type . "S_IMAGENAME$"] = $this->getUserImage($id); self::$rep["$" . $type . "S_CRMID$"] = $id; self::$rep["$" . $type . "S_CURRENCY_NAME$"] = $currency_info["currency_name"]; self::$rep["$" . $type . "S_CURRENCY_CODE$"] = $currency_info["currency_code"]; self::$rep["$" . $type . "S_CURRENCY_SYMBOL$"] = $currency_info["currency_symbol"]; $this->replaceContent(); } private function replaceLabels() { $PDFMaker = new PDFMaker_PDFMaker_Model(); $app_lang_array = Vtiger_Language_Handler::getModuleStringsFromFile(self::$language); $mod_lang_array = Vtiger_Language_Handler::getModuleStringsFromFile(self::$language, self::$module); $app_lang = $app_lang_array["languageStrings"]; $mod_lang = $mod_lang_array["languageStrings"]; list($custom_lang, $languages) = $PDFMaker->GetCustomLabels(); $currLangId = ""; foreach ($languages as $langId => $langVal) { if ($langVal["prefix"] == self::$language) { $currLangId = $langId; break; } } self::$rep["%G_Qty%"] = $app_lang["Quantity"]; self::$rep["%G_Subtotal%"] = $app_lang["Sub Total"]; self::$rep["%M_LBL_VENDOR_NAME_TITLE%"] = $app_lang["Vendor Name"]; $this->replaceContent(); if (strpos(self::$content, "%G_") !== false) { foreach ($app_lang as $key => $value) { self::$rep["%G_" . $key . "%"] = $value; } $this->replaceContent(); } if (strpos(self::$content, "%M_") !== false) { foreach ($mod_lang as $key => $value) { self::$rep["%M_" . $key . "%"] = $value; } $this->replaceContent(); foreach ($app_lang as $key => $value) { self::$rep["%M_" . $key . "%"] = $value; } if (self::$module == "SalesOrder") { self::$rep["%G_SO Number%"] = $mod_lang["SalesOrder No"]; } if (self::$module == "Invoice") { self::$rep["%G_Invoice No%"] = $mod_lang["Invoice No"]; } self::$rep["%M_Grand Total%"] = vtranslate('Grand Total', self::$module); $this->replaceContent(); } if (strpos(self::$content, "%C_") !== false) { foreach ($custom_lang as $key => $value) { self::$rep["%" . $value->GetKey() . "%"] = $value->GetLangValue($currLangId); } $this->replaceContent(); } if (count(self::$relBlockModules) > 0) { $services_lang = return_specified_module_language(self::$language, "Services"); $contacts_lang = return_specified_module_language(self::$language, "Contacts"); foreach (self::$relBlockModules as $relBlockModule) { if ($relBlockModule != "") { $relMod_lang = return_specified_module_language(self::$language, $relBlockModule); $r_rbm_upper = "%R_" . strtoupper($relBlockModule); self::$rep[$r_rbm_upper . "_Service Name%"] = $services_lang["Service Name"]; self::$rep[$r_rbm_upper . "_Secondary Email%"] = $contacts_lang["Secondary Email"]; $LD = $this->getRelBlockLabels(); foreach ($LD as $lkey => $llabel) { self::$rep[$r_rbm_upper . "_" . $lkey . "%"] = $app_lang[$llabel]; } $rl_res = self::$db->pquery("SELECT vtiger_field.fieldlabel FROM vtiger_field INNER JOIN vtiger_tab ON vtiger_tab.tabid = vtiger_field.tabid WHERE vtiger_tab.name = ?", array($relBlockModule)); while ($rl_row = self::$db->fetchByAssoc($rl_res)) { $key = $rl_row["fieldlabel"]; if ($relMod_lang[$key]) { $value = $relMod_lang[$key]; } elseif ($app_lang[$key]) { $value = $app_lang[$key]; } else { $value = $key; } self::$rep[$r_rbm_upper . "_" . htmlentities($key, ENT_QUOTES, self::$def_charset) . "%"] = $value; } $this->setCustomReplace($relBlockModule); $this->replaceContent(); } } } } /** * @param string $value * @param string $module * @return string */ public function translateString($value, $module) { return Vtiger_Language_Handler::getTranslatedString($value, $module, self::$language); } /** * @param string $module */ public function setCustomReplace($module) { $relStartReplace = "%R_" . strtoupper($module); if ('Products' === $module) { self::$rep[$relStartReplace . '_LBL_LIST_PRICE%'] = $this->translateString('LBL_LIST_PRICE', $module); } if ('Calendar' == $module) { self::$rep[$relStartReplace . '_Start Date & Time%'] = $this->translateString('Start Date & Time', $module); } } /** * @param string $type */ private function convertHideTR($type = '') { $regex = '/[^<]*(?:<(?!tr\b)[^<]*)*#' . $type . 'HIDETR#[^<]*(?:<(?!\/tr>)[^<]*)*<\/tr>/'; self::$content = preg_replace($regex, '', self::$content); } private function replaceCustomFunctions() { global $PDFContent; $PDFContent = $this; self::$content = $this->stringToCustomFunction(self::$content); self::$filename = $this->stringToCustomFunction(self::$filename); } /** * @param string $value * @return string */ private function stringToCustomFunction($value) { if (false !== strpos($value, '[CUSTOMFUNCTION|')) { foreach (glob('modules/PDFMaker/resources/functions/*.php') as $file) { include_once $file; } $AllowedFunctions = (new PDFMaker_AllowedFunctions_Helper())->getAllowedFunctions(); $startFunctions = explode('[CUSTOMFUNCTION|', $value); $content = $startFunctions[0]; foreach ($startFunctions as $function) { $endFunction = explode("|CUSTOMFUNCTION]", $function); $html = $endFunction[0]; if (!empty($html)) { $Params = $this->getCustomfunctionParams($html); $func = $Params[0]; unset($Params[0]); if (in_array($func, $AllowedFunctions)) { $content .= call_user_func_array($func, $Params); } } $content .= $endFunction[1]; } $value = $content; } return $value; } public function getFilename() { return $this->getInputContent("filename"); } /** * @return string */ public function getTemplateName() { return self::$templatename; } /** * @param string $type * @return string */ public function getInputContent($type) { if ('filename' === $type) { $val = self::$filename; } elseif ('pdfpassword' === $type) { $val = self::$pdf_password; } elseif ('watermark_text' === $type) { $val = self::$watermark_text; } if (empty($val)) { return ''; } $Rep = array(); $Rep['$#TEMPLATE_NAME#$'] = self::$templatename; $Rep['$#DD-MM-YYYY#$'] = date('d-m-Y'); $Rep['$#MM-DD-YYYY#$'] = date('m-d-Y'); $Rep['$#YYYY-MM-DD#$'] = date('Y-m-d'); $Rep["\r\n"] = $Rep["\n\r"] = $Rep["\n"] = $Rep["\r"] = ''; $val = str_replace(array_keys($Rep), $Rep, $val); $val = html_entity_decode($val, ENT_QUOTES, self::$def_charset); if ('filename' === $type) { return str_replace(' ', '_', substr(strip_tags($val), 0, 255)); } elseif ('pdfpassword' === $type) { return trim(strip_tags($val)); } else { return $val; } } public function getPDFPassword() { return $this->getInputContent("pdfpassword"); } public function getWatermarkText() { return $this->getInputContent("watermark_text"); } public function getSettings() { $Settings = $this->getSettingsForId(self::$templateid); $Settings["watermark"] = array( "type" => $Settings["watermark_type"], "text" => $Settings["watermark_text"], "img_id" => $Settings["watermark_img_id"], "alpha" => ($Settings["watermark_alpha"] != "" ? $Settings["watermark_alpha"] : "0.1") ); return $Settings; } private function getInventoryTaxTypeCustom($module, $focus) { if (!empty($focus->id)) { $res = self::$db->pquery("SELECT taxtype FROM " . self::$inventory_table_array[$module] . " WHERE " . self::$inventory_id_array[$module] . "=?", array($focus->id)); return self::$db->query_result($res, 0, 'taxtype'); } return ""; } private function itsmd($val) { return md5($val); } public function isAllowedExportEdit() { return '1' !== self::$disable_export_edit; } public function retrievePageBreak($data = array()) { if (!empty($data)) { self::$pagebreak = ''; } else { self::$pagebreak = '
    '; } } public function getPageBreak($data = array()) { if (!self::$pagebreak) { $this->retrievePageBreak($data); } return self::$pagebreak; } public function getDocumentFileName() { return self::$filename; } public static $numberFormat = []; public static function getNumberFormat($templateId) { if (empty(self::$numberFormat[$templateId])) { $adb = PearDatabase::getInstance(); $result = $adb->pquery('SELECT decimals, decimal_point, thousands_separator, currency, currency_point, currency_thousands FROM vtiger_pdfmaker_settings WHERE templateid=?', [$templateId] ); self::$numberFormat[$templateId] = $adb->fetch_array($result); } return self::$numberFormat[$templateId]; } /** * @param Vtiger_Field_Model $field * @param Vtiger_Record_Model $record * @throws Exception */ public function updateCalendarField($field, $record) { switch ($field->get('name')) { case 'date_start': $field->set('fieldvalue', $record->get('date_start') . ' ' . $record->get('time_start')); break; case 'due_date': $field->set('fieldvalue', $record->get('due_date') . ' ' . $record->get('time_end')); break; } } }