src/Entity/Expediting/ShippingPlan.php line 68

  1. <?php
  2. namespace App\Entity\Expediting;
  3. use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
  4. use ApiPlatform\Metadata\ApiFilter;
  5. use ApiPlatform\Metadata\ApiProperty;
  6. use ApiPlatform\Metadata\ApiResource;
  7. use ApiPlatform\Metadata\Get;
  8. use ApiPlatform\Metadata\GetCollection;
  9. use ApiPlatform\Metadata\Link;
  10. use App\Doctrine\Type\Expediting\ShippingPlanStatus;
  11. use App\Doctrine\Type\Expediting\ShippingSegmentStatus;
  12. use App\Entity\Common as Common;
  13. use App\Entity\Finance\Bill;
  14. use App\Entity\Finance\Invoice;
  15. use App\Entity\Finance\Proforma;
  16. use App\Entity\Finance\BaseQuotation;
  17. use App\Entity\Sales\WorkOrder;
  18. use App\Entity\Scheduler\Task;
  19. use App\Provider\Expediting\ShippingPlansProvider;
  20. use App\Provider\Finance\ShippingPlanQuotationsProvider;
  21. use App\Validator\IsValidEnum\IsValidEnum;
  22. use Doctrine\Common\Collections\ArrayCollection;
  23. use Doctrine\Common\Collections\Collection;
  24. use Doctrine\DBAL\Types\Types;
  25. use Doctrine\ORM\Mapping as ORM;
  26. use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
  27. use Symfony\Component\Uid\Ulid;
  28. use Symfony\Component\Validator\Constraints as Assert;
  29. use Symfony\Component\Validator\Context\ExecutionContextInterface;
  30. #[ORM\Table(name'expediting_shipping_plan')]
  31. #[ORM\Index(columns: ['original_plan_id'], name'expediting_shipping_plan_original_plan_id_idx')]
  32. #[ORM\Index(columns: ['work_order_id'], name'expediting_shipping_plan_work_order_idx')]
  33. #[ORM\Index(columns: ['shipment_id'], name'expediting_shipping_plan_shipment_idx')]
  34. #[ORM\Index(columns: ['created_by'], name'expediting_shipping_plan_created_by_idx')]
  35. #[ORM\Index(columns: ['updated_by'], name'expediting_shipping_plan_updated_by_idx')]
  36. #[ORM\UniqueConstraint(name'expediting_shipping_plan_original_plan_id_key'columns: ['original_plan_id'])]
  37. #[ORM\UniqueConstraint(name'expediting_shipping_plan_identifier_key'columns: ['identifier'])]
  38. #[ORM\Entity]
  39. #[UniqueEntity(fields: ['identifier'])]
  40. #[ApiResource(
  41.     uriTemplate'/work_orders/{slug}/shipping_plans',
  42.     operations: [
  43.         new GetCollection(providerShippingPlansProvider::class),
  44.     ],
  45.     uriVariables: [
  46.         'slug' => new Link(fromProperty'shippingPlans'fromClassWorkOrder::class),
  47.     ],
  48. )]
  49. #[ApiResource(
  50.     operations: [
  51.         new Get(),
  52.         new GetCollection(order: ['id' => 'DESC'], providerShippingPlanQuotationsProvider::class),
  53.     ],
  54.     routePrefix'/expediting',
  55. )]
  56. #[ApiFilter(SearchFilter::class, properties: [
  57.     'workOrder.reference' => 'ipartial',
  58.     'quotations.payableTo' => 'exact',
  59.     'quotations.status' => 'exact',
  60.     'quotations.type' => 'exact',
  61.     'tasks.status' => 'exact',
  62.     'tasks.type' => 'exact',
  63.     'status' => 'exact',
  64. ])]
  65. class ShippingPlan
  66. {
  67.     use Common\Blameable;
  68.     use Common\Trackable;
  69.     #[ORM\Id]
  70.     #[ORM\GeneratedValue(strategy'IDENTITY')]
  71.     #[ORM\SequenceGenerator(sequenceName'expediting_shipping_plan_id_seq')]
  72.     #[ORM\Column(typeTypes::INTEGER)]
  73.     #[ApiProperty(identifierfalse)]
  74.     private ?int $id null;
  75.     #[Assert\Ulid]
  76.     #[Assert\NotNull]
  77.     #[ORM\Column(type'ulid'uniquetrue)]
  78.     #[ApiProperty(identifiertrue)]
  79.     private ?Ulid $identifier null;
  80.     #[Assert\NotNull]
  81.     #[IsValidEnum(enumShippingPlanStatus::class)]
  82.     #[ORM\Column(typeTypes::STRINGenumTypeShippingPlanStatus::class, options: ['default' => 'DRAFTED'])]
  83.     private ?ShippingPlanStatus $status ShippingPlanStatus::DRAFTED;
  84.     #[ORM\ManyToOne(targetEntityWorkOrder::class, inversedBy'shippingPlans')]
  85.     #[ORM\JoinColumn(name'work_order_id')]
  86.     private ?WorkOrder $workOrder null;
  87.     #[ORM\ManyToOne(targetEntityShipment::class, inversedBy'shippingPlans')]
  88.     #[ORM\JoinColumn(name'shipment_id')]
  89.     private ?Shipment $shipment null;
  90.     /** @var Collection<int, BaseQuotation> */
  91.     #[ORM\OneToMany(mappedBy'shippingPlan'targetEntityBaseQuotation::class)]
  92.     private Collection $quotations;
  93.     /** @var Collection<int, Proforma> */
  94.     #[ORM\OneToMany(mappedBy'shippingPlan'targetEntityProforma::class)]
  95.     private Collection $proformas;
  96.     #[Assert\Type(typeShippingPlan::class)]
  97.     #[ORM\OneToOne(targetEntityShippingPlan::class)]
  98.     #[ORM\JoinColumn(name'original_plan_id')]
  99.     private ?ShippingPlan $originalPlan null;
  100.     /** @var Collection<int, ShippingSegment> */
  101.     #[ORM\OneToMany(mappedBy'shippingPlan'targetEntityShippingSegment::class, cascade: ['persist''remove'], orphanRemovaltrue)]
  102.     #[ORM\OrderBy(['id' => 'ASC'])]
  103.     #[ApiProperty(readableLinktrue)]
  104.     private Collection $shippingSegments;
  105.     /** @var Collection<int, Task> */
  106.     #[ORM\ManyToMany(targetEntityTask::class, mappedBy'shippingPlans')]
  107.     private Collection $tasks;
  108.     #[Assert\Callback]
  109.     public function validate(ExecutionContextInterface $context$payload): void
  110.     {
  111.         if (empty($this->workOrder) && empty($this->shipment)) {
  112.             $context->buildViolation('Shipping plan must be associated only with either, a work order, or a shipment')
  113.                 ->atPath('workOrder')
  114.                 ->addViolation();
  115.             $context->buildViolation('Shipping plan must be associated only with either, a work order, or a shipment')
  116.                 ->atPath('shipment')
  117.                 ->addViolation();
  118.         }
  119.     }
  120.     public function __construct()
  121.     {
  122.         $this->identifier = new Ulid();
  123.         $this->proformas = new ArrayCollection();
  124.         $this->quotations = new ArrayCollection();
  125.         $this->shippingSegments = new ArrayCollection();
  126.         $this->tasks = new ArrayCollection();
  127.     }
  128.     public function getId(): ?int
  129.     {
  130.         return $this->id;
  131.     }
  132.     public function getIdentifier(): ?Ulid
  133.     {
  134.         return $this->identifier;
  135.     }
  136.     public function setIdentifier(Ulid $identifier): self
  137.     {
  138.         $this->identifier $identifier;
  139.         return $this;
  140.     }
  141.     public function getStatus(): ?ShippingPlanStatus
  142.     {
  143.         return $this->status;
  144.     }
  145.     public function setStatus(?ShippingPlanStatus $status): self
  146.     {
  147.         $this->status $status;
  148.         return $this;
  149.     }
  150.     public function getWorkOrder(): ?WorkOrder
  151.     {
  152.         return $this->workOrder;
  153.     }
  154.     public function setWorkOrder(?WorkOrder $workOrder): static
  155.     {
  156.         $this->workOrder $workOrder;
  157.         return $this;
  158.     }
  159.     public function getShipment(): ?Shipment
  160.     {
  161.         return $this->shipment;
  162.     }
  163.     public function setShipment(?Shipment $shipment): static
  164.     {
  165.         $this->shipment $shipment;
  166.         return $this;
  167.     }
  168.     /**
  169.      * @return Collection<int, Package>
  170.      */
  171.     public function getPackages(): Collection
  172.     {
  173.         return (null !== $this->workOrder)
  174.             ? $this->workOrder->getPackages()
  175.             : $this->shipment->getPackages();
  176.     }
  177.     public function getOriginalPlan(): ?self
  178.     {
  179.         return $this->originalPlan;
  180.     }
  181.     public function setOriginalPlan(?self $originalPlan): self
  182.     {
  183.         $this->originalPlan $originalPlan;
  184.         return $this;
  185.     }
  186.     /**
  187.      * @return Collection<int, ShippingSegment>
  188.      */
  189.     public function getShippingSegments(): Collection
  190.     {
  191.         return $this->shippingSegments;
  192.     }
  193.     public function getCurrentSegment(): ?ShippingSegment
  194.     {
  195.         if (!in_array($this->status, [ShippingPlanStatus::DRAFTEDShippingPlanStatus::QUOTEDShippingPlanStatus::APPROVED])) {
  196.             return null;
  197.         }
  198.         foreach ($this->shippingSegments as $segment) {
  199.             if (in_array($segment->getStatus(), [ShippingSegmentStatus::COMPLETEDShippingPlanStatus::CANCELED])) {
  200.                 continue;
  201.             }
  202.             return $segment;
  203.         }
  204.         return null;
  205.     }
  206.     public function addShippingSegment(ShippingSegment $shippingSegment): self
  207.     {
  208.         if (!$this->shippingSegments->contains($shippingSegment)) {
  209.             $this->shippingSegments->add($shippingSegment);
  210.             $shippingSegment->setShippingPlan($this);
  211.         }
  212.         return $this;
  213.     }
  214.     public function removeShippingSegment(ShippingSegment $shippingSegment): self
  215.     {
  216.         if ($this->shippingSegments->removeElement($shippingSegment)) {
  217.             // set the owning side to null (unless already changed)
  218.             if ($shippingSegment->getShippingPlan() === $this) {
  219.                 $shippingSegment->setShippingPlan(null);
  220.             }
  221.         }
  222.         return $this;
  223.     }
  224.     /**
  225.      * @return Collection<int, BaseQuotation>
  226.      */
  227.     public function getQuotations(): Collection
  228.     {
  229.         $quotations = new ArrayCollection();
  230.         foreach ($this->quotations as $entity) {
  231.             if (!$entity instanceof Bill) {
  232.                 $quotations->add($entity);
  233.             }
  234.         }
  235.         return $quotations;
  236.     }
  237.     public function addQuotation(BaseQuotation $quotation): self
  238.     {
  239.         if (!$this->quotations->contains($quotation)) {
  240.             $this->quotations->add($quotation);
  241.             $quotation->setShippingPlan($this);
  242.         }
  243.         return $this;
  244.     }
  245.     public function removeQuotation(BaseQuotation $quotation): self
  246.     {
  247.         if ($this->quotations->removeElement($quotation)) {
  248.             // set the owning side to null (unless already changed)
  249.             if ($quotation->getShippingPlan() === $this) {
  250.                 $quotation->setShippingPlan(null);
  251.             }
  252.         }
  253.         return $this;
  254.     }
  255.     /**
  256.      * @return Collection<int, Bill>
  257.      */
  258.     public function getBills(): Collection
  259.     {
  260.         $bills = new ArrayCollection();
  261.         foreach ($this->quotations as $entity) {
  262.             if ($entity instanceof Bill) {
  263.                 $bills->add($entity);
  264.             }
  265.         }
  266.         return $bills;
  267.     }
  268.     public function addBill(Bill $bill): self
  269.     {
  270.         if (!$this->quotations->contains($bill)) {
  271.             $this->quotations->add($bill);
  272.             $bill->setShippingPlan($this);
  273.         }
  274.         return $this;
  275.     }
  276.     public function removeBill(Bill $bill): self
  277.     {
  278.         if ($this->quotations->removeElement($bill)) {
  279.             // set the owning side to null (unless already changed)
  280.             if ($bill->getShippingPlan() === $this) {
  281.                 $bill->setShippingPlan(null);
  282.             }
  283.         }
  284.         return $this;
  285.     }
  286.     /**
  287.      * @return Collection<int, Proforma>
  288.      */
  289.     public function getProformas(): Collection
  290.     {
  291.         $proformas = new ArrayCollection();
  292.         foreach ($this->proformas as $entity) {
  293.             if (!$entity instanceof Invoice) {
  294.                 $proformas->add($entity);
  295.             }
  296.         }
  297.         return $proformas;
  298.     }
  299.     public function addProforma(Proforma $proforma): self
  300.     {
  301.         if (!$this->proformas->contains($proforma)) {
  302.             $this->proformas->add($proforma);
  303.             $proforma->setShippingPlan($this);
  304.         }
  305.         return $this;
  306.     }
  307.     public function removeProforma(Proforma $proforma): self
  308.     {
  309.         if ($this->proformas->removeElement($proforma)) {
  310.             // set the owning side to null (unless already changed)
  311.             if ($proforma->getShippingPlan() === $this) {
  312.                 $proforma->setShippingPlan(null);
  313.             }
  314.         }
  315.         return $this;
  316.     }
  317.     /**
  318.      * @return Collection<int, Bill>
  319.      */
  320.     public function getInvoices(): Collection
  321.     {
  322.         $invoices = new ArrayCollection();
  323.         foreach ($this->proformas as $entity) {
  324.             if ($entity instanceof Bill) {
  325.                 $invoices->add($entity);
  326.             }
  327.         }
  328.         return $invoices;
  329.     }
  330.     public function addInvoice(Invoice $invoice): self
  331.     {
  332.         if (!$this->proformas->contains($invoice)) {
  333.             $this->proformas->add($invoice);
  334.             $invoice->setShippingPlan($this);
  335.         }
  336.         return $this;
  337.     }
  338.     public function removeInvoice(Invoice $invoice): self
  339.     {
  340.         if ($this->proformas->removeElement($invoice)) {
  341.             // set the owning side to null (unless already changed)
  342.             if ($invoice->getShippingPlan() === $this) {
  343.                 $invoice->setShippingPlan(null);
  344.             }
  345.         }
  346.         return $this;
  347.     }
  348.     /**
  349.      * @return Collection<int, Task>
  350.      */
  351.     public function getTasks(): Collection
  352.     {
  353.         return $this->tasks;
  354.     }
  355.     public function addTask(Task $task): self
  356.     {
  357.         if (!$this->tasks->contains($task)) {
  358.             $this->tasks[] = $task;
  359.             $task->addShippingPlan($this);
  360.         }
  361.         return $this;
  362.     }
  363.     public function removeTask(Task $task): self
  364.     {
  365.         if ($this->tasks->removeElement($task)) {
  366.             $task->removeShippingPlan($this);
  367.         }
  368.         return $this;
  369.     }
  370. }