src/Entity/Common/Company.php line 210
<?php
namespace App\Entity\Common;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use ApiPlatform\OpenApi\Model;
use App\Controller\Upload\CreateAttachmentAction;
use App\Doctrine\Type\Common\CompanyStatus;
use App\Doctrine\Type\Common\CompanyType;
use App\Doctrine\Type\SelectableType;
use App\Dto\Common\AddressInput;
use App\Dto\Common\CompanyExtendedInput;
use App\Dto\Common\CompanyInput;
use App\Dto\Common\LogoInput;
use App\Dto\Common\CompanyStatusInput;
use App\Dto\Sales\CallOffOrderInput;
use App\Dto\User\ContactInput;
use App\Entity\File\Upload;
use App\Entity\Identity\User;
use App\Entity\Places\Address;
use App\Processor\Common\CompanyAddressInputProcessor;
use App\Processor\Common\CompanyContactInputProcessor;
use App\Processor\Common\CompanyInputProcessor;
use App\Processor\Common\LogoInputProcessor;
use App\Processor\Common\CompanyStatusInputProcessor;
use App\Processor\Sales\CallOffOrderInputProcessor;
use App\Provider\Common\TransporterCompanyProvider;
use App\Repository\Common\CompanyRepository;
use App\Validator\IsValidEnumArray\IsValidEnumArray;
use ArrayObject;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Table(name: 'company')]
#[ORM\Index(columns: ['logo_id'], name: 'company_logo_id_idx')]
#[ORM\Index(columns: ['parent_id'], name: 'company_parent_id_idx')]
#[ORM\Index(columns: ['created_by'], name: 'company_created_by_idx')]
#[ORM\Index(columns: ['updated_by'], name: 'company_updated_by_idx')]
#[ORM\UniqueConstraint(name: 'company_slug_key', columns: ['slug'])]
#[ORM\UniqueConstraint(name: 'company_name_key', columns: ['name'])]
#[ORM\UniqueConstraint(name: 'company_code_key', columns: ['code'])]
#[ORM\Entity(repositoryClass: CompanyRepository::class)]
#[UniqueEntity('slug')]
#[UniqueEntity('name')]
#[UniqueEntity('code')]
#[ApiResource(
operations: [
new GetCollection(),
new Get(provider: TransporterCompanyProvider::class),
new Post(uriTemplate: '/companies/{slug}/status', inputFormats: ['json' => ['application/json']], input: CompanyStatusInput::class, processor: CompanyStatusInputProcessor::class),
new Post(uriTemplate: '/companies/{slug}/logo', inputFormats: ['multipart' => ['multipart/form-data']], input: LogoInput::class, provider: TransporterCompanyProvider::class, processor: LogoInputProcessor::class),
new Patch(inputFormats: ['json' => ['application/merge-patch+json'], 'multipart' => ['multipart/form-data']], provider: TransporterCompanyProvider::class),
new Put(inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], provider: TransporterCompanyProvider::class),
new Delete(),
],
input: CompanyInput::class,
processor: CompanyInputProcessor::class,
)]
#[ApiResource(
operations: [
new GetCollection(uriTemplate: '/providers'),
new GetCollection(uriTemplate: '/consumers'),
new GetCollection(uriTemplate: '/transporters'),
],
)]
#[GetCollection(
uriTemplate: '/companies/{parent}/subsidiaries',
uriVariables: [
'parent' => new Link(fromProperty: 'subsidiaries', fromClass: Company::class),
],
)]
#[Post(
uriTemplate: '/companies/{slug}/users',
shortName: 'User',
input: ContactInput::class,
processor: CompanyContactInputProcessor::class,
)]
#[Post(
uriTemplate: '/companies/{slug}/addresses',
shortName: 'Address',
input: AddressInput::class,
processor: CompanyAddressInputProcessor::class,
)]
#[ApiResource(
// FIXME : This does not work well with docker
uriTemplate: '/companies/{slug}/attachments',
operations: [
new Post(
controller: CreateAttachmentAction::class,
openapi: new Model\Operation(
requestBody: new Model\RequestBody(
content: new ArrayObject([
'multipart/form-data' => [
'schema' => [
'type' => 'object',
'properties' => [
'file' => [
'type' => 'string',
'format' => 'binary'
]
]
]
]
])
)
),
shortName: 'Upload',
validationContext: ['groups' => ['Default', 'upload:create']],
deserialize: false,
),
],
)]
#[Post(
uriTemplate: '/sales/clients/{slug}/call_off_orders',
inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']],
shortName: 'CallOffOrder',
input: CallOffOrderInput::class,
processor: CallOffOrderInputProcessor::class,
)]
#[ApiResource(
uriTemplate: '/sales/tenants',
operations: [
new GetCollection(),
new Post(inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_tenant'),
new Post(uriTemplate: '/sales/tenants/{slug}', inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_tenant_subsidiary'),
],
input: CompanyExtendedInput::class,
processor: CompanyInputProcessor::class,
)]
#[ApiResource(
uriTemplate: '/sales/clients',
operations: [
new GetCollection(),
new Post(inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_client'),
new Post(uriTemplate: '/sales/clients/{slug}', inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_client_subsidiary'),
],
input: CompanyExtendedInput::class,
processor: CompanyInputProcessor::class,
)]
#[ApiResource(
uriTemplate: '/sales/customers',
operations: [
new GetCollection(),
new Post(inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_customer'),
new Post(uriTemplate: '/sales/customers/{slug}', inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_customer_subsidiary'),
],
input: CompanyExtendedInput::class,
processor: CompanyInputProcessor::class,
)]
#[ApiResource(
uriTemplate: '/procurement/suppliers',
operations: [
new GetCollection(),
new Post(inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_supplier'),
new Post(uriTemplate: '/procurement/suppliers/{slug}', inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_supplier_subsidiary'),
],
input: CompanyExtendedInput::class,
processor: CompanyInputProcessor::class,
)]
#[ApiResource(
uriTemplate: '/purchasing/manufacturers',
operations: [
new GetCollection(),
new Post(inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_manufacturer'),
new Post(uriTemplate: '/purchasing/manufacturers/{slug}', inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_manufacturer_subsidiary'),
],
input: CompanyExtendedInput::class,
processor: CompanyInputProcessor::class,
)]
#[ApiResource(
uriTemplate: '/procurement/transporters',
operations: [
new GetCollection(),
new Post(inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_transporter'),
new Post(uriTemplate: '/procurement/transporters/{slug}', inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_transporter_subsidiary'),
],
input: CompanyExtendedInput::class,
processor: CompanyInputProcessor::class,
)]
#[ApiResource(
uriTemplate: '/procurement/carriers',
operations: [
new GetCollection(),
new Post(inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_carrier'),
new Post(uriTemplate: '/procurement/carriers/{slug}', inputFormats: ['json' => ['application/json'], 'multipart' => ['multipart/form-data']], name: 'create_carrier_subsidiary'),
],
input: CompanyExtendedInput::class,
processor: CompanyInputProcessor::class,
)]
#[ApiFilter(SearchFilter::class, properties: [
'name' => 'ipartial',
'code' => 'ipartial',
])]
class Company
{
use Blameable;
use Trackable;
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'IDENTITY')]
#[ORM\SequenceGenerator(sequenceName: 'company_id_seq')]
#[ORM\Column(type: Types::INTEGER)]
#[ApiProperty(identifier: false)]
private ?int $id = null;
#[Gedmo\Slug(fields: ['name'])]
#[ORM\Column(type: Types::STRING)]
#[ApiProperty(identifier: true)]
private ?string $slug = null;
#[Assert\NotBlank]
#[Assert\Type(type: Types::STRING)]
#[ORM\Column(type: Types::STRING)]
private ?string $name = null;
#[Assert\Type(type: Types::STRING)]
#[ORM\Column(type: Types::STRING)]
private ?string $code = null;
#[Assert\Type(type: Types::STRING)]
#[ORM\Column(type: Types::STRING, nullable: true)]
private ?string $tradeRegister = null;
#[Assert\Type(type: Types::STRING)]
#[ORM\Column(type: Types::STRING, nullable: true)]
private ?string $taxIdentificationNumber = null;
/** @var CompanyType[] $types */
#[Assert\Count(min: 1)]
#[IsValidEnumArray(enum: CompanyType::class)]
#[ORM\Column(type: SelectableType::NAME, nullable: true, enumType: CompanyType::class)]
private array $types = [];
#[ORM\Column(type: Types::JSON, nullable: true)]
private ?array $servedContinents = [];
#[ORM\Column(type: Types::JSON, nullable: true)]
private ?array $servedCountries = [];
public ?array $serviceArea = [];
#[Assert\NotNull]
#[IsValidEnumArray(enum: CompanyStatus::class)]
#[ORM\Column(type: Types::STRING, enumType: CompanyStatus::class, options: ['default' => 'ACTIVE'])]
private ?CompanyStatus $status = CompanyStatus::ACTIVE;
#[ORM\ManyToOne(targetEntity: Upload::class, cascade: ['persist', 'remove'])]
#[ORM\JoinColumn(name: 'logo_id', referencedColumnName: 'id')]
#[ApiProperty(readableLink: true)]
private ?Upload $logo = null;
/** @var Collection<int, Address> */
#[ORM\OneToMany(mappedBy: 'owner', targetEntity: Address::class, cascade: ['persist', 'remove'])]
private Collection $addresses;
/** @var Collection<int, Upload> */
#[ORM\ManyToMany(targetEntity: Upload::class, cascade: ['persist', 'remove'])]
#[ORM\JoinTable(name: 'company_file_map')]
#[ORM\JoinColumn(name: 'company_id')]
#[ORM\InverseJoinColumn(name: 'file_id')]
private Collection $attachments;
#[ORM\ManyToOne(targetEntity: Company::class, inversedBy: 'subsidiaries')]
#[ORM\JoinColumn(name: 'parent_id', referencedColumnName: 'id')]
private ?Company $parent = null;
#[ORM\OneToMany(mappedBy: 'parent', targetEntity: Company::class)]
private Collection $subsidiaries;
/** @var Collection<int, User> */
#[ORM\OneToMany(mappedBy: 'company', targetEntity: User::class, cascade: ['persist', 'remove'])]
private Collection $users;
public function __construct()
{
$this->addresses = new ArrayCollection();
$this->attachments = new ArrayCollection();
$this->subsidiaries = new ArrayCollection();
$this->users = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(string $slug): self
{
$this->slug = $slug;
return $this;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getCode(): ?string
{
return $this->code;
}
public function setCode(string $code): self
{
$this->code = $code;
return $this;
}
public function getTradeRegister(): ?string
{
return $this->tradeRegister;
}
public function setTradeRegister(?string $tradeRegister): self
{
$this->tradeRegister = $tradeRegister;
return $this;
}
public function getTaxIdentificationNumber(): ?string
{
return $this->taxIdentificationNumber;
}
public function setTaxIdentificationNumber(?string $taxIdentificationNumber): self
{
$this->taxIdentificationNumber = $taxIdentificationNumber;
return $this;
}
public function getTypes(): array
{
return $this->types;
}
public function addType(CompanyType $type): static
{
if (!in_array($type, $this->types)) {
$this->types []= $type;
}
return $this;
}
public function setTypes($types): self
{
$this->types = $types;
return $this;
}
public function removeType(CompanyType $type): static
{
$key = array_search($type, $this->types, true);
if ($key !== false) {
unset($this->types[$key]);
}
return $this;
}
public function getServedContinents(): ?array
{
return $this->servedContinents;
}
public function setServedContinents(?array $servedContinents): self
{
$this->servedContinents = $servedContinents;
return $this;
}
public function getServedCountries(): ?array
{
return $this->servedCountries;
}
public function setServedCountries(?array $servedCountries): self
{
$this->servedCountries = $servedCountries;
return $this;
}
public function getStatus(): ?CompanyStatus
{
return $this->status;
}
public function setStatus(CompanyStatus $status): self
{
$this->status = $status;
return $this;
}
#[ApiProperty(readableLink: true)]
public function getMainAddress(): ?Address
{
$criteria = Criteria::create();
$criteria->andWhere(Criteria::expr()->eq('main', true));
$entities = $this->addresses->matching($criteria);
return (count($entities) && $entities[0] instanceof Address)
? $entities[0]
: null;
}
/** @return Collection<int, Address> */
public function getAddresses(): Collection
{
return $this->addresses;
}
public function addAddress(Address $address): static
{
if (!$this->addresses->contains($address)) {
$this->addresses[] = $address;
$address->setOwner($this);
}
return $this;
}
public function removeAddress(Address $address): static
{
if ($this->addresses->removeElement($address)) {
// set the owning side to null (unless already changed)
if ($address->getOwner() === $this) {
$address->setOwner(null);
}
}
return $this;
}
/**
* @return Collection<int, Upload>
*/
public function getAttachments(): Collection
{
return $this->attachments;
}
public function addAttachment(Upload $attachment): self
{
if (!$this->attachments->contains($attachment)) {
$this->attachments->add($attachment);
}
return $this;
}
public function removeAttachment(Upload $attachment): self
{
$this->attachments->removeElement($attachment);
return $this;
}
public function getParent(): ?self
{
return $this->parent;
}
public function setParent(?self $parent): self
{
$this->parent = $parent;
return $this;
}
/**
* @return Collection<int, Company>
*/
public function getSubsidiaries(): Collection
{
return $this->subsidiaries;
}
public function addSubsidiary(Company $subsidiary): self
{
if (!$this->subsidiaries->contains($subsidiary)) {
$this->subsidiaries->add($subsidiary);
$subsidiary->setParent($this);
}
return $this;
}
public function removeSubsidiary(Company $subsidiary): self
{
if ($this->subsidiaries->removeElement($subsidiary)) {
// set the owning side to null (unless already changed)
if ($subsidiary->getParent() === $this) {
$subsidiary->setParent(null);
}
}
return $this;
}
/**
* @return Collection<int, User>
*/
public function getUsers(): Collection
{
return $this->users;
}
public function addUser(User $user): self
{
if (!$this->users->contains($user)) {
$this->users->add($user);
$user->setCompany($this);
}
return $this;
}
public function removeUser(User $user): self
{
if ($this->subsidiaries->removeElement($user)) {
// set the owning side to null (unless already changed)
if ($user->getCompany() === $this) {
$user->setCompany(null);
}
}
return $this;
}
public function getLogo(): ?Upload
{
return $this->logo;
}
public function setLogo(?Upload $logo): self
{
$this->logo = $logo;
return $this;
}
}