src/Entity/ProjectOrderExpenses.php line 34

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Repository\ProjectOrderExpensesRepository;
  4. use Doctrine\Common\Collections\ArrayCollection;
  5. use Doctrine\Common\Collections\Collection;
  6. use Doctrine\ORM\Mapping as ORM;
  7. use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
  8. use Symfony\Component\Serializer\Annotation\Groups;
  9. use Symfony\Component\Serializer\Annotation\MaxDepth;
  10. /**
  11.  * TODO Replace Entity Name with Expenses (Too Props)
  12.  * ORM\Entity(repositoryClass=ProjectOrderExpensesRepository::class)
  13.  * @UniqueEntity(
  14.  *     fields={"supplier", "invoice_nr"},
  15.  *     message="This invoice already created, please try another one|This invoice with combination %s %s already created, please try another one"
  16.  * )
  17.  * FULL TEXT SEARCH INDEX SUPPORT
  18.  * @ORM\Entity(repositoryClass=ProjectOrderExpensesRepository::class)
  19.  * @ORM\Table(
  20.  *      name="project_order_expenses",
  21.  *      indexes={
  22.  *          @ORM\Index(name="search_indx", columns={"invoice_nr", "expense_nr"}, flags={"fulltext"})
  23.  *      },
  24.  *     options={"comment": "Replace this table name to expenses"}
  25.  * )
  26.  *
  27.  */
  28. // README annotation info
  29. //
  30. class ProjectOrderExpenses
  31. {
  32.     /**
  33.      * @ORM\Id
  34.      * @ORM\GeneratedValue
  35.      * @ORM\Column(type="integer")
  36.      * 👉project.orders.expense.minify.base.for.position  Expense Position Project ordar'a related oldugu icin bu Positionnun bagli oldugu expense mini bilgileri veriyori, yoksa circular reference olusuyor
  37.      * @Groups({
  38.      *     "project.orders.expense.base",
  39.      *     "project.orders.expense.minify.version",
  40.      *
  41.      *     "expense.core",
  42.      *     "expense:core",
  43.      *
  44.      *     "expense@base",
  45.      *     "expense@core"
  46.      * })
  47.      */
  48.     private $id;
  49.     /**
  50.      * @ORM\ManyToOne(targetEntity=Suppliers::class, inversedBy="projectOrderExpenses")
  51.      * @ORM\JoinColumn(nullable=false)
  52.      * @Groups({
  53.      *      "supplier.base",
  54.      *      "project.orders.expense.minify.version",
  55.      *
  56.      *     "expense.supplier",
  57.      *
  58.      *     "expense@supplier"
  59.      * })
  60.      */
  61.     private $supplier;
  62. //    /**
  63. //     * ❌❌❌❌❌❌ use in positions
  64. //     * @deprecated will remove completelly
  65. //     * ORM\ManyToOne(targetEntity=ProjectOrders::class, inversedBy="projectOrderExpenses")
  66. //     * Groups({
  67. //     *         "project.orders.expense.assigned.order",
  68. //     *
  69. //     *        })
  70. //     */
  71. //    private $project_order;
  72.     /**
  73.      * Tedarikçinin gönderdiği faturanın üzerindeki numara (dışarıdan gelir).
  74.      * supplier + invoice_nr kombinasyonu unique — aynı tedarikçinin aynı faturası sisteme iki kez işlenemez.
  75.      * @ORM\Column(type="string", length=64, nullable=true, unique=true )
  76.      * @ORM\JoinColumn(nullable=true)
  77.      * @Groups({
  78.      *     "project.orders.expense.base",
  79.      *     "expense.core",
  80.      *     "expense:core",
  81.      *
  82.      *     "expense@base",
  83.      *     "expense@core"
  84.      * })
  85.      */
  86.     private $invoice_nr;
  87.     /**
  88.      * @ORM\Column(type="datetime_immutable")
  89.      * @Groups({
  90.      *      "project.orders.expense.base",
  91.      *      "expense.core",
  92.      *      "expense:core",
  93.      *
  94.      *     "expense@base",
  95.      *     "expense@core"
  96.      *  })
  97.      */
  98.     private $created_at;
  99.     /**
  100.      * @MaxDepth(1)
  101.      * "project.orders.expense.minify.version" for count
  102.      * @ORM\OneToMany(targetEntity=ProjectOrderExpensePositions::class, mappedBy="project_order_expense", cascade={"persist", "remove"})
  103.      * @Groups({
  104.      *     "@deprecated_.project.orders.expense.positions",
  105.      *     "expense.positions",
  106.      *     "project.orders.expense.minify.version",
  107.      *     "expense.positions",
  108.      *
  109.      *     "expense@positions"
  110.      * })
  111.      * @ORM\OrderBy({"id": "DESC"})
  112.      */
  113.     private $project_order_expense_positions;
  114.     /**
  115.      * @deprecated ❌❌❌❌❌❌❌ Amount use for older vers. with new use positions amount
  116.      *
  117.      * @ORM\Column(type="decimal", precision=10, scale=2, nullable=true)
  118.      * @Groups({
  119.      *     "project.orders.expense.base"
  120.      * })
  121.      */
  122.     private $amount;
  123.     /**
  124.      * Persisted canonical total of all positions, written on every upsert
  125.      * (ExpenseService::computeExpenseTotal). The list reads this directly —
  126.      * no client-side math. Formula mirrors FE calcPositionLineTotal:
  127.      * per position buying_price>0 ? (unit / PE) * buying_price : amount, plus delivery_amount.
  128.      *
  129.      * @ORM\Column(type="decimal", precision=10, scale=2, nullable=true)
  130.      * @Groups({
  131.      *     "expense@core"
  132.      * })
  133.      */
  134.     private $total;
  135.     /**
  136.      * Multi-pass extraction audit trail (FAZ H). JSON blob written by
  137.      * ExpenseV2Upsert when the expense is created/updated from an AI
  138.      * extraction task. Shape:
  139.      *   { mode, pass_count, confidence, verify_result, hint_used_ids,
  140.      *     new_hint_prompt, timeline: [ { pass, took_ms, verdict, ... } ] }
  141.      * Details dialog + toolbar/context menu read this; visibility guarded
  142.      * against `!= null`.
  143.      *
  144.      * @ORM\Column(type="json", nullable=true)
  145.      * @Groups({
  146.      *     "expense@core"
  147.      * })
  148.      */
  149.     private $ai_extraction_metadata;
  150.     /**
  151.      * @ORM\Column(type="datetime_immutable", nullable=true)
  152.      * @Groups({
  153.      *     "project.orders.expense.base",
  154.      *     "project.orders.expense.minify.version",
  155.      *     "project.orders.expense.position.expense",
  156.      *
  157.      *     "expense.core", "expense:core",
  158.      *
  159.      *
  160.      *     "expense@base",
  161.      *     "expense@core"
  162.      * })
  163.      */
  164.     private $expensed_at;
  165.     /**
  166.      * @ORM\Column(type="string", length=64, nullable=true, unique=true, options={"comment": "Bu bir siparis numarasi bir Proje>Orderlar icin yapilan siparislerin geneli"})
  167.      * @Groups({
  168.      *     "project.orders.expense.base",
  169.      *     "project.orders.expense.minify.version",
  170.      *     "expense.core", "expense:core",
  171.      *     "expense@base",
  172.      *     "expense@core"
  173.      * })
  174.      */
  175.     private $expense_nr;
  176.     /**
  177.      * @ORM\Column(type="string", length=64, nullable=true)
  178.      * @Groups({"expense@core"})
  179.      */
  180.     private $offer_nr;
  181.     /**
  182.      * @ORM\Column(type="datetime_immutable", nullable=true)
  183.      * @Groups({"expense@core"})
  184.      */
  185.     private $offer_at;
  186.     /**
  187.      * @ORM\Column(type="datetime_immutable", nullable=true)
  188.      * @Groups({"expense@core"})
  189.      */
  190.     private $delivery_due_at;
  191.     /**
  192.      * @ORM\ManyToOne(targetEntity=Locations::class)
  193.      * @ORM\JoinColumn(nullable=true)
  194.      * @Groups({"expense@deliver_location"})
  195.      */
  196.     private $deliver_location;
  197.     /**
  198.      * @ORM\Column(type="text", nullable=true)
  199.      * @Groups({
  200.      *     "project.orders.expense.base",
  201.      *
  202.      *     "expense.core", "expense:core",
  203.      *
  204.      *     "expense@base",
  205.      *     "expense@core"
  206.      * })
  207.      */
  208.     private $comment;
  209.     /**
  210.      * @deprecated use documents as json
  211.      * TODO Replace with json and the name Documents!!!
  212.      * @ORM\Column(type="text", nullable=true)
  213.      * @Groups({
  214.      *     "project.orders.expense.base",
  215.      *     "project.orders.expense.minify.version",
  216.      *
  217.      *     "expense.core", "expense:core",
  218.      *
  219.      *     "expense@core"
  220.      * })
  221.      */
  222.     private $document;
  223.     /**
  224.      * TODO Replace with json and the name Documents!!!
  225.      * @ORM\Column(type="json", nullable=true)
  226.      * @Groups({
  227.      *     "expense@core"
  228.      * })
  229.      */
  230.     private $documents;
  231.     /**
  232.      * ORM\OneToOne(targetEntity=PurchaseRequest::class, mappedBy="expense", cascade={"persist", "remove"})
  233.      * @ORM\ManyToOne(targetEntity=PurchaseRequest::class, inversedBy="expense", cascade={"persist", "remove"})
  234.      * @ORM\JoinColumn(nullable=true, onDelete="CASCADE")
  235.      * @Groups({
  236.      *      "expense:purchse_request",
  237.      *
  238.      *
  239.      *      "expense@purchse_request"
  240.      *  })
  241.      */
  242.     private $purchase_request;
  243.     public function __construct()
  244.     {
  245.         $this->project_order_expense_positions = new ArrayCollection();
  246.     }
  247.     public function getId(): ?int
  248.     {
  249.         return $this->id;
  250.     }
  251.     public function getSupplier(): ?Suppliers
  252.     {
  253.         return $this->supplier;
  254.     }
  255.     public function setSupplier(?Suppliers $supplier): self
  256.     {
  257.         $this->supplier $supplier;
  258.         return $this;
  259.     }
  260. //    public function getProjectOrder(): ?ProjectOrders
  261. //    {
  262. //        return $this->project_order;
  263. //    }
  264. //
  265. //    public function setProjectOrder(?ProjectOrders $project_order): self
  266. //    {
  267. //        $this->project_order = $project_order;
  268. //
  269. //        return $this;
  270. //    }
  271.     public function getInvoiceNr(): ?string
  272.     {
  273.         return $this->invoice_nr;
  274.     }
  275.     public function setInvoiceNr(?string $invoice_nr): self
  276.     {
  277.         $this->invoice_nr $invoice_nr;
  278.         return $this;
  279.     }
  280.     public function getCreatedAt(): ?\DateTimeImmutable
  281.     {
  282.         return $this->created_at;
  283.     }
  284.     public function setCreatedAt(\DateTimeImmutable $created_at): self
  285.     {
  286.         $this->created_at $created_at;
  287.         return $this;
  288.     }
  289.     /**
  290.      * @return Collection<int, ProjectOrderExpensePositions>
  291.      */
  292.     public function getProjectOrderExpensePositions(): Collection
  293.     {
  294.         return $this->project_order_expense_positions;
  295.     }
  296.     public function addProjectOrderExpensePosition(ProjectOrderExpensePositions $projectOrderExpensePosition): self
  297.     {
  298.         if (!$this->project_order_expense_positions->contains($projectOrderExpensePosition)) {
  299.             $this->project_order_expense_positions[] = $projectOrderExpensePosition;
  300.             $projectOrderExpensePosition->setProjectOrderExpense($this);
  301.         }
  302.         return $this;
  303.     }
  304.     public function removeProjectOrderExpensePosition(ProjectOrderExpensePositions $projectOrderExpensePosition): self
  305.     {
  306.         if ($this->project_order_expense_positions->removeElement($projectOrderExpensePosition)) {
  307.             // set the owning side to null (unless already changed)
  308.             if ($projectOrderExpensePosition->getProjectOrderExpense() === $this) {
  309.                 $projectOrderExpensePosition->setProjectOrderExpense(null);
  310.             }
  311.         }
  312.         return $this;
  313.     }
  314.     public function getAmount(): ?string
  315.     {
  316.         return $this->amount;
  317.     }
  318.     public function setAmount(?string $amount): self
  319.     {
  320.         $this->amount $amount;
  321.         return $this;
  322.     }
  323.     public function getTotal(): ?string
  324.     {
  325.         return $this->total;
  326.     }
  327.     public function setTotal(?string $total): self
  328.     {
  329.         $this->total $total;
  330.         return $this;
  331.     }
  332.     public function getAiExtractionMetadata(): ?array
  333.     {
  334.         return $this->ai_extraction_metadata;
  335.     }
  336.     public function setAiExtractionMetadata(?array $ai_extraction_metadata): self
  337.     {
  338.         $this->ai_extraction_metadata $ai_extraction_metadata;
  339.         return $this;
  340.     }
  341.     public function getExpensedAt(): ?\DateTimeImmutable
  342.     {
  343.         return $this->expensed_at;
  344.     }
  345.     public function setExpensedAt(?\DateTimeImmutable $expensed_at): self
  346.     {
  347.         $this->expensed_at $expensed_at;
  348.         return $this;
  349.     }
  350.     public function getExpenseNr(): ?string
  351.     {
  352.         return $this->expense_nr;
  353.     }
  354.     public function setExpenseNr(?string $expense_nr): self
  355.     {
  356.         $this->expense_nr $expense_nr;
  357.         return $this;
  358.     }
  359.     public function getOfferNr(): ?string
  360.     {
  361.         return $this->offer_nr;
  362.     }
  363.     public function setOfferNr(?string $offer_nr): self
  364.     {
  365.         $this->offer_nr $offer_nr;
  366.         return $this;
  367.     }
  368.     public function getOfferAt(): ?\DateTimeImmutable
  369.     {
  370.         return $this->offer_at;
  371.     }
  372.     public function setOfferAt(?\DateTimeImmutable $offer_at): self
  373.     {
  374.         $this->offer_at $offer_at;
  375.         return $this;
  376.     }
  377.     public function getComment(): ?string
  378.     {
  379.         return $this->comment;
  380.     }
  381.     public function setComment(?string $comment): self
  382.     {
  383.         $this->comment $comment;
  384.         return $this;
  385.     }
  386.     /**
  387.      * TODO remove this forever
  388.      * @deprecated use documents as json
  389.      */
  390.     public function getDocument(): ?string
  391.     {
  392.         return $this->document;
  393.     }
  394.     /**
  395.      * TODO remove this forever
  396.      * @deprecated use documents as json
  397.      */
  398.     public function setDocument(?string $document): self
  399.     {
  400.         $this->document $document;
  401.         return $this;
  402.     }
  403.     public function getDocuments(): ?array { return $this->documents; }
  404.     public function setDocuments(?array $documents): self $this->documents $documents; return $this;}
  405.     public function getDeliveryDueAt(): ?\DateTimeImmutable
  406.     {
  407.         return $this->delivery_due_at;
  408.     }
  409.     public function setDeliveryDueAt(?\DateTimeImmutable $delivery_due_at): self
  410.     {
  411.         $this->delivery_due_at $delivery_due_at;
  412.         return $this;
  413.     }
  414.     public function getDeliverLocation(): ?Locations
  415.     {
  416.         return $this->deliver_location;
  417.     }
  418.     public function setDeliverLocation(?Locations $deliver_location): self
  419.     {
  420.         $this->deliver_location $deliver_location;
  421.         return $this;
  422.     }
  423.     public function getPurchaseRequest(): ?PurchaseRequest
  424.     {
  425.         return $this->purchase_request;
  426.     }
  427.     public function setPurchaseRequest(?PurchaseRequest $purchase_request): self
  428.     {
  429.         $this->purchase_request $purchase_request;
  430.         return $this;
  431.     }
  432. }