From b8df2a8051da700883575bb47ff07ed32889e957 Mon Sep 17 00:00:00 2001 From: Rohan Katkar Date: Tue, 27 May 2014 14:24:42 +0530 Subject: [PATCH] VAT-388 Added new files for generation of invoice. --- CRM/Contribute/Form/Task/Invoice.php | 414 ++++++++++++++++++ .../CRM/Contribute/Form/Task/Invoice.tpl | 74 ++++ .../contribution_invoice_receipt_html.tpl | 240 ++++++++++ .../contribution_invoice_receipt_subject.tpl | 2 + .../contribution_invoice_receipt_text.tpl | 1 + 5 files changed, 731 insertions(+) create mode 100644 CRM/Contribute/Form/Task/Invoice.php create mode 100644 templates/CRM/Contribute/Form/Task/Invoice.tpl create mode 100644 xml/templates/message_templates/contribution_invoice_receipt_html.tpl create mode 100644 xml/templates/message_templates/contribution_invoice_receipt_subject.tpl create mode 100644 xml/templates/message_templates/contribution_invoice_receipt_text.tpl diff --git a/CRM/Contribute/Form/Task/Invoice.php b/CRM/Contribute/Form/Task/Invoice.php new file mode 100644 index 0000000000..4060ab1559 --- /dev/null +++ b/CRM/Contribute/Form/Task/Invoice.php @@ -0,0 +1,414 @@ +_contributionIds = array($id); + $this->_componentClause = " civicrm_contribution.id IN ( $id ) "; + $this->_single = TRUE; + $this->assign('totalSelectedContributions', 1); + } + else { + parent::preProcess(); + } + + // check that all the contribution ids have pending status + $query = " +SELECT count(*) +FROM civicrm_contribution +WHERE contribution_status_id != 1 +AND contribution_status_id != 7 +AND contribution_status_id != 2 +AND {$this->_componentClause}"; + $count = CRM_Core_DAO::singleValueQuery($query); + if ($count != 0) { + CRM_Core_Error::statusBounce("Please select only online contributions with Completed status."); + } + + // we have all the contribution ids, so now we get the contact ids + parent::setContactIDs(); + $this->assign('single', $this->_single); + + $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $this); + $urlParams = 'force=1'; + if (CRM_Utils_Rule::qfKey($qfKey)) { + $urlParams .= "&qfKey=$qfKey"; + } + + $url = CRM_Utils_System::url('civicrm/contribute/search', $urlParams); + $breadCrumb = array( + array('url' => $url, + 'title' => ts('Search Results'), + )); + + CRM_Utils_System::appendBreadCrumb($breadCrumb); + CRM_Utils_System::setTitle(ts('Print Contribution Invoice')); + } + + /** + * Build the form + * + * @access public + * + * @return void + */ + public function buildQuickForm() { + $this->addElement('radio', 'output', NULL, ts('Email Invoice'), 'email_invoice', + array('onClick' => "document.getElementById('selectPdfFormat').style.display = 'none';document.getElementById ('comment').style.display = 'block';") + ); + $this->addElement('radio', 'output', NULL, ts('PDF Invoice'), 'pdf_invoice', + array('onClick' => "document.getElementById('comment').style.display = 'none';document.getElementById('selectPdfFormat').style.display = 'block';") + ); + $this->addRule('output', ts('Selection required'), 'required'); + $this->add('textarea', 'email_comment', ts('If you would like to add personal message to email please add it here. (The same messages will sent to all receipients.)')); + $this->addButtons(array( + array( + 'type' => 'next', + 'name' => ts('Process Invoice(s)'), + 'isDefault' => TRUE, + ), + array( + 'type' => 'back', + 'name' => ts('Cancel'), + ), + ) + ); + } + + /** + * process the form after the input has been submitted and validated + * + * @access public + * + * @return void + */ + public function postProcess() { + // get all the details needed to generate a invoice + $contribIDs = implode(',', $this->_contributionIds); + + $details = CRM_Contribute_Form_Task_Status::getDetails($contribIDs); + + $baseIPN = new CRM_Core_Payment_BaseIPN(); + + $messageInvoice = array(); + + $template = CRM_Core_Smarty::singleton(); + + $params = $this->controller->exportValues($this->_name); + + $createPdf = FALSE; + if ($params['output'] == "pdf_invoice") { + $createPdf = TRUE; + } + + $excludeContactIds = array(); + if (!$createPdf) { + $returnProperties = array( + 'email' => 1, + 'do_not_email' => 1, + 'is_deceased' => 1, + 'on_hold' => 1, + ); + + list($contactDetails) = CRM_Utils_Token::getTokenDetails($this->_contactIds, $returnProperties, FALSE, FALSE); + $suppressedEmails = 0; + foreach ($contactDetails as $id => $values) { + if (empty($values['email']) || !empty($values['do_not_email']) || + CRM_Utils_Array::value('is_deceased', $values) || !empty($values['on_hold'])) { + $suppressedEmails++; + $excludeContactIds[] = $values['contact_id']; + } + } + } + + foreach ($details as $contribID => $detail) { + $input = $ids = $objects = array(); + + if (in_array($detail['contact'], $excludeContactIds)) { + continue; + } + + $input['component'] = $detail['component']; + + $ids['contact'] = $detail['contact']; + $ids['contribution'] = $contribID; + $ids['contributionRecur'] = NULL; + $ids['contributionPage'] = NULL; + $ids['membership'] = CRM_Utils_Array::value('membership', $detail); + $ids['participant'] = CRM_Utils_Array::value('participant', $detail); + $ids['event'] = CRM_Utils_Array::value('event', $detail); + + if (!$baseIPN->validateData($input, $ids, $objects, FALSE)) { + CRM_Core_Error::fatal(); + } + + $contribution = &$objects['contribution']; + + $input['amount'] = $contribution->total_amount; + $input['invoice_id'] = $contribution->invoice_id; + $input['receive_date'] = $contribution->receive_date; + $input['source'] = $contribution->source; + $input['contribution_status_id'] = $contribution->contribution_status_id; + $input['organization_name'] = $contribution->_relatedObjects['contact']->organization_name; + $input['trxn_date'] = isset($contribution->trxn_date) ? $contribution->trxn_date : NULL; + + $objects['contribution']->receive_date = CRM_Utils_Date::isoToMysql($objects['contribution']->receive_date); + + $contributionStatusId = key(CRM_Core_PseudoConstant::accountOptionValues('contribution_status', NULL, " AND v.name LIKE 'Refunded' ")); + + $addressParams = array('contact_id' => $contribution->contact_id); + $addressDetails = CRM_Core_BAO_Address::getValues($addressParams); + + // to get billing address if present + $billingAddress = array(); + foreach ($addressDetails as $key => $address) { + if ((isset($address['is_billing']) && $address['is_billing'] == 1) && (isset($address['is_primary']) && $address['is_primary'] == 1) && $address['contact_id'] == $contribution->contact_id) { + $billingAddress[$address['contact_id']] = $address; + break; + } + elseif (($address['is_billing'] == 0 && $address['is_primary'] == 1) || (isset($address['is_billing']) && $address['is_billing'] == 1) && $address['contact_id'] == $contribution->contact_id) { + $billingAddress[$address['contact_id']] = $address; + } + } + + $stateProvinceAbbreviation = CRM_Core_PseudoConstant::stateProvinceAbbreviation($billingAddress[$contribution->contact_id]['state_province_id']); + + // getting data from admin page + $prefixValue = CRM_Contribute_BAO_Contribution::getContributionSettings(); + + if ($contribution->contribution_status_id == $contributionStatusId) { + $invoiceId = CRM_Utils_Array::value('credit_notes_prefix', $prefixValue)."".$contribution->id; + } + else { + $invoiceId = CRM_Utils_Array::value('invoice_prefix', $prefixValue)."".$contribution->id; + } + + //to obtain due date for PDF invoice + $contributionReceiveDate = date('F j,Y', strtotime(date($input['receive_date']))); + $invoiceDate = date("F j, Y"); + $dueDate = date('F j ,Y', strtotime($contributionReceiveDate."+".$prefixValue['due_date']."". $prefixValue['due_date_period'])); + + if ($input['component'] == 'contribute') { + $eid = $contribID; + $etable = 'contribution'; + } + else { + $eid = $contribution->_relatedObjects['participant']->id; + $etable = 'participant'; + } + + //TO DO: Need to do changes for partially paid to display amount due on PDF invoice + $amountDue = ($input['amount'] - $input['amount']); + + // retreiving the subtotal and sum of same tax_rate + $lineItem = CRM_Price_BAO_LineItem::getLineItems($eid, $etable); + $dataArray = array(); + $subTotal = 0; + foreach ($lineItem as $entity_id => $taxRate) { + if (isset($dataArray[$taxRate['tax_rate']])) { + $dataArray[$taxRate['tax_rate']] = $dataArray[$taxRate['tax_rate']] + CRM_Utils_Array::value('tax_amount', $taxRate); + } + else { + $dataArray[$taxRate['tax_rate']] = CRM_Utils_Array::value('tax_amount', $taxRate); + } + $subTotal += CRM_Utils_Array::value('subTotal', $taxRate); + } + + // to email the invoice + $mailDetails = array(); + $values = array(); + if ($contribution->_component == 'event') { + $daoName = 'CRM_Event_DAO_Event'; + $pageId = $contribution->_relatedObjects['event']->id; + $mailElements = array( + 'title', + 'confirm_from_name', + 'confirm_from_email', + 'cc_confirm', + 'bcc_confirm', + ); + CRM_Core_DAO::commonRetrieveAll($daoName, 'id', $pageId, $mailDetails, $mailElements); + + $values['title'] = CRM_Utils_Array::value('title', $mailDetails[$contribution->_relatedObjects['event']->id]); + $values['confirm_from_name'] = CRM_Utils_Array::value('confirm_from_name', $mailDetails[$contribution->_relatedObjects['event']->id]); + $values['confirm_from_email'] = CRM_Utils_Array::value('confirm_from_email', $mailDetails[$contribution->_relatedObjects['event']->id]); + $values['cc_confirm'] = CRM_Utils_Array::value('cc_confirm', $mailDetails[$contribution->_relatedObjects['event']->id]); + $values['bcc_confirm'] = CRM_Utils_Array::value('bcc_confirm', $mailDetails[$contribution->_relatedObjects['event']->id]); + + $title = CRM_Utils_Array::value('title', $mailDetails[$contribution->_relatedObjects['event']->id]); + } + elseif ($contribution->_component == 'contribute') { + $daoName = 'CRM_Contribute_DAO_ContributionPage'; + $pageId = $contribution->contribution_page_id; + $mailElements = array( + 'title', + 'receipt_from_name', + 'receipt_from_email', + 'cc_receipt', + 'bcc_receipt', + ); + CRM_Core_DAO::commonRetrieveAll($daoName, 'id', $pageId, $mailDetails, $mailElements); + + $values['title'] = CRM_Utils_Array::value('title',$mailDetails[$contribution->contribution_page_id]); + $values['receipt_from_name'] = CRM_Utils_Array::value('receipt_from_name', $mailDetails[$contribution->contribution_page_id]); + $values['receipt_from_email'] = CRM_Utils_Array::value('receipt_from_email', $mailDetails[$contribution->contribution_page_id]); + $values['cc_receipt'] = CRM_Utils_Array::value('cc_receipt', $mailDetails[$contribution->contribution_page_id]); + $values['bcc_receipt'] = CRM_Utils_Array::value('bcc_receipt', $mailDetails[$contribution->contribution_page_id]); + + $title = CRM_Utils_Array::value('title', $mailDetails[$contribution->contribution_page_id]); + } + + $config = CRM_Core_Config::singleton(); + + // parameters to be assign for template + $tplParams = array( + 'title' => $title, + 'component' => $input['component'], + 'id' => $contribution->id, + 'invoice_id' => $invoiceId, + 'defaultCurrency' => $config->defaultCurrency, + 'amount' => $contribution->total_amount, + 'amountDue' => $amountDue, + 'invoice_date' => $invoiceDate, + 'dueDate' => $dueDate, + 'notes' => CRM_Utils_Array::value('notes', $prefixValue), + 'display_name' => $contribution->_relatedObjects['contact']->display_name, + 'lineItem' => $lineItem, + 'dataArray' => $dataArray, + 'contributionStatusId' => $contributionStatusId, + 'contribution_status_id' => $contribution->contribution_status_id, + 'subTotal' => $subTotal, + 'street_address' => CRM_Utils_Array::value('street_address', $billingAddress[$contribution->contact_id]), + 'supplemental_address_1' => CRM_Utils_Array::value('supplemental_address_1', $billingAddress[$contribution->contact_id]), + 'supplemental_address_2' => CRM_Utils_Array::value('supplemental_address_2', $billingAddress[$contribution->contact_id]), + 'city' => CRM_Utils_Array::value('city', $billingAddress[$contribution->contact_id]), + 'stateProvinceAbbreviation' => $stateProvinceAbbreviation, + 'postal_code' => CRM_Utils_Array::value('postal_code', $billingAddress[$contribution->contact_id]), + 'is_pay_later' => $contribution->is_pay_later, + 'organization_name' => $contribution->_relatedObjects['contact']->organization_name, + ); + + $config->doNotAttachPDFReceipt = 1; + $sendTemplateParams = array( + 'groupName' => 'msg_tpl_workflow_contribution', + 'valueName' => 'contribution_invoice_receipt', + 'contactId' => $contribution->contact_id, + 'tplParams' => $tplParams, + 'PDFFilename' => 'Invoice.pdf', + ); + + + // condition to check for download PDF Invoice or email Invoice + if ($createPdf) { + list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams); + $mail = array( + 'subject' => $subject, + 'body' => $message, + 'html' => $html, + ); + + if ($mail['html']) { + $messageInvoice[] = $mail['html']; + } + else { + $messageInvoice[] = nl2br($mail['body']); + } + } + elseif ($contribution->_component == 'contribute') { + $email = CRM_Contact_BAO_Contact::getPrimaryEmail($contribution->contact_id); + + $sendTemplateParams['tplParams'] =array_merge($tplParams,array('email_comment'=>$params['email_comment'])); + $sendTemplateParams['from'] = CRM_Utils_Array::value('receipt_from_name', $values) . ' <' . $mailDetails[$contribution->contribution_page_id]['receipt_from_email']. '>'; + $sendTemplateParams['toEmail'] = $email; + $sendTemplateParams['cc'] = CRM_Utils_Array::value('cc_receipt', $values); + $sendTemplateParams['bcc'] = CRM_Utils_Array::value('bcc_receipt', $values); + + list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams); + } + elseif ($contribution->_component == 'event') { + $email = CRM_Contact_BAO_Contact::getPrimaryEmail($contribution->contact_id); + + $sendTemplateParams['tplParams'] =array_merge($tplParams,array('email_comment'=>$params['email_comment'])); + $sendTemplateParams['from'] = CRM_Utils_Array::value('confirm_from_name', $values) . ' <' . $mailDetails[$contribution->_relatedObjects['event']->id]['confirm_from_email']. '>'; + $sendTemplateParams['toEmail'] = $email; + $sendTemplateParams['cc'] = CRM_Utils_Array::value('cc_confirm', $values); + $sendTemplateParams['bcc'] = CRM_Utils_Array::value('bcc_confirm', $values); + + list($sent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams); + } + + $updateInvoiceId = CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $contribution->id, 'invoice_id', $invoiceId); + $template->clearTemplateVars(); + } + + if ($createPdf) { + CRM_Utils_PDF_Utils::html2pdf($messageInvoice, 'Invoice.pdf', FALSE); + CRM_Utils_System::civiExit(); + } + else { + if ($suppressedEmails) { + $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 => $suppressedEmails)); + $msgTitle = ts('Email Error'); + $msgType = 'error'; + } + else { + $status = ts('Your mail has been sent.'); + $msgTitle = ts('Sent'); + $msgType = 'success'; + } + CRM_Core_Session::setStatus($status, $msgTitle, $msgType); + } + } +} + diff --git a/templates/CRM/Contribute/Form/Task/Invoice.tpl b/templates/CRM/Contribute/Form/Task/Invoice.tpl new file mode 100644 index 0000000000..b0e4039cc6 --- /dev/null +++ b/templates/CRM/Contribute/Form/Task/Invoice.tpl @@ -0,0 +1,74 @@ +{* + +--------------------------------------------------------------------+ + | CiviCRM version 4.5 | + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC (c) 2004-2014 | + +--------------------------------------------------------------------+ + | This file is a part of CiviCRM. | + | | + | CiviCRM is free software; you can copy, modify, and distribute it | + | under the terms of the GNU Affero General Public License | + | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | + | | + | CiviCRM is distributed in the hope that it will be useful, but | + | WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | + | See the GNU Affero General Public License for more details. | + | | + | You should have received a copy of the GNU Affero General Public | + | License and the CiviCRM Licensing Exception along | + | with this program; if not, contact CiviCRM LLC | + | at info[AT]civicrm[DOT]org. If you have questions about the | + | GNU Affero General Public License or the licensing of CiviCRM, | + | see the CiviCRM license FAQ at http://civicrm.org/licensing | + +--------------------------------------------------------------------+ +*} +
+
+ {include file="CRM/Contribute/Form/Task.tpl"} +
+
+ {ts}You may choose to email invoice to contributors OR download a PDF file containing one invoice per page to your local computer by clicking Process Invoice(s). Your browser may display the file for you automatically, or you may need to open it for printing using any PDF reader (such as Adobe® Reader).{/ts} +
+ + + {if $smarty.get.select == 'email'} + {literal} + + {/literal} + {/if} + + {if $smarty.get.select == 'pdf'} + {literal} + + {/literal} + {/if} + + + + + + + + + + + + +
{$form.output.email_invoice.html}
{$form.output.pdf_invoice.html}
+ +
+
+ {$form.buttons.html} +
diff --git a/xml/templates/message_templates/contribution_invoice_receipt_html.tpl b/xml/templates/message_templates/contribution_invoice_receipt_html.tpl new file mode 100644 index 0000000000..e9c6ed5c3b --- /dev/null +++ b/xml/templates/message_templates/contribution_invoice_receipt_html.tpl @@ -0,0 +1,240 @@ + + + + + + + + + + + +
+
+

+ + + {if $contribution_status_id == $contributionStatusId} + + {else} + + {/if} + + {if $contribution_status_id == $contributionStatusId} + + {else} + + {/if} + + + + {if $organization_name} + + {else} + + {/if} + + + + + + + {if $contribution_status_id == $contributionStatusId} + + {else} + + {/if} + + + + + + + + + + + +
CREDIT NOTETAX INVOICEDate:Invoice Date:{$organization_name}
{$display_name} ({$organization_name}){$display_name}{$invoice_date}
{$street_address} {$supplemental_address_1}Credit Note Number:Incoice Number:
{$supplemental_address_2} {$stateProvinceAbbreviation}{$invoice_id}
{$city} {$postal_code}Reference: {$title}
+ + + + + +
+ {* FIXME: style this table so that it looks like the text version (justification, etc.) *} + + + + + + + + {foreach from=$lineItem item=value key=priceset} + + + + + + {if $value.tax_rate} + + {elseif $value.tax_amount != ''} + + {else} + + {/if} + + + {/foreach} + + + + + + + {foreach from = $dataArray item = value key = priceset} + + + {if $priceset} + + + {elseif $priceset == 0} + + + + {/if} + {/foreach} + + + + + + + + + + + + {if $is_pay_later == 0} + + + {if $contribution_status_id == $contributionStatusId} + + {else} + + {/if} + + + + + + + + + {if $contribution_status_id == $contributionStatusId} + + + {else} + + + {/if} + + + {/if} +


