Skip to content

Commit

Permalink
Merge pull request #976 from compucorp/BTHAB-182-quote-attach
Browse files Browse the repository at this point in the history
BTHAB-182: Attach quotation invoice to contribution mail
  • Loading branch information
erawat authored Sep 21, 2023
2 parents 27073c4 + 1cb9a44 commit 13b7c16
Show file tree
Hide file tree
Showing 6 changed files with 303 additions and 109 deletions.
112 changes: 3 additions & 109 deletions CRM/Civicase/Form/CaseSalesOrderInvoice.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
<?php

use Civi\Api4\Address;
use Civi\Api4\CaseSalesOrder;
use Civi\Api4\CaseSalesOrderLine;
use Civi\Api4\Contact;
use Civi\Api4\Setting;
use Civi\Token\TokenProcessor;

/**
Expand Down Expand Up @@ -159,101 +155,10 @@ protected function getContactIds(): array {
*/
public static function getQuotationInvoice(): array {
$salesOrderId = CRM_Utils_Request::retrieveValue('id', 'Positive');
$caseSalesOrder = CaseSalesOrder::get()
->addWhere('id', '=', $salesOrderId)
->addChain('items', CaseSalesOrderLine::get()
->addWhere('sales_order_id', '=', '$id')
->addSelect('*', 'product_id.name', 'financial_type_id.name')
)
->addChain('computedRates', CaseSalesOrder::computeTotal()
->setLineItems('$items')
)
->addChain('client', Contact::get()
->addWhere('id', '=', '$client_id'), 0
)
->execute()
->first();

if (!empty($caseSalesOrder['client_id'])) {
$caseSalesOrder['clientAddress'] = Address::get()
->addSelect('*', 'country_id:label', 'state_province_id:label')
->addWhere('contact_id', '=', $caseSalesOrder['client_id'])
->execute()
->first();
$caseSalesOrder['clientAddress']['country'] = $caseSalesOrder['clientAddress']['country_id:label'];
$caseSalesOrder['clientAddress']['state'] = $caseSalesOrder['clientAddress']['state_province_id:label'];
}

$caseSalesOrder['taxRates'] = $caseSalesOrder['computedRates'][0]['taxRates'] ?? [];
$caseSalesOrder['quotation_date'] = date('Y-m-d', strtotime($caseSalesOrder['quotation_date']));

$domain = CRM_Core_BAO_Domain::getDomain();
$organisation = Contact::get()
->addSelect('image_URL')
->addWhere('id', '=', $domain->contact_id)
->execute()
->first();

$model = new CRM_Civicase_WorkflowMessage_SalesOrderInvoice();
$terms = self::getTerms();
$model->setDomainLogo($organisation['image_URL']);
$model->setSalesOrder($caseSalesOrder);
$model->setTerms($terms);
$model->setSalesOrderId($salesOrderId);
$model->setDomainLocation(self::getDomainLocation());
$model->setDomainName($domain->name ?? '');
$rendered = $model->renderTemplate();

$rendered['format'] = $rendered['format'] ?? self::defaultInvoiceFormat();

return $rendered;
}

/**
* Returns the Quotation invoice terms.
*/
private static function getTerms() {
$terms = NULL;
$invoicing = Setting::get()
->addSelect('invoicing')
->execute()
->first();

if (!empty($invoicing['value'])) {
$terms = Civi::settings()->get('quotations_notes');
}

return $terms;
}

/**
* Gets domain location.
*
* @return array
* An array of address lines.
*/
private static function getDomainLocation() {
$domain = CRM_Core_BAO_Domain::getDomain();
$locParams = ['contact_id' => $domain->contact_id];
$locationDefaults = CRM_Core_BAO_Location::getValues($locParams);
if (empty($locationDefaults['address'][1])) {
return [];
}
$stateProvinceId = $locationDefaults['address'][1]['state_province_id'] ?? NULL;
$stateProvinceAbbreviationDomain = !empty($stateProvinceId) ? CRM_Core_PseudoConstant::stateProvinceAbbreviation($stateProvinceId) : '';
$countryId = $locationDefaults['address'][1]['country_id'];
$countryDomain = !empty($countryId) ? CRM_Core_PseudoConstant::country($countryId) : '';

return [
'street_address' => CRM_Utils_Array::value('street_address', CRM_Utils_Array::value('1', $locationDefaults['address'])),
'supplemental_address_1' => CRM_Utils_Array::value('supplemental_address_1', CRM_Utils_Array::value('1', $locationDefaults['address'])),
'supplemental_address_2' => CRM_Utils_Array::value('supplemental_address_2', CRM_Utils_Array::value('1', $locationDefaults['address'])),
'supplemental_address_3' => CRM_Utils_Array::value('supplemental_address_3', CRM_Utils_Array::value('1', $locationDefaults['address'])),
'city' => CRM_Utils_Array::value('city', CRM_Utils_Array::value('1', $locationDefaults['address'])),
'postal_code' => CRM_Utils_Array::value('postal_code', CRM_Utils_Array::value('1', $locationDefaults['address'])),
'state' => $stateProvinceAbbreviationDomain,
'country' => $countryDomain,
];
/** @var \CRM_Civicase_Service_CaseSalesOrderInvoice */
$invoiceService = new \CRM_Civicase_Service_CaseSalesOrderInvoice(new \CRM_Civicase_WorkflowMessage_SalesOrderInvoice());
return $invoiceService->render($salesOrderId);
}

/**
Expand All @@ -273,17 +178,6 @@ protected function getRows(): array {
return $rows;
}

/**
* Returns the default format to use for Invoice.
*/
private static function defaultInvoiceFormat() {
return [
'margin_top' => 10,
'margin_left' => 65,
'metric' => 'px',
];
}

/**
* Renders and return the generated PDF to the browser.
*/
Expand Down
63 changes: 63 additions & 0 deletions CRM/Civicase/Hook/BuildForm/AttachQuotationToInvoiceMail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

use Civi\Api4\CaseSalesOrder;
use Civi\Api4\Contribution;

/**
* Gives user the option to attach quotation to invoice mail.
*/
class CRM_Civicase_Hook_BuildForm_AttachQuotationToInvoiceMail {

/**
* Adds the Attach Quote checkbox to invoice mail form.
*
* @param CRM_Core_Form $form
* Form Class object.
* @param string $formName
* Form Name.
*/
public function run(CRM_Core_Form &$form, $formName) {
if (!$this->shouldRun($formName)) {
return;
}

$form->add('checkbox', 'attach_quote', ts('Attach Quotation'));

CRM_Core_Region::instance('page-body')->add([
'template' => "CRM/Civicase/Form/Contribute/AttachQuotation.tpl",
]);
}

/**
* Determines if the hook will run.
*
* @param string $formName
* Form Name.
*
* @return bool
* TRUE if the hook should run, FALSE otherwise.
*/
private function shouldRun($formName) {
if ($formName != 'CRM_Contribute_Form_Task_Invoice') {
return FALSE;
}

$contributionId = CRM_Utils_Request::retrieve('id', 'Positive');
if (!$contributionId) {
return FALSE;
}

$salesOrder = Contribution::get()
->addSelect('Opportunity_Details.Quotation')
->addWhere('Opportunity_Details.Quotation', 'IS NOT EMPTY')
->addWhere('id', '=', $contributionId)
->addChain('salesOrder', CaseSalesOrder::get()
->addWhere('id', '=', '$Opportunity_Details.Quotation')
)
->execute()
->first()['salesOrder'];

return !empty($salesOrder);
}

}
79 changes: 79 additions & 0 deletions CRM/Civicase/Hook/alterMailParams/AttachQuotation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

use Civi\Api4\CaseSalesOrder;
use Civi\Api4\Contribution;

/**
* Adds Quotation invoice as an attachement.
*/
class CRM_Civicase_Hook_alterMailParams_AttachQuotation {

/**
* Attaches quotation to single invoice.
*
* @param array $params
* Mail parameters.
* @param string $context
* Mail context.
*/
public function run(array &$params, $context) {
$shouldAttachQuote = CRM_Utils_Request::retrieve('attach_quote', 'String');

if (!$this->shouldRun($params, $context, $shouldAttachQuote)) {
return;
}

$rendered = $this->getContributionQuotationInvoice($params['tokenContext']['contributionId']);

$params['attachments'][] = CRM_Utils_Mail::appendPDF('quotation_invoice.pdf', $rendered['html'], $rendered['format']);
}

/**
* Renders the Invoice for the quotation linked to the contribution.
*
* @param int $contributionId
* The contribution ID.
*/
private function getContributionQuotationInvoice($contributionId) {
$salesOrder = Contribution::get()
->addSelect('Opportunity_Details.Quotation')
->addWhere('Opportunity_Details.Quotation', 'IS NOT EMPTY')
->addWhere('id', '=', $contributionId)
->addChain('salesOrder', CaseSalesOrder::get()
->addWhere('id', '=', '$Opportunity_Details.Quotation')
)
->execute()
->first()['salesOrder'];

if (empty($salesOrder)) {
return;
}

/** @var \CRM_Civicase_Service_CaseSalesOrderInvoice */
$invoiceService = new \CRM_Civicase_Service_CaseSalesOrderInvoice(new CRM_Civicase_WorkflowMessage_SalesOrderInvoice());
return $invoiceService->render($salesOrder[0]['id']);
}

/**
* Determines if the hook will run.
*
* @param array $params
* Mail parameters.
* @param string $context
* Mail context.
* @param string $shouldAttachQuote
* If the Attach Quote is set.
*
* @return bool
* returns TRUE if hook should run, FALSE otherwise.
*/
private function shouldRun(array $params, $context, $shouldAttachQuote) {
$component = $params['tplParams']['component'] ?? '';
if ($component !== 'contribute' || $context !== 'messageTemplate' || empty($shouldAttachQuote)) {
return FALSE;
}

return TRUE;
}

}
Loading

0 comments on commit 13b7c16

Please sign in to comment.