Skip to content

Commit

Permalink
Merge pull request #20779 from eileenmcnaughton/batch2
Browse files Browse the repository at this point in the history
 Clean up code to determine line items for membership batch entry
  • Loading branch information
colemanw authored Jul 6, 2021
2 parents 9718821 + 7727463 commit 6d2cfff
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 77 deletions.
60 changes: 12 additions & 48 deletions CRM/Batch/Form/Entry.php
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,7 @@ private function processContribution(&$params) {
*
* @throws \CRM_Core_Exception
* @throws \CiviCRM_API3_Exception
* @throws \API_Exception
*/
private function processMembership(array $params) {
$batchTotal = 0;
Expand All @@ -737,7 +738,6 @@ private function processMembership(array $params) {
$value[$fieldKey] = CRM_Utils_Rule::cleanMoney($fieldValue);
}
}
$membershipOrganizationID = $value['membership_type'][0];
$value = $this->standardiseRow($value);

// update contact information
Expand All @@ -764,57 +764,21 @@ private function processMembership(array $params) {
$value['soft_credit'][$key]['soft_credit_type_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_ContributionSoft', 'soft_credit_type_id', 'Gift');
}
}

$batchTotal += $value['total_amount'];

$value['batch_id'] = $this->_batchId;
$value['skipRecentView'] = TRUE;

// make entry in line item for contribution

$editedFieldParams = [
'price_set_id' => $priceSetId,
'name' => $membershipOrganizationID,
];

$editedResults = [];
CRM_Price_BAO_PriceField::retrieve($editedFieldParams, $editedResults);

if (!empty($editedResults)) {
unset($this->_priceSet['fields']);
$this->_priceSet['fields'][$editedResults['id']] = $priceSets['fields'][$editedResults['id']];
unset($this->_priceSet['fields'][$editedResults['id']]['options']);
$fid = $editedResults['id'];
$editedFieldParams = [
'price_field_id' => $editedResults['id'],
'membership_type_id' => $value['membership_type_id'],
];

$editedResults = [];
CRM_Price_BAO_PriceFieldValue::retrieve($editedFieldParams, $editedResults);
$this->_priceSet['fields'][$fid]['options'][$editedResults['id']] = $priceSets['fields'][$fid]['options'][$editedResults['id']];
if (!empty($value['total_amount'])) {
$this->_priceSet['fields'][$fid]['options'][$editedResults['id']]['amount'] = $value['total_amount'];
}

$fieldID = key($this->_priceSet['fields']);
$value['price_' . $fieldID] = $editedResults['id'];

$lineItem = [];
CRM_Price_BAO_PriceSet::processAmount($this->_priceSet['fields'],
$value, $lineItem[$priceSetId]
);

//CRM-11529 for backoffice transactions
//when financial_type_id is passed in form, update the
//lineitems with the financial type selected in form
if (!empty($value['financial_type_id']) && !empty($lineItem[$priceSetId])) {
foreach ($lineItem[$priceSetId] as &$values) {
$values['financial_type_id'] = $value['financial_type_id'];
}
}

$value['lineItems'] = $lineItem;
$order = new CRM_Financial_BAO_Order();
// We use the override total amount because we are dealing with a
// possibly tax_inclusive total, which is assumed for the override total.
$order->setOverrideTotalAmount($value['total_amount']);
$order->setLineItem([
'membership_type_id' => $value['membership_type_id'],
'financial_type_id' => $value['financial_type_id'],
], $key);

if (!empty($order->getLineItems())) {
$value['lineItems'] = [$order->getPriceSetID() => $order->getPriceFieldIndexedLineItems()];
$value['processPriceSet'] = TRUE;
}
// end of contribution related section
Expand Down
99 changes: 70 additions & 29 deletions CRM/Financial/BAO/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,12 @@ public function _unserialize(array $data): void {
* @return float|false
*/
public function getOverrideTotalAmount() {
if (count($this->getPriceOptions()) !== 1) {
// The override amount is only valid for quick config price sets where more
// than one field has not been selected.
if (!$this->overrideTotalAmount || !$this->supportsOverrideAmount() || count($this->getPriceOptions()) > 1) {
return FALSE;
}
return $this->overrideTotalAmount ?? FALSE;
return $this->overrideTotalAmount;
}

/**
Expand All @@ -191,9 +193,7 @@ public function getOverrideTotalAmount() {
* @param float $overrideTotalAmount
*/
public function setOverrideTotalAmount(float $overrideTotalAmount): void {
if ($this->supportsOverrideAmount()) {
$this->overrideTotalAmount = $overrideTotalAmount;
}
$this->overrideTotalAmount = $overrideTotalAmount;
}

/**
Expand All @@ -217,7 +217,7 @@ public function getOverrideFinancialTypeID() {
*
* @param int $overrideFinancialTypeID
*/
public function setOverrideFinancialTypeID(int $overrideFinancialTypeID) {
public function setOverrideFinancialTypeID(int $overrideFinancialTypeID): void {
$this->overrideFinancialTypeID = $overrideFinancialTypeID;
}

Expand Down Expand Up @@ -479,6 +479,22 @@ public function getLineItems():array {
return $this->lineItems;
}

/**
* Get line items in a 'traditional' indexing format.
*
* This ensures the line items are indexed by
* price field id - as required by the contribution BAO.
*
* @throws \CiviCRM_API3_Exception
*/
public function getPriceFieldIndexedLineItems(): array {
$lines = [];
foreach ($this->getLineItems() as $item) {
$lines[$item['price_field_id']] = $item;
}
return $lines;
}

/**
* Get line items that specifically relate to memberships.
*
Expand Down Expand Up @@ -566,14 +582,7 @@ protected function calculateLineItems(): array {
}
$taxRate = $this->getTaxRate((int) $lineItem['financial_type_id']);
if ($this->getOverrideTotalAmount() !== FALSE) {
if ($taxRate) {
// Total is tax inclusive.
$lineItem['tax_amount'] = ($taxRate / 100) * $this->getOverrideTotalAmount() / (1 + ($taxRate / 100));
$lineItem['line_total'] = $lineItem['unit_price'] = $this->getOverrideTotalAmount() - $lineItem['tax_amount'];
}
else {
$lineItem['line_total'] = $lineItem['unit_price'] = $this->getOverrideTotalAmount();
}
$this->addTotalsToLineBasedOnOverrideTotal((int) $lineItem['financial_type_id'], $lineItem);
}
elseif ($taxRate) {
$lineItem['tax_amount'] = ($taxRate / 100) * $lineItem['line_total'];
Expand Down Expand Up @@ -674,23 +683,32 @@ protected function setPriceSetIDFromSelectedField($fieldID): void {
*
*/
public function setLineItem(array $lineItem, $index): void {
if (!empty($lineItem['price_field_id']) && !isset($this->priceSetID)) {
$this->setPriceSetIDFromSelectedField($lineItem['price_field_id']);
if (!isset($this->priceSetID)) {
if (!empty($lineItem['price_field_id'])) {
$this->setPriceSetIDFromSelectedField($lineItem['price_field_id']);
}
else {
// we are using either the default membership or default contribution
// If membership type is passed in we use the default price field.
$component = !empty($lineItem['membership_type_id']) ? 'membership' : 'contribution';
$this->setPriceSetToDefault($component);
}
}
if (!isset($lineItem['financial_type_id'])) {
$lineItem['financial_type_id'] = $this->getDefaultFinancialTypeID();
}
if (!is_numeric($lineItem['financial_type_id'])) {
$lineItem['financial_type_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', $lineItem['financial_type_id']);
}
$lineItem['tax_amount'] = ($this->getTaxRate($lineItem['financial_type_id']) / 100) * $lineItem['line_total'];
if ($this->getOverrideTotalAmount()) {
$this->addTotalsToLineBasedOnOverrideTotal((int) $lineItem['financial_type_id'], $lineItem);
}
else {
$lineItem['tax_amount'] = ($this->getTaxRate($lineItem['financial_type_id']) / 100) * $lineItem['line_total'];
}
if (!empty($lineItem['membership_type_id'])) {
$lineItem['entity_table'] = 'civicrm_membership';
if (empty($lineItem['price_field_id']) && empty($lineItem['price_field_value_id'])) {
// If only the membership type is passed in we use the default price field.
if (!isset($this->priceSetID)) {
$this->setPriceSetToDefault('membership');
}
$lineItem = $this->fillMembershipLine($lineItem);
}
}
Expand Down Expand Up @@ -742,22 +760,45 @@ public function getLineItem($index): array {
*/
protected function fillMembershipLine(array $lineItem): array {
$fields = $this->getPriceFieldsMetadata();
$field = reset($fields);
if (!isset($lineItem['price_field_value_id'])) {
foreach ($field['options'] as $option) {
if ((int) $option['membership_type_id'] === (int) $lineItem['membership_type_id']) {
$lineItem['price_field_id'] = $field['id'];
$lineItem['price_field_value_id'] = $option['id'];
$lineItem['qty'] = 1;
foreach ($fields as $field) {
if (!isset($lineItem['price_field_value_id'])) {
foreach ($field['options'] as $option) {
if ((int) $option['membership_type_id'] === (int) $lineItem['membership_type_id']) {
$lineItem['price_field_id'] = $field['id'];
$lineItem['price_field_value_id'] = $option['id'];
$lineItem['qty'] = 1;
}
}
}
if (isset($lineItem['price_field_value_id'], $field['options'][$lineItem['price_field_value_id']])) {
$option = $field['options'][$lineItem['price_field_value_id']];
}
}
$option = $field['options'][$lineItem['price_field_value_id']];
$lineItem['unit_price'] = $lineItem['line_total'] ?? $option['amount'];
$lineItem['label'] = $lineItem['label'] ?? $option['label'];
$lineItem['field_title'] = $lineItem['field_title'] ?? $option['label'];
$lineItem['financial_type_id'] = $lineItem['financial_type_id'] ?: ($this->getDefaultFinancialTypeID() ?? $option['financial_type_id']);
return $lineItem;
}

/**
* Add total_amount and tax_amount to the line from the override total.
*
* @param int $financialTypeID
* @param array $lineItem
*
* @return void
*/
protected function addTotalsToLineBasedOnOverrideTotal(int $financialTypeID, array &$lineItem): void {
$taxRate = $this->getTaxRate($financialTypeID);
if ($taxRate) {
// Total is tax inclusive.
$lineItem['tax_amount'] = ($taxRate / 100) * $this->getOverrideTotalAmount() / (1 + ($taxRate / 100));
$lineItem['line_total'] = $lineItem['unit_price'] = $this->getOverrideTotalAmount() - $lineItem['tax_amount'];
}
else {
$lineItem['line_total'] = $lineItem['unit_price'] = $this->getOverrideTotalAmount();
}
}

}

0 comments on commit 6d2cfff

Please sign in to comment.