sozsoft-platform/configs/seeds/docs/modules/App.Inventory.md
2026-10-08 01:07:28 +03:00

643 lines
57 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Envanter (`App.Inventory`)
> Menünün altındaki her dal bu dosyada bir bölümdür (`module-doc:section`); dosya ve bölümler ilk deploy'da otomatik açılır. `module-doc:todo` işaretli alt bölümleri modülü üreten kişi ya da AI doldurur (`lowcode.instructions.md` §0.13); MCP ile üretimde talep bu bölümler doldurulmadan Testing'e alınamaz. "Ek — Ekran envanteri" bölümü wizard dosyalarından üretilir, elle düzenlenmez.
<!-- module-doc:section App.Inventory.Definitions -->
## Tanımlamalar (`App.Inventory.Definitions`)
### 1. Amaç ve kapsam
Envanter ve üretimin ana verisi: ürün kartı (satış/masraf/satınalma bayrakları, mal/hizmet, envanter takibi ve yöntemi, nitelik–varyant, tedarikçi fiyatları, stok ve muhasebe bilgileri), ölçü birimine bağlı reçeteler (bileşen + operasyon; ürün ya da varyant bazında), iş merkezleri, operasyonlar ve çok seviyeli reçete patlatma raporu. Kullanıcılar: stok, satınalma ve üretim planlama ekipleri. Stok hareketi, sipariş ve üretim emri bu dalın kapsamı dışındadır.
### 2. Analiz ve kararlar
Onaylanan analiz (talep "Inventory -> Tanımlamalar"):
- Menü `Envanter › Tanımlamalar`; ara menü kodu `App.Inventory.Definitions` (Satınalmadaki `App.Prc.Definitions` kalıbı).
- Görsellerdeki Kategori ve Etiket alanları için Ürün Kategorileri ve İş Merkezi Etiketleri tanım ekranları eklendi.
- Ürün Türü yalnız Mal / Hizmet; Kombo yok. BoM Türü alanı yok (talep).
- Vergiler oran (varsayılan %20), muhasebe hesapları serbest metin kod olarak tutulur (onaylı).
- Varyantlar kalıcı tabloda tutulmaz: `VariantKey` = seçili nitelik değeri Id'lerinin, nitelik adı sırasıyla `|` birleşimi; aynı kombinasyon hep aynı anahtarı üretir. "Varyant Oluşturma = Asla" olan nitelik kartezyene girmez, Hemen/Dinamik aynı davranır (onaylı).
- Haftalık çalışma saati ayardan (`%WeeklyWorkingTimeLimit%`) okunur, yoksa 40 (onaylı).
- Reçete patlatmada alt reçete: önce bileşenin varyantına özel, yoksa genel; birden fazlaysa en eski oluşturulan.
Üretimde verilen ek kararlar:
- Query kaynağı türetilmiş tabloya (`FROM (…) AS "Q"`) sarıldığı için özyinelemeli CTE kullanılamaz. Varyant kartezyeni ürün başına en fazla **5 nitelik**, reçete patlatma en fazla **4 bileşen seviyesi** ile sabit derinlikli birleşimlerle kuruldu; derinlik sınırı döngü korumasıdır.
- Genel Bakış'ta kök reçete satırının maliyeti boştur; maliyetler bileşen ve operasyon satırlarındadır.
### 3. Menü ve ekranlar
`Envanter (App.Inventory) › Tanımlamalar (App.Inventory.Definitions)` altında sırasıyla: Ürün Kategorileri, Nitelikler, İş Merkezi Etiketleri, İş Merkezleri, Operasyonlar, Ürün Varyantları, Reçeteye Genel Bakış, Reçeteler, Ürünler.
Sekmeler (menüsüz alt formlar):
- Nitelikler › Nitelik Değerleri
- İş Merkezleri › Genel Bilgi (aynı satır), Ürün Kapasitesi
- Operasyonlar › Açıklamalar
- Reçeteler › Bileşenler, Operasyonlar, Diğer (aynı satır), Genel Bakış (menülü, Tree)
- Ürünler › Genel Bilgi, Stok, Muhasebe (aynı satır), Nitelik & Varyantlar, Varyantlar (menülü, salt okunur), Satınalma, Reçeteler (menülü)
### 4. Veri modeli
Tüm tablolar kiracı + tam audit + soft delete, anahtar `Id uniqueidentifier`. Birim kolonları `nvarchar(64)` → `Adm_T_Uom.Id`; tedarikçi → `Adm_T_Contact`; para birimi → `Sas_H_Currency`; menşe → `Sas_H_Country`; sorumlu → `AbpUsers`.
| Tablo | İçerik |
| --- | --- |
| `Inv_T_ProductCategory` | Ad, üst kategori, aktif |
| `Inv_T_Attribute` / `Inv_T_AttributeValue` | Nitelik (görünüm türü, varyant oluşturma) ve değerleri (serbest metin, ekstra fiyat, renk, sıra) |
| `Inv_T_WorkCenterTag` | Etiket adı, renk |
| `Inv_T_WorkCenter` | Ad, kod, etiketler (`|` Id), alternatif iş merkezleri (`|` Id), haftalık saat, verimlilik, OEE, kurulum/temizlik, saatlik maliyetler |
| `Inv_T_WorkCenterCapacity` | İş merkezi × ürün kapasitesi |
| `Inv_T_Operation` / `Inv_T_OperationInstruction` | Operasyon (iş merkezi, varsayılan süre, varyantlara uygula) ve talimatları |
| `Inv_T_Product` | Ürün kartı ve Genel Bilgi/Stok/Muhasebe sekmelerinin alanları |
| `Inv_T_ProductAttributeLine` | Ürün × nitelik, `ValueIds` (`|` ayrımlı değer Id) |
| `Inv_T_ProductSupplier` | Tedarikçi, min. miktar, birim, fiyat, kur, teslim süresi, varyant |
| `Inv_T_Bom` / `Inv_T_BomComponent` / `Inv_T_BomOperation` | Reçete başlığı (ürün, varyant, miktar, birim, planlama), bileşenler (operasyona bağlanabilir), operasyonlar (iş merkezi, süre) |
### 5. İş kuralları ve hesaplar
- **Varyant satış fiyatı** = ürün satış fiyatı + seçili değerlerin ekstra fiyatları toplamı.
- **Genel Bakış miktarı:** seviye k bileşen miktarı = üst miktar × bileşen miktarı ÷ alt reçete miktarı.
- **Genel Bakış maliyeti:** bileşen maliyeti = miktar × ürün maliyeti. Operasyon süresi aynı oranla ölçeklenir; maliyet = süre ÷ 60 × iş merkezi saatlik maliyeti. Operasyonlar her seviyede "Operasyonlar" düğümünde toplanır.
- **Ürün formu:** Hizmet seçilince envanter takibi kapanır ve kilitlenir. Takip yöntemi yalnız takip açıkken girilir; takip açılınca "Miktara göre" gelir. Satınalma birimi boşsa birimi izler.
- **Reçete bileşeni:** ürün seçilince birim üründen dolar.
- **Reçete operasyonu:** operasyon seçilince iş merkezi ve varsayılan süre dolar.
- **Çoklu değer alanları** (`dxTagBox`) `|` ile ayrılmış metin kolonunda saklanır.
### 6. Yetki ve görünürlük
İzin grubu `App.Inventory`. Her ekranın okuma yetkisi `App.Inventory.Definitions` altında; alt formların yetkisi bağlı oldukları listenin altındadır. Her listede `.Create/.Update/.Delete/.Export/.Import/.Note`. Yetkiler hiçbir role otomatik verilmez. Yeni sekmelerin yetkisi role verilmeden sekmeler boş görünür. Tüm ekranlar kiracı filtrelidir.
### 7. Entegrasyonlar
Dış entegrasyon yok. Ölçü Birimleri, Kontaklar, Para Birimleri, Ülkeler ve Kullanıcılar yalnız lookup kaynağıdır. Satış ve satınalma sipariş ekranları ürünü `CanBeSold` / `CanBePurchased` ile süzecek; bu dalda sipariş ekranı yoktur.
### 8. Akış örneği
1. Nitelikler'de renk (kırmızı, mavi), malzeme (çelik, tahta), boyut (40x40, 80x100, 10x30) değerlerini gir.
2. İş Merkezleri'nde "ram makinası"nın saatlik maliyetini gir.
3. Operasyonlar'da "Apre"yi ram makinası, 60 dk olarak tanımla.
4. Ürünler'de "(40X40mm) Mamül Sepeti Üst Geçme Kepi" › Nitelik & Varyantlar sekmesine üç niteliği ekle. Varyantlar sekmesinde 12 kombinasyon görünür.
5. Reçeteler'de kep için 1 Adet reçete aç. Bileşenler'e 20 Adet AUTONİCS PR12-4DN Sensör, Operasyonlar'a Apre ekle.
6. Genel Bakış sekmesi ağacı ve maliyetleri gösterir.
### 9. Sık sorulanlar
- **Varyant neden kayboldu?** Nitelik satırından değer ya da nitelik silinirse kombinasyon ve anahtarı değişir. O varyantı kullanan reçete ve tedarikçi satırlarının varyantı yeniden seçilmelidir.
- **Genel Bakış'ta alt seviye görünmüyor?** Bileşenin aktif ve miktarı > 0 bir reçetesi olmalıdır. 4 seviyeden derin yapılar gösterilmez.
- **Kaç nitelik desteklenir?** Ürün başına 5. Fazlası varyant listesine katılmaz.
- **Form açılınca Aktif kutusu boş geliyor?** Form varsayılanları wizard deploy'unda yazılamadı (bkz. 10). Kayıtta kutu işaretlenmelidir; tablo varsayılanları yalnızca alan gönderilmezse uygulanır.
### 10. Dosyalar ve geri alma
- **Tablolar:** `sql/object/Inv_T_*.sql` (14 tablo).
- **Wizard'lar:** ProductCategory, Attribute, AttributeValue, WorkCenterTag, WorkCenter, WorkCenterGeneral, WorkCenterCapacity, Operation, OperationInstruction, ProductVariant, BomOverview, Bom, BomComponent, BomOperation, BomOther, Product, ProductGeneral, ProductAttributeLine, ProductSupplier, ProductStock, ProductAccounting (`.json`).
- **Demo veri aynaları:** `data/App.Inventory.{ProductCategory,Attribute,WorkCenterTag,WorkCenter,Product}.json`.
- **Geri alma:** Wizard Manager'da ana ekranlar (Product, Bom, WorkCenter, Operation, Attribute) önce, alt formları sonra silinir. Tablolar ancak açık onayla `dropTables` ile düşürülür.
- **Sorgu bağımlılığı:** Sorgular SQL Server'a özgüdür (`STRING_SPLIT`, `CONCAT_WS`, `STRING_AGG`, `CROSS APPLY`).
- **Açık nokta:** Form varsayılanları (Aktif = true, Birim = Adet, Miktar = 1, Süre = 60, Kur = TRY) düz wizard biçimiyle dosyaya yazılmadı. ListForm düzenleyicisinden ya da `ListForm` bölümlü yeniden deploy ile eklenmelidir.
<!-- module-doc:auto:begin -->
## Ek — Ekran envanteri (otomatik)
> Wizard dosyalarından üretilir; deploy, silme, tasarımcı kaydı ve import'ta yenilenir. Elle düzenleme bir sonraki yenilemede kaybolur.
### Tanımlamalar (`App.Inventory.Definitions`)
#### Ürün Kategorileri — `App.Inventory.ProductCategory`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/ProductCategory.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.ProductCategory` (sıra 1) |
| Yetki | `App.Inventory.ProductCategory` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Ürün Kategorileri — ürünleri raporlama, filtreleme ve varsayılan muhasebe için gruplar (ör. Elektrik ve Elektronik Malzemeler, Mamuller). |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_ProductCategory` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Widget'lar | `App.Widget.Total`, `App.Widget.Active`, `App.Widget.Passive` |
| Veri aynası | `data/App.Inventory.ProductCategory.json` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `Name` | Ad | dxTextBox | ✓ | ✓ | |
| `ParentId` | Üst Kategori | dxSelectBox | | ✓ | sorgu: Inv_T_ProductCategory |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
#### Nitelikler — `App.Inventory.Attribute`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Attribute.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.Attribute` (sıra 2) |
| Yetki | `App.Inventory.Attribute` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Nitelikler — varyant oluşturan ürün özellikleri (renk, malzeme, boyut). |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_Attribute` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Inventory.AttributeValue` (Id → AttributeId) |
| Widget'lar | `App.Widget.Total`, `App.Widget.Active`, `App.Widget.Passive` |
| Veri aynası | `data/App.Inventory.Attribute.json` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `Name` | Nitelik Adı | dxTextBox | ✓ | ✓ | |
| `DisplayType` | Görünüm Türü | dxRadioGroup | ✓ | ✓ | liste: Radio, Pills, Select, Color, Multi, Image |
| `VariantCreation` | Varyant Oluşturma | dxRadioGroup | ✓ | ✓ | liste: Always, Dynamic, Never |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
#### İş Merkezi Etiketleri — `App.Inventory.WorkCenterTag`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/WorkCenterTag.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.WorkCenterTag` (sıra 3) |
| Yetki | `App.Inventory.WorkCenterTag` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | İş Merkezi Etiketleri — iş merkezlerini sınıflandırmak için kullanılan etiketler (boyahane, apre, montaj…). |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_WorkCenterTag` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Widget'lar | `App.Widget.Total`, `App.Widget.Active`, `App.Widget.Passive` |
| Veri aynası | `data/App.Inventory.WorkCenterTag.json` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `Name` | Ad | dxTextBox | ✓ | ✓ | |
| `Color` | Renk | dxColorBox | | ✓ | |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
#### İş Merkezleri — `App.Inventory.WorkCenter`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/WorkCenter.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.WorkCenter` (sıra 4) |
| Yetki | `App.Inventory.WorkCenter` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | İş Merkezleri — operasyonların yapıldığı makine ya da istasyonlar (ör. ram makinası). |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_WorkCenter` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Inventory.WorkCenterGeneral` (Id → Id), `App.Inventory.WorkCenterCapacity` (Id → WorkCenterId) |
| Widget'lar | `App.Widget.Total`, `App.Widget.Active`, `App.Widget.Passive` |
| Form varsayılanları | IsActive=true |
| Veri aynası | `data/App.Inventory.WorkCenter.json` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `Name` | İş Merkezi Adı | dxTextBox | ✓ | ✓ | |
| `Code` | Kod | dxTextBox | | ✓ | |
| `Tags` | Etiketler | dxTagBox | | ✓ | sorgu: Inv_T_WorkCenterTag |
| `WeeklyWorkingHours` | Çalışma Saatleri (Haftalık) | dxNumberBox | ✓ | ✓ | |
| `AlternativeWorkCenterIds` | Alternatif İş Merkezleri | dxTagBox | | ✓ | sorgu: Inv_T_WorkCenter |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
#### Operasyonlar — `App.Inventory.Operation`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Operation.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.Operation` (sıra 5) |
| Yetki | `App.Inventory.Operation` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Operasyonlar — bir iş merkezinde yapılan üretim adımları (ör. ram makinasında Apre). |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_Operation` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Inventory.OperationInstruction` (Id → OperationId) |
| Widget'lar | `App.Widget.Total`, `App.Widget.Active`, `App.Widget.Passive` |
| Form varsayılanları | IsActive=true |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `Name` | Operasyon Adı | dxTextBox | ✓ | ✓ | |
| `WorkCenterId` | İş Merkezi | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_WorkCenter |
| `DefaultDurationMin` | Varsayılan Süre (dk) | dxNumberBox | ✓ | ✓ | |
| `ApplyOnVariants` | Varyantlara Uygula | dxTagBox | | ✓ | sorgu: Inv_T_AttributeValue |
| `CostBasis` | Maliyete Dayalı | dxRadioGroup | ✓ | ✓ | liste: Actual, Theoretical |
| `DurationMode` | Süre Hesaplama | dxRadioGroup | ✓ | ✓ | liste: Fixed, Computed |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
#### Ürün Varyantları — `App.Inventory.ProductVariant`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/ProductVariant.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.ProductVariant` (sıra 6) |
| Yetki | `App.Inventory.ProductVariant` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Ürün Varyantları — üründe seçilen nitelik değerlerinin her kombinasyonu (ör. kırmızı · çelik · 40x40), salt okunur. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `SELECT CAST(p.Id AS nvarchar(36)) + ':' + CONCAT_WS('\|', l1.VId, l2.VId, l3.VId, l4.VId, l5.VId) AS [Key], p.Id AS ProductId, p.Name AS ProductName, CONCAT_WS('\|', l1.VId, l2.VId, l3.VId, l4.VId, l5.VId) AS VariantKey, CONCAT_WS(', ', l1.VName, l2.VName, l3.VName, l4.VName, l5.VName) AS VariantName, p.InternalReference, CAST(p.SalesPrice + ISNULL(l1.XP, 0) + ISNULL(l2.XP, 0) + ISNULL(l3.XP, 0) + ISNULL(l4.XP, 0) + ISNULL(l5.XP, 0) AS decimal(18,4)) AS SalesPrice, p.Cost, p.UomId, p.CategoryId, p.IsActive, p.TenantId, p.IsDeleted FROM Inv_T_Product p LEFT JOIN (SELECT x.ProductId, x.Rk, CAST(s.value AS nvarchar(36)) AS VId, av.Name AS VName, av.ExtraPrice AS XP FROM (SELECT pl.ProductId, pl.ValueIds, DENSE_RANK() OVER (PARTITION BY pl.ProductId ORDER BY a.Name, a.Id) AS Rk FROM Inv_T_ProductAttributeLine pl INNER JOIN Inv_T_Attribute a ON a.Id = pl.AttributeId AND a.IsDeleted = 'false' AND a.VariantCreation <> 'Never' WHERE pl.IsDeleted = 'false') x CROSS APPLY STRING_SPLIT(x.ValueIds, '\|') s INNER JOIN Inv_T_AttributeValue av ON CAST(av.Id AS nvarchar(36)) = s.value AND av.IsDeleted = 'false') l1 ON l1.ProductId = p.Id AND l1.Rk = 1 LEFT JOIN (SELECT x.ProductId, x.Rk, CAST(s.value AS nvarchar(36)) AS VId, av.Name AS VName, av.ExtraPrice AS XP FROM (SELECT pl.ProductId, pl.ValueIds, DENSE_RANK() OVER (PARTITION BY pl.ProductId ORDER BY a.Name, a.Id) AS Rk FROM Inv_T_ProductAttributeLine pl INNER JOIN Inv_T_Attribute a ON a.Id = pl.AttributeId AND a.IsDeleted = 'false' AND a.VariantCreation <> 'Never' WHERE pl.IsDeleted = 'false') x CROSS APPLY STRING_SPLIT(x.ValueIds, '\|') s INNER JOIN Inv_T_AttributeValue av ON CAST(av.Id AS nvarchar(36)) = s.value AND av.IsDeleted = 'false') l2 ON l2.ProductId = p.Id AND l2.Rk = 2 LEFT JOIN (SELECT x.ProductId, x.Rk, CAST(s.value AS nvarchar(36)) AS VId, av.Name AS VName, av.ExtraPrice AS XP FROM (SELECT pl.ProductId, pl.ValueIds, DENSE_RANK() OVER (PARTITION BY pl.ProductId ORDER BY a.Name, a.Id) AS Rk FROM Inv_T_ProductAttributeLine pl INNER JOIN Inv_T_Attribute a ON a.Id = pl.AttributeId AND a.IsDeleted = 'false' AND a.VariantCreation <> 'Never' WHERE pl.IsDeleted = 'false') x CROSS APPLY STRING_SPLIT(x.ValueIds, '\|') s INNER JOIN Inv_T_AttributeValue av ON CAST(av.Id AS nvarchar(36)) = s.value AND av.IsDeleted = 'false') l3 ON l3.ProductId = p.Id AND l3.Rk = 3 LEFT JOIN (SELECT x.ProductId, x.Rk, CAST(s.value AS nvarchar(36)) AS VId, av.Name AS VName, av.ExtraPrice AS XP FROM (SELECT pl.ProductId, pl.ValueIds, DENSE_RANK() OVER (PARTITION BY pl.ProductId ORDER BY a.Name, a.Id) AS Rk FROM Inv_T_ProductAttributeLine pl INNER JOIN Inv_T_Attribute a ON a.Id = pl.AttributeId AND a.IsDeleted = 'false' AND a.VariantCreation <> 'Never' WHERE pl.IsDeleted = 'false') x CROSS APPLY STRING_SPLIT(x.ValueIds, '\|') s INNER JOIN Inv_T_AttributeValue av ON CAST(av.Id AS nvarchar(36)) = s.value AND av.IsDeleted = 'false') l4 ON l4.ProductId = p.Id AND l4.Rk = 4 LEFT JOIN (SELECT x.ProductId, x.Rk, CAST(s.value AS nvarchar(36)) AS VId, av.Name AS VName, av.ExtraPrice AS XP FROM (SELECT pl.ProductId, pl.ValueIds, DENSE_RANK() OVER (PARTITION BY pl.ProductId ORDER BY a.Name, a.Id) AS Rk FROM Inv_T_ProductAttributeLine pl INNER JOIN Inv_T_Attribute a ON a.Id = pl.AttributeId AND a.IsDeleted = 'false' AND a.VariantCreation <> 'Never' WHERE pl.IsDeleted = 'false') x CROSS APPLY STRING_SPLIT(x.ValueIds, '\|') s INNER JOIN Inv_T_AttributeValue av ON CAST(av.Id AS nvarchar(36)) = s.value AND av.IsDeleted = 'false') l5 ON l5.ProductId = p.Id AND l5.Rk = 5` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✗ · sil ✗ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `ProductId` | Ürün | dxSelectBox | | | sorgu: Inv_T_Product |
| `InternalReference` | İç Referans | dxTextBox | | ✓ | |
| `ProductName` | Adı | dxTextBox | | ✓ | |
| `VariantName` | Varyant Değerleri | dxTextBox | | ✓ | |
| `SalesPrice` | Satış Fiyatı | dxNumberBox | | ✓ | |
| `Cost` | Maliyet | dxNumberBox | | ✓ | |
| `UomId` | Birim | dxSelectBox | | ✓ | sorgu: Adm_T_Uom |
| `CategoryId` | Kategori | dxSelectBox | | ✓ | sorgu: Inv_T_ProductCategory |
| `IsActive` | Aktif | dxCheckBox | | ✓ | |
| `IsDeleted` | Silindi | dxCheckBox | | | |
#### Reçeteye Genel Bakış — `App.Inventory.BomOverview`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/BomOverview.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.BomOverview` (sıra 7) |
| Yetki | `App.Inventory.BomOverview` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Reçeteye Genel Bakış — her aktif reçetenin çok seviyeli patlatılmış hali, ağaç olarak (salt okunur). |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) AS nvarchar(400)) AS NodeKey, CAST(NULL AS nvarchar(400)) AS ParentKey, b0.Id AS BomId, 0 AS NodeLevel, CAST('Product' AS nvarchar(20)) AS NodeType, CAST(p0.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(b0.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') AS nvarchar(400)) AS Name, CAST(b0.Quantity AS decimal(18,4)) AS Quantity, CAST(u0.Name AS nvarchar(64)) AS UomName, CAST(NULL AS decimal(18,4)) AS Cost, b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_Product p0 ON p0.Id = b0.ProductId LEFT JOIN Adm_T_Uom u0 ON u0.Id = b0.UomId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1 UNION ALL SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) AS nvarchar(400)), CAST('B' + CAST(b0.Id AS nvarchar(36)) AS nvarchar(400)), b0.Id, 1, 'Component', CAST(p1.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(c1.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') AS nvarchar(400)), CAST(c1.Quantity AS decimal(18,4)), u1.Name, CAST(c1.Quantity * p1.Cost AS decimal(18,4)), b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomComponent c1 ON c1.BomId = b0.Id AND c1.IsDeleted = 'false' INNER JOIN Inv_T_Product p1 ON p1.Id = c1.ProductId LEFT JOIN Adm_T_Uom u1 ON u1.Id = c1.UomId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1 UNION ALL SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) AS nvarchar(400)), CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) AS nvarchar(400)), b0.Id, 2, 'Component', CAST(p2.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(c2.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') AS nvarchar(400)), CAST(c1.Quantity * c2.Quantity / b1.Quantity AS decimal(18,4)), u2.Name, CAST(c1.Quantity * c2.Quantity / b1.Quantity * p2.Cost AS decimal(18,4)), b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomComponent c1 ON c1.BomId = b0.Id AND c1.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c1.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c1.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c1.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b1 INNER JOIN Inv_T_BomComponent c2 ON c2.BomId = b1.Id AND c2.IsDeleted = 'false' INNER JOIN Inv_T_Product p2 ON p2.Id = c2.ProductId LEFT JOIN Adm_T_Uom u2 ON u2.Id = c2.UomId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1 UNION ALL SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) + '/C' + CAST(c3.Id AS nvarchar(36)) AS nvarchar(400)), CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) AS nvarchar(400)), b0.Id, 3, 'Component', CAST(p3.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(c3.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') AS nvarchar(400)), CAST(c1.Quantity * c2.Quantity / b1.Quantity * c3.Quantity / b2.Quantity AS decimal(18,4)), u3.Name, CAST(c1.Quantity * c2.Quantity / b1.Quantity * c3.Quantity / b2.Quantity * p3.Cost AS decimal(18,4)), b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomComponent c1 ON c1.BomId = b0.Id AND c1.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c1.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c1.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c1.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b1 INNER JOIN Inv_T_BomComponent c2 ON c2.BomId = b1.Id AND c2.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c2.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c2.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c2.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b2 INNER JOIN Inv_T_BomComponent c3 ON c3.BomId = b2.Id AND c3.IsDeleted = 'false' INNER JOIN Inv_T_Product p3 ON p3.Id = c3.ProductId LEFT JOIN Adm_T_Uom u3 ON u3.Id = c3.UomId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1 UNION ALL SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) + '/C' + CAST(c3.Id AS nvarchar(36)) + '/C' + CAST(c4.Id AS nvarchar(36)) AS nvarchar(400)), CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) + '/C' + CAST(c3.Id AS nvarchar(36)) AS nvarchar(400)), b0.Id, 4, 'Component', CAST(p4.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(c4.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') AS nvarchar(400)), CAST(c1.Quantity * c2.Quantity / b1.Quantity * c3.Quantity / b2.Quantity * c4.Quantity / b3.Quantity AS decimal(18,4)), u4.Name, CAST(c1.Quantity * c2.Quantity / b1.Quantity * c3.Quantity / b2.Quantity * c4.Quantity / b3.Quantity * p4.Cost AS decimal(18,4)), b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomComponent c1 ON c1.BomId = b0.Id AND c1.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c1.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c1.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c1.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b1 INNER JOIN Inv_T_BomComponent c2 ON c2.BomId = b1.Id AND c2.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c2.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c2.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c2.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b2 INNER JOIN Inv_T_BomComponent c3 ON c3.BomId = b2.Id AND c3.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c3.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c3.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c3.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b3 INNER JOIN Inv_T_BomComponent c4 ON c4.BomId = b3.Id AND c4.IsDeleted = 'false' INNER JOIN Inv_T_Product p4 ON p4.Id = c4.ProductId LEFT JOIN Adm_T_Uom u4 ON u4.Id = c4.UomId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1 UNION ALL SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/OPS' AS nvarchar(400)), CAST('B' + CAST(b0.Id AS nvarchar(36)) AS nvarchar(400)), b0.Id, 1, 'OperationGroup', 'Operasyonlar', CAST(SUM(o.DurationMin) AS decimal(18,4)), 'Dakika', CAST(SUM(o.DurationMin / 60 * w.CostPerHour) AS decimal(18,4)), b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomOperation o ON o.BomId = b0.Id AND o.IsDeleted = 'false' INNER JOIN Inv_T_WorkCenter w ON w.Id = o.WorkCenterId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1 GROUP BY b0.Id, b0.TenantId, b0.IsDeleted UNION ALL SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/OPS/O' + CAST(o.Id AS nvarchar(36)) AS nvarchar(400)), CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/OPS' AS nvarchar(400)), b0.Id, 2, 'Operation', op.Name + ' - ' + w.Name, CAST(o.DurationMin AS decimal(18,4)), 'Dakika', CAST(o.DurationMin / 60 * w.CostPerHour AS decimal(18,4)), b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomOperation o ON o.BomId = b0.Id AND o.IsDeleted = 'false' INNER JOIN Inv_T_Operation op ON op.Id = o.OperationId INNER JOIN Inv_T_WorkCenter w ON w.Id = o.WorkCenterId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1 UNION ALL SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/OPS' AS nvarchar(400)), CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) AS nvarchar(400)), b0.Id, 2, 'OperationGroup', 'Operasyonlar', CAST(SUM(o.DurationMin * c1.Quantity / b1.Quantity) AS decimal(18,4)), 'Dakika', CAST(SUM(o.DurationMin * c1.Quantity / b1.Quantity / 60 * w.CostPerHour) AS decimal(18,4)), b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomComponent c1 ON c1.BomId = b0.Id AND c1.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c1.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c1.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c1.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b1 INNER JOIN Inv_T_BomOperation o ON o.BomId = b1.Id AND o.IsDeleted = 'false' INNER JOIN Inv_T_WorkCenter w ON w.Id = o.WorkCenterId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1 GROUP BY b0.Id, b0.TenantId, b0.IsDeleted, c1.Id UNION ALL SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/OPS/O' + CAST(o.Id AS nvarchar(36)) AS nvarchar(400)), CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/OPS' AS nvarchar(400)), b0.Id, 3, 'Operation', op.Name + ' - ' + w.Name, CAST(o.DurationMin * c1.Quantity / b1.Quantity AS decimal(18,4)), 'Dakika', CAST(o.DurationMin * c1.Quantity / b1.Quantity / 60 * w.CostPerHour AS decimal(18,4)), b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomComponent c1 ON c1.BomId = b0.Id AND c1.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c1.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c1.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c1.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b1 INNER JOIN Inv_T_BomOperation o ON o.BomId = b1.Id AND o.IsDeleted = 'false' INNER JOIN Inv_T_Operation op ON op.Id = o.OperationId INNER JOIN Inv_T_WorkCenter w ON w.Id = o.WorkCenterId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1 UNION ALL SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) + '/OPS' AS nvarchar(400)), CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) AS nvarchar(400)), b0.Id, 3, 'OperationGroup', 'Operasyonlar', CAST(SUM(o.DurationMin * c1.Quantity * c2.Quantity / b1.Quantity / b2.Quantity) AS decimal(18,4)), 'Dakika', CAST(SUM(o.DurationMin * c1.Quantity * c2.Quantity / b1.Quantity / b2.Quantity / 60 * w.CostPerHour) AS decimal(18,4)), b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomComponent c1 ON c1.BomId = b0.Id AND c1.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c1.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c1.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c1.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b1 INNER JOIN Inv_T_BomComponent c2 ON c2.BomId = b1.Id AND c2.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c2.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c2.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c2.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b2 INNER JOIN Inv_T_BomOperation o ON o.BomId = b2.Id AND o.IsDeleted = 'false' INNER JOIN Inv_T_WorkCenter w ON w.Id = o.WorkCenterId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1 GROUP BY b0.Id, b0.TenantId, b0.IsDeleted, c1.Id, c2.Id UNION ALL SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) + '/OPS/O' + CAST(o.Id AS nvarchar(36)) AS nvarchar(400)), CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) + '/OPS' AS nvarchar(400)), b0.Id, 4, 'Operation', op.Name + ' - ' + w.Name, CAST(o.DurationMin * c1.Quantity * c2.Quantity / b1.Quantity / b2.Quantity AS decimal(18,4)), 'Dakika', CAST(o.DurationMin * c1.Quantity * c2.Quantity / b1.Quantity / b2.Quantity / 60 * w.CostPerHour AS decimal(18,4)), b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomComponent c1 ON c1.BomId = b0.Id AND c1.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c1.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c1.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c1.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b1 INNER JOIN Inv_T_BomComponent c2 ON c2.BomId = b1.Id AND c2.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c2.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c2.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c2.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b2 INNER JOIN Inv_T_BomOperation o ON o.BomId = b2.Id AND o.IsDeleted = 'false' INNER JOIN Inv_T_Operation op ON op.Id = o.OperationId INNER JOIN Inv_T_WorkCenter w ON w.Id = o.WorkCenterId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1 UNION ALL SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) + '/C' + CAST(c3.Id AS nvarchar(36)) + '/OPS' AS nvarchar(400)), CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) + '/C' + CAST(c3.Id AS nvarchar(36)) AS nvarchar(400)), b0.Id, 4, 'OperationGroup', 'Operasyonlar', CAST(SUM(o.DurationMin * c1.Quantity * c2.Quantity / b1.Quantity * c3.Quantity / b2.Quantity / b3.Quantity) AS decimal(18,4)), 'Dakika', CAST(SUM(o.DurationMin * c1.Quantity * c2.Quantity / b1.Quantity * c3.Quantity / b2.Quantity / b3.Quantity / 60 * w.CostPerHour) AS decimal(18,4)), b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomComponent c1 ON c1.BomId = b0.Id AND c1.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c1.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c1.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c1.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b1 INNER JOIN Inv_T_BomComponent c2 ON c2.BomId = b1.Id AND c2.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c2.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c2.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c2.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b2 INNER JOIN Inv_T_BomComponent c3 ON c3.BomId = b2.Id AND c3.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c3.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c3.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c3.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b3 INNER JOIN Inv_T_BomOperation o ON o.BomId = b3.Id AND o.IsDeleted = 'false' INNER JOIN Inv_T_WorkCenter w ON w.Id = o.WorkCenterId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1 GROUP BY b0.Id, b0.TenantId, b0.IsDeleted, c1.Id, c2.Id, c3.Id UNION ALL SELECT CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) + '/C' + CAST(c3.Id AS nvarchar(36)) + '/OPS/O' + CAST(o.Id AS nvarchar(36)) AS nvarchar(400)), CAST('B' + CAST(b0.Id AS nvarchar(36)) + '/C' + CAST(c1.Id AS nvarchar(36)) + '/C' + CAST(c2.Id AS nvarchar(36)) + '/C' + CAST(c3.Id AS nvarchar(36)) + '/OPS' AS nvarchar(400)), b0.Id, 5, 'Operation', op.Name + ' - ' + w.Name, CAST(o.DurationMin * c1.Quantity * c2.Quantity / b1.Quantity * c3.Quantity / b2.Quantity / b3.Quantity AS decimal(18,4)), 'Dakika', CAST(o.DurationMin * c1.Quantity * c2.Quantity / b1.Quantity * c3.Quantity / b2.Quantity / b3.Quantity / 60 * w.CostPerHour AS decimal(18,4)), b0.TenantId, b0.IsDeleted FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomComponent c1 ON c1.BomId = b0.Id AND c1.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c1.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c1.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c1.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b1 INNER JOIN Inv_T_BomComponent c2 ON c2.BomId = b1.Id AND c2.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c2.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c2.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c2.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b2 INNER JOIN Inv_T_BomComponent c3 ON c3.BomId = b2.Id AND c3.IsDeleted = 'false' CROSS APPLY (SELECT TOP 1 bb.Id, bb.Quantity FROM Inv_T_Bom bb WHERE bb.ProductId = c3.ProductId AND bb.IsDeleted = 'false' AND bb.IsActive = 1 AND bb.Quantity > 0 AND (bb.VariantKey IS NULL OR bb.VariantKey = '' OR bb.VariantKey = c3.VariantKey) ORDER BY CASE WHEN bb.VariantKey = c3.VariantKey THEN 0 ELSE 1 END, bb.CreationTime) b3 INNER JOIN Inv_T_BomOperation o ON o.BomId = b3.Id AND o.IsDeleted = 'false' INNER JOIN Inv_T_Operation op ON op.Id = o.OperationId INNER JOIN Inv_T_WorkCenter w ON w.Id = o.WorkCenterId WHERE b0.IsDeleted = 'false' AND b0.IsActive = 1` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart, Tree (açılış tree) |
| Düzenleme | ekle ✗ · düzenle ✗ · sil ✗ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `ParentKey` | Üst Düğüm | dxTextBox | | | |
| `Name` | Ürün | dxTextBox | | ✓ | |
| `Quantity` | Miktar | dxNumberBox | | ✓ | |
| `UomName` | Birim | dxTextBox | | ✓ | |
| `Cost` | Maliyet | dxNumberBox | | ✓ | |
| `NodeType` | Satır Türü | dxSelectBox | | ✓ | liste: Product, Component, OperationGroup, Operation |
| `NodeLevel` | Seviye | dxNumberBox | | ✓ | |
| `BomId` | Reçete | dxTextBox | | | |
| `IsDeleted` | Silindi | dxCheckBox | | | |
#### Reçeteler — `App.Inventory.Bom`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Bom.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.Bom` (sıra 8) |
| Yetki | `App.Inventory.Bom` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Reçeteler — bir ürünü üretmek için gereken hammadde, yarı mamul ve operasyonlar. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_Bom` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Inventory.BomComponent` (Id → BomId), `App.Inventory.BomOperation` (Id → BomId), `App.Inventory.BomOther` (Id → Id), `App.Inventory.BomOverview` (Id → BomId) |
| Widget'lar | `App.Widget.Total`, `App.Widget.VariantBased`, `App.Widget.Active` |
| Form varsayılanları | UomId=Adet, IsActive=true, Quantity=0 |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `ProductId` | Ürün | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Product |
| `Reference` | Referans | dxTextBox | | ✓ | |
| `VariantKey` | Ürün Varyantı | dxSelectBox | | ✓ | sorgu: Inv_T_Product (← ProductId) |
| `Quantity` | Miktar | dxNumberBox | ✓ | ✓ | |
| `UomId` | Birim | dxSelectBox | ✓ | ✓ | sorgu: Adm_T_Uom |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
#### Ürünler — `App.Inventory.Product`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Product.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.Product` (sıra 9) |
| Yetki | `App.Inventory.Product` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Ürünler — satış, satınalma, stok ve üretimin ortak kullandığı ürün kartı. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_Product` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Inventory.ProductGeneral` (Id → Id), `App.Inventory.ProductAttributeLine` (Id → ProductId), `App.Inventory.ProductVariant` (Id → ProductId), `App.Inventory.ProductSupplier` (Id → ProductId), `App.Inventory.ProductStock` (Id → Id), `App.Inventory.ProductAccounting` (Id → Id), `App.Inventory.Bom` (Id → ProductId) |
| Widget'lar | `App.Widget.Total`, `App.Widget.Saleable`, `App.Widget.Purchasable`, `App.Widget.Service` |
| Form varsayılanları | IsActive=true, IsFavorite=false, CanBeSold=true, CanBeExpensed=false, CanBePurchased=false, IsFavorite=false, UomId=Adet, PurchaseUomId=Adet, SalesPrice=0, Cost=0, TrackInventory=true, TrackingMethod=Quantity, ProductType=Wares |
| Veri aynası | `data/App.Inventory.Product.json` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `Name` | Ürün Adı | dxTextBox | ✓ | ✓ | |
| `IsFavorite` | Favori | dxCheckBox | | ✓ | |
| `CanBeSold` | Satış | dxCheckBox | | ✓ | |
| `CanBeExpensed` | Masraflar | dxCheckBox | | ✓ | |
| `CanBePurchased` | Satınalma | dxCheckBox | | ✓ | |
| `ProductType` | Ürün Türü | dxSelectBox | ✓ | ✓ | liste: Wares, Service · script |
| `CategoryId` | Kategori | dxSelectBox | | ✓ | sorgu: Inv_T_ProductCategory |
| `TrackInventory` | Envanter Takibi | dxCheckBox | | ✓ | script |
| `TrackingMethod` | Takip Yöntemi | dxSelectBox | | ✓ | liste: Serial, Lot, Quantity |
| `SalesPrice` | Satış Fiyatı | dxNumberBox | | ✓ | |
| `Cost` | Maliyet | dxNumberBox | | ✓ | |
| `InternalReference` | İç Referans | dxTextBox | | ✓ | |
| `UomId` | Birim | dxSelectBox | ✓ | ✓ | sorgu: Adm_T_Uom · script |
| `PurchaseUomId` | Satınalma Birimi | dxSelectBox | | ✓ | sorgu: Adm_T_Uom |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
| `Image` | Resim | dxImageUpload | | ✓ | |
#### Nitelik Değerleri — `App.Inventory.AttributeValue`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/AttributeValue.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.AttributeValue` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Nitelik Değerleri — bir niteliğin alabileceği değerler (ör. renk: kırmızı, mavi; boyut: 40x40). |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_AttributeValue` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Form varsayılanları | IsCustom=false, IsActive=true |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `AttributeId` | Nitelik | dxSelectBox | | | sorgu: Inv_T_Attribute |
| `Name` | Değer | dxTextBox | ✓ | ✓ | |
| `IsCustom` | Serbest Metin | dxCheckBox | | ✓ | |
| `ExtraPrice` | Varsayılan Ekstra Fiyat | dxNumberBox | | ✓ | |
| `ColorCode` | Renk Kodu | dxColorBox | | ✓ | |
| `SortOrder` | Sıra | dxNumberBox | | ✓ | |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
#### Genel Bilgi — `App.Inventory.WorkCenterGeneral`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/WorkCenterGeneral.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.WorkCenterGeneral` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | İş Merkezi Genel Bilgi — iş merkezinin üretim ve maliyetlendirme bilgileri. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_WorkCenter` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `TimeEfficiency` | Zaman Verimliliği (%) | dxNumberBox | ✓ | ✓ | |
| `OeeTarget` | OEE Hedefi (%) | dxNumberBox | ✓ | ✓ | |
| `SetupTimeMin` | Kurulum Zamanı (dk) | dxNumberBox | | ✓ | |
| `CleanupTimeMin` | Temizlik Zamanı (dk) | dxNumberBox | | ✓ | |
| `CostPerHour` | Saat Başına Maliyet (İş Merkezi) | dxNumberBox | | ✓ | |
| `EmployeeCostPerHour` | Saat Başına Maliyet (Çalışan) | dxNumberBox | | ✓ | |
| `Description` | Açıklama | dxTextArea | | ✓ | |
#### Ürün Kapasitesi — `App.Inventory.WorkCenterCapacity`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/WorkCenterCapacity.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.WorkCenterCapacity` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | İş Merkezi Ürün Kapasitesi — iş merkezinin bir çevrimde bir üründen kaç birim işleyebildiği. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_WorkCenterCapacity` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `WorkCenterId` | İş Merkezi | dxSelectBox | | | sorgu: Inv_T_WorkCenter |
| `ProductId` | Ürün | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Product |
| `Capacity` | Kapasite | dxNumberBox | ✓ | ✓ | |
| `UomId` | Birim | dxSelectBox | | ✓ | sorgu: Adm_T_Uom |
| `SetupTimeMin` | Kurulum Zamanı (dk) | dxNumberBox | | ✓ | |
| `CleanupTimeMin` | Temizlik Zamanı (dk) | dxNumberBox | | ✓ | |
#### Açıklamalar — `App.Inventory.OperationInstruction`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/OperationInstruction.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.OperationInstruction` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Operasyon Açıklamaları — bir operasyonda operatöre gösterilen iş talimatları. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_OperationInstruction` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `OperationId` | Operasyon | dxSelectBox | | | sorgu: Inv_T_Operation |
| `Title` | Başlık | dxTextBox | ✓ | ✓ | |
| `InstructionType` | Tip | dxSelectBox | ✓ | ✓ | liste: Text, Pdf, Image, Link |
| `Reference` | Referans | dxTextBox | | ✓ | |
| `Note` | Not | dxTextArea | | ✓ | |
| `SortOrder` | Sıra | dxNumberBox | | ✓ | |
#### Bileşenler — `App.Inventory.BomComponent`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/BomComponent.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.BomComponent` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Reçete Bileşenleri — reçetenin tükettiği hammadde ve yarı mamuller. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_BomComponent` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `BomId` | Reçete | dxTextBox | | | |
| `ProductId` | Komponent | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Product · script |
| `VariantKey` | Bileşen Varyantı | dxSelectBox | | ✓ | sorgu: Inv_T_Product (← ProductId) |
| `Quantity` | Miktar | dxNumberBox | ✓ | ✓ | |
| `UomId` | Birim | dxSelectBox | ✓ | ✓ | sorgu: Adm_T_Uom |
| `BomOperationId` | Operasyonda Tüketilenler | dxSelectBox | | ✓ | sorgu: Inv_T_BomOperation (← BomId) |
| `SortOrder` | Sıra | dxNumberBox | | ✓ | |
#### Operasyonlar — `App.Inventory.BomOperation`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/BomOperation.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.BomOperation` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Reçete Operasyonları — reçetenin üretim adımları ve süreleri. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_BomOperation` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `BomId` | Reçete | dxTextBox | | | |
| `OperationId` | Operasyon | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Operation · script |
| `WorkCenterId` | İş Merkezi | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_WorkCenter |
| `DurationMin` | Süre (dakika) | dxNumberBox | ✓ | ✓ | |
| `SortOrder` | Sıra | dxNumberBox | | ✓ | |
#### Diğer — `App.Inventory.BomOther`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/BomOther.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.BomOther` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Reçete Diğer Ayarlar — reçetenin üretim hazırlığı ve planlama parametreleri. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_Bom` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `ReadyToProduce` | Üretim Hazırlığı | dxRadioGroup | ✓ | ✓ | liste: AllAvailable, FirstOperation |
| `ProductionLeadDays` | Üretim Akış Zamanı (gün) | dxNumberBox | | ✓ | |
| `FlexibleConsumption` | Esnek Tüketim | dxRadioGroup | ✓ | ✓ | liste: Allowed, Warning, Blocked |
| `PreparationDays` | Üretim Siparişi Hazırlama Günleri | dxNumberBox | | ✓ | |
| `BatchSize` | Parti Büyüklüğü | dxNumberBox | | ✓ | |
#### Genel Bilgi — `App.Inventory.ProductGeneral`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/ProductGeneral.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.ProductGeneral` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Ürün Genel Bilgi — ürünün vergi, barkod, satınalma kontrol ve iç not bilgileri. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_Product` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `SalesTaxRate` | Satış Vergisi (%) | dxNumberBox | ✓ | ✓ | |
| `PurchaseTaxRate` | Satınalma Vergisi (%) | dxNumberBox | ✓ | ✓ | |
| `Barcode` | Barkod | dxTextBox | | ✓ | |
| `PurchaseControlPolicy` | Kontrol Kuralı | dxRadioGroup | ✓ | ✓ | liste: Ordered, Received |
| `PurchaseDescription` | Satınalma Açıklaması | dxTextArea | | ✓ | |
| `InternalNotes` | İç Notlar | dxTextArea | | ✓ | |
#### Nitelik & Varyantlar — `App.Inventory.ProductAttributeLine`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/ProductAttributeLine.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.ProductAttributeLine` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Ürün Nitelik & Varyantlar — ürünün nitelikleri ve bu ürün için kullanılan değerler. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_ProductAttributeLine` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `ProductId` | Ürün | dxTextBox | | | |
| `AttributeId` | Nitelik | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Attribute |
| `ValueIds` | Değerler | dxTagBox | ✓ | ✓ | sorgu: Inv_T_AttributeValue (← AttributeId) |
#### Satınalma — `App.Inventory.ProductSupplier`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/ProductSupplier.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.ProductSupplier` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Ürün Tedarikçi Fiyatları — ürünün hangi tedarikçiden hangi bedele alındığı. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_ProductSupplier` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `ProductId` | Ürün | dxTextBox | | | |
| `ContactId` | Tedarikçi | dxSelectBox | ✓ | ✓ | sorgu: Adm_T_Contact |
| `VariantKey` | Ürün Varyantı | dxSelectBox | | ✓ | sorgu: Inv_T_Product (← ProductId) |
| `MinQuantity` | Miktar | dxNumberBox | ✓ | ✓ | |
| `UomId` | Birim | dxSelectBox | | ✓ | sorgu: Adm_T_Uom |
| `Price` | Birim Fiyat | dxNumberBox | ✓ | ✓ | |
| `CurrencyId` | Kur | dxSelectBox | | ✓ | sorgu: Sas_H_Currency |
| `LeadTimeDays` | Teslim Süresi (gün) | dxNumberBox | | ✓ | |
#### Stok — `App.Inventory.ProductStock`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/ProductStock.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.ProductStock` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Ürün Stok — ürünün lojistik ve izlenebilirlik bilgileri. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_Product` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `ResponsibleUserId` | Sorumlu | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `LotValuation` | Lot/Seri Bazında Değerleme | dxCheckBox | | ✓ | |
| `Weight` | Ağırlık (kg) | dxNumberBox | | ✓ | |
| `CustomLotSerial` | Özel Lot/Seri | dxTextBox | | ✓ | |
| `Volume` | Hacim (m³) | dxNumberBox | | ✓ | |
| `GtipCode` | GTİP Kodu | dxTextBox | | ✓ | |
| `OriginCountryId` | Malların Menşei | dxSelectBox | | ✓ | sorgu: Sas_H_Country |
| `ReceiptNote` | Alım İçin Açıklama | dxTextArea | | ✓ | |
| `DeliveryNote` | Teslimatlar İçin Açıklama | dxTextArea | | ✓ | |
| `InternalTransferNote` | İç Transferler İçin Açıklama | dxTextArea | | ✓ | |
#### Muhasebe — `App.Inventory.ProductAccounting`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/ProductAccounting.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.ProductAccounting` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Ürün Muhasebe — ürünün maliyet ve gelir hesapları. |
| Geliştirme talebi | Inventory -> Tanımlamalar |
| Kaynak | `Inv_T_Product` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `IncomeAccount` | Gelir Hesabı | dxTextBox | | ✓ | |
| `ExpenseAccount` | Gider Hesabı | dxTextBox | | ✓ | |
<!-- module-doc:auto:end -->