['supplier:read:accounting']], ), new Post( uriTemplate: '/suppliers/{supplierId}/ribs', uriVariables: [ 'supplierId' => new Link(fromClass: Supplier::class, toProperty: 'supplier'), ], // read:false : pas de stade lecture du parent. Le Link toProperty // resoudrait l'enfant (SELECT SupplierRib ... WHERE supplier = :id) et // casse en NonUniqueResult des >= 2 enfants. Le parent est rattache // manuellement par SupplierRibProcessor::linkParent (404 si absent). read: false, security: "is_granted('commercial.suppliers.accounting.manage')", normalizationContext: ['groups' => ['supplier:read:accounting']], denormalizationContext: ['groups' => ['supplier:write:accounting']], processor: SupplierRibProcessor::class, ), new Patch( security: "is_granted('commercial.suppliers.accounting.manage')", normalizationContext: ['groups' => ['supplier:read:accounting']], denormalizationContext: ['groups' => ['supplier:write:accounting']], processor: SupplierRibProcessor::class, ), new Delete( security: "is_granted('commercial.suppliers.accounting.manage')", processor: SupplierRibProcessor::class, ), ], )] #[ORM\Entity(repositoryClass: DoctrineSupplierRibRepository::class)] #[ORM\Table(name: 'supplier_rib')] #[ORM\Index(name: 'idx_supplier_rib_supplier', columns: ['supplier_id'])] #[Auditable] class SupplierRib implements TimestampableInterface, BlamableInterface { use TimestampableBlamableTrait; #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] #[Groups(['supplier:read:accounting'])] private ?int $id = null; #[ORM\ManyToOne(targetEntity: Supplier::class, inversedBy: 'ribs')] #[ORM\JoinColumn(name: 'supplier_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')] private ?Supplier $supplier = null; #[ORM\Column(length: 120)] #[Assert\NotBlank(message: 'Le libellé du RIB est obligatoire.', normalizer: 'trim')] #[Assert\Length(max: 120, maxMessage: 'Le libellé ne peut dépasser {{ limit }} caractères.', normalizer: 'trim')] #[Groups(['supplier:read:accounting', 'supplier:write:accounting'])] private ?string $label = null; // Bic/Iban bornent deja le format (et donc la longueur) : pas de Length // redondant calee sur la colonne (auto-exempte du miroir ERP-107). #[ORM\Column(length: 20)] #[Assert\NotBlank(message: 'Le BIC est obligatoire.', normalizer: 'trim')] #[Assert\Bic(message: 'Le BIC n\'est pas valide.')] #[Groups(['supplier:read:accounting', 'supplier:write:accounting'])] private ?string $bic = null; #[ORM\Column(length: 34)] #[Assert\NotBlank(message: 'L\'IBAN est obligatoire.', normalizer: 'trim')] #[Assert\Iban(message: 'L\'IBAN n\'est pas valide.')] #[Groups(['supplier:read:accounting', 'supplier:write:accounting'])] private ?string $iban = null; // Ordre d'affichage du RIB (gere serveur, non expose au M2). #[ORM\Column(options: ['default' => 0])] private int $position = 0; public function getId(): ?int { return $this->id; } public function getSupplier(): ?Supplier { return $this->supplier; } public function setSupplier(?Supplier $supplier): static { $this->supplier = $supplier; return $this; } public function getLabel(): ?string { return $this->label; } public function setLabel(string $label): static { $this->label = $label; return $this; } public function getBic(): ?string { return $this->bic; } public function setBic(string $bic): static { $this->bic = $bic; return $this; } public function getIban(): ?string { return $this->iban; } public function setIban(string $iban): static { $this->iban = $iban; return $this; } public function getPosition(): int { return $this->position; } public function setPosition(int $position): static { $this->position = $position; return $this; } }