feat(composant) : create composant slot tables and migrate data from structure JSON
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
47
migrations/Version20260312171810.php
Normal file
47
migrations/Version20260312171810.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
final class Version20260312171810 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Create piece_products join table and migrate data from Piece.productIds JSON column';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('CREATE TABLE IF NOT EXISTS piece_products (piece_id VARCHAR(36) NOT NULL, product_id VARCHAR(36) NOT NULL, PRIMARY KEY (piece_id, product_id))');
|
||||||
|
$this->addSql('CREATE INDEX IF NOT EXISTS IDX_87C835B5C40FCFA8 ON piece_products (piece_id)');
|
||||||
|
$this->addSql('CREATE INDEX IF NOT EXISTS IDX_87C835B54584665A ON piece_products (product_id)');
|
||||||
|
$this->addSql('ALTER TABLE piece_products DROP CONSTRAINT IF EXISTS FK_87C835B5C40FCFA8');
|
||||||
|
$this->addSql('ALTER TABLE piece_products ADD CONSTRAINT FK_87C835B5C40FCFA8 FOREIGN KEY (piece_id) REFERENCES pieces (id) ON DELETE CASCADE NOT DEFERRABLE');
|
||||||
|
$this->addSql('ALTER TABLE piece_products DROP CONSTRAINT IF EXISTS FK_87C835B54584665A');
|
||||||
|
$this->addSql('ALTER TABLE piece_products ADD CONSTRAINT FK_87C835B54584665A FOREIGN KEY (product_id) REFERENCES products (id) ON DELETE CASCADE NOT DEFERRABLE');
|
||||||
|
|
||||||
|
// Migrate Piece.productIds JSON array → piece_products join table
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
INSERT INTO piece_products (piece_id, product_id)
|
||||||
|
SELECT DISTINCT p.id, pid.value
|
||||||
|
FROM pieces p,
|
||||||
|
LATERAL jsonb_array_elements_text(p.productids::jsonb) AS pid(value)
|
||||||
|
WHERE p.productids IS NOT NULL
|
||||||
|
AND p.productids::jsonb != '[]'::jsonb
|
||||||
|
AND jsonb_array_length(p.productids::jsonb) > 0
|
||||||
|
AND EXISTS (SELECT 1 FROM products pr WHERE pr.id = pid.value)
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM piece_products pp WHERE pp.piece_id = p.id AND pp.product_id = pid.value)
|
||||||
|
SQL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE piece_products DROP CONSTRAINT IF EXISTS FK_87C835B5C40FCFA8');
|
||||||
|
$this->addSql('ALTER TABLE piece_products DROP CONSTRAINT IF EXISTS FK_87C835B54584665A');
|
||||||
|
$this->addSql('DROP TABLE IF EXISTS piece_products');
|
||||||
|
}
|
||||||
|
}
|
||||||
248
migrations/Version20260312190000.php
Normal file
248
migrations/Version20260312190000.php
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create composant slot tables and migrate existing JSON data from composant.structure.
|
||||||
|
*/
|
||||||
|
final class Version20260312190000 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Create composant_piece_slots, composant_subcomponent_slots, composant_product_slots tables and migrate data from composant.structure JSON';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// ── Table creation (idempotent) ──────────────────────────────────────
|
||||||
|
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
CREATE TABLE IF NOT EXISTS composant_piece_slots (
|
||||||
|
id VARCHAR(36) NOT NULL,
|
||||||
|
"composantid" VARCHAR(36) NOT NULL,
|
||||||
|
"typepieceid" VARCHAR(36) DEFAULT NULL,
|
||||||
|
"selectedpieceid" VARCHAR(36) DEFAULT NULL,
|
||||||
|
quantity INT NOT NULL DEFAULT 1,
|
||||||
|
position INT NOT NULL DEFAULT 0,
|
||||||
|
"createdat" TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
|
||||||
|
"updatedat" TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
)
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
CREATE TABLE IF NOT EXISTS composant_subcomponent_slots (
|
||||||
|
id VARCHAR(36) NOT NULL,
|
||||||
|
"composantid" VARCHAR(36) NOT NULL,
|
||||||
|
alias VARCHAR(255) DEFAULT NULL,
|
||||||
|
"familycode" VARCHAR(255) DEFAULT NULL,
|
||||||
|
"typecomposantid" VARCHAR(36) DEFAULT NULL,
|
||||||
|
"selectedcomposantid" VARCHAR(36) DEFAULT NULL,
|
||||||
|
position INT NOT NULL DEFAULT 0,
|
||||||
|
"createdat" TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
|
||||||
|
"updatedat" TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
)
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
CREATE TABLE IF NOT EXISTS composant_product_slots (
|
||||||
|
id VARCHAR(36) NOT NULL,
|
||||||
|
"composantid" VARCHAR(36) NOT NULL,
|
||||||
|
"typeproductid" VARCHAR(36) DEFAULT NULL,
|
||||||
|
"selectedproductid" VARCHAR(36) DEFAULT NULL,
|
||||||
|
"familycode" VARCHAR(255) DEFAULT NULL,
|
||||||
|
position INT NOT NULL DEFAULT 0,
|
||||||
|
"createdat" TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
|
||||||
|
"updatedat" TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
)
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
// ── Indexes (idempotent) ─────────────────────────────────────────────
|
||||||
|
|
||||||
|
$this->addSql('CREATE INDEX IF NOT EXISTS idx_comp_piece_slot_composant ON composant_piece_slots("composantid")');
|
||||||
|
$this->addSql('CREATE INDEX IF NOT EXISTS idx_comp_piece_slot_piece ON composant_piece_slots("selectedpieceid")');
|
||||||
|
$this->addSql('CREATE INDEX IF NOT EXISTS idx_comp_piece_slot_type ON composant_piece_slots("typepieceid")');
|
||||||
|
$this->addSql('CREATE INDEX IF NOT EXISTS idx_comp_sub_slot_composant ON composant_subcomponent_slots("composantid")');
|
||||||
|
$this->addSql('CREATE INDEX IF NOT EXISTS idx_comp_sub_slot_typecomp ON composant_subcomponent_slots("typecomposantid")');
|
||||||
|
$this->addSql('CREATE INDEX IF NOT EXISTS idx_comp_sub_slot_selected ON composant_subcomponent_slots("selectedcomposantid")');
|
||||||
|
$this->addSql('CREATE INDEX IF NOT EXISTS idx_comp_prod_slot_composant ON composant_product_slots("composantid")');
|
||||||
|
$this->addSql('CREATE INDEX IF NOT EXISTS idx_comp_prod_slot_type ON composant_product_slots("typeproductid")');
|
||||||
|
$this->addSql('CREATE INDEX IF NOT EXISTS idx_comp_prod_slot_selected ON composant_product_slots("selectedproductid")');
|
||||||
|
|
||||||
|
// ── Foreign keys (idempotent via DO $$ block) ────────────────────────
|
||||||
|
|
||||||
|
// composant_piece_slots FKs
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
DO $$ BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_comp_piece_slot_composant') THEN
|
||||||
|
ALTER TABLE composant_piece_slots
|
||||||
|
ADD CONSTRAINT fk_comp_piece_slot_composant
|
||||||
|
FOREIGN KEY ("composantid") REFERENCES composants (id) ON DELETE CASCADE;
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
DO $$ BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_comp_piece_slot_type') THEN
|
||||||
|
ALTER TABLE composant_piece_slots
|
||||||
|
ADD CONSTRAINT fk_comp_piece_slot_type
|
||||||
|
FOREIGN KEY ("typepieceid") REFERENCES model_types (id) ON DELETE SET NULL;
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
DO $$ BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_comp_piece_slot_piece') THEN
|
||||||
|
ALTER TABLE composant_piece_slots
|
||||||
|
ADD CONSTRAINT fk_comp_piece_slot_piece
|
||||||
|
FOREIGN KEY ("selectedpieceid") REFERENCES pieces (id) ON DELETE SET NULL;
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
// composant_subcomponent_slots FKs
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
DO $$ BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_comp_sub_slot_composant') THEN
|
||||||
|
ALTER TABLE composant_subcomponent_slots
|
||||||
|
ADD CONSTRAINT fk_comp_sub_slot_composant
|
||||||
|
FOREIGN KEY ("composantid") REFERENCES composants (id) ON DELETE CASCADE;
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
DO $$ BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_comp_sub_slot_typecomp') THEN
|
||||||
|
ALTER TABLE composant_subcomponent_slots
|
||||||
|
ADD CONSTRAINT fk_comp_sub_slot_typecomp
|
||||||
|
FOREIGN KEY ("typecomposantid") REFERENCES model_types (id) ON DELETE SET NULL;
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
DO $$ BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_comp_sub_slot_selected') THEN
|
||||||
|
ALTER TABLE composant_subcomponent_slots
|
||||||
|
ADD CONSTRAINT fk_comp_sub_slot_selected
|
||||||
|
FOREIGN KEY ("selectedcomposantid") REFERENCES composants (id) ON DELETE SET NULL;
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
// composant_product_slots FKs
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
DO $$ BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_comp_prod_slot_composant') THEN
|
||||||
|
ALTER TABLE composant_product_slots
|
||||||
|
ADD CONSTRAINT fk_comp_prod_slot_composant
|
||||||
|
FOREIGN KEY ("composantid") REFERENCES composants (id) ON DELETE CASCADE;
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
DO $$ BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_comp_prod_slot_type') THEN
|
||||||
|
ALTER TABLE composant_product_slots
|
||||||
|
ADD CONSTRAINT fk_comp_prod_slot_type
|
||||||
|
FOREIGN KEY ("typeproductid") REFERENCES model_types (id) ON DELETE SET NULL;
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
DO $$ BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_comp_prod_slot_selected') THEN
|
||||||
|
ALTER TABLE composant_product_slots
|
||||||
|
ADD CONSTRAINT fk_comp_prod_slot_selected
|
||||||
|
FOREIGN KEY ("selectedproductid") REFERENCES products (id) ON DELETE SET NULL;
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
// ── Data migration: composant.structure.pieces → composant_piece_slots ──
|
||||||
|
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
INSERT INTO composant_piece_slots (id, "composantid", "typepieceid", "selectedpieceid", quantity, position, "createdat", "updatedat")
|
||||||
|
SELECT
|
||||||
|
'cl' || encode(gen_random_bytes(12), 'hex'),
|
||||||
|
c.id,
|
||||||
|
NULLIF(piece->'definition'->>'typePieceId', ''),
|
||||||
|
NULLIF(piece->>'selectedPieceId', ''),
|
||||||
|
1,
|
||||||
|
(ordinality - 1)::int,
|
||||||
|
NOW(), NOW()
|
||||||
|
FROM composants c,
|
||||||
|
LATERAL jsonb_array_elements(c.structure::jsonb->'pieces') WITH ORDINALITY AS t(piece, ordinality)
|
||||||
|
WHERE c.structure IS NOT NULL
|
||||||
|
AND (c.structure::jsonb->'pieces') IS NOT NULL
|
||||||
|
AND jsonb_array_length(c.structure::jsonb->'pieces') > 0
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM composant_piece_slots cps WHERE cps."composantid" = c.id)
|
||||||
|
AND (NULLIF(piece->'definition'->>'typePieceId', '') IS NULL OR EXISTS (SELECT 1 FROM model_types mt WHERE mt.id = piece->'definition'->>'typePieceId'))
|
||||||
|
AND (NULLIF(piece->>'selectedPieceId', '') IS NULL OR EXISTS (SELECT 1 FROM pieces p WHERE p.id = piece->>'selectedPieceId'))
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
// ── Data migration: composant.structure.subcomponents → composant_subcomponent_slots ──
|
||||||
|
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
INSERT INTO composant_subcomponent_slots (id, "composantid", alias, "familycode", "typecomposantid", "selectedcomposantid", position, "createdat", "updatedat")
|
||||||
|
SELECT
|
||||||
|
'cl' || encode(gen_random_bytes(12), 'hex'),
|
||||||
|
c.id,
|
||||||
|
COALESCE(sub->'definition'->>'alias', ''),
|
||||||
|
COALESCE(sub->'definition'->>'familyCode', ''),
|
||||||
|
NULLIF(sub->'definition'->>'typeComposantId', ''),
|
||||||
|
NULLIF(sub->>'selectedComponentId', ''),
|
||||||
|
(ordinality - 1)::int,
|
||||||
|
NOW(), NOW()
|
||||||
|
FROM composants c,
|
||||||
|
LATERAL jsonb_array_elements(c.structure::jsonb->'subcomponents') WITH ORDINALITY AS t(sub, ordinality)
|
||||||
|
WHERE c.structure IS NOT NULL
|
||||||
|
AND (c.structure::jsonb->'subcomponents') IS NOT NULL
|
||||||
|
AND jsonb_array_length(c.structure::jsonb->'subcomponents') > 0
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM composant_subcomponent_slots css WHERE css."composantid" = c.id)
|
||||||
|
AND (NULLIF(sub->'definition'->>'typeComposantId', '') IS NULL OR EXISTS (SELECT 1 FROM model_types mt WHERE mt.id = sub->'definition'->>'typeComposantId'))
|
||||||
|
AND (NULLIF(sub->>'selectedComponentId', '') IS NULL OR EXISTS (SELECT 1 FROM composants sc WHERE sc.id = sub->>'selectedComponentId'))
|
||||||
|
SQL);
|
||||||
|
|
||||||
|
// ── Data migration: composant.structure.products → composant_product_slots ──
|
||||||
|
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
INSERT INTO composant_product_slots (id, "composantid", "typeproductid", "selectedproductid", "familycode", position, "createdat", "updatedat")
|
||||||
|
SELECT
|
||||||
|
'cl' || encode(gen_random_bytes(12), 'hex'),
|
||||||
|
c.id,
|
||||||
|
NULLIF(prod->'definition'->>'typeProductId', ''),
|
||||||
|
NULLIF(prod->>'selectedProductId', ''),
|
||||||
|
prod->'definition'->>'familyCode',
|
||||||
|
(ordinality - 1)::int,
|
||||||
|
NOW(), NOW()
|
||||||
|
FROM composants c,
|
||||||
|
LATERAL jsonb_array_elements(c.structure::jsonb->'products') WITH ORDINALITY AS t(prod, ordinality)
|
||||||
|
WHERE c.structure IS NOT NULL
|
||||||
|
AND (c.structure::jsonb->'products') IS NOT NULL
|
||||||
|
AND jsonb_array_length(c.structure::jsonb->'products') > 0
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM composant_product_slots cps WHERE cps."composantid" = c.id)
|
||||||
|
AND (NULLIF(prod->'definition'->>'typeProductId', '') IS NULL OR EXISTS (SELECT 1 FROM model_types mt WHERE mt.id = prod->'definition'->>'typeProductId'))
|
||||||
|
AND (NULLIF(prod->>'selectedProductId', '') IS NULL OR EXISTS (SELECT 1 FROM products p WHERE p.id = prod->>'selectedProductId'))
|
||||||
|
SQL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('DROP TABLE IF EXISTS composant_product_slots');
|
||||||
|
$this->addSql('DROP TABLE IF EXISTS composant_subcomponent_slots');
|
||||||
|
$this->addSql('DROP TABLE IF EXISTS composant_piece_slots');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -109,6 +109,15 @@ class Piece
|
|||||||
#[Groups(['piece:read'])]
|
#[Groups(['piece:read'])]
|
||||||
private Collection $customFieldValues;
|
private Collection $customFieldValues;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<int, Product>
|
||||||
|
*/
|
||||||
|
#[ORM\ManyToMany(targetEntity: Product::class, inversedBy: 'linkedPieces')]
|
||||||
|
#[ORM\JoinTable(name: 'piece_products')]
|
||||||
|
#[ORM\JoinColumn(name: 'piece_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
|
||||||
|
#[ORM\InverseJoinColumn(name: 'product_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
|
||||||
|
private Collection $products;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Collection<int, MachinePieceLink>
|
* @var Collection<int, MachinePieceLink>
|
||||||
*/
|
*/
|
||||||
@@ -130,6 +139,7 @@ class Piece
|
|||||||
$this->constructeurs = new ArrayCollection();
|
$this->constructeurs = new ArrayCollection();
|
||||||
$this->documents = new ArrayCollection();
|
$this->documents = new ArrayCollection();
|
||||||
$this->customFieldValues = new ArrayCollection();
|
$this->customFieldValues = new ArrayCollection();
|
||||||
|
$this->products = new ArrayCollection();
|
||||||
$this->machineLinks = new ArrayCollection();
|
$this->machineLinks = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,4 +308,28 @@ class Piece
|
|||||||
{
|
{
|
||||||
return $this->customFieldValues;
|
return $this->customFieldValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, Product>
|
||||||
|
*/
|
||||||
|
public function getProducts(): Collection
|
||||||
|
{
|
||||||
|
return $this->products;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addProduct(Product $product): static
|
||||||
|
{
|
||||||
|
if (!$this->products->contains($product)) {
|
||||||
|
$this->products->add($product);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeProduct(Product $product): static
|
||||||
|
{
|
||||||
|
$this->products->removeElement($product);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,12 @@ class Product
|
|||||||
#[ORM\OneToMany(mappedBy: 'product', targetEntity: Composant::class)]
|
#[ORM\OneToMany(mappedBy: 'product', targetEntity: Composant::class)]
|
||||||
private Collection $composants;
|
private Collection $composants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<int, Piece>
|
||||||
|
*/
|
||||||
|
#[ORM\ManyToMany(targetEntity: Piece::class, mappedBy: 'products')]
|
||||||
|
private Collection $linkedPieces;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Collection<int, MachineProductLink>
|
* @var Collection<int, MachineProductLink>
|
||||||
*/
|
*/
|
||||||
@@ -129,6 +135,7 @@ class Product
|
|||||||
$this->customFieldValues = new ArrayCollection();
|
$this->customFieldValues = new ArrayCollection();
|
||||||
$this->pieces = new ArrayCollection();
|
$this->pieces = new ArrayCollection();
|
||||||
$this->composants = new ArrayCollection();
|
$this->composants = new ArrayCollection();
|
||||||
|
$this->linkedPieces = new ArrayCollection();
|
||||||
$this->machineLinks = new ArrayCollection();
|
$this->machineLinks = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,4 +226,12 @@ class Product
|
|||||||
{
|
{
|
||||||
return $this->customFieldValues;
|
return $this->customFieldValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, Piece>
|
||||||
|
*/
|
||||||
|
public function getLinkedPieces(): Collection
|
||||||
|
{
|
||||||
|
return $this->linkedPieces;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user