3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
36 * This class provides the functionality to email a group of
39 class CRM_Contribute_Form_Task_Invoice
extends CRM_Contribute_Form_Task
{
41 * Are we operating in "single mode", i.e. updating the task of only
42 * one specific contribution?
46 public $_single = FALSE;
49 * gives all the statues for conribution
53 public $_contributionStatusId;
56 * gives the HTML template of PDF Invoice
60 public $_messageInvoice;
63 * This variable is used to assign parameters for HTML template of PDF Invoice
67 public $_invoiceTemplate;
72 public $_selectedOutput;
75 * build all the data structures needed to build the form
80 function preProcess() {
81 $id = CRM_Utils_Request
::retrieve('id', 'Positive', $this, FALSE);
83 $this->_contributionIds
= array($id);
84 $this->_componentClause
= " civicrm_contribution.id IN ( $id ) ";
85 $this->_single
= TRUE;
86 $this->assign('totalSelectedContributions', 1);
92 // check that all the contribution ids have status Completed, Pending, Refunded.
93 $this->_contributionStatusId
= CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
94 $status = array('Completed', 'Pending', 'Refunded');
96 foreach ($this->_contributionStatusId
as $key => $value) {
97 if (in_array($value, $status)) {
101 $Id = implode(",", $statusId);
102 $query = "SELECT count(*) FROM civicrm_contribution WHERE contribution_status_id NOT IN ($Id) AND {$this->_componentClause}";
103 $count = CRM_Core_DAO
::singleValueQuery($query);
105 CRM_Core_Error
::statusBounce(ts('Please select only contributions with Completed, Pending, Refunded status.'));
108 // we have all the contribution ids, so now we get the contact ids
109 parent
::setContactIDs();
110 $this->assign('single', $this->_single
);
112 $qfKey = CRM_Utils_Request
::retrieve('qfKey', 'String', $this);
113 $urlParams = 'force=1';
114 if (CRM_Utils_Rule
::qfKey($qfKey)) {
115 $urlParams .= "&qfKey=$qfKey";
118 $url = CRM_Utils_System
::url('civicrm/contribute/search', $urlParams);
122 'title' => ts('Search Results'),
126 CRM_Utils_System
::appendBreadCrumb($breadCrumb);
128 $this->_selectedOutput
= CRM_Utils_Request
::retrieve('select', 'String', $this);
129 $this->assign('selectedOutput', $this->_selectedOutput
);
131 if ($this->_selectedOutput
== 'email') {
132 CRM_Utils_System
::setTitle(ts('Email Invoice'));
135 CRM_Utils_System
::setTitle(ts('Print Contribution Invoice'));
146 public function buildQuickForm() {
147 $session = CRM_Core_Session
::singleton();
148 if (CRM_Core_Permission
::check('administer CiviCRM')) {
149 $this->assign('isAdmin', 1);
151 $contactID = $session->get('userID');
152 $contactEmails = CRM_Core_BAO_Email
::allEmails($contactID);
154 $fromDisplayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
155 $contactID, 'display_name'
157 foreach ($contactEmails as $emailId => $item) {
158 $email = $item['email'];
160 $emails[$emailId] = '"' . $fromDisplayName . '" <' . $email . '> ';
162 if (isset($emails[$emailId])) {
163 $emails[$emailId] .= $item['locationType'];
164 if ($item['is_primary']) {
165 $emails[$emailId] .= ' ' . ts('(preferred)');
167 $emails[$emailId] = htmlspecialchars($emails[$emailId]);
170 $fromEmailAddress = CRM_Core_OptionGroup
::values('from_email_address');
171 foreach ($fromEmailAddress as $key => $email) {
172 $fromEmailAddress[$key] = htmlspecialchars($fromEmailAddress[$key]);
174 $fromEmail = CRM_Utils_Array
::crmArrayMerge($emails, $fromEmailAddress);
175 $this->add('select', 'from_email_address', ts('From Email Address'), array('' => '- select -') +
$fromEmail);
176 if ($this->_selectedOutput
!= 'email') {
177 $this->addElement('radio', 'output', NULL, ts('Email Invoice'), 'email_invoice');
178 $this->addElement('radio', 'output', NULL, ts('PDF Invoice'), 'pdf_invoice');
179 $this->addRule('output', ts('Selection required'), 'required');
180 $this->addFormRule(array('CRM_Contribute_Form_Task_Invoice', 'formRule'));
183 $this->addRule('from_email_address', ts('From Email Address is required'), 'required');
186 $this->addWysiwyg('email_comment', ts('If you would like to add personal message to email please add it here. (If sending to more then one receipient the same message will be sent to each contact.)'), array(
191 if (in_array("email", $this->urlPath
)) {
192 $this->addButtons(array(
195 'name' => ts('Email Invoice'),
200 'name' => ts('Cancel'),
206 $this->addButtons(array(
209 'name' => ts('Process Invoice(s)'),
214 'name' => ts('Cancel'),
222 * global validation rules for the form
226 * @internal param array $fields posted values of the form
228 * @return array list of errors to be posted back to the form
232 static function formRule($values) {
235 if ($values['output'] == 'email_invoice' && empty($values['from_email_address'])) {
236 $errors['from_email_address'] = ts("From Email Address is required");
243 * process the form after the input has been submitted and validated
249 public function postProcess() {
250 $params = $this->controller
->exportValues($this->_name
);
251 $this->printPDF($this->_contributionIds
, $params, $this->_contactIds
);
256 * process the PDf and email with activity and attachment
257 * on click of Print Invoices
259 * @param array $contribIDs Contribution Id
260 * @param array $params for pdf or email invoices
261 * @param array $contactIds Contact Id
265 static function printPDF($contribIDs, $params, $contactIds) {
266 // get all the details needed to generate a invoice
267 $messageInvoice = array();
268 $invoiceTemplate = CRM_Core_Smarty
::singleton();
269 $invoiceElements = CRM_Contribute_Form_Task_PDF
::getElements($contribIDs, $params, $contactIds);
271 // gives the status id when contribution status is 'Refunded'
272 $contributionStatusID = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
273 $refundedStatusId = CRM_Utils_Array
::key('Refunded', $contributionStatusID);
275 // getting data from admin page
276 $prefixValue = CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::CONTRIBUTE_PREFERENCES_NAME
, 'contribution_invoice_settings');
278 foreach ($invoiceElements['details'] as $contribID => $detail) {
279 $input = $ids = $objects = array();
280 if (in_array($detail['contact'], $invoiceElements['excludeContactIds'])) {
284 $input['component'] = $detail['component'];
286 $ids['contact'] = $detail['contact'];
287 $ids['contribution'] = $contribID;
288 $ids['contributionRecur'] = NULL;
289 $ids['contributionPage'] = NULL;
290 $ids['membership'] = CRM_Utils_Array
::value('membership', $detail);
291 $ids['participant'] = CRM_Utils_Array
::value('participant', $detail);
292 $ids['event'] = CRM_Utils_Array
::value('event', $detail);
294 if (!$invoiceElements['baseIPN']->validateData($input, $ids, $objects, FALSE)) {
295 CRM_Core_Error
::fatal();
298 $contribution = & $objects['contribution'];
300 $input['amount'] = $contribution->total_amount
;
301 $input['invoice_id'] = $contribution->invoice_id
;
302 $input['receive_date'] = $contribution->receive_date
;
303 $input['contribution_status_id'] = $contribution->contribution_status_id
;
304 $input['organization_name'] = $contribution->_relatedObjects
['contact']->organization_name
;
306 $objects['contribution']->receive_date
= CRM_Utils_Date
::isoToMysql($objects['contribution']->receive_date
);
308 $addressParams = array('contact_id' => $contribution->contact_id
);
309 $addressDetails = CRM_Core_BAO_Address
::getValues($addressParams);
311 // to get billing address if present
312 $billingAddress = array();
313 foreach ($addressDetails as $key => $address) {
314 if ((isset($address['is_billing']) && $address['is_billing'] == 1) && (isset($address['is_primary']) && $address['is_primary'] == 1) && $address['contact_id'] == $contribution->contact_id
) {
315 $billingAddress[$address['contact_id']] = $address;
318 elseif (($address['is_billing'] == 0 && $address['is_primary'] == 1) ||
(isset($address['is_billing']) && $address['is_billing'] == 1) && $address['contact_id'] == $contribution->contact_id
) {
319 $billingAddress[$address['contact_id']] = $address;
323 if (!empty($billingAddress[$contribution->contact_id
]['state_province_id'])) {
324 $stateProvinceAbbreviation = CRM_Core_PseudoConstant
::stateProvinceAbbreviation($billingAddress[$contribution->contact_id
]['state_province_id']);
327 $stateProvinceAbbreviation = '';
330 if ($contribution->contribution_status_id
== $refundedStatusId) {
331 $creditNoteId = CRM_Utils_Array
::value('credit_notes_prefix', $prefixValue) . "" . $contribution->id
;
333 $invoiceId = CRM_Utils_Array
::value('invoice_prefix', $prefixValue) . "" . $contribution->id
;
335 //to obtain due date for PDF invoice
336 $contributionReceiveDate = date('F j,Y', strtotime(date($input['receive_date'])));
337 $invoiceDate = date("F j, Y");
338 $dueDate = date('F j ,Y', strtotime($contributionReceiveDate . "+" . $prefixValue['due_date'] . "" . $prefixValue['due_date_period']));
340 if ($input['component'] == 'contribute') {
342 $etable = 'contribution';
343 $lineItem = CRM_Price_BAO_LineItem
::getLineItems($eid, $etable, NULL, TRUE, TRUE);
346 $eid = $contribution->_relatedObjects
['participant']->id
;
347 $etable = 'participant';
348 $lineItem = CRM_Price_BAO_LineItem
::getLineItems($eid, $etable);
351 //TO DO: Need to do changes for partially paid to display amount due on PDF invoice
352 $amountDue = ($input['amount'] - $input['amount']);
354 // retreiving the subtotal and sum of same tax_rate
355 $dataArray = array();
357 foreach ($lineItem as $entity_id => $taxRate) {
358 if (isset($dataArray[(string) $taxRate['tax_rate']])) {
359 $dataArray[(string) $taxRate['tax_rate']] = $dataArray[(string) $taxRate['tax_rate']] + CRM_Utils_Array
::value('tax_amount', $taxRate);
362 $dataArray[(string) $taxRate['tax_rate']] = CRM_Utils_Array
::value('tax_amount', $taxRate);
364 $subTotal +
= CRM_Utils_Array
::value('subTotal', $taxRate);
367 // to email the invoice
368 $mailDetails = array();
370 if ($contribution->_component
== 'event') {
371 $daoName = 'CRM_Event_DAO_Event';
372 $pageId = $contribution->_relatedObjects
['event']->id
;
373 $mailElements = array(
376 'confirm_from_email',
380 CRM_Core_DAO
::commonRetrieveAll($daoName, 'id', $pageId, $mailDetails, $mailElements);
381 $values['title'] = CRM_Utils_Array
::value('title', $mailDetails[$contribution->_relatedObjects
['event']->id
]);
382 $values['confirm_from_name'] = CRM_Utils_Array
::value('confirm_from_name', $mailDetails[$contribution->_relatedObjects
['event']->id
]);
383 $values['confirm_from_email'] = CRM_Utils_Array
::value('confirm_from_email', $mailDetails[$contribution->_relatedObjects
['event']->id
]);
384 $values['cc_confirm'] = CRM_Utils_Array
::value('cc_confirm', $mailDetails[$contribution->_relatedObjects
['event']->id
]);
385 $values['bcc_confirm'] = CRM_Utils_Array
::value('bcc_confirm', $mailDetails[$contribution->_relatedObjects
['event']->id
]);
387 $title = CRM_Utils_Array
::value('title', $mailDetails[$contribution->_relatedObjects
['event']->id
]);
389 elseif ($contribution->_component
== 'contribute') {
390 $daoName = 'CRM_Contribute_DAO_ContributionPage';
391 $pageId = $contribution->contribution_page_id
;
392 $mailElements = array(
395 'receipt_from_email',
399 CRM_Core_DAO
::commonRetrieveAll($daoName, 'id', $pageId, $mailDetails, $mailElements);
401 $values['title'] = CRM_Utils_Array
::value('title', CRM_Utils_Array
::value($contribution->contribution_page_id
, $mailDetails));
402 $values['receipt_from_name'] = CRM_Utils_Array
::value('receipt_from_name', CRM_Utils_Array
::value($contribution->contribution_page_id
, $mailDetails));
403 $values['receipt_from_email'] = CRM_Utils_Array
::value('receipt_from_email', CRM_Utils_Array
::value($contribution->contribution_page_id
, $mailDetails));
404 $values['cc_receipt'] = CRM_Utils_Array
::value('cc_receipt', CRM_Utils_Array
::value($contribution->contribution_page_id
, $mailDetails));
405 $values['bcc_receipt'] = CRM_Utils_Array
::value('bcc_receipt', CRM_Utils_Array
::value($contribution->contribution_page_id
, $mailDetails));
407 $title = CRM_Utils_Array
::value('title', CRM_Utils_Array
::value($contribution->contribution_page_id
, $mailDetails));
409 $source = $contribution->source
;
411 $config = CRM_Core_Config
::singleton();
412 if (!isset($params['forPage'])) {
413 $config->doNotAttachPDFReceipt
= 1;
416 // get organization address
417 $domain = CRM_Core_BAO_Domain
::getDomain();
418 $locParams = array('contact_id' => $domain->id
);
419 $locationDefaults = CRM_Core_BAO_Location
::getValues($locParams);
420 if (isset($locationDefaults['address'][1]['state_province_id'])) {
421 $stateProvinceAbbreviationDomain = CRM_Core_PseudoConstant
::stateProvinceAbbreviation($locationDefaults['address'][1]['state_province_id']);
424 $stateProvinceAbbreviationDomain = '';
426 if (isset($locationDefaults['address'][1]['country_id'])) {
427 $countryDomain = CRM_Core_PseudoConstant
::country($locationDefaults['address'][1]['country_id']);
433 // parameters to be assign for template
436 'component' => $input['component'],
437 'id' => $contribution->id
,
439 'invoice_id' => $invoiceId,
440 'resourceBase' => $config->userFrameworkResourceURL
,
441 'defaultCurrency' => $config->defaultCurrency
,
442 'amount' => $contribution->total_amount
,
443 'amountDue' => $amountDue,
444 'invoice_date' => $invoiceDate,
445 'dueDate' => $dueDate,
446 'notes' => CRM_Utils_Array
::value('notes', $prefixValue),
447 'display_name' => $contribution->_relatedObjects
['contact']->display_name
,
448 'lineItem' => $lineItem,
449 'dataArray' => $dataArray,
450 'refundedStatusId' => $refundedStatusId,
451 'contribution_status_id' => $contribution->contribution_status_id
,
452 'subTotal' => $subTotal,
453 'street_address' => CRM_Utils_Array
::value('street_address', CRM_Utils_Array
::value($contribution->contact_id
, $billingAddress)),
454 'supplemental_address_1' => CRM_Utils_Array
::value('supplemental_address_1', CRM_Utils_Array
::value($contribution->contact_id
, $billingAddress)),
455 'supplemental_address_2' => CRM_Utils_Array
::value('supplemental_address_2', CRM_Utils_Array
::value($contribution->contact_id
, $billingAddress)),
456 'city' => CRM_Utils_Array
::value('city', CRM_Utils_Array
::value($contribution->contact_id
, $billingAddress)),
457 'stateProvinceAbbreviation' => $stateProvinceAbbreviation,
458 'postal_code' => CRM_Utils_Array
::value('postal_code', CRM_Utils_Array
::value($contribution->contact_id
, $billingAddress)),
459 'is_pay_later' => $contribution->is_pay_later
,
460 'organization_name' => $contribution->_relatedObjects
['contact']->organization_name
,
461 'domain_organization' => $domain->name
,
462 'domain_street_address' => CRM_Utils_Array
::value('street_address', CRM_Utils_Array
::value('1', $locationDefaults['address'])),
463 'domain_supplemental_address_1' => CRM_Utils_Array
::value('supplemental_address_1', CRM_Utils_Array
::value('1', $locationDefaults['address'])),
464 'domain_supplemental_address_2' => CRM_Utils_Array
::value('supplemental_address_2', CRM_Utils_Array
::value('1', $locationDefaults['address'])),
465 'domain_city' => CRM_Utils_Array
::value('city', CRM_Utils_Array
::value('1', $locationDefaults['address'])),
466 'domain_postal_code' => CRM_Utils_Array
::value('postal_code', CRM_Utils_Array
::value('1', $locationDefaults['address'])),
467 'domain_state' => $stateProvinceAbbreviationDomain,
468 'domain_country' => $countryDomain,
469 'domain_email' => CRM_Utils_Array
::value('email', CRM_Utils_Array
::value('1', $locationDefaults['email'])),
470 'domain_phone' => CRM_Utils_Array
::value('phone', CRM_Utils_Array
::value('1', $locationDefaults['phone'])),
473 if (isset($creditNoteId)) {
474 $tplParams['creditnote_id'] = $creditNoteId;
477 $sendTemplateParams = array(
478 'groupName' => 'msg_tpl_workflow_contribution',
479 'valueName' => 'contribution_invoice_receipt',
480 'contactId' => $contribution->contact_id
,
481 'tplParams' => $tplParams,
482 'PDFFilename' => 'Invoice.pdf',
484 $session = CRM_Core_Session
::singleton();
485 $contactID = $session->get('userID');
486 $contactEmails = CRM_Core_BAO_Email
::allEmails($contactID);
488 $fromDisplayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
489 $contactID, 'display_name'
492 foreach ($contactEmails as $emailId => $item) {
493 $email = $item['email'];
495 $emails[$emailId] = '"' . $fromDisplayName . '" <' . $email . '> ';
498 $fromEmail = CRM_Utils_Array
::crmArrayMerge($emails, CRM_Core_OptionGroup
::values('from_email_address'));
500 // from email address
501 if (isset($params['from_email_address'])) {
502 $fromEmailAddress = CRM_Utils_Array
::value($params['from_email_address'], $fromEmail);
504 // condition to check for download PDF Invoice or email Invoice
505 if ($invoiceElements['createPdf']) {
506 list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate
::sendTemplate($sendTemplateParams);
507 if (isset($params['forPage'])) {
512 'subject' => $subject,
517 $messageInvoice[] = $mail['html'];
520 $messageInvoice[] = nl2br($mail['body']);
524 elseif ($contribution->_component
== 'contribute') {
525 $email = CRM_Contact_BAO_Contact
::getPrimaryEmail($contribution->contact_id
);
527 $sendTemplateParams['tplParams'] = array_merge($tplParams, array('email_comment' => $invoiceElements['params']['email_comment']));
528 $sendTemplateParams['from'] = $fromEmailAddress;
529 $sendTemplateParams['toEmail'] = $email;
530 $sendTemplateParams['cc'] = CRM_Utils_Array
::value('cc_receipt', $values);
531 $sendTemplateParams['bcc'] = CRM_Utils_Array
::value('bcc_receipt', $values);
533 list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate
::sendTemplate($sendTemplateParams);
534 // functions call for adding activity with attachment
535 $fileName = self
::putFile($html);
536 self
::addActivities($subject, $contribution->contact_id
, $fileName, $params);
538 elseif ($contribution->_component
== 'event') {
539 $email = CRM_Contact_BAO_Contact
::getPrimaryEmail($contribution->contact_id
);
541 $sendTemplateParams['tplParams'] = array_merge($tplParams, array('email_comment' => $invoiceElements['params']['email_comment']));
542 $sendTemplateParams['from'] = $fromEmailAddress;
543 $sendTemplateParams['toEmail'] = $email;
544 $sendTemplateParams['cc'] = CRM_Utils_Array
::value('cc_confirm', $values);
545 $sendTemplateParams['bcc'] = CRM_Utils_Array
::value('bcc_confirm', $values);
547 list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate
::sendTemplate($sendTemplateParams);
548 // functions call for adding activity with attachment
549 $fileName = self
::putFile($html);
550 self
::addActivities($subject, $contribution->contact_id
, $fileName, $params);
553 CRM_Core_DAO
::setFieldValue('CRM_Contribute_DAO_Contribution', $contribution->id
, 'invoice_id', $invoiceId);
554 if ($contribution->contribution_status_id
== $refundedStatusId) {
555 CRM_Core_DAO
::setFieldValue('CRM_Contribute_DAO_Contribution', $contribution->id
, 'creditnote_id', $creditNoteId);
557 $invoiceTemplate->clearTemplateVars();
560 if ($invoiceElements['createPdf']) {
561 if (isset($params['forPage'])) {
565 CRM_Utils_PDF_Utils
::html2pdf($messageInvoice, 'Invoice.pdf', FALSE, array(
570 // functions call for adding activity with attachment
571 $fileName = self
::putFile($html);
572 self
::addActivities($subject, $contactIds, $fileName, $params);
574 CRM_Utils_System
::civiExit();
578 if ($invoiceElements['suppressedEmails']) {
579 $status = ts('Email was NOT sent to %1 contacts (no email address on file, or communication preferences specify DO NOT EMAIL, or contact is deceased).', array(1 => $invoiceElements['suppressedEmails']));
580 $msgTitle = ts('Email Error');
584 $status = ts('Your mail has been sent.');
585 $msgTitle = ts('Sent');
586 $msgType = 'success';
588 CRM_Core_Session
::setStatus($status, $msgTitle, $msgType);
594 * This function is use for adding activity for
595 * Email Invoice and the PDF Invoice
597 * @param string $subject Activity subject
598 * @param array $contactIds Contact Id
599 * @param string $fileName gives the location with name of the file
600 * @param array $params for invoices
605 static public function addActivities($subject, $contactIds, $fileName, $params) {
606 $session = CRM_Core_Session
::singleton();
607 $userID = $session->get('userID');
608 $config = CRM_Core_Config
::singleton();
609 $config->doNotAttachPDFReceipt
= 1;
611 if (!empty($params['output']) && $params['output'] == 'pdf_invoice') {
612 $activityTypeID = CRM_Core_OptionGroup
::getValue('activity_type',
613 'Downloaded Invoice',
618 $activityTypeID = CRM_Core_OptionGroup
::getValue('activity_type',
624 $activityParams = array(
625 'subject' => $subject,
626 'source_contact_id' => $userID,
627 'target_contact_id' => $contactIds,
628 'activity_type_id' => $activityTypeID,
629 'activity_date_time' => date('YmdHis'),
630 'attachFile_1' => array(
632 'type' => 'application/pdf',
633 'location' => $fileName,
634 'upload_date' => date('YmdHis'),
637 CRM_Activity_BAO_Activity
::create($activityParams);
642 * This function is use for creating the Invoice file in upload folder
645 * @param $html content for pdf in html format
647 * return $fileName of file which is in pdf format
650 static public function putFile($html) {
651 require_once("packages/dompdf/dompdf_config.inc.php");
652 spl_autoload_register('DOMPDF_autoload');
654 $doc->load_html($html);
656 $html = $doc->output();
657 $config = CRM_Core_Config
::singleton();
658 $fileName = $config->uploadDir
. 'Invoice.pdf';
659 file_put_contents($fileName, $html);