Note: since writing this post I’ve added a another entry on doing with with bulk PDFs to see part 2 of this blog click here.
I’m a big advocate of open source so when my company wanted to investigate CRM, SuiteCRM was an obvious choice. However, occasionally things aren’t always as straightforward.
The brief was simple, created a module for recording internal production issues. SuiteCRM has an inbuilt cases module which it was a breeze to create a version of in the Module builder. As part of this we needed a means of printing PDFs ad-hoc.
Before you begin…
Replace all [CUSTOM MODULE NAME] with your module name and [PACKAGE NAME] with your package name. All files should be owned by www-data, to do this run ‘chown www-data:www-data’ on any and all new files you create.
Configure a module for printing PDFs.
1. Change directory to the custom module directory
/var/www/html/suitecrm/custom/modulebuilder/packages/[PACKAGE NAME]/modules/[CUSTOM MODULE NAME]
2. In metadata/detailviewdefs.php add the line
4 => array ( 'customCode' => '<input type="button" class="button" onClick="showPopup(\'pdf\');" value="{$MOD.LBL_PRINT_AS_PDF}">')
below
'buttons' => array ( 0 => 'EDIT', 1 => 'DUPLICATE', 2 => 'DELETE', 3 => 'FIND_DUPLICATES',
3. In vim language/en_us.lang.php ensure the line
'LBL_PRINT_AS_PDF' => 'Print as PDF',
Is in the array $mod_strings
4. Make a directory view in the module directory
mkdir views chown www-data:www-data views
5. in views/view.detail.php add the following code
<?php if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); require_once('include/MVC/View/views/view.detail.php'); class remed_RemedialsViewDetail extends ViewDetail { function __construct(){ parent::__construct(); } /** * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead */ function remed_RemedialsViewDetail(){ $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code'; if(isset($GLOBALS['log'])) { $GLOBALS['log']->deprecated($deprecatedMessage); } else { trigger_error($deprecatedMessage, E_USER_DEPRECATED); } self::__construct(); } function display(){ if(empty($this->bean->id)){ global $app_strings; sugar_die($app_strings['ERROR_NO_RECORD']); } require_once('modules/AOS_PDF_Templates/formLetter.php'); formLetter::DVPopupHtml('remed_Remedials'); $this->dv->process(); if(ACLController::checkAccess('Contacts', 'edit', true)) { $push_billing = $this->generatePushCode('billing'); $push_shipping = $this->generatePushCode('shipping'); } else { $push_billing = ''; $push_shipping = ''; } $this->ss->assign("custom_code_billing", $push_billing); $this->ss->assign("custom_code_shipping", $push_shipping); if(empty($this->bean->id)){ global $app_strings; sugar_die($app_strings['ERROR_NO_RECORD']); } echo $this->dv->display(); } function generatePushCode($param) { global $mod_strings; $address_fields = array('street', 'city', 'state', 'postalcode','country'); // $html = '<input class="button" title="' . $mod_strings['LBL_PUSH_CONTACTS_BUTTON_LABEL'] . '" type="button" onclick=\'open_contact_popup("Contacts", 600, 600, "&account_name=' . $this->bean->name . '&html=change_address'; foreach ($address_fields as $value) { $field_name = $param.'_address_'.$value; // $html .= '&primary_address_'.$value.'='.str_replace(array("\rn", "\r", "\n"), array('','','<br>'), urlencode($this->bean->$field_name)) ; } // $html .= '", true, false);\' value="' . $mod_strings['LBL_PUSH_CONTACTS_BUTTON_TITLE']. '">'; // return $html; } } <?php if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); require_once('include/MVC/View/views/view.detail.php'); class remed_RemedialsViewDetail extends ViewDetail { function __construct(){ parent::__construct(); } /** * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead */ function remed_RemedialsViewDetail(){ $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code'; if(isset($GLOBALS['log'])) { $GLOBALS['log']->deprecated($deprecatedMessage); } else { trigger_error($deprecatedMessage, E_USER_DEPRECATED); } self::__construct(); } function display(){ if(empty($this->bean->id)){ global $app_strings; sugar_die($app_strings['ERROR_NO_RECORD']); } require_once('modules/AOS_PDF_Templates/formLetter.php'); formLetter::DVPopupHtml('remed_Remedials'); $this->dv->process(); if(ACLController::checkAccess('Contacts', 'edit', true)) { $push_billing = $this->generatePushCode('billing'); $push_shipping = $this->generatePushCode('shipping'); } else { $push_billing = ''; $push_shipping = ''; } $this->ss->assign("custom_code_billing", $push_billing); $this->ss->assign("custom_code_shipping", $push_shipping); if(empty($this->bean->id)){ global $app_strings; sugar_die($app_strings['ERROR_NO_RECORD']); } echo $this->dv->display(); } function generatePushCode($param) { global $mod_strings; $address_fields = array('street', 'city', 'state', 'postalcode','country'); // $html = '<input class="button" title="' . $mod_strings['LBL_PUSH_CONTACTS_BUTTON_LABEL'] . '" type="button" onclick=\'open_contact_popup("Contacts", 600, 600, "&account_name=' . $this->bean->name . '&html=change_address'; foreach ($address_fields as $value) { $field_name = $param.'_address_'.$value; // $html .= '&primary_address_'.$value.'='.str_replace(array("\rn", "\r", "\n"), array('','','<br>'), urlencode($this->bean->$field_name)) ; } // $html .= '", true, false);\' value="' . $mod_strings['LBL_PUSH_CONTACTS_BUTTON_TITLE']. '">'; // return $html; } }
Configure a module for printing bulk PDFs
Follow steps 1, 3 and 4 from the previous steps for creating a single PDF function in your module.
1. Create a views.list.php with the following
require_once('include/MVC/View/views/view.list.php'); require_once('modules/[CUSTOM MODULE NAME]/[CUSTOM MODULE NAME]ListViewSmarty.php'); class [CUSTOM MODULE NAME]ViewList extends ViewList { /** * @see ViewList::preDisplay() */ public function preDisplay(){ require_once('modules/AOS_PDF_Templates/formLetter.php'); formLetter::LVPopupHtml('[CUSTOM MODULE NAME]'); parent::preDisplay(); $this->lv = new [CUSTOM MODULE NAME]ListViewSmarty(); } }
2. Create a [modulename]ListViewSmarty.php with the following
require_once('include/ListView/ListViewSmarty.php'); require_once('modules/AOS_PDF_Templates/formLetter.php'); class [CUSTOM MODULE NAME]ListViewSmarty extends ListViewSmarty { function __construct(){ parent::__construct(); $this->targetList = true; } /** * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead */ function [CUSTOM MODULE NAME]ListViewSmarty(){ $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code'; if(isset($GLOBALS['log'])) { $GLOBALS['log']->deprecated($deprecatedMessage); } else { trigger_error($deprecatedMessage, E_USER_DEPRECATED); } self::__construct(); } /** * * @param file $file Template file to use * @param array $data from ListViewData * @param string $htmlVar the corresponding html public in xtpl per row * @return bool|void */ public function process($file, $data, $htmlVar) { $configurator = new Configurator(); if ($configurator->isConfirmOptInEnabled()) { $this->actionsMenuExtraItems[] = $this->buildSendConfirmOptInEmailToPersonAndCompany(); } $ret = parent::process($file, $data, $htmlVar); if (!ACLController::checkAccess($this->seed->module_dir, 'export', true) || !$this->export) { $this->ss->assign('exportLink', $this->buildExportLink()); } return $ret; } function buildExportLink($id = 'export_link'){ global $app_strings; global $sugar_config; $script = ""; if(ACLController::checkAccess($this->seed->module_dir,'export',true)) { if($this->export) { $script = parent::buildExportLink($id); } } $script .= " " onclick=\"return sListView.send_form(true, 'jjwg_Maps', " . "'index.php?entryPoint=jjwg_Maps&display_module={$_REQUEST['module']}', " . "'{$app_strings['LBL_LISTVIEW_NO_SELECTED']}')\">{$app_strings['LBL_MAP']}"; return formLetter::LVSmarty().$script; } }
Creating PDF templates
From here you’ll need to add your module to the dropdown list ‘pdf_template_type_dom’ and create your template in ‘PDF – Templates’.