+ + + + + {if $contribution_status_id == $contributionStatusId} + + {else} + + {/if} + + +
Description
Quantity
Unit Price
VAT
Amount {$defaultCurrency}

+ {if $value.html_type eq 'Text'}{$value.label}{else}{$value.field_title} - {$value.label}{/if} {if $value.description}
{$value.description|truncate:30:"..."}
{/if} +
{$value.qty} {$value.unit_price|crmMoney:$currency}
{$value.tax_rate}%
VAT (exempt)
No VAT
{$value.subTotal|crmMoney:$currency}

Sub Total {$subTotal|crmMoney:$currency}
TOTAL VAT {$priceset}%{$value|crmMoney:$currency} TOTAL NO VAT{$value|crmMoney:$currency}

TOTAL {$defaultCurrency}{$amount|crmMoney:$currency}
LESS Credit to invoice(s)LESS Amount Paid{$amount|crmMoney:$currency}

REMAINING CREDIT{$amountDue|crmMoney:$currency}AMOUNT DUE: {$amountDue|crmMoney:$currency}
DUE DATE: {$dueDate}
+
+ + + + + +
+ + {if $contribution_status_id == $contributionStatusId} + + + + + +
CREDIT ADVICE

{$notes}
+ + + + + + + + + + + + + + + + + +
Customer: {$display_name}
Credit Note#: {$invoice_id}

