Skip to content

Commit

Permalink
allow products with self-selected price
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcMichalsky committed May 10, 2024
1 parent ab4b0e0 commit 519a724
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 16 deletions.
5 changes: 3 additions & 2 deletions CRM/Twingle/Submission.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class CRM_Twingle_Submission {
* List of allowed product attributes.
*/
const ALLOWED_PRODUCT_ATTRIBUTES = [
'id',
'name',
'internal_id',
'price',
Expand Down Expand Up @@ -513,8 +514,8 @@ public static function createLineItems($values, $submission, $profile): array {
// 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']) {
// Log warning if price is not variable and differs from the submission
if ($price_field->price !== Null && $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']]);
Expand Down
41 changes: 35 additions & 6 deletions Civi/Twingle/Shop/BAO/TwingleProduct.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use function Civi\Twingle\Shop\Utils\convert_int_to_bool;
use function Civi\Twingle\Shop\Utils\convert_str_to_date;
use function Civi\Twingle\Shop\Utils\convert_str_to_int;
use function Civi\Twingle\Shop\Utils\convert_null_to_int;
use function Civi\Twingle\Shop\Utils\convert_empty_string_to_null;
use function Civi\Twingle\Shop\Utils\filter_attributes;
use function Civi\Twingle\Shop\Utils\validate_data_types;

Expand Down Expand Up @@ -112,9 +112,9 @@ class TwingleProduct extends TwingleProductDAO {
];

/**
* Attributes that need to be converted from NULL to int.
* Empty string to null conversion.
*/
protected const NULL_TO_INT_CONVERSION = [
protected const EMPTY_STRING_TO_NULL = [
"price",
];

Expand Down Expand Up @@ -198,6 +198,28 @@ public function load(array $product_data): void {
self::CAN_BE_ZERO,
);

// Does this product allow to enter a custom price?
$custom_price = array_key_exists('price', $product_data) && $product_data['price'] === Null;
if (!$custom_price && isset($product_data['price_field_id'])) {
try {
$price_field = civicrm_api3('PriceField', 'getsingle', [
'id' => $product_data['price_field_id'],
'return' => 'is_enter_qty',
]);
$custom_price = (bool) $price_field['is_enter_qty'];
}
catch (CRM_Core_Exception $e) {
throw new ProductException(
E::ts("Could not find PriceField for Twingle Product ['id': %1, 'external_id': %2]: %3",
[
1 => $product_data['id'],
2 => $product_data['external_id'],
3 => $e->getMessage(),
]),
ProductException::ERROR_CODE_PRICE_FIELD_NOT_FOUND);
}
}

// Amend data from corresponding PriceFieldValue
if (isset($product_data['price_field_id'])) {
try {
Expand All @@ -216,7 +238,7 @@ public function load(array $product_data): void {
ProductException::ERROR_CODE_PRICE_FIELD_VALUE_NOT_FOUND);
}
$product_data['name'] = $product_data['name'] ?? $price_field_value['label'];
$product_data['price'] = $product_data['price'] ?? $price_field_value['amount'];
$product_data['price'] = $custom_price ? Null : $product_data['price'] ?? $price_field_value['amount'];
$product_data['financial_type_id'] = $product_data['financial_type_id'] ?? $price_field_value['financial_type_id'];
$product_data['is_active'] = $product_data['is_active'] ?? $price_field_value['is_active'];
$product_data['sort'] = $product_data['sort'] ?? $price_field_value['weight'];
Expand All @@ -228,7 +250,7 @@ public function load(array $product_data): void {
convert_str_to_int($product_data, self::STR_TO_INT_CONVERSION);
convert_int_to_bool($product_data, self::INT_TO_BOOL_CONVERSION);
convert_str_to_date($product_data, self::STR_TO_DATE_CONVERSION);
convert_null_to_int($product_data, self::NULL_TO_INT_CONVERSION);
convert_empty_string_to_null($product_data, self::EMPTY_STRING_TO_NULL);
}
catch (\Exception $e) {
throw new ProductException($e->getMessage(), ProductException::ERROR_CODE_ATTRIBUTE_WRONG_DATA_TYPE);
Expand Down Expand Up @@ -308,6 +330,13 @@ public function createPriceField() {
'html_type' => 'Text',
'is_required' => false,
];

// If the product has no fixed price, allow the user to enter a custom price
if ($this->price === Null) {
$price_field_data['is_enter_qty'] = true;
$price_field_data['is_display_amounts'] = false;
}

// Add id if in edit mode
if ($mode == 'edit') {
$price_field_data['id'] = $this->price_field_id;
Expand Down Expand Up @@ -348,7 +377,7 @@ public function createPriceField() {
'price_field_id' => $this->price_field_id,
'financial_type_id' => $this->financial_type_id,
'label' => $this->name,
'amount' => $this->price,
'amount' => $this->price === Null ? 1 : $this->price,
'is_active' => $this->is_active,
'description' => $this->description,
];
Expand Down
15 changes: 7 additions & 8 deletions Civi/Twingle/Shop/Utils/TwingleShopUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function($value, $key) use ($can_be_zero) {
function convert_str_to_int(array &$data, array $str_to_int_conversion): void {
// Convert string to int
foreach ($str_to_int_conversion as $attribute) {
if (isset($data[$attribute])) {
if (isset($data[$attribute]) && $data[$attribute] !== '') {
try {
$data[$attribute] = (int) $data[$attribute];
} catch (\Exception $e) {
Expand Down Expand Up @@ -108,18 +108,17 @@ function convert_str_to_date(array &$data, array $str_to_date_conversion): void
}

/**
* Convert null to int
* Convert an empty string to null.
*
* @param array $data
* @param array $null_to_int_conversion
* @param array $empty_string_to_null
*
* @return void
*/
function convert_null_to_int(array &$data, array $null_to_int_conversion): void {
// Convert null to int
foreach ($null_to_int_conversion as $attribute) {
if (array_key_exists($attribute, $data) && $data[$attribute] === NULL) {
$data[$attribute] = 0;
function convert_empty_string_to_null(array &$data, array $empty_string_to_null): void {
foreach ($empty_string_to_null as $attribute) {
if (isset($data[$attribute]) && $data[$attribute] === '') {
$data[$attribute] = NULL;
}
}
}
Expand Down

0 comments on commit 519a724

Please sign in to comment.