I'd like to create an entry in Craft that talks about a new discount, and then choose that discount via a field (so a bit like you can choose an entry or a product). That way, should the parameters of the discount change, I'm not having to manually update the information in the entry to match any changes to the discount details. Is there a plugin for this?
1 Answer
That field type doesn’t currently exist, but it wouldn’t be hard to create it.
Here’s the relevant code you’d need if you want to take a stab at it:
use Craft;
use craft\base\ElementInterface;
use craft\commerce\models\Discount;
use craft\commerce\Plugin as Commerce;
// ...
public function normalizeValue($value, ElementInterface $element = null)
{
if ($value !== null) {
return Commerce::getInstance()->discounts->getDiscountById($value);
}
return $value;
}
public function getInputHtml($value, ElementInterface $element = null): string
{
$options = [];
foreach (Commerce::getInstance()->discounts->getAllDiscounts() as $discount) {
$options[] = ['value' => $discount->id, 'label' => $discount->name];
}
/** @var Discount|null $value */
return Craft::$app->view->renderTemplate('_includes/forms/select', [
'id' => $this->handle,
'name' => $this->handle,
'options' => $options,
'value' => $value->id ?? null,
]);
}
With that, the field type’s value would always either be a Discount model or null
, so in your templates you could do this:
{% if entry.myDiscountField %}
Code: <code>{{ entry.myDiscountField.code }}</code>
...
{% endif %}
Alternatively, you could pull this off with a simple Plain Text field that stores a discount code, and then fetch the discount manually from your template.
{% if entry.myDiscountCodeField %}
{% set discount = craft.commerce.discounts.getDiscountByCode(entry.myDiscountCodeField) %}
{% else %}
{% set discount = null %}
{% endif %}
{% if discount %}
Code: <code>{{ discount.code }}</code>
...
{% endif %}
-
I am having a problem after create the discount field. When I try to save the entry with discount field, I got the error "Discount Field should contain at most 255 characters." I checked the code in the field, and commented out "normalizeValue" function. Or instead of commenting
public function normalizeValue($value, ElementInterface $element = null) { if ($value !== null) { return Commerce::getInstance()->discounts->getDiscountById($value)->id; } return $value; }
might be right? Commented Jul 10, 2019 at 1:27