Credit Amount:{$amount|crmMoney:$currency}
+
+ {else} + + + + + +
PAYMENT ADVICE

To: + {$organization_name}

{$notes} +
+ + + + + + + + + + + + + {if $is_pay_later == 1} + + + + + + {else} + + + + + + {/if} + + + + + + + + +
Customer: {$display_name}
Invoice Number: {$invoice_id}

Amount Due:{$amount|crmMoney:$currency}
Amount Due: {$amountDue|crmMoney:$currency}
Due Date: {$dueDate}

+
+ {/if} +
+ + diff --git a/xml/templates/message_templates/contribution_invoice_receipt_subject.tpl b/xml/templates/message_templates/contribution_invoice_receipt_subject.tpl new file mode 100644 index 0000000000..0035d669ed --- /dev/null +++ b/xml/templates/message_templates/contribution_invoice_receipt_subject.tpl @@ -0,0 +1,2 @@ +{if $title}{if $component}{if $component == 'event'} {ts}Event Registration Invoice:- {$title}{/ts}{else}{ts}Contribution Invoice : + {$title}{/ts}{/if}{/if} {else} {ts}Invoice {/ts} {/if} diff --git a/xml/templates/message_templates/contribution_invoice_receipt_text.tpl b/xml/templates/message_templates/contribution_invoice_receipt_text.tpl new file mode 100644 index 0000000000..37e2edf09d --- /dev/null +++ b/xml/templates/message_templates/contribution_invoice_receipt_text.tpl @@ -0,0 +1 @@ +{ts}Contribution Invoice{/ts} -- 2.25.1