implement TwingleShop integration
This commit is contained in:
parent
ea46e6a747
commit
8cfa270dff
60 changed files with 5200 additions and 106 deletions
|
@ -17,6 +17,8 @@ declare(strict_types = 1);
|
|||
|
||||
use CRM_Twingle_ExtensionUtil as E;
|
||||
use Civi\Twingle\Exceptions\BaseException;
|
||||
use Civi\Twingle\Shop\Exceptions\LineItemException;
|
||||
use Civi\Twingle\Shop\BAO\TwingleProduct;
|
||||
|
||||
class CRM_Twingle_Submission {
|
||||
|
||||
|
@ -41,7 +43,18 @@ class CRM_Twingle_Submission {
|
|||
public const EMPLOYER_RELATIONSHIP_TYPE_ID = 5;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> &$params
|
||||
* List of allowed product attributes.
|
||||
*/
|
||||
const ALLOWED_PRODUCT_ATTRIBUTES = [
|
||||
'name',
|
||||
'internal_id',
|
||||
'price',
|
||||
'count',
|
||||
'total_value',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param array &$params
|
||||
* A reference to the parameters array of the submission.
|
||||
*
|
||||
* @param \CRM_Twingle_Profile $profile
|
||||
|
@ -123,6 +136,22 @@ class CRM_Twingle_Submission {
|
|||
}
|
||||
}
|
||||
|
||||
// Validate products
|
||||
if (!empty($params['products']) && $profile->isShopEnabled()) {
|
||||
if (is_string($params['products'])) {
|
||||
$products = json_decode($params['products'], TRUE);
|
||||
$params['products'] = array_map(function ($product) {
|
||||
return array_intersect_key($product, array_flip(self::ALLOWED_PRODUCT_ATTRIBUTES));
|
||||
}, $products);
|
||||
}
|
||||
if (!is_array($params['products'])) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
E::ts('Invalid format for products.'),
|
||||
'invalid_format'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate campaign_id, if given.
|
||||
if (isset($params['campaign_id'])) {
|
||||
// Check whether campaign_id is a numeric string and cast it to an integer.
|
||||
|
@ -433,4 +462,131 @@ class CRM_Twingle_Submission {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $values
|
||||
* Processed data
|
||||
* @param $submission
|
||||
* Submission data
|
||||
* @param $profile
|
||||
* The twingle profile used
|
||||
*
|
||||
* @throws \CiviCRM_API3_Exception
|
||||
* @throws \CRM_Core_Exception
|
||||
* @throws \Civi\Twingle\Shop\Exceptions\LineItemException
|
||||
*/
|
||||
public static function createLineItems($values, $submission, $profile): array {
|
||||
$line_items = [];
|
||||
$sum_line_items = 0;
|
||||
|
||||
$contribution_id = $values['contribution']['id'];
|
||||
if (empty($contribution_id)) {
|
||||
throw new LineItemException(
|
||||
"Could not find contribution id for line item assignment.",
|
||||
LineItemException::ERROR_CODE_CONTRIBUTION_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($submission['products'] as $product) {
|
||||
|
||||
$line_item_data = [
|
||||
'entity_table' => "civicrm_contribution",
|
||||
'contribution_id' => $contribution_id,
|
||||
'entity_id' => $contribution_id,
|
||||
'label' => $product['name'],
|
||||
'qty' => $product['count'],
|
||||
'unit_price' => $product['price'],
|
||||
'line_total' => $product['total_value'],
|
||||
'sequential' => 1,
|
||||
];
|
||||
|
||||
// Try to find the TwingleProduct with its corresponding PriceField
|
||||
// for this product
|
||||
try {
|
||||
$price_field = TwingleProduct::findByExternalId($product['id']);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
Civi::log()->error(E::LONG_NAME .
|
||||
": An error occurred when searching for TwingleShop with the external ID " .
|
||||
$product['id'], ['exception' => $e]);
|
||||
$price_field = NULL;
|
||||
}
|
||||
// If found, use the financial type and price field id from the price field
|
||||
if ($price_field) {
|
||||
|
||||
// Log warning if price differs from the submission
|
||||
if ($price_field->price != (int) $product['price']) {
|
||||
Civi::log()->warning(E::LONG_NAME .
|
||||
": Price for product " . $product['name'] . " differs from the PriceField. " .
|
||||
"Using the price from the submission.", ['price_field' => $price_field->price, 'submission' => $product['price']]);
|
||||
}
|
||||
|
||||
// Log warning if name differs from the submission
|
||||
if ($price_field->name != $product['name']) {
|
||||
Civi::log()->warning(E::LONG_NAME .
|
||||
": Name for product " . $product['name'] . " differs from the PriceField " .
|
||||
"Using the name from the submission.", ['price_field' => $price_field->name, 'submission' => $product['name']]);
|
||||
}
|
||||
|
||||
// Set the financial type and price field id
|
||||
$line_item_data['financial_type_id'] = $price_field->financial_type_id;
|
||||
$line_item_data['price_field_value_id'] = $price_field->getPriceFieldValueId();
|
||||
$line_item_data['price_field_id'] = $price_field->price_field_id;
|
||||
$line_item_data['description'] = $price_field->description;
|
||||
}
|
||||
// If not found, use the shops default financial type
|
||||
else {
|
||||
$financial_type_id = $profile->getAttribute('shop_financial_type', 1);
|
||||
$line_item_data['financial_type_id'] = $financial_type_id;
|
||||
}
|
||||
|
||||
// Create the line item
|
||||
$line_item = civicrm_api3('LineItem', 'create', $line_item_data);
|
||||
|
||||
if (!empty($line_item['is_error'])) {
|
||||
$line_item_name = $line_item_data['name'];
|
||||
throw new CiviCRM_API3_Exception(
|
||||
E::ts("Could not create line item for product '$line_item_name'"),
|
||||
'api_error'
|
||||
);
|
||||
}
|
||||
$line_items[] = array_pop($line_item['values']);
|
||||
|
||||
$sum_line_items += $product['total_value'];
|
||||
}
|
||||
|
||||
// Create line item for donation part
|
||||
$donation_sum = (float) $values['contribution']['total_amount'] - $sum_line_items;
|
||||
if ($donation_sum > 0) {
|
||||
$donation_financial_type_id = $profile->getAttribute('shop_donation_financial_type', 1);
|
||||
$donation_label = civicrm_api3('FinancialType', 'getsingle', [
|
||||
'return' => ['name'],
|
||||
'id' => $donation_financial_type_id,
|
||||
])['name'];
|
||||
|
||||
$donation_line_item_data = [
|
||||
'entity_table' => "civicrm_contribution",
|
||||
'contribution_id' => $contribution_id,
|
||||
'entity_id' => $contribution_id,
|
||||
'label' => $donation_label,
|
||||
'qty' => 1,
|
||||
'unit_price' => $donation_sum,
|
||||
'line_total' => $donation_sum,
|
||||
'financial_type_id' => $donation_financial_type_id,
|
||||
'sequential' => 1,
|
||||
];
|
||||
|
||||
$donation_line_item = civicrm_api3('LineItem', 'create', $donation_line_item_data);
|
||||
|
||||
if (!empty($donation_line_item['is_error'])) {
|
||||
throw new CiviCRM_API3_Exception(
|
||||
E::ts("Could not create line item for donation"),
|
||||
'api_error'
|
||||
);
|
||||
}
|
||||
|
||||
$line_items[] = array_pop($donation_line_item['values']);
|
||||
}
|
||||
|
||||
return $line_items;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue