Add CC as EntityRef Field, Correct Layout of Email invoice, same as downloaded invoic...
[civicrm-core.git] / CRM / Contribute / Form / Task / Invoice.php
CommitLineData
b8df2a80
RK
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
b8df2a80 5 | |
bc77d7c0
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
b8df2a80 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
b8df2a80
RK
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
b8df2a80
RK
16 */
17
9fa2c2ff 18use Civi\Api4\Email;
b8df2a80
RK
19/**
20 * This class provides the functionality to email a group of
21 * contacts.
22 */
23class CRM_Contribute_Form_Task_Invoice extends CRM_Contribute_Form_Task {
dce4c3ea 24 /**
b8df2a80
RK
25 * Are we operating in "single mode", i.e. updating the task of only
26 * one specific contribution?
27 *
b67daa72 28 * @var bool
b8df2a80
RK
29 */
30 public $_single = FALSE;
31
3a1261ac 32 /**
fe482240 33 * Gives all the statues for conribution.
1330f57a 34 * @var int
3a1261ac
RK
35 */
36 public $_contributionStatusId;
37
38 /**
fe482240 39 * Gives the HTML template of PDF Invoice.
1330f57a 40 * @var string
3a1261ac
RK
41 */
42 public $_messageInvoice;
43
44 /**
fe482240 45 * This variable is used to assign parameters for HTML template of PDF Invoice.
1330f57a 46 * @var string
3a1261ac
RK
47 */
48 public $_invoiceTemplate;
dce4c3ea 49
830b3e83 50 /**
fe482240 51 * Selected output.
1330f57a 52 * @var string
830b3e83 53 */
54 public $_selectedOutput;
55
b8df2a80 56 /**
fe482240 57 * Build all the data structures needed to build the form.
dce4c3ea 58 */
00be9182 59 public function preProcess() {
b8df2a80
RK
60 $id = CRM_Utils_Request::retrieve('id', 'Positive', $this, FALSE);
61 if ($id) {
be2fb01f 62 $this->_contributionIds = [$id];
b8df2a80
RK
63 $this->_componentClause = " civicrm_contribution.id IN ( $id ) ";
64 $this->_single = TRUE;
65 $this->assign('totalSelectedContributions', 1);
b5c3483d 66
67 // set the redirection after actions
68 $contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE);
69 $url = CRM_Utils_System::url('civicrm/contact/view/contribution',
70 "action=view&reset=1&id={$id}&cid={$contactId}&context=contribution&selectedChild=contribute"
71 );
72
73 CRM_Core_Session::singleton()->pushUserContext($url);
b8df2a80
RK
74 }
75 else {
76 parent::preProcess();
77 }
dce4c3ea 78
46bee19a 79 // check that all the contribution ids have status Completed, Pending, Refunded, or Partially Paid.
3a1261ac 80 $this->_contributionStatusId = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
46bee19a 81 $status = ['Completed', 'Pending', 'Refunded', 'Partially paid'];
be2fb01f 82 $statusId = [];
3a1261ac
RK
83 foreach ($this->_contributionStatusId as $key => $value) {
84 if (in_array($value, $status)) {
2826a42e 85 $statusId[] = $key;
3a1261ac
RK
86 }
87 }
88 $Id = implode(",", $statusId);
89 $query = "SELECT count(*) FROM civicrm_contribution WHERE contribution_status_id NOT IN ($Id) AND {$this->_componentClause}";
b8df2a80
RK
90 $count = CRM_Core_DAO::singleValueQuery($query);
91 if ($count != 0) {
46bee19a 92 CRM_Core_Error::statusBounce(ts('Please select only contributions with Completed, Pending, Refunded, or Partially Paid status.'));
b8df2a80 93 }
dce4c3ea 94
b8df2a80
RK
95 // we have all the contribution ids, so now we get the contact ids
96 parent::setContactIDs();
97 $this->assign('single', $this->_single);
dce4c3ea 98
b8df2a80
RK
99 $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $this);
100 $urlParams = 'force=1';
101 if (CRM_Utils_Rule::qfKey($qfKey)) {
102 $urlParams .= "&qfKey=$qfKey";
103 }
dce4c3ea 104
b8df2a80 105 $url = CRM_Utils_System::url('civicrm/contribute/search', $urlParams);
be2fb01f
CW
106 $breadCrumb = [
107 [
dce4c3ea 108 'url' => $url,
109 'title' => ts('Search Results'),
be2fb01f
CW
110 ],
111 ];
dce4c3ea 112
b8df2a80 113 CRM_Utils_System::appendBreadCrumb($breadCrumb);
830b3e83 114
115 $this->_selectedOutput = CRM_Utils_Request::retrieve('select', 'String', $this);
116 $this->assign('selectedOutput', $this->_selectedOutput);
117
beac1417 118 CRM_Contact_Form_Task_EmailCommon::preProcessFromAddress($this);
830b3e83 119 if ($this->_selectedOutput == 'email') {
6efffa5d 120 CRM_Utils_System::setTitle(ts('Email Invoice'));
dce4c3ea 121 }
122 else {
6efffa5d
PB
123 CRM_Utils_System::setTitle(ts('Print Contribution Invoice'));
124 }
b8df2a80 125 }
dce4c3ea 126
b8df2a80 127 /**
fe482240 128 * Build the form object.
b8df2a80
RK
129 */
130 public function buildQuickForm() {
33313a73 131 $this->preventAjaxSubmit();
6efffa5d
PB
132 if (CRM_Core_Permission::check('administer CiviCRM')) {
133 $this->assign('isAdmin', 1);
134 }
beac1417
MW
135
136 $this->add('select', 'from_email_address', ts('From'), $this->_fromEmails, TRUE);
830b3e83 137 if ($this->_selectedOutput != 'email') {
138 $this->addElement('radio', 'output', NULL, ts('Email Invoice'), 'email_invoice');
139 $this->addElement('radio', 'output', NULL, ts('PDF Invoice'), 'pdf_invoice');
140 $this->addRule('output', ts('Selection required'), 'required');
be2fb01f 141 $this->addFormRule(['CRM_Contribute_Form_Task_Invoice', 'formRule']);
830b3e83 142 }
143 else {
144 $this->addRule('from_email_address', ts('From Email Address is required'), 'required');
145 }
146
c8025280 147 $attributes = ['class' => 'huge'];
9fa2c2ff
SP
148 $this->addEntityRef('cc_id', ts('CC'), [
149 'entity' => 'Email',
150 'multiple' => TRUE,
151 ]);
c8025280 152 $this->add('text', 'subject', ts('Subject'), $attributes + ['placeholder' => ts('Optional')]);
be2fb01f 153 $this->add('wysiwyg', '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.)'), [
dce4c3ea 154 'rows' => 2,
21dfd5f5 155 'cols' => 40,
be2fb01f 156 ]);
6efffa5d 157
be2fb01f 158 $this->addButtons([
1330f57a
SL
159 [
160 'type' => 'upload',
161 'name' => $this->_selectedOutput == 'email' ? ts('Send Email') : ts('Process Invoice(s)'),
162 'isDefault' => TRUE,
163 ],
164 [
165 'type' => 'cancel',
166 'name' => ts('Cancel'),
167 ],
168 ]);
b8df2a80 169 }
6f39f13a
PB
170
171 /**
fe482240 172 * Global validation rules for the form.
6f39f13a 173 *
c490a46a 174 * @param array $values
6f39f13a 175 *
a6c01b45
CW
176 * @return array
177 * list of errors to be posted back to the form
6f39f13a 178 */
00be9182 179 public static function formRule($values) {
be2fb01f 180 $errors = [];
830b3e83 181
182 if ($values['output'] == 'email_invoice' && empty($values['from_email_address'])) {
183 $errors['from_email_address'] = ts("From Email Address is required");
6f39f13a 184 }
830b3e83 185
6f39f13a 186 return $errors;
b8df2a80 187 }
dce4c3ea 188
189 /**
fe482240 190 * Process the form after the input has been submitted and validated.
b8df2a80
RK
191 */
192 public function postProcess() {
6efffa5d 193 $params = $this->controller->exportValues($this->_name);
1273d77c 194 self::printPDF($this->_contributionIds, $params, $this->_contactIds);
6efffa5d
PB
195 }
196
dce4c3ea 197 /**
95cdcc0f 198 * Process the PDf and email with activity and attachment on click of Print Invoices.
dce4c3ea 199 *
014c4014
TO
200 * @param array $contribIDs
201 * Contribution Id.
202 * @param array $params
203 * Associated array of submitted values.
204 * @param array $contactIds
205 * Contact Id.
6efffa5d 206 */
1273d77c 207 public static function printPDF($contribIDs, &$params, $contactIds) {
b8df2a80 208 // get all the details needed to generate a invoice
be2fb01f 209 $messageInvoice = [];
6efffa5d 210 $invoiceTemplate = CRM_Core_Smarty::singleton();
6efffa5d 211 $invoiceElements = CRM_Contribute_Form_Task_PDF::getElements($contribIDs, $params, $contactIds);
dce4c3ea 212
3a1261ac 213 // gives the status id when contribution status is 'Refunded'
6efffa5d
PB
214 $contributionStatusID = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
215 $refundedStatusId = CRM_Utils_Array::key('Refunded', $contributionStatusID);
41e050b3 216 $cancelledStatusId = CRM_Utils_Array::key('Cancelled', $contributionStatusID);
2f3e0ab6 217 $pendingStatusId = CRM_Utils_Array::key('Pending', $contributionStatusID);
f2d5e719 218
2826a42e 219 foreach ($invoiceElements['details'] as $contribID => $detail) {
be2fb01f 220 $input = $ids = $objects = [];
3a1261ac 221 if (in_array($detail['contact'], $invoiceElements['excludeContactIds'])) {
b8df2a80
RK
222 continue;
223 }
dce4c3ea 224
b8df2a80 225 $input['component'] = $detail['component'];
dce4c3ea 226
b8df2a80 227 $ids['contact'] = $detail['contact'];
2826a42e 228 $ids['contribution'] = $contribID;
b8df2a80
RK
229 $ids['contributionRecur'] = NULL;
230 $ids['contributionPage'] = NULL;
9c1bc317
CW
231 $ids['membership'] = $detail['membership'] ?? NULL;
232 $ids['participant'] = $detail['participant'] ?? NULL;
233 $ids['event'] = $detail['event'] ?? NULL;
dce4c3ea 234
3a1261ac 235 if (!$invoiceElements['baseIPN']->validateData($input, $ids, $objects, FALSE)) {
7980012b 236 CRM_Core_Error::statusBounce('Supplied data was not able to be validated');
b8df2a80 237 }
dce4c3ea 238
353ffa53 239 $contribution = &$objects['contribution'];
dce4c3ea 240
b8df2a80
RK
241 $input['amount'] = $contribution->total_amount;
242 $input['invoice_id'] = $contribution->invoice_id;
243 $input['receive_date'] = $contribution->receive_date;
b8df2a80
RK
244 $input['contribution_status_id'] = $contribution->contribution_status_id;
245 $input['organization_name'] = $contribution->_relatedObjects['contact']->organization_name;
dce4c3ea 246
b8df2a80 247 $objects['contribution']->receive_date = CRM_Utils_Date::isoToMysql($objects['contribution']->receive_date);
dce4c3ea 248
66bc5236
ML
249 // Fetch the billing address. getValues should prioritize the billing
250 // address, otherwise will return the primary address.
be2fb01f 251 $billingAddress = [];
dce4c3ea 252
66bc5236
ML
253 $addressDetails = CRM_Core_BAO_Address::getValues([
254 'contact_id' => $contribution->contact_id,
255 'is_billing' => 1,
256 ]);
257
258 if (!empty($addressDetails)) {
259 $billingAddress = array_shift($addressDetails);
6efffa5d 260 }
dce4c3ea 261
41e050b3 262 if ($contribution->contribution_status_id == $refundedStatusId || $contribution->contribution_status_id == $cancelledStatusId) {
38c87aa2 263 $creditNoteId = $contribution->creditnote_id;
b8df2a80 264 }
b07b172b 265 if (!$contribution->invoice_number) {
266 $contribution->invoice_number = CRM_Contribute_BAO_Contribution::getInvoiceNumber($contribution->id);
12a8f9d7 267 }
dce4c3ea 268
b8df2a80
RK
269 //to obtain due date for PDF invoice
270 $contributionReceiveDate = date('F j,Y', strtotime(date($input['receive_date'])));
271 $invoiceDate = date("F j, Y");
e3eb0205
SL
272 $dueDateSetting = Civi::settings()->get('invoice_due_date');
273 $dueDatePeriodSetting = Civi::settings()->get('invoice_due_date_period');
274 $dueDate = date('F j, Y', strtotime($contributionReceiveDate . "+" . $dueDateSetting . "" . $dueDatePeriodSetting));
dce4c3ea 275
449b5e65 276 $amountPaid = CRM_Core_BAO_FinancialTrxn::getTotalPayments($contribID, TRUE);
8f4f19ca 277 $amountDue = ($input['amount'] - $amountPaid);
dce4c3ea 278
8f4f19ca 279 // retrieving the subtotal and sum of same tax_rate
be2fb01f 280 $dataArray = [];
b8df2a80 281 $subTotal = 0;
449b5e65 282 $lineItem = CRM_Price_BAO_LineItem::getLineItemsByContributionID($contribID);
fd9e1183 283 foreach ($lineItem as $taxRate) {
dce4c3ea 284 if (isset($dataArray[(string) $taxRate['tax_rate']])) {
285 $dataArray[(string) $taxRate['tax_rate']] = $dataArray[(string) $taxRate['tax_rate']] + CRM_Utils_Array::value('tax_amount', $taxRate);
b8df2a80
RK
286 }
287 else {
9c1bc317 288 $dataArray[(string) $taxRate['tax_rate']] = $taxRate['tax_amount'] ?? NULL;
b8df2a80
RK
289 }
290 $subTotal += CRM_Utils_Array::value('subTotal', $taxRate);
291 }
dce4c3ea 292
b8df2a80 293 // to email the invoice
be2fb01f
CW
294 $mailDetails = [];
295 $values = [];
b8df2a80
RK
296 if ($contribution->_component == 'event') {
297 $daoName = 'CRM_Event_DAO_Event';
298 $pageId = $contribution->_relatedObjects['event']->id;
be2fb01f 299 $mailElements = [
dce4c3ea 300 'title',
301 'confirm_from_name',
302 'confirm_from_email',
be2fb01f 303 ];
b8df2a80 304 CRM_Core_DAO::commonRetrieveAll($daoName, 'id', $pageId, $mailDetails, $mailElements);
9c1bc317
CW
305 $values['title'] = $mailDetails[$contribution->_relatedObjects['event']->id]['title'] ?? NULL;
306 $values['confirm_from_name'] = $mailDetails[$contribution->_relatedObjects['event']->id]['confirm_from_name'] ?? NULL;
307 $values['confirm_from_email'] = $mailDetails[$contribution->_relatedObjects['event']->id]['confirm_from_email'] ?? NULL;
dce4c3ea 308
9c1bc317 309 $title = $mailDetails[$contribution->_relatedObjects['event']->id]['title'] ?? NULL;
b8df2a80
RK
310 }
311 elseif ($contribution->_component == 'contribute') {
312 $daoName = 'CRM_Contribute_DAO_ContributionPage';
313 $pageId = $contribution->contribution_page_id;
be2fb01f 314 $mailElements = [
dce4c3ea 315 'title',
316 'receipt_from_name',
317 'receipt_from_email',
318 'cc_receipt',
319 'bcc_receipt',
be2fb01f 320 ];
b8df2a80 321 CRM_Core_DAO::commonRetrieveAll($daoName, 'id', $pageId, $mailDetails, $mailElements);
6efffa5d 322
dce4c3ea 323 $values['title'] = CRM_Utils_Array::value('title', CRM_Utils_Array::value($contribution->contribution_page_id, $mailDetails));
6efffa5d
PB
324 $values['receipt_from_name'] = CRM_Utils_Array::value('receipt_from_name', CRM_Utils_Array::value($contribution->contribution_page_id, $mailDetails));
325 $values['receipt_from_email'] = CRM_Utils_Array::value('receipt_from_email', CRM_Utils_Array::value($contribution->contribution_page_id, $mailDetails));
326 $values['cc_receipt'] = CRM_Utils_Array::value('cc_receipt', CRM_Utils_Array::value($contribution->contribution_page_id, $mailDetails));
327 $values['bcc_receipt'] = CRM_Utils_Array::value('bcc_receipt', CRM_Utils_Array::value($contribution->contribution_page_id, $mailDetails));
328
329 $title = CRM_Utils_Array::value('title', CRM_Utils_Array::value($contribution->contribution_page_id, $mailDetails));
b8df2a80 330 }
d88a0337 331 $source = $contribution->source;
dce4c3ea 332
b8df2a80 333 $config = CRM_Core_Config::singleton();
c4d3b8d3 334 if (!isset($params['forPage'])) {
d88a0337
PD
335 $config->doNotAttachPDFReceipt = 1;
336 }
337
338 // get organization address
339 $domain = CRM_Core_BAO_Domain::getDomain();
be2fb01f 340 $locParams = ['contact_id' => $domain->contact_id];
b69fc6b5 341 $locationDefaults = CRM_Core_BAO_Location::getValues($locParams);
d88a0337 342 if (isset($locationDefaults['address'][1]['state_province_id'])) {
dce4c3ea 343 $stateProvinceAbbreviationDomain = CRM_Core_PseudoConstant::stateProvinceAbbreviation($locationDefaults['address'][1]['state_province_id']);
d88a0337
PD
344 }
345 else {
346 $stateProvinceAbbreviationDomain = '';
347 }
348 if (isset($locationDefaults['address'][1]['country_id'])) {
dce4c3ea 349 $countryDomain = CRM_Core_PseudoConstant::country($locationDefaults['address'][1]['country_id']);
d88a0337
PD
350 }
351 else {
352 $countryDomain = '';
353 }
6efffa5d 354
e3eb0205
SL
355 $invoiceNotes = Civi::settings()->get('invoice_notes') ?? NULL;
356
b8df2a80 357 // parameters to be assign for template
be2fb01f 358 $tplParams = [
dce4c3ea 359 'title' => $title,
360 'component' => $input['component'],
361 'id' => $contribution->id,
362 'source' => $source,
b07b172b 363 'invoice_number' => $contribution->invoice_number,
9cad3ff4 364 'invoice_id' => $contribution->invoice_id,
9f8fe885 365 'resourceBase' => $config->userFrameworkResourceURL,
dce4c3ea 366 'defaultCurrency' => $config->defaultCurrency,
367 'amount' => $contribution->total_amount,
368 'amountDue' => $amountDue,
77680511 369 'amountPaid' => $amountPaid,
dce4c3ea 370 'invoice_date' => $invoiceDate,
371 'dueDate' => $dueDate,
e3eb0205 372 'notes' => $invoiceNotes,
dce4c3ea 373 'display_name' => $contribution->_relatedObjects['contact']->display_name,
374 'lineItem' => $lineItem,
375 'dataArray' => $dataArray,
376 'refundedStatusId' => $refundedStatusId,
2f3e0ab6 377 'pendingStatusId' => $pendingStatusId,
41e050b3 378 'cancelledStatusId' => $cancelledStatusId,
dce4c3ea 379 'contribution_status_id' => $contribution->contribution_status_id,
ef425b3b 380 'contributionStatusName' => CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $contribution->contribution_status_id),
dce4c3ea 381 'subTotal' => $subTotal,
6b409353
CW
382 'street_address' => $billingAddress['street_address'] ?? NULL,
383 'supplemental_address_1' => $billingAddress['supplemental_address_1'] ?? NULL,
384 'supplemental_address_2' => $billingAddress['supplemental_address_2'] ?? NULL,
385 'supplemental_address_3' => $billingAddress['supplemental_address_3'] ?? NULL,
386 'city' => $billingAddress['city'] ?? NULL,
387 'postal_code' => $billingAddress['postal_code'] ?? NULL,
388 'state_province' => $billingAddress['state_province'] ?? NULL,
389 'state_province_abbreviation' => $billingAddress['state_province_abbreviation'] ?? NULL,
66bc5236 390 // Kept for backwards compatibility
6b409353
CW
391 'stateProvinceAbbreviation' => $billingAddress['state_province_abbreviation'] ?? NULL,
392 'country' => $billingAddress['country'] ?? NULL,
dce4c3ea 393 'is_pay_later' => $contribution->is_pay_later,
394 'organization_name' => $contribution->_relatedObjects['contact']->organization_name,
395 'domain_organization' => $domain->name,
396 'domain_street_address' => CRM_Utils_Array::value('street_address', CRM_Utils_Array::value('1', $locationDefaults['address'])),
397 'domain_supplemental_address_1' => CRM_Utils_Array::value('supplemental_address_1', CRM_Utils_Array::value('1', $locationDefaults['address'])),
398 'domain_supplemental_address_2' => CRM_Utils_Array::value('supplemental_address_2', CRM_Utils_Array::value('1', $locationDefaults['address'])),
207f62c6 399 'domain_supplemental_address_3' => CRM_Utils_Array::value('supplemental_address_3', CRM_Utils_Array::value('1', $locationDefaults['address'])),
dce4c3ea 400 'domain_city' => CRM_Utils_Array::value('city', CRM_Utils_Array::value('1', $locationDefaults['address'])),
401 'domain_postal_code' => CRM_Utils_Array::value('postal_code', CRM_Utils_Array::value('1', $locationDefaults['address'])),
402 'domain_state' => $stateProvinceAbbreviationDomain,
403 'domain_country' => $countryDomain,
404 'domain_email' => CRM_Utils_Array::value('email', CRM_Utils_Array::value('1', $locationDefaults['email'])),
405 'domain_phone' => CRM_Utils_Array::value('phone', CRM_Utils_Array::value('1', $locationDefaults['phone'])),
be2fb01f 406 ];
dc0bdd34 407
c4d3b8d3
PD
408 if (isset($creditNoteId)) {
409 $tplParams['creditnote_id'] = $creditNoteId;
410 }
d75f2f47 411
b07b172b 412 $pdfFileName = $contribution->invoice_number . ".pdf";
be2fb01f 413 $sendTemplateParams = [
dce4c3ea 414 'groupName' => 'msg_tpl_workflow_contribution',
415 'valueName' => 'contribution_invoice_receipt',
416 'contactId' => $contribution->contact_id,
417 'tplParams' => $tplParams,
c119e8ae 418 'PDFFilename' => $pdfFileName,
be2fb01f 419 ];
6f39f13a 420
6efffa5d 421 // from email address
9c1bc317 422 $fromEmailAddress = $params['from_email_address'] ?? NULL;
c8025280 423 if (!empty($params['cc_id'])) {
9fa2c2ff
SP
424 // get contacts and their emails from email id
425 $emailIDs = $params['cc_id'] ? explode(',', $params['cc_id']) : [];
426 $emails = Email::get()
427 ->addWhere('id', 'IN', $emailIDs)
428 ->setCheckPermissions(FALSE)
429 ->setSelect(['contact_id', 'email', 'contact.sort_name', 'contact.display_name'])->execute();
430 $emailStrings = $contactUrlStrings = [];
431 foreach ($emails as $email) {
432 $emailStrings[] = '"' . $email['contact.sort_name'] . '" <' . $email['email'] . '>';
433 // generate the contact url to put in Activity
434 $contactURL = CRM_Utils_System::url('civicrm/contact/view', ['reset' => 1, 'force' => 1, 'cid' => $email['contact_id']], TRUE);
435 $contactUrlStrings[] = "<a href='{$contactURL}'>" . $email['contact.display_name'] . '</a>';
436 }
437 $cc_emails = implode(',', $emailStrings);
438 $values['cc_receipt'] = $cc_emails;
439 $ccContactsDetails = implode(',', $contactUrlStrings);
440 // add CC emails as activity details
441 $params['activity_details'] = "\ncc : " . $ccContactsDetails;
442
443 // unset bcc to avoid unknown email come from online page configuration.
444 unset($values['bcc_receipt']);
c8025280
SP
445 }
446
447 // get subject from UI
448 if (!empty($params['subject'])) {
449 $sendTemplateParams['subject'] = $values['subject'] = $params['subject'];
450 }
511c5767 451
b8df2a80 452 // condition to check for download PDF Invoice or email Invoice
3a1261ac 453 if ($invoiceElements['createPdf']) {
b8df2a80 454 list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
c4d3b8d3 455 if (isset($params['forPage'])) {
d88a0337
PD
456 return $html;
457 }
b8df2a80 458 else {
be2fb01f 459 $mail = [
d88a0337 460 'subject' => $subject,
dce4c3ea 461 'body' => $message,
d88a0337 462 'html' => $html,
be2fb01f 463 ];
d88a0337
PD
464 if ($mail['html']) {
465 $messageInvoice[] = $mail['html'];
dce4c3ea 466 }
d88a0337
PD
467 else {
468 $messageInvoice[] = nl2br($mail['body']);
469 }
b8df2a80
RK
470 }
471 }
472 elseif ($contribution->_component == 'contribute') {
473 $email = CRM_Contact_BAO_Contact::getPrimaryEmail($contribution->contact_id);
dce4c3ea 474
be2fb01f 475 $sendTemplateParams['tplParams'] = array_merge($tplParams, ['email_comment' => $invoiceElements['params']['email_comment']]);
6efffa5d 476 $sendTemplateParams['from'] = $fromEmailAddress;
b8df2a80 477 $sendTemplateParams['toEmail'] = $email;
9c1bc317
CW
478 $sendTemplateParams['cc'] = $values['cc_receipt'] ?? NULL;
479 $sendTemplateParams['bcc'] = $values['bcc_receipt'] ?? NULL;
dce4c3ea 480
481 list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
6efffa5d 482 // functions call for adding activity with attachment
9fa2c2ff
SP
483 // make sure page layout is same for email and download invoices.
484 $fileName = self::putFile($html, $pdfFileName, [
485 'margin_top' => 10,
486 'margin_left' => 65,
487 'metric' => 'px',
488 ]);
3e31220c 489 self::addActivities($subject, $contribution->contact_id, $fileName, $params, $contribution->id);
b8df2a80
RK
490 }
491 elseif ($contribution->_component == 'event') {
492 $email = CRM_Contact_BAO_Contact::getPrimaryEmail($contribution->contact_id);
dce4c3ea 493
be2fb01f 494 $sendTemplateParams['tplParams'] = array_merge($tplParams, ['email_comment' => $invoiceElements['params']['email_comment']]);
6efffa5d 495 $sendTemplateParams['from'] = $fromEmailAddress;
b8df2a80 496 $sendTemplateParams['toEmail'] = $email;
9c1bc317
CW
497 $sendTemplateParams['cc'] = $values['cc_confirm'] ?? NULL;
498 $sendTemplateParams['bcc'] = $values['bcc_confirm'] ?? NULL;
dce4c3ea 499
500 list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
6efffa5d 501 // functions call for adding activity with attachment
c119e8ae 502 $fileName = self::putFile($html, $pdfFileName);
3e31220c 503 self::addActivities($subject, $contribution->contact_id, $fileName, $params, $contribution->id);
b8df2a80 504 }
6efffa5d 505 $invoiceTemplate->clearTemplateVars();
b8df2a80 506 }
dce4c3ea 507
3a1261ac 508 if ($invoiceElements['createPdf']) {
c4d3b8d3 509 if (isset($params['forPage'])) {
d88a0337
PD
510 return $html;
511 }
512 else {
be2fb01f 513 CRM_Utils_PDF_Utils::html2pdf($messageInvoice, $pdfFileName, FALSE, [
dce4c3ea 514 'margin_top' => 10,
515 'margin_left' => 65,
21dfd5f5 516 'metric' => 'px',
be2fb01f 517 ]);
d88a0337 518 // functions call for adding activity with attachment
e67ef530
PN
519 $fileName = self::putFile($html, $pdfFileName, [
520 'margin_top' => 10,
521 'margin_left' => 65,
522 'metric' => 'px',
523 ]);
413796ce 524 self::addActivities($subject, $contactIds, $fileName, $params);
6efffa5d 525
d88a0337
PD
526 CRM_Utils_System::civiExit();
527 }
b8df2a80
RK
528 }
529 else {
3a1261ac 530 if ($invoiceElements['suppressedEmails']) {
be2fb01f 531 $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).', [1 => $invoiceElements['suppressedEmails']]);
b8df2a80
RK
532 $msgTitle = ts('Email Error');
533 $msgType = 'error';
534 }
535 else {
536 $status = ts('Your mail has been sent.');
537 $msgTitle = ts('Sent');
538 $msgType = 'success';
539 }
540 CRM_Core_Session::setStatus($status, $msgTitle, $msgType);
541 }
542 }
6efffa5d 543
dce4c3ea 544 /**
fe482240 545 * Add activity for Email Invoice and the PDF Invoice.
6efffa5d 546 *
014c4014
TO
547 * @param string $subject
548 * Activity subject.
549 * @param array $contactIds
550 * Contact Id.
551 * @param string $fileName
552 * Gives the location with name of the file.
553 * @param array $params
554 * For invoices.
3e31220c
PN
555 * @param int $contributionId
556 * Contribution Id.
6efffa5d
PB
557 *
558 */
3e31220c 559 public static function addActivities($subject, $contactIds, $fileName, $params, $contributionId = NULL) {
dce4c3ea 560 $session = CRM_Core_Session::singleton();
561 $userID = $session->get('userID');
6efffa5d
PB
562 $config = CRM_Core_Config::singleton();
563 $config->doNotAttachPDFReceipt = 1;
413796ce 564
565 if (!empty($params['output']) && $params['output'] == 'pdf_invoice') {
ac844df6 566 $activityType = 'Downloaded Invoice';
dce4c3ea 567 }
92e4c2a5 568 else {
ac844df6 569 $activityType = 'Emailed Invoice';
6efffa5d 570 }
413796ce 571
be2fb01f 572 $activityParams = [
6efffa5d
PB
573 'subject' => $subject,
574 'source_contact_id' => $userID,
575 'target_contact_id' => $contactIds,
ac844df6 576 'activity_type_id' => $activityType,
6efffa5d 577 'activity_date_time' => date('YmdHis'),
9fa2c2ff 578 'details' => $params['activity_details'] ?? NULL,
be2fb01f 579 'attachFile_1' => [
dce4c3ea 580 'uri' => $fileName,
581 'type' => 'application/pdf',
582 'location' => $fileName,
583 'upload_date' => date('YmdHis'),
be2fb01f
CW
584 ],
585 ];
3e31220c
PN
586 if ($contributionId) {
587 $activityParams['source_record_id'] = $contributionId;
588 }
589 civicrm_api3('Activity', 'create', $activityParams);
6efffa5d 590 }
dce4c3ea 591
592 /**
fe482240 593 * Create the Invoice file in upload folder for attachment.
dce4c3ea 594 *
76e7a76c 595 * @param string $html
014c4014 596 * Content for pdf in html format.
6efffa5d 597 *
ad37ac8e 598 * @param string $name
e67ef530 599 * @param array $format
ad37ac8e 600 *
03110609 601 * @return string
76e7a76c 602 * Name of file which is in pdf format
6efffa5d 603 */
e67ef530
PN
604 public static function putFile($html, $name = 'Invoice.pdf', $format = NULL) {
605 return CRM_Utils_Mail::appendPDF($name, $html, $format)['fullPath'] ?? '';
6efffa5d 606 }
b5c3483d 607
608 /**
609 * Callback to perform action on Print Invoice button.
610 */
00be9182 611 public static function getPrintPDF() {
b5c3483d 612 $contributionId = CRM_Utils_Request::retrieve('id', 'Positive', CRM_Core_DAO::$_nullObject, FALSE);
be2fb01f 613 $contributionIDs = [$contributionId];
b5c3483d 614 $contactId = CRM_Utils_Request::retrieve('cid', 'Positive', CRM_Core_DAO::$_nullObject, FALSE);
be2fb01f 615 $params = ['output' => 'pdf_invoice'];
1273d77c 616 CRM_Contribute_Form_Task_Invoice::printPDF($contributionIDs, $params, $contactId);
b5c3483d 617 }
96025800 618
b8df2a80 619}