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