OroCommerce: Forms with extended oro entities

Viewed 318

I need to implement some additional things to the ordering process - for every ordered item crm user should select one of customer "options" and that selection should be saved in order. So I've created new entity that has ManyToOne relation with Customer, implemented CRUD for it and all works ok, succesfully created number of items with different Customer.

Than I extended Oro ShoppingList LineItem - created migration with addManyToOneRelation to my enitity and new dropdown magically appeared allowing to select entity using autocomplete box. All works ok except I need to see there only items that related to the customer instead of all created entities. Its pretty easy to get customer (LineItem->customerUser->customer) but how to spesify it for the query used for dropdown? For the moment everything was created by oro (which is really cool), I've only made a migration adding relation, I didnt written any code where can specify customer parameter.

Also it would be perfect to implement some logic verifing that the option selected for product in LineItem is related to the customer and throw exception if for some reason its wrong. But where I can implement that?

Here is pic with form. Also wonder why new fields are misaligned?

2 Answers

To have a custom list of entities, you have to override the form type used for the entity field you've created. To create a custom form type, follow the Symfony guide: https://symfony.com/doc/4.4/form/create_custom_field_type.html#creating-form-types-based-on-symfony-built-in-types.

Then use the new form type for the migration at the ['form']['form_type'] option, like in this example: https://github.com/oroinc/platform/blob/67d71ffdb3491e767d323b3a775920db252718d2/src/Oro/Bundle/UserBundle/Migrations/Schema/v2_2/UpdateUserFormType.php#L17-L24. Omit the last argument from the example, as you should replace the value in any case.

Finally it works! Need to use migration like in prev answer and here is code for the FormType

class CustomersOptionSelectType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->addEventListener(FormEvents::PRE_SET_DATA, function (PreSetDataEvent $event) {
            $form = $event->getForm();
            $lineItem = $event->getForm()->getParent()->getData();
            $customer = $lineItem->getCustomerUser()->getCustomer();

            $qb = $event->getForm()->getConfig()->getOption('query_builder');
            $qb->setParameter('customer', $customer->getId());
        });
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'class'         => Option::class,
            'choice_label'  => 'name',
            'required'      => true,
            'query_builder' => function (EntityRepository $er) {
                return $er->createQueryBuilder('o')
                    ->where('o.customer = :customer')
                    ->orderBy('o.name', 'ASC')
                ;
            },
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public function getParent(): string
    {
        return Type\Select2EntityType::class;
    }

}
Related