src/Entity/TaskFulfillmentStage.php line 44

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Repository\TaskFulfillmentStageRepository;
  4. use Doctrine\ORM\Mapping as ORM;
  5. use Symfony\Component\Serializer\Annotation\Groups;
  6. /**
  7.  * Uretim asamasi (Produktionsstatus) — TODO #109.
  8.  *
  9.  * Bir task'in uretim hattindaki yerini anlatan siralı liste (Auftragseingang →
  10.  * ... → Montagebereit). Asamayi SERVIS tarafi (icraci) secer, ERP salt-okur —
  11.  * modulun K5 kuralinin devami.
  12.  *
  13.  * NEDEN ENUM DEGIL TABLO (kullanici karari 2026-08-19): asama bir OZELLIK
  14.  * tasiyor (`is_start_stage` / `is_completion_stage`). ENUM degeri ozellik
  15.  * tasiyamaz. Ayrica liste zamanla degisecek — yeni asama eklenebilir, biri
  16.  * emekli edilebilir; bunun icin kod degisikligi/migration gerekmemeli.
  17.  *
  18.  * ETIKET BURADA TUTULUR, CEVIRI KATALOGUNDA DEGIL — ve bu bir eksiklik degil,
  19.  * kullanicinin karari (2026-08-19): asamalari sisteme koyan kisi KENDI dilinde
  20.  * yazar (Alman firma Almanca, Turk firma Turkce) ve o kurulumu kim acarsa acsin
  21.  * ayni metni gorur. Cok dilli karsilik ARANMIYOR. Teknik olarak da zorunlu:
  22.  * katalog derleme zamanina bagli, bu liste calisma zamanina — yarin eklenen bir
  23.  * asamanin katalogda karsiligi olamaz.
  24.  *
  25.  * 🪤 SILME YASAK — EMEKLILIK VAR (kullanici karari 2026-08-19). Bir asama bir
  26.  * task'a bagliysa SILINMEZ; yalnizca `active = false` yapilir. Boylece listede
  27.  * gorunmez ama gecmisteki task'lar hala ona baglidir ve etiketleri okunur.
  28.  *
  29.  * Bu kural yorumda BIRAKILMADI: `ProjectOrderTasks::$fulfillment_stage` ve
  30.  * gunluk kayitlari bu tabloya FK ile baglanir ve `onDelete` VERILMEZ —
  31.  * Doctrine varsayilani RESTRICT oldugu icin bagli bir satiri DB'nin kendisi
  32.  * sildirmez. Kurali kodu okumayan da ihlal edemez.
  33.  *
  34.  * Onceki tasarimda task kodu STRING olarak tutuyordu (gerekce: "asama silinirse
  35.  * gecmis bozulmasin"). Silme iptal edilince o gerekce dustu, geriye yalnizca
  36.  * kod ile etiketi senkron tutma zorunlulugu — yani tutarsizlik riski — kaldi.
  37.  *
  38.  * @ORM\Entity(repositoryClass=TaskFulfillmentStageRepository::class)
  39.  * @ORM\Table(name="task_fulfillment_stages")
  40.  */
  41. class TaskFulfillmentStage
  42. {
  43.     /**
  44.      * @ORM\Id
  45.      * @ORM\GeneratedValue
  46.      * @ORM\Column(type="integer")
  47.      * @Groups({
  48.      *     "task_fulfillment_stage@ref",
  49.      *     "task_fulfillment_stage@base",
  50.      *     "task_fulfillment_stage@core"
  51.      * })
  52.      */
  53.     private $id;
  54.     /**
  55.      * Dogal anahtar — task'a KOPYALANAN deger budur. Etiket degisse de anlam
  56.      * kaymasin diye sabit; ikinci kez ayni kod acilmasin diye UNIQUE.
  57.      * @ORM\Column(type="string", length=64, unique=true)
  58.      * @Groups({
  59.      *     "task_fulfillment_stage@base",
  60.      *     "task_fulfillment_stage@core"
  61.      * })
  62.      */
  63.     private $code;
  64.     /**
  65.      * Ekranda gorunen ad (ör. "Montagebereit").
  66.      * @ORM\Column(type="string", length=255)
  67.      * @Groups({
  68.      *     "task_fulfillment_stage@base",
  69.      *     "task_fulfillment_stage@core"
  70.      * })
  71.      */
  72.     private $label;
  73.     /**
  74.      * Listedeki sira. Araya yeni asama girebilsin diye 10'ar artan degerlerle
  75.      * seed edilir (10, 20, 30 …) — aradaki bosluk yeniden numaralandirmayi
  76.      * gereksiz kilar.
  77.      * @ORM\Column(type="integer")
  78.      * @Groups({
  79.      *     "task_fulfillment_stage@base",
  80.      *     "task_fulfillment_stage@core"
  81.      * })
  82.      */
  83.     private $sort_index;
  84.     /**
  85.      * Is BASLADIGINDA (execution published) kullanilacak asama.
  86.      * 🪤 EN FAZLA BIR satirda true — guard servis tarafinda (MySQL'de kosullu
  87.      * unique index yok).
  88.      * @ORM\Column(type="boolean", options={"default": false})
  89.      * @Groups({
  90.      *     "task_fulfillment_stage@core"
  91.      * })
  92.      */
  93.     private $is_start_stage = false;
  94.     /**
  95.      * Task %100'e ulastiginda kullanilacak asama. Bayrakli satir yoksa ekranda
  96.      * genel "Completed" gosterilir.
  97.      * 🪤 EN FAZLA BIR satirda true (yukaridaki ile ayni guard).
  98.      * @ORM\Column(type="boolean", options={"default": false})
  99.      * @Groups({
  100.      *     "task_fulfillment_stage@core"
  101.      * })
  102.      */
  103.     private $is_completion_stage = false;
  104.     /**
  105.      * Rozet ARKA PLAN rengi — `#RRGGBB` (kullanici karari 2026-08-19).
  106.      *
  107.      * Her asamanin rengini YONETICI belirler ve o renk her yerde ayni kalir:
  108.      * pano, yeni gelenler, listeler, ERP kolonu, ERP ozeti. Renk kodda degil
  109.      * VERIDE oldugu icin yeni bir asama eklendiginde kod degisikligi gerekmez.
  110.      *
  111.      * 🪤 METIN RENGI AYRI KOLON DEGIL, HESAPLANIR. Iki kolon (bg + text)
  112.      * koysaydik yonetici koyu zemine koyu yazi secebilir ve rozet okunmaz
  113.      * hale gelirdi — kimse de fark etmezdi. Tek renk aliniyor, yazi rengi
  114.      * zeminin parlakligindan turetiliyor (bkz. FE `okunakliMetinRengi`).
  115.      * Boylece "okunmaz rozet" YAPISAL olarak imkansiz.
  116.      *
  117.      * NULL = tema varsayilani kullanilir; renk zorunlu degil.
  118.      *
  119.      * @ORM\Column(type="string", length=9, nullable=true)
  120.      * @Groups({
  121.      *     "task_fulfillment_stage@base",
  122.      *     "task_fulfillment_stage@core"
  123.      * })
  124.      */
  125.     private $bg_color;
  126.     /**
  127.      * Bu asama HANGI NITELIKTEKI ise ait — gruplama icin (kullanici karari
  128.      * 2026-08-19).
  129.      *
  130.      * NULL = HER task icin gecerli (ortak asamalar).
  131.      * 'production' / 'service' = yalniz o nitelikteki isler icin anlamli.
  132.      *
  133.      * NEDEN AYRI LISTE DEGIL: kullanici tek liste istedi, ayrimi GRUPLAMA ile
  134.      * yapiyoruz. Boylece "Warten auf Verzinkerei" bir servis isinde ayri bir
  135.      * baslik altinda durur, ama liste yonetimi tek yerde kalir.
  136.      *
  137.      * 🪤 SUZME DEGIL GRUPLAMA: yanlis nitelikteki asamayi SECILEMEZ yapmiyoruz.
  138.      * Gercek hayatta servis isi de malzeme bekleyebiliyor; sert filtre koymak
  139.      * kullaniciyi cikmaza sokardi. Ekran gruplar, karari insan verir.
  140.      *
  141.      * 🪤 Tip `task_execution_work_nature` — task'in kendi nitelik kolonuyla AYNI
  142.      * enum. Ikinci bir "nitelik" listesi UYDURULMADI; yoksa iki liste zamanla
  143.      * ayrisirdi ('support' degeri yalniz burada olmaz).
  144.      *
  145.      * @ORM\Column(type="task_execution_work_nature", nullable=true)
  146.      * @Groups({
  147.      *     "task_fulfillment_stage@base",
  148.      *     "task_fulfillment_stage@core"
  149.      * })
  150.      */
  151.     private $work_nature;
  152.     /**
  153.      * Emeklilik anahtari. SILMEK YERINE bunu false yap: satir durdugu icin eski
  154.      * task'larin kodu hala okunabilir bir etikete cevrilebilir, ama listede
  155.      * secilemez.
  156.      * @ORM\Column(type="boolean", options={"default": true})
  157.      * @Groups({
  158.      *     "task_fulfillment_stage@core"
  159.      * })
  160.      */
  161.     private $active = true;
  162.     public function getId(): ?int
  163.     {
  164.         return $this->id;
  165.     }
  166.     public function getCode(): ?string
  167.     {
  168.         return $this->code;
  169.     }
  170.     public function setCode(string $code): self
  171.     {
  172.         $this->code = $code;
  173.         return $this;
  174.     }
  175.     public function getLabel(): ?string
  176.     {
  177.         return $this->label;
  178.     }
  179.     public function setLabel(string $label): self
  180.     {
  181.         $this->label = $label;
  182.         return $this;
  183.     }
  184.     public function getSortIndex(): ?int
  185.     {
  186.         return $this->sort_index;
  187.     }
  188.     public function setSortIndex(int $sort_index): self
  189.     {
  190.         $this->sort_index = $sort_index;
  191.         return $this;
  192.     }
  193.     public function isStartStage(): bool
  194.     {
  195.         return (bool) $this->is_start_stage;
  196.     }
  197.     public function setIsStartStage(bool $is_start_stage): self
  198.     {
  199.         $this->is_start_stage = $is_start_stage;
  200.         return $this;
  201.     }
  202.     public function isCompletionStage(): bool
  203.     {
  204.         return (bool) $this->is_completion_stage;
  205.     }
  206.     public function setIsCompletionStage(bool $is_completion_stage): self
  207.     {
  208.         $this->is_completion_stage = $is_completion_stage;
  209.         return $this;
  210.     }
  211.     public function getBgColor(): ?string
  212.     {
  213.         return $this->bg_color;
  214.     }
  215.     public function setBgColor(?string $bg_color): self
  216.     {
  217.         $this->bg_color = $bg_color;
  218.         return $this;
  219.     }
  220.     public function getWorkNature(): ?string
  221.     {
  222.         return $this->work_nature;
  223.     }
  224.     public function setWorkNature(?string $work_nature): self
  225.     {
  226.         $this->work_nature = $work_nature;
  227.         return $this;
  228.     }
  229.     public function isActive(): bool
  230.     {
  231.         return (bool) $this->active;
  232.     }
  233.     public function setActive(bool $active): self
  234.     {
  235.         $this->active = $active;
  236.         return $this;
  237.     }
  238. }