easyadmin crud controllers: adding value into related entity

1.3k Views Asked by At

I have question concerning easyadmin3. In my admin panel I have a productCrudController and one of the values I want to be able to set when creating a new product is the price. For the price I have a separate table though which contains all my prices with a date. The idea being that the price of a product van change over time and my client wants to be able to have an overview of the price history for each product.

So in my productCrudController I work with an associationField to link to my prices entity. However I'm really stuck with the following practical issue: I don't want to have to add a price in a priceCrudController which I would then be able to select in my productCrudController (the way the associationField expects me to do).

What I want is that I can create a product and input a price which would then be inserted into my prices table.

My code:

productCrudController ->

Right now I have a field for prices where I can select a price in a dropdown menu, but so I have to add the price first with a priceCrudController, which really isn't practical.

class ProductsCrudController extends AbstractCrudController
{
    public static function getEntityFqcn(): string
    {
        return Products::class;
    }


    public function configureFields(string $pageName): iterable
    {
        $image = ImageField::new('image')->setBasePath('resources/images');
        $imageFile = TextField::new('imageFile')->setFormType(VichImageType::class);
        $fields = [
            IdField::new('id', 'ID')->hideOnForm(),
            TextField::new('name'),
            TextEditorField::new('description'),
            AssociationField::new('category'),
            AssociationField::new('plants')->setTemplatePath('list.html.twig'),
            NumberField::new('stock'),
            AssociationField::new('prices', 'bruto price')->onlyOnIndex()->setTemplatePath('price.html.twig'),

        ];

        if($pageName == Crud::PAGE_INDEX || $pageName == Crud::PAGE_DETAIL){
            $fields[] = $image;
        } else {
            $fields[] = $imageFile;
        }

        return $fields;
    }

I tried just making a numberField for 'prices' to see if I could just enter a value that would then be persisted in the database, but I get the following error:

Object of class Doctrine\ORM\PersistentCollection could not be converted to string

This is my 'prices' property in my 'products' entity and the methods:

   /**
     * @ORM\OneToMany(targetEntity=Prices::class, mappedBy="product")
     * @Groups({"products:read"})
     */
    private $prices;

   /**
     * @return Collection|Prices[]
     */
    public function getPrices(): Collection
    {
        return $this->prices;
    }

    public function addPrice(Prices $price): self
    {
        if (!$this->prices->contains($price)) {
            $this->prices[] = $price;
            $price->setProduct($this);
        }

        return $this;
    }

    public function removePrice(Prices $price): self
    {
        if ($this->prices->removeElement($price)) {
            // set the owning side to null (unless already changed)
            if ($price->getProduct() === $this) {
                $price->setProduct(null);
            }
        }

        return $this;
    }

I have the feeling I might need to do something with event listeners, but I don't really know how to go about it as I haven't really worked with them before.

I'd be very grateful for any help

1

There are 1 best solutions below

1
On BEST ANSWER

You can create a form for the Prices entity and then use it in your product

CollectionField::new('prices')
    ->hideOnIndex()
    ->setLabel('bruto price')
    ->setTemplatePath('price.html.twig')
    ->setFormTypeOptions([
        'label' => false,
        'delete_empty' => true,
        'by_reference' => false,
    ])
    ->setEntryIsComplex(false)
    ->setCustomOptions([
        'allowAdd' => true,
        'allowDelete' => false,
        'entryType' => PricesType::class, // Your price form class here
        'showEntryLabel' => false,
    ])
    ;