Shopware 6 - form field for entity extension in administration

Viewed 541

This is a Shopware 6 question. I want to extend the PromotionEntity by adding a max_budget field and display it as a form field in administration. Currently only max_redemptions_global and max_redemptions_per_customer fields exist. The max_budget field should appear in administration right under max_redemptions_global and max_redemptions_per_customer fields. max_budget would act similar to the other two. If the discount for this promotion from total orders combined reaches the value from max_budget, then the promotion does not work anymore.

So I created an entity extension as following:

class PromotionMaxBudgetExtension extends EntityExtension
{
    public function extendFields(FieldCollection $collection): void
    {
        $collection->add(
            new OneToOneAssociationField('maxBudget', 'id', 'promotion_id', PromotionMaxBudgetDefinition::class, false)
        );
    }

    public function getDefinitionClass(): string
    {
        return PromotionDefinition::class;
    }
}

Then the definition of the extension:

class PromotionMaxBudgetDefinition extends EntityDefinition
{
    public const ENTITY_NAME = 'promotion_max_budget';

    public function getEntityName(): string
    {
        return self::ENTITY_NAME;
    }

    public function getEntityClass(): string
    {
        return PromotionMaxBudgetEntity::class;
    }

    protected function defineFields(): FieldCollection
    {
        return new FieldCollection([
            (new IdField('id', 'id'))->addFlags(new Required(), new PrimaryKey()),
            (new FkField('promotion_id', 'promotionId', PromotionDefinition::class)),
            (new IntField('max_budget', 'maxBudget')),
            (new IntField('left_budget', 'leftBudget')),

            (new OneToOneAssociationField('promotion', 'promotion_id', 'id', PromotionDefinition::class, false))
        ]);
    }
}

In order to display the field I had to override the sw-promotion-v2-detail-base. So I modified the sw-promotion-v2-detail-base.html.twig like this:

{% block sw_promotion_v2_detail_base_general_max_uses_customer %}
{% parent %}

<sw-number-field
        v-model="??????"
        class="sw-promotion-v2-detail-base__field-max-uses-per-customer"
        number-type="int"
        :label="Max budget"
        :placeholder="$tc('sw-promotion-v2.detail.base.general.maxUsesPerCustomerPlaceholder')"
        :disabled="!acl.can('promotion.editor')"
        allow-empty
/>
{% endblock %}

So, my question would be, how would I tell Shopware this field is for the max_budget entity extension, so that it would save the changes I make to it, at onSave ? Seems like even though the entity extension exists, it is not fetched as an association for the promotion (even with autoload true).

1 Answers

Ok, so I saw how this needs to be done to work perfectly.

Firstly I had to override sw-promotion-v2-detail component and add this js:

Shopware.Component.override('sw-promotion-v2-detail', {
    computed: {
        promotionCriteria() {
            const criteria = this.$super('promotionCriteria');

            criteria.addAssociation('maxBudget');

            return criteria;
        }
    },
});

Secondly, in the sw-promotion-v2-detail-base.html.twig the field will look like this:

<sw-number-field
        v-if="promotion.extensions.maxBudget"
        v-model="promotion.extensions.maxBudget.maxBudget"
        class="sw-promotion-v2-detail-base__field-max-budget"
        number-type="int"
        :label="$tc('vouchers.maxBudget')"
        :placeholder="$tc('sw-promotion-v2.detail.base.codes.individual.generateModal.labelPrefix')"
        :disabled="!acl.can('promotion.editor')"
        allow-empty
/>

Notice the v-model changed to promotion.extensions.....

So the answer would be this: To add a Shopware 6 form field for an entity extension in admin you have to add the entity association for the extension to the component where the extended entity is fetched (in this case sw-promotion-v2-detail). After that you can use the extension in twig with promotion.extensions.extensionName....

Related