sozsoft-platform/configs/seeds/docs/modules/App.Inventory.md
2026-10-14 12:07:11 +03:00

1112 lines
103 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
Envanterin 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), çok seviyeli reçete patlatma raporu ve fiziksel stok yapısı: şubeye bağlı depolar, depolarda iç içe konumlar, şube/depo bazında operasyon türleri. İş merkezleri ve operasyonlar Üretim modülündedir ([App.Production.md](App.Production.md)). Kullanıcılar: stok, satınalma ve üretim planlama ekipleri. Stok hareketleri Operasyonlar, stok ve hareket listeleri doğrudan Envanter altındaki Stok ve Hareketler ekranlarıdır; 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.
- İş Merkezi Etiketleri, İş Merkezleri ve Operasyonlar (alt formlarıyla) sonradan `Üretim › Tanımlamalar` altına taşındı: kod `App.Production.*`, tablo `Prd_T_*` (`App.Production.md` §2).
- Ü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.
Onaylanan analiz (talep "Envanter -> Tanımlamalar"):
- Depolar, Konumlar, Operasyon Türleri üç ayrı liste ekranı; tablolar `Inv_T_Warehouse`, `Inv_T_Location`, `Inv_T_OperationType`.
- Şube platform şube filtresiyle değil kolonla tutulur (`IsBranch = false`, `BranchId` → `Sas_T_Branch`): talep Şube Adı'nı listede görünen, seçilen alan olarak istedi. Görsellerdeki "Firma" sütunu Şube'ye karşılık gelir.
- Konum ve Operasyon Türü'nde şube ayrıca tutulur ("şube ve depo bazında"); depo listesini süzer.
- Konumlar'da Malzeme Türü ve Depolama Kategorisi alınmadı (talepte yok, kaynak tablo yok). Operasyon Türü'nde yalnız Genel sekmesinin çekirdek alanları alındı; Donanım, Barkod Uygulaması, lot/seri, paket, iade türü, kart rengi kapsam dışı.
- Depolar demo verisi: görseldeki 4 depo (WH, GRP, IKT, KZL), ilk aktif şubeye (Branch1) bağlı (onaylı).
Ü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.
- Depo kodu tekilliği `UQ_Inv_T_Warehouse_TenantId_Code` kısıtıyla sağlanır (ayrı InsertBefore kontrolü yazılmadı; aynı kod kaydedilirken veritabanı hatası döner).
- `Inv_T_Location`'da `WarehouseId`/`ParentId`/`DepartmentId` için FK yazılmadı: migrate scriptleri dosya adı sırasıyla çalışır ve `Inv_T_Location` `Inv_T_Warehouse`'tan önce sıralanır. Bütünlük lookup'larla korunur; `Inv_T_OperationType` → `Inv_T_Location` FK'leri vardır.
### 3. Menü ve ekranlar
`Envanter (App.Inventory) › Tanımlamalar (App.Inventory.Definitions)` altında sırasıyla: Ürün Kategorileri, Nitelikler, Ürünler, Ürün Varyantları, Reçeteler, Reçeteye Genel Bakış, Depolar, Konumlar, Operasyon Türleri.
Sekmeler (menüsüz alt formlar):
- Nitelikler › Nitelik Değerleri
- 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ü)
Konumlar ağaç görünümüyle açılır (`ParentId`); Grid'e geçilebilir.
### 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`; şube → `Sas_T_Branch`.
| 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_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, son alım tarihi (siparişli alımın Doğrula'sı yazar) |
| `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 `Prd_T_WorkCenter`, operasyon `Prd_T_Operation`, süre) |
| `Inv_T_Warehouse` | Şube, kod (kiracı içinde tekil, 16), ad, aktif |
| `Inv_T_Location` | Şube, depo, üst konum, kod (32), ad, konum türü (`Internal`/`External`), departman (`Hr_T_Department`), depo sorumlusu, aktif |
| `Inv_T_OperationType` | Şube, depo, ad, tür (`Receipt`/`Delivery`/`InternalTransfer`/`Manufacturing`/`Repair`), numaratör (`SequenceName` → `Adm_T_Sequence.Name`; belge numarası buradan), barkod, kaynak ve hedef konum, aktif |
### 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.
- **Şube › depo › konum zinciri:** Konum ve Operasyon Türü formunda depo seçili şubenin aktif depolarına, üst/kaynak/hedef konum seçili deponun konumlarına, departman seçili şubenin departmanlarına süzülür. Şube değişince depo, konum ve departman; depo değişince konum alanları temizlenir.
- **Varsayılanlar:** yeni konumda tür İç, yeni operasyon türünde tür Alım, tüm yeni tanımlarda Aktif işaretli.
### 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. Depolar, Konumlar ve Operasyon Türleri platform şube filtresi kullanmaz; kullanıcı yetkisi olan her ekranda kiracının tüm şubelerinin kayıtlarını görür.
### 7. Entegrasyonlar
Dış entegrasyon yok. Reçete operasyonları iş merkezi ve operasyonu Üretim modülünden okur; Üretim de ürün ve nitelik değerlerini buradan okur. Ölçü Birimleri, Kontaklar, Para Birimleri, Ülkeler, Şubeler, Departmanlar ve Kullanıcılar yalnız lookup kaynağıdır. Satış ve satınalma sipariş ekranları ürünü `CanBeSold` / `CanBePurchased` ile süzecek; stok hareket belgeleri (Operasyonlar dalı) operasyon türünü, numaratörünü ve konumları bu daldan alır; ürünün Envanter Takibi ve Takip Yöntemi hareketin stoğa ve lota nasıl işleneceğini belirler.
### 8. Akış örneği
1. Nitelikler'de renk (kırmızı, mavi), malzeme (çelik, tahta), boyut (40x40, 80x100, 10x30) değerlerini gir.
2. Üretim › İş Merkezleri'nde "ram makinası"nın saatlik maliyetini gir.
3. Üretim › 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.
7. Depolar'da "Grup Şirketler" (GRP) deposunu şubeye bağla.
8. Konumlar'da GRP için "Stock" kök konumunu, altına "ALDORA MOBİLYA G/Ç" (kod GRP ALD, departman, sorumlu), onun altına "ANA DEPO AB07" konumunu İç türüyle gir; ağaç üç seviye gösterir.
9. Operasyon Türleri'nde GRP için "Alımlar" (tür Alım, numaratör GRP/IN/ önekli, kaynak konum dış "Tedarikçiler", hedef konum Stock) tanımla.
### 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?** Eski ürün ekranlarında form varsayılanları wizard deploy'unda yazılamadı (bkz. 10). Kayıtta kutu işaretlenmelidir. Depolar, Konumlar ve Operasyon Türleri'nde varsayılan tablodan okunur.
- **Depo seçimi boş geliyor?** Önce şube seçilmelidir; depo listesi şubeye göre süzülür ve yalnız aktif depolar gelir.
- **Aynı depo kodu kaydedilemiyor?** Depo kodu kiracı içinde tekildir; silinen (soft delete) bir deponun kodu da tekrar kullanılamaz.
- **Depo ya da konum silinebilir mi?** Konumu veya operasyon türü olan depoyu, alt konumu olan konumu silmeyin; pasife alın.
### 10. Dosyalar ve geri alma
- **Tablolar:** `sql/object/Inv_T_*.sql` (12 tablo; bu talepte `Inv_T_Warehouse`, `Inv_T_Location`, `Inv_T_OperationType`).
- **Wizard'lar:** ProductCategory, Attribute, AttributeValue, ProductVariant, BomOverview, Bom, BomComponent, BomOperation, BomOther, Product, ProductGeneral, ProductAttributeLine, ProductSupplier, ProductStock, ProductAccounting, Warehouse, Location, OperationType (`.json`).
- **Demo veri aynaları:** `data/App.Inventory.{ProductCategory,Attribute,Product,Warehouse}.json`.
- **Geri alma:** Wizard Manager'da ana ekranlar (Product, Bom, Attribute) önce, alt formları sonra silinir. Depolar/Konumlar/Operasyon Türleri bağımsızdır; tablo düşürülecekse sıra OperationType → Location → Warehouse (FK). 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:** Eski ürün ekranlarının 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:section App.Inventory.Operations -->
## Operasyonlar (`App.Inventory.Operations`)
### 1. Amaç ve kapsam
Depoya giren, depodan çıkan ve depo içinde taşınan malların belgeleri: Alımlar, Teslimatlar, İç Transferler; hepsinin belgeleri Envanter › Hareketler'de, ürün satırları Envanter › Ürün Hareketleri'nde salt okunur listelenir. Belgeler Tanımlamalar dalındaki Depolar, Konumlar ve Operasyon Türleri'ni kullanır; tamamlanan belge stoğu şube › depo › konum › ürün › lot bazında günceller (Envanter › Stok). Kullanıcılar: depo, satınalma ve sevkiyat ekipleri. Üretim (`Manufacturing`) ve Onarım türleri Üretim menüsünde ayrıca yapılacaktır; Toplu Transfer, Bakım Talebi, Ekipman, Satış Siparişi ve İzlenebilirlik raporu kapsam dışıdır.
### 2. Analiz ve kararlar
Onaylanan analiz (talep "Envanter giriş ve çıkışları"):
- Bütün operasyon türleri tek veri kaynağındadır: başlık `Inv_T_Transfer`, satır `Inv_T_TransferLine`, lot dağılımı `Inv_T_TransferLineLot`; tür `OperationKind` kolonuyla ayrılır. Her tür kendi ekranında (aynı tablo, `DefaultFilter` ile) yönetilir.
- Stok bakiyesi ayrı tablodadır (`Inv_T_Stock`, kullanıcı kararı): yalnız Doğrula yordamı yazar.
- Stok yetmezse belge Bekleyen kalır, Doğrula yapılamaz (negatif stok yok). Rezervasyon yoktur; Doğrula stoğu yeniden kontrol eder.
- Kısmi işlemde kalan, aynı türde yeni belgeye (backorder) geçer.
- Ek kapsam: İade, iç transferde kaynak depo onayı ve teslim, malzeme talebinden iç transfer, transfer fişi yazdırma.
- Belge numarası operasyon türünün numaratöründen gelir: `Inv_T_OperationType.SequencePrefix` kaldırıldı, yerine `SequenceName` (Diziler) geldi; demo operasyon türleri için `Inventory.IKT.*` numaratörleri eklendi.
- Lot/seri bu turdadır: hareket satırında Detaylar butonu lot dağılımını açar; çıkışta lot stoktan gelir, girişte yazılır; Lot/Seri Oluştur ve Otomatik Ata yardımcı butonlardır.
- Giriş ve çıkışın lot ekranı ayrıdır (kullanıcı kararı): stoğa giren satır (alım, teslimat iadesi) **Lot/Seri Numaraları**'nı açar, numara serbest yazılır; stoktan çıkan satır (teslimat, iç transfer, alım iadesi) **Stoktan Lot Seçimi**'ni açar: kaynak konumdaki bütün lotlar eldeki miktarıyla listelenir, Seç işaretlenince Seçilen Miktar eldeki miktarla dolar (EditorScript), azaltılabilir ama eldeki miktarı aşamaz; Değişiklikleri Kaydet ile yazılır (kullanıcı kararı: 100 lotu tek tek yazmak yerine işaretleyerek seçmek). Ayrım belgenin kaynak konumundan gelir (iç konum = stoktan) ve satırın `LotFromStock` kolonunda durur; Lot/Seri Oluştur yalnız giren, Otomatik Ata yalnız çıkan satırda görünür.
- Lot/seri takipli satırda lot girilmişse yapılan miktar lot toplamıdır (kullanıcı kararı: lot seçmek o kadar teslim etmektir); Recalc miktarı lotlardan yazar ve seçilen lotları satırın Lotlar kolonunda (Açıklama'nın sağı) listeler. Tamamlanmış/iptal belgenin miktarına dokunulmaz. Doğrula'nın eşitlik hatası iki miktarı da yazar.
- Ek Bilgi: nakliye bilgileri, sorumlu, proje; ayrı Not sekmesi. Ürün Teslimat Politikası yalnız Teslimatlar'dadır.
- Ürünün Envanter Takibi ve Takip Yöntemi belirleyicidir: takip kapalı ürün stoğa hiç işlenmez ve stok kontrolüne girmez; `Lot`/`Serial` üründe lot dağılımı zorunludur; `Quantity` üründe lot boş tutulur.
Üretimde verilen ek kararlar:
- Stok konum türüne göre işlenir: kaynak konum `Internal` ise stoktan düşer, hedef konum `Internal` ise stoğa eklenir. Tedarikçiler/Müşteriler gibi dış (`External`) konumlar stok tutmaz; alım türünün kaynağı ve teslimat türünün hedefi dış konumdur. Demo veride IKT deposuna "Tedarikçiler" ve "Müşteriler" dış konumları eklendi.
- Formda gösterilmeyen konum (alımın kaynağı, teslimatın hedefi) kayıtta her zaman operasyon türünden yazılır (iade belgesi hariç).
- İç transfer onaycısı kaynak konumun depo sorumlusudur (`Inv_T_Location.ResponsibleUserName`, kullanıcı adı — iş akışı onaycıyı adla eşlediği için Guid tutulmaz (kullanıcı kararı); kayıt sonrası `SourceApproverUserNames`'e kullanıcı adı yazılır). Sorumlu yoksa `ApprovalStatus` "Onay Gerekmez" olur ve akış beklenmez. Ekranda belge durumu (`Status`) ile onay durumu (`ApprovalStatus`) birlikte bulunur: tablo bütün türler için ortak olduğundan durum akış düğümü değil belge yaşam döngüsüdür (standing default 24'ten bilinçli sapma).
- Teslim Alan / Teslim Alma Tarihi iç transferin Doğrula işleminde yazılır (Doğrula'ya basan kullanıcı).
- Birim çevrimi `Inv_F_UomConvert` ile (Adm_T_Uom Type + Ratio, aynı kategori); stok ürünün biriminde, lot miktarı satırın biriminde tutulur.
- Transfer Fişi rapor şablonu (Raporlar kategorisi) satırları belgenin `LineSummary` kolonundan basar: DynamicReport yalnız kaydın alanlarını yer tutucu olarak doldurduğu için satır özeti başlıkta tutulur (`Inv_P_TransferRecalc`).
- Durum butonları satınalmadaki kalıpla çalışır: işlem gizli `PendingAction` alanına yazılır, kayıt sonrası yordam çalıştırır. Başlık kancaları `@PendingAction` kullanmaz; iş akışı güncellemesi yalnız akış alanlarını gönderir.
- Malzeme talebi kalemleri iç transfere yalnız Satınalma › Talepler › Planlama'daki İç Transfer kararıyla gelir (`Prc_P_MaterialRequestPlan`, [App.Prc.md](App.Prc.md)): aynı kaynak → hedef konum için onaya girmemiş taslak transfer varsa satır ona eklenir, yoksa kaynak deponun iç transfer türüyle yeni taslak açılır. İç Transferler'deki Talepten Aktar butonu ve Transfer Talep Kalemleri ekranı 2026-10-13'te kaldırıldı.
- Detaylar satınalmanın `PurchaseDocGrid` diyaloğunu kullanır (ekran `BaseId` ile süzülür; yeni lot satırına `BaseId` filtreden yazılır, `InsertCommand` tabloya yazar).
- Hata kodları 50301–50321.
### 3. Menü ve ekranlar
`Envanter (App.Inventory) › Operasyonlar (App.Inventory.Operations)`: Alımlar, Teslimatlar, İç Transferler. Bütün belgelerin listesi Hareketler (`App.Inventory.Transfer`) Operasyonlar dışında, doğrudan Envanter altındadır (Stok ve Hareketler bölümü).
Sekmeler (menüsüz alt formlar, üç belge ekranında ortak): Operasyonlar (`App.Inventory.TransferLine`), Ek Bilgi (`App.Inventory.TransferOther`, aynı satır), Not (`App.Inventory.TransferNote`, aynı satır); yalnız İç Transferler'de Onay ve Teslim (`App.Inventory.TransferApproval`, aynı satır, salt okunur).
Diyaloglar: Lot/Seri Numaraları (`App.Inventory.TransferLineLot`, giren satırın Detaylar'ı), Stoktan Lot Seçimi (`App.Inventory.TransferLineLotStock`, çıkan satırın Detaylar'ı).
Durum butonları satırdadır ve belgenin durumuna göre görünür (araç çubuğu butonu kayda göre gizlenemez): Yapılacak olarak işaretle (Taslak; iç transferde onay tamamlanmışsa — ve Bekleyen), Doğrula (Hazır), İptal Et (Taslak, Bekleyen, Hazır), İade Et (Tamamlandı), Yazdır (her durumda); İç Transferler'de ayrıca iş akışı butonları. Buton adları durum adlarıyla eşleşir: Yapılacak olarak işaretle › Hazır, Doğrula › Tamamlandı, İptal Et › İptal. Satır butonları (yalnız ürünün takip yöntemi Lot ya da Seri olan satırda görünür): Lot/Seri Oluştur, Otomatik Ata, Detaylar; görünürlük satırın `TrackingMethod` kolonundan okunur. Hareketler'de (`App.Inventory.Transfer`) satırda Detay (salt okunur başlık + Operasyonlar sekmesi), Not ve belgeyi kendi ekranında açan Aç vardır; Ürün Hareketleri'nde de Aç hareketin belgesini açar (`/admin/form/App.Inventory.{Receipt|Delivery|InternalTransfer}/@TransferId`).
### 4. Veri modeli
Tüm tablolar kiracı + tam audit + soft delete, anahtar `Id uniqueidentifier`.
| Tablo / nesne | İçerik |
| --- | --- |
| `Inv_T_Transfer` | TransferNo, BranchId, WarehouseId, OperationTypeId, OperationKind, PartnerId (Kontak), Source/DestinationLocationId, ScheduledDate, EffectiveDate, SourceDocument, PurchaseOrderId, BackorderOfId, ReturnOfId, CarrierId, TrackingReference, Weight (hesap), ShippingWeight, ResponsibleUserId, ProjectId, DeliveryPolicy (`Direct`/`OneTime`, yalnız teslimat), Note, LineSummary (fiş özeti), Status (`Draft`/`Waiting`/`Ready`/`Done`/`Cancelled`), PendingAction, SourceApproverUserNames, iş akışı dörtlüsü, ReceivedByUserId, ReceivedDate |
| `Inv_T_TransferLine` | TransferId (FK cascade), ProductId, Description, DemandQuantity (talep), Quantity (yapılan), UomId, PurchaseOrderLineId, MaterialRequestItemId, PendingAction, TrackingMethod (üründen; envanter takibi kapalıysa boş — Recalc yazar), LotFromStock (kaynak iç konumsa 1 — Recalc yazar), LotNumbers (seçilen lotlar; Lotlar kolonu — Recalc yazar) |
| `Inv_T_TransferLineLot` | TransferLineId (FK cascade), LotNo, Quantity (satırın biriminde) |
| `Inv_T_Stock` | BranchId, WarehouseId, LocationId, ProductId, LotNo (takipsiz üründe boş), Quantity (ürün biriminde), UomId, InDate (FIFO), LastMoveDate; tekil (TenantId, LocationId, ProductId, LotNo) |
| `Inv_V_TransferLineLot` | Lot/Seri Numaraları diyaloğunun kaynağı (`BaseId` = satır) |
| `Inv_V_TransferLineLotStock` | Stoktan Lot Seçimi'nin kaynağı: satırın kaynak konumundaki lotlar (eldeki miktar satırın biriminde) + atanmış miktar; `Id` = satır:stok kaydı, kaydı `Inv_P_TransferLineLotStockSave` yapar |
| `Inv_F_UomConvert` | Birim çevrimi |
| Yordamlar | `Inv_P_Transfer{AfterSave,SetStatus,CheckAvailability,Validate,Copy,Number,Recalc,FromPurchaseOrder,SupplierPrice,LineAfterSave,LineLotGenerate,LineLotAssign}` |
### 5. İş kuralları ve hesaplar
- **Yapılacak olarak işaretle** (taslak, satırlı, konumları dolu; iç transferde onaylı ya da Onay Gerekmez): dış konumdan girişte yapılan miktar talep kadar dolar ve belge Hazır olur. İç konumdan çıkışta satırlar ürün bazında sırayla stoktan karşılanır; tümü karşılanırsa Hazır, değilse Bekleyen. Teslimatta "Mümkün olduğunca kısa sürede" kısmi karşılamada da Hazır yapar, "Tüm ürünler hazır olduğunda" bütün satırları bekler.
- **Yapılacak olarak işaretle** (Bekleyen): aynı hesabı yeniden yapar; stok girdiyse belge Hazır olur.
- **Doğrula** (yalnız Hazır): yapılan miktarı olan satır şarttır; lot/seri takipli üründe lot toplamı yapılan miktara eşit, seride her seri 1 adet ve tekil olmalıdır; iç kaynakta stok (ürün × lot) yetmezse durur. Stok güncellenir, belge Tamamlandı olur, Geçerlilik Tarihi yazılır. Sipariş kaleminin `ReceivedQuantity`'si ve talep kaleminin `DeliveredQuantity`'si artar (iadede azalır); talep kalemi tam karşılanınca `Done` olur. Siparişten açılan alımda ürünün tedarikçi fiyat listesi siparişin birim fiyatı ve son alım tarihiyle yenilenir (`Inv_P_TransferSupplierPrice`; kural [App.Prc.md](App.Prc.md) Talepler bölümünde). Recalc ve İptal Et talep kaleminin satır durumunu plana eşler (`Prc_P_MaterialRequestItemSync`): transferle tamamen planlanmış kalem kapanır, transfer iptal edilir ya da satırı silinirse yeniden açılır ve miktar Planlama'ya döner. Talepten az yapılan satırların kalanı backorder belgesine geçer ve stok kontrolüyle Hazır/Bekleyen açılır.
- **İade Et** (Tamamlandı): kaynak/hedef yer değiştirmiş, yapılan miktarlar ve lotlarıyla taslak belge; iadeden backorder açılmaz.
- **İptal Et**: Tamamlandı ya da İptal dışındaki belgede. İptal edilmiş belge düzenlenemez; tamamlanmış ya da iptal edilmiş belgenin satırı ve lotu değiştirilemez. Yalnız elle açılmış taslak (siparişten, backorder ya da iadeden gelmeyen) silinebilir.
- **Lot/Seri Oluştur**: yalnız giriş satırında; lot takipte kalan miktar için `Inventory.LotNumber`'tan tek lot, seri takipte kalan her birim için `Inventory.SerialNumber`'dan seri (miktar tam sayı olmalı). **Otomatik Ata**: yalnız çıkış satırında; mevcut lotları siler, kaynak konumdaki lotları ilk giren ilk çıkar sırasıyla atar.
- **Satır**: ürün seçilince birim üründen gelir; yeni satırda talep 1, birim Adet. Ürün listesi aktif mal (`Wares`) ürünlerdir.
- **Ağırlık** = Σ ürün ağırlığı × miktar (yapılan, yoksa talep; ürün biriminde).
- **Siparişten alım**: Satınalma Siparişi onaylanınca (ya da tekliften onaylı açılınca) taslak alım açılır; ayrıntı [App.Prc.md](App.Prc.md) › Siparişler.
### 6. Yetki ve görünürlük
İzin grubu `App.Inventory`. Ekran yetkileri `App.Inventory.Operations` altında (Alımlar, Teslimatlar, İç Transferler); üç belge ekranının ortak sekmeleri (Transfer Satırları, Ek Bilgi, Not) da `App.Inventory.Operations` altındadır; Lot/Seri Numaraları Transfer Satırları'nın, Onay ve Teslim İç Transferler'in altındadır. Durum butonları ekranın `.Update`, satır butonları Transfer Satırları'nın `.Update`, Detaylar Lot/Seri Numaraları'nın okuma yetkisini ister. Belge ekranını kullanan role sekme ve diyalog yetkileri de verilmelidir. Yetkiler hiçbir role otomatik atanmaz. Kiracı kapsamlı; şube kolonla tutulur.
### 7. Entegrasyonlar
Satınalma Siparişleri (onayda taslak alım, alınan miktar), Malzeme Talepleri (Planlama › İç Transfer kararı, teslim edilen miktar, kalem kapanışı), Envanter › Tanımlamalar (Depolar, Konumlar, Operasyon Türleri, Ürünler), Kontaklar, Proje, Kullanıcılar, Yönetim › Tanımlamalar › Diziler (operasyon türü numaratörleri, `Inventory.LotNumber`, `Inventory.SerialNumber`), Raporlar (`Transfer Fişi`).
### 8. Akış örneği
1. Satınalma'da P00012 (10 Adet sensör, lot takipli) onaylanır; Alımlar'da IKT/IN/00001 taslak açılır (Tedarikçiler › Ana Depo).
2. Yapılacak olarak işaretle: belge Hazır, yapılan 10. Satırda Lot/Seri Oluştur LOT000001 (10) üretir; Doğrula Ana Depo'ya 10 Adet LOT000001 ekler, P00012 kalemine Alınan 10 yazılır.
3. Teslimatlar'da 4 Adet sensör için belge açılır; Yapılacak olarak işaretle Hazır yapar, Otomatik Ata LOT000001 (4) atar, Doğrula stoğu 6'ya düşürür.
4. İç Transferler'de Ana Depo'dan (sorumlusu var) başka bir iç konuma 2 Adet; Onayla, sorumlu onaylar (belge kendiliğinden hazırlanır), lotlar seçilir, Doğrula; Onay ve Teslim sekmesinde onaylayan ve teslim alan görünür.
### 9. Sık sorulanlar
- **Belge Bekleyen'de kaldı?** Kaynak konumda yeterli stok yok; stok girdikten sonra Yapılacak olarak işaretle'ye basın. Teslimatta politika "Mümkün olduğunca kısa sürede" ise eldeki kısım gönderilir.
- **Doğrula "lot/seri miktarı eşit değil" diyor?** Ürün lot/seri takiplidir; satırdaki Detaylar'dan lot girin ya da Lot/Seri Oluştur (giriş) / Otomatik Ata (çıkış) kullanın.
- **Ürün stokta görünmüyor?** Ürünün Envanter Takibi kapalıysa hareket stoğa işlenmez.
- **"Numaratör bulunamadı"?** Operasyon türünün numaratörü Diziler'de bu kiracı için tanımlı ve aktif olmalıdır.
- **İç transfer hazırlanamıyor?** Kaynak konumun sorumlusu varsa önce Onayla ile onay alınmalıdır; onay verilince belge kendiliğinden hazırlanır.
- **İç transferde sıra nedir?** Satırlar › Onayla › Kaynak Depo Onayı › (otomatik Yapılacak olarak işaretle) › lot seçimi › Doğrula. Onay stok hareketinden önce gelir, çünkü malın kaynak depodan çıkmasına verilen izindir (kullanıcı kararı: onay sonrası Yapılacak olarak işaretle otomatik). Otomatik Yapılacak olarak işaretle şartları sağlanmazsa (satır yok, konum kuralı) belge Taslak kalır ve Yapılacak olarak işaretle elle basılır.
- **İç transfer onay istemiyor, "Onay Gerekmez" yazıyor?** Onaycı kaynak konumun Sorumlu'sudur (kullanıcı adı); Konumlar'da sorumlu girilmemişse belge onay beklemez. Seed'deki konumların sorumlusu `system@sozsoft.com`'dur. Onay akışı için konuma sorumlu atanır (yeni ve taslak belgelerde geçerli olur).
- **İç transferde dış konum ya da aynı konum seçilemiyor?** İç transfer depo içinde taşımadır: Kaynak ve Hedef Konum listeleri yalnız iç konumları gösterir, hedef kaynaktan farklı olmalıdır (formda kural, Yapılacak olarak işaretle/Doğrula'da 50325 ve 50326). İade belgesi bu kuraldan muaftır; yanlışlıkla dış konuma yapılmış eski transfer İade Et ile geri alınır.
- **Siparişten alım açılmadı?** Siparişte envanter takipli ürün kalemi olmalı; siparişin iptal olmayan bir alımı zaten varsa yenisi açılmaz.
### 10. Dosyalar ve geri alma
- **SQL (sql + postgres):** `Inv_T_{Transfer,TransferLine,TransferLineLot,Stock}`, `Inv_V_{StockMove,TransferLineLot,TransferLineLotStock}`, `Inv_F_UomConvert`, `Inv_P_Transfer*`; değişen: `Inv_T_OperationType` (SequenceName), `Prc_T_PurchaseOrderLine` (ReceivedQuantity), `Prc_P_PurchaseOrderSetStatus`, `Prc_P_PurchaseRfqAward`.
- **Wizard'lar:** `Inventory_{Receipt,Delivery,InternalTransfer,Transfer,TransferLine,TransferLineLot,TransferLineLotStock,TransferOther,TransferNote,TransferApproval}.json`; değişen `Inventory_OperationType.json`, `Prc_PurchaseOrderLine.json`.
- **Seed verisi:** numaratörler `data/App.Definitions.Sequence.json` (`Inventory.IKT.*`, `Inventory.LotNumber`, `Inventory.SerialNumber`), dış konumlar `data/App.Inventory.Location.json`, operasyon türü bağları `data/App.Inventory.OperationType.json`, şablon `data/App.Reports.ReportTemplates.json` (Transfer Fişi).
- **Geri alma:** Wizard Manager'da önce belge ekranları, sonra sekmeler ve diyaloglar silinir; tablolar ancak açık onayla düşürülür (sıra: TransferLineLot → TransferLine → Transfer, Stock).
<!-- module-doc:section App.Inventory.Stock claims=App.Inventory.Transfer, App.Inventory.StockMove -->
## Stok, Hareketler ve Ürün Hareketleri (`App.Inventory.Stock`, `App.Inventory.Transfer`, `App.Inventory.StockMove`)
### 1. Amaç ve kapsam
Stok bakiyesi ve bütün hareketlerin salt okunur listeleri: Stok (şube › depo › konum › ürün › lot) ve Hareketler (bütün operasyon türlerinin satırları ortak kolonlarla). Kullanıcılar: depo, satınalma, üretim planlama ve yönetim. Değerleme (maliyet) ve izlenebilirlik raporu kapsam dışıdır.
### 2. Analiz ve kararlar
- Stok `Inv_T_Stock` tablosundan okunur; tabloya yalnız Doğrula yazar (Operasyonlar §2).
- Hareketler `Inv_V_StockMove` görünümüdür: satır başına bir kayıt, lot dağılımı varsa lot başına bir kayıt; bütün durumlar listelenir, stoğu yalnız Tamamlandı satırları değiştirir.
- Görünümler Grid, Card, Pivot, Chart; depo × ürün toplamı Pivot ile alınır.
### 3. Menü ve ekranlar
Ayrı bir Raporlama dalı yoktur (kullanıcı kararı): Stok (`App.Inventory.Stock`, sıra 3), Hareketler (`App.Inventory.Transfer`, sıra 4 — alım, teslimat ve iç transfer belgeleri; satırda Detay, Not ve belgeyi kendi ekranında açan Aç) ve Ürün Hareketleri (`App.Inventory.StockMove`, sıra 5 — ürün/lot satırları; satırda Aç) doğrudan `Envanter` altında, Operasyonlar'dan sonradır; hepsi salt okunur. Yetkiler aynı sırada `App.Inventory` kökündedir.
### 4. Veri modeli
`Inv_T_Stock` (Operasyonlar §4) ve `Inv_V_StockMove`: Id (lot ya da satır), TransferId, TransferNo, OperationKind, OperationTypeId, Status, MoveDate (geçerlilik, yoksa planlanan tarih), BranchId, WarehouseId, Source/DestinationLocationId, PartnerId, SourceDocument, ProductId, LotNo, DemandQuantity, Quantity, UomId.
### 5. İş kuralları ve hesaplar
- Stok miktarı ürünün birimindedir; hareket miktarı satırın (lotta lotun) birimindedir.
- Sıfıra inen stok satırı silinmez (Sıfır Stok kartı); yeniden girişte giriş tarihi yenilenir.
- Kartlar: Stok — Stoktaki Ürün, Stoktaki Lot, Sıfır Stok; Hareketler — Açık Alım, Açık Teslimat, Açık İç Transfer, Geciken; Ürün Hareketleri — Bugün Tamamlanan, Tamamlanan Giriş, Tamamlanan Çıkış, Açık Hareket.
### 6. Yetki ve görünürlük
İki ekranın yetkisi menüyle aynı sırada `App.Inventory` izin grubunun kökündedir (`App.Inventory.Stock` sıra 3, `App.Inventory.StockMove` sıra 4); yetkiler hiçbir role otomatik atanmaz. Kiracı kapsamlı.
### 7. Entegrasyonlar
Kaynak Operasyonlar dalının belgeleridir; lookup kaynakları Şubeler, Depolar, Konumlar, Ürünler, Ölçü Birimleri, Kontaklar.
### 8. Akış örneği
Operasyonlar §8'deki akıştan sonra Stok'ta Ana Depo / sensör / LOT000001 = 4 görünür; Ürün Hareketleri'nde IKT/IN/00001 (+10), teslimat (−4) ve iç transfer satırları listelenir.
### 9. Sık sorulanlar
- **Hareket listede ama stok değişmedi?** Hareket Tamamlandı değildir ya da ürünün envanter takibi kapalıdır.
- **Dış konum stokta yok mu?** Tedarikçiler/Müşteriler gibi dış konumlar stok tutmaz.
### 10. Dosyalar ve geri alma
Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_Stock`, `Inv_V_StockMove` (sql + postgres). Ekranlar Wizard Manager'dan silinir; tablo ve görünüm Operasyonlar'a bağlıdır.
<!-- 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/Inventory_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, Tree (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/Inventory_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` |
| Form varsayılanları | IsActive=true |
| 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 | ✓ | ✓ | |
#### Ürünler — `App.Inventory.Product`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_Product.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.Product` (sıra 3) |
| 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.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 | | ✓ | |
#### Ürün Varyantları — `App.Inventory.ProductVariant`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_ProductVariant.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.ProductVariant` (sıra 4) |
| Yetki | `App.Inventory.ProductVariant` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import` |
| 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ı |
| Form varsayılanları | IsActive=true |
| 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 | | ✓ | |
#### Reçeteler — `App.Inventory.Bom`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_Bom.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.Bom` (sıra 5) |
| 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 | ✓ | ✓ | |
#### Reçeteye Genel Bakış — `App.Inventory.BomOverview`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_BomOverview.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.BomOverview` (sıra 6) |
| Yetki | `App.Inventory.BomOverview` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import` |
| 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, CAST(NULL AS nvarchar(400)) AS ParentName 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, CAST((SELECT pp.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(bp.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') FROM Inv_T_Bom bp INNER JOIN Inv_T_Product pp ON pp.Id = bp.ProductId WHERE bp.Id = b0.Id) AS nvarchar(400)) 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, CAST((SELECT pp.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(cp.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') FROM Inv_T_BomComponent cp INNER JOIN Inv_T_Product pp ON pp.Id = cp.ProductId WHERE cp.Id = c1.Id) AS nvarchar(400)) 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, CAST((SELECT pp.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(cp.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') FROM Inv_T_BomComponent cp INNER JOIN Inv_T_Product pp ON pp.Id = cp.ProductId WHERE cp.Id = c2.Id) AS nvarchar(400)) 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, CAST((SELECT pp.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(cp.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') FROM Inv_T_BomComponent cp INNER JOIN Inv_T_Product pp ON pp.Id = cp.ProductId WHERE cp.Id = c3.Id) AS nvarchar(400)) 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, CAST((SELECT pp.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(bp.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') FROM Inv_T_Bom bp INNER JOIN Inv_T_Product pp ON pp.Id = bp.ProductId WHERE bp.Id = b0.Id) AS nvarchar(400)) FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomOperation o ON o.BomId = b0.Id AND o.IsDeleted = 'false' INNER JOIN Prd_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, CAST('Operasyonlar' AS nvarchar(400)) FROM Inv_T_Bom b0 INNER JOIN Inv_T_BomOperation o ON o.BomId = b0.Id AND o.IsDeleted = 'false' INNER JOIN Prd_T_Operation op ON op.Id = o.OperationId INNER JOIN Prd_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, CAST((SELECT pp.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(cp.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') FROM Inv_T_BomComponent cp INNER JOIN Inv_T_Product pp ON pp.Id = cp.ProductId WHERE cp.Id = c1.Id) AS nvarchar(400)) 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 Prd_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, CAST('Operasyonlar' AS nvarchar(400)) 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 Prd_T_Operation op ON op.Id = o.OperationId INNER JOIN Prd_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, CAST((SELECT pp.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(cp.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') FROM Inv_T_BomComponent cp INNER JOIN Inv_T_Product pp ON pp.Id = cp.ProductId WHERE cp.Id = c2.Id) AS nvarchar(400)) 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 Prd_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, CAST('Operasyonlar' AS nvarchar(400)) 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 Prd_T_Operation op ON op.Id = o.OperationId INNER JOIN Prd_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, CAST((SELECT pp.Name + ISNULL(' (' + (SELECT STRING_AGG(avn.Name, ', ') FROM STRING_SPLIT(cp.VariantKey, '\|') sn INNER JOIN Inv_T_AttributeValue avn ON CAST(avn.Id AS nvarchar(36)) = sn.value) + ')', '') FROM Inv_T_BomComponent cp INNER JOIN Inv_T_Product pp ON pp.Id = cp.ProductId WHERE cp.Id = c3.Id) AS nvarchar(400)) 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 Prd_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, CAST('Operasyonlar' AS nvarchar(400)) 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 Prd_T_Operation op ON op.Id = o.OperationId INNER JOIN Prd_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 |
| --- | --- | --- | --- | --- | --- |
| `Name` | Ürün | dxTextBox | | ✓ | |
| `ParentKey` | Üst Düğüm | dxTextBox | | | |
| `ParentName` | Üst Düğüm | 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 | | | |
#### Depolar — `App.Inventory.Warehouse`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_Warehouse.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.Warehouse` (sıra 7) |
| Yetki | `App.Inventory.Warehouse` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Depolar — stoğun fiziksel olarak tutulduğu yerler; her depo bir şubeye bağlıdır. |
| Geliştirme talebi | Envanter -> Tanımlamalar |
| Kaynak | `Inv_T_Warehouse` · 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` |
| Form varsayılanları | IsActive=true |
| Veri aynası | `data/App.Inventory.Warehouse.json` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `BranchId` | Şube Adı | dxSelectBox | ✓ | ✓ | sorgu: Sas_T_Branch |
| `Code` | Depo Kodu | dxTextBox | ✓ | ✓ | |
| `Name` | Depo Adı | dxTextBox | ✓ | ✓ | |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
#### Konumlar — `App.Inventory.Location`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_Location.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.Location` (sıra 8) |
| Yetki | `App.Inventory.Location` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Konumlar — şube ve depo bazında iç içe tanımlanan stok konumları (ör. GRP › Stock › Ana Depo AB07). |
| Geliştirme talebi | Envanter -> Tanımlamalar |
| Kaynak | `Inv_T_Location` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart, Tree (açılış tree) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Widget'lar | `App.Widget.Total`, `App.Widget.Active`, `App.Widget.Passive` |
| Form varsayılanları | LocationType=Internal, IsActive=true |
| Veri aynası | `data/App.Inventory.Location.json` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `BranchId` | Şube Adı | dxSelectBox | ✓ | ✓ | sorgu: Sas_T_Branch |
| `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse (← BranchId) |
| `Code` | Konum Kodu | dxTextBox | | ✓ | |
| `Name` | Konum | dxTextBox | ✓ | ✓ | |
| `DepartmentId` | Departman | dxSelectBox | | ✓ | sorgu: Hr_T_Department (← BranchId) |
| `ResponsibleUserName` | Depo Sorumlusu | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `LocationType` | Konum Türü | dxSelectBox | ✓ | ✓ | liste: Internal, External |
| `ParentId` | Üst Lokasyon | dxSelectBox | | ✓ | sorgu: Inv_T_Location (← WarehouseId) |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
#### Operasyon Türleri — `App.Inventory.OperationType`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_OperationType.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Definitions` › `App.Inventory.OperationType` (sıra 9) |
| Yetki | `App.Inventory.OperationType` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Operasyon Türleri — şube ve depo bazında tanımlanan stok operasyon türleri (ör. Alımlar, Teslimatlar, İç Transferler). |
| Geliştirme talebi | Envanter -> Tanımlamalar |
| Kaynak | `Inv_T_OperationType` · 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` |
| Form varsayılanları | OperationKind=Receipt, IsActive=true |
| Veri aynası | `data/App.Inventory.OperationType.json` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `BranchId` | Şube Adı | dxSelectBox | ✓ | ✓ | sorgu: Sas_T_Branch |
| `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse (← BranchId) |
| `Name` | Operasyon Türü | dxTextBox | ✓ | ✓ | |
| `OperationKind` | Tür | dxSelectBox | ✓ | ✓ | liste: Receipt, Delivery, InternalTransfer, Manufacturing, Repair |
| `SequenceName` | Numaratör | dxSelectBox | ✓ | ✓ | sorgu: Adm_T_Sequence |
| `Barcode` | Barkod | dxTextBox | | ✓ | |
| `SourceLocationId` | Kaynak Konum | dxSelectBox | | ✓ | sorgu: Inv_T_Location (← WarehouseId) |
| `DestinationLocationId` | Hedef Konum | dxSelectBox | | ✓ | sorgu: Inv_T_Location (← WarehouseId) |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
#### Nitelik Değerleri — `App.Inventory.AttributeValue`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_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 | ✓ | ✓ | |
#### Bileşenler — `App.Inventory.BomComponent`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_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/Inventory_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: Prd_T_Operation · script |
| `WorkCenterId` | İş Merkezi | dxSelectBox | ✓ | ✓ | sorgu: Prd_T_WorkCenter |
| `DurationMin` | Süre (dakika) | dxNumberBox | ✓ | ✓ | |
| `SortOrder` | Sıra | dxNumberBox | | ✓ | |
#### Diğer — `App.Inventory.BomOther`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_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/Inventory_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ı | dxTextBox | | ✓ | |
| `InternalNotes` | İç Notlar | dxTextBox | | ✓ | |
#### Nitelik & Varyantlar — `App.Inventory.ProductAttributeLine`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_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/Inventory_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ı |
| Form varsayılanları | MinQuantity=0, CurrencyId=TRY, UomId=Adet, Price=0 |
| 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 | | ✓ | |
| `LastPurchaseDate` | Son Alım Tarihi | dxDateBox | | | |
#### Stok — `App.Inventory.ProductStock`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_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 | dxTextBox | | ✓ | |
| `DeliveryNote` | Teslimatlar İçin Açıklama | dxTextArea | | ✓ | |
| `InternalTransferNote` | İç Transferler İçin Açıklama | dxTextArea | | ✓ | |
#### Muhasebe — `App.Inventory.ProductAccounting`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_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 | | ✓ | |
### Operasyonlar (`App.Inventory.Operations`)
#### Alımlar — `App.Inventory.Receipt`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_Receipt.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Operations` › `App.Inventory.Receipt` (sıra 1) |
| Yetki | `App.Inventory.Receipt` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Alımlar — tedarikçiden depoya giren mallar. |
| Kaynak | `Inv_T_Transfer` · filtre `"IsDeleted" = 'false' AND "OperationKind" = 'Receipt'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Inventory.TransferLine` (Id → TransferId), `App.Inventory.TransferOther` (Id → Id), `App.Inventory.TransferNote` (Id → Id) |
| Widget'lar | `App.Widget.Draft`, `App.Inventory.Widget.Waiting`, `App.Inventory.Widget.Ready`, `App.Inventory.Widget.Late` |
| Komutlar | InsertAfter: `Inv_P_TransferAfterSave` · UpdateBefore: SQL · UpdateAfter: `Inv_P_TransferAfterSave` · DeleteBefore: SQL |
| Form varsayılanları | Status=Draft, OperationKind=Receipt, ScheduledDate=@NOW, BranchId= |
| Butonlar | `App.Inventory.Transfer.Action.Confirm`, `App.Inventory.Transfer.Action.Validate`, `App.Inventory.Transfer.Action.Cancel`, `App.Inventory.Transfer.Action.Return`, `App.Inventory.Transfer.Action.Print` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `PartnerId` | Tedarikçi Adı | dxSelectBox | | ✓ | sorgu: Adm_T_Contact |
| `TransferNo` | Fiş No | dxTextBox | | ✓ | |
| `Status` | Durum | dxSelectBox | | ✓ | liste: Draft, Waiting, Ready, Done, Cancelled |
| `ScheduledDate` | Planlanan Tarih | dxDateBox | ✓ | ✓ | |
| `EffectiveDate` | Geçerlilik Tarihi | dxDateBox | | ✓ | |
| `BranchId` | Şube | dxSelectBox | ✓ | ✓ | sorgu: Sas_T_Branch |
| `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse (← BranchId) |
| `OperationTypeId` | Operasyon Türü | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_OperationType (← WarehouseId) · script |
| `DestinationLocationId` | Hedef Konum | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Location (← WarehouseId) |
| `SourceLocationId` | Kaynak Konum | dxSelectBox | | | sorgu: Inv_T_Location |
| `OperationKind` | OperationKind | dxSelectBox | | | liste: Receipt, Delivery, InternalTransfer, Manufacturing, Repair |
| `PendingAction` | PendingAction | dxTextBox | | | |
| `LineSummary` | LineSummary | dxTextBox | | | |
| `SourceDocument` | Kaynak Belge | dxTextBox | | ✓ | |
#### Teslimatlar — `App.Inventory.Delivery`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_Delivery.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Operations` › `App.Inventory.Delivery` (sıra 2) |
| Yetki | `App.Inventory.Delivery` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Teslimatlar — depodan müşteriye çıkan mallar. |
| Kaynak | `Inv_T_Transfer` · filtre `"IsDeleted" = 'false' AND "OperationKind" = 'Delivery'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Inventory.TransferLine` (Id → TransferId), `App.Inventory.TransferOther` (Id → Id), `App.Inventory.TransferNote` (Id → Id) |
| Widget'lar | `App.Widget.Draft`, `App.Inventory.Widget.Waiting`, `App.Inventory.Widget.Ready`, `App.Inventory.Widget.Late` |
| Komutlar | InsertAfter: `Inv_P_TransferAfterSave` · UpdateBefore: SQL · UpdateAfter: `Inv_P_TransferAfterSave` · DeleteBefore: SQL |
| Form varsayılanları | Status=Draft, OperationKind=Delivery, ScheduledDate=@NOW, BranchId=, DeliveryPolicy=Direct |
| Butonlar | `App.Inventory.Transfer.Action.Confirm`, `App.Inventory.Transfer.Action.Validate`, `App.Inventory.Transfer.Action.Cancel`, `App.Inventory.Transfer.Action.Return`, `App.Inventory.Transfer.Action.Print` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `TransferNo` | Fiş No | dxTextBox | | ✓ | |
| `Status` | Durum | dxSelectBox | | ✓ | liste: Draft, Waiting, Ready, Done, Cancelled |
| `ScheduledDate` | Planlanan Tarih | dxDateBox | ✓ | ✓ | |
| `PartnerId` | Teslim Adresi | dxSelectBox | | ✓ | sorgu: Adm_T_Contact |
| `BranchId` | Şube | dxSelectBox | ✓ | ✓ | sorgu: Sas_T_Branch |
| `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse (← BranchId) |
| `OperationTypeId` | Operasyon Türü | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_OperationType (← WarehouseId) · script |
| `SourceLocationId` | Kaynak Konum | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Location (← WarehouseId) |
| `DestinationLocationId` | Hedef Konum | dxSelectBox | | | sorgu: Inv_T_Location |
| `EffectiveDate` | Geçerlilik Tarihi | dxDateBox | | ✓ | |
| `SourceDocument` | Kaynak Belge | dxTextBox | | ✓ | |
| `DeliveryPolicy` | Ürün Teslimat Politikası | dxSelectBox | ✓ | ✓ | liste: Direct, OneTime |
| `OperationKind` | OperationKind | dxSelectBox | | | liste: Receipt, Delivery, InternalTransfer, Manufacturing, Repair |
| `PendingAction` | PendingAction | dxTextBox | | | |
| `LineSummary` | LineSummary | dxTextBox | | | |
#### İç Transferler — `App.Inventory.InternalTransfer`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_InternalTransfer.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory.Operations` › `App.Inventory.InternalTransfer` (sıra 3) |
| Yetki | `App.Inventory.InternalTransfer` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | İç Transferler — iç konumlar arasında taşıma (aynı depo ya da depolar arası). |
| Kaynak | `Inv_T_Transfer` · filtre `"IsDeleted" = 'false' AND "OperationKind" = 'InternalTransfer'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Inventory.TransferLine` (Id → TransferId), `App.Inventory.TransferOther` (Id → Id), `App.Inventory.TransferNote` (Id → Id), `App.Inventory.TransferApproval` (Id → Id) |
| Widget'lar | `App.Widget.Draft`, `App.Inventory.Widget.Waiting`, `App.Inventory.Widget.Ready`, `App.Inventory.Widget.Late` |
| Komutlar | InsertAfter: `Inv_P_TransferAfterSave` · UpdateBefore: SQL · UpdateAfter: `Inv_P_TransferAfterSave` · DeleteBefore: SQL |
| Form varsayılanları | Status=Draft, OperationKind=InternalTransfer, ScheduledDate=@NOW, BranchId= |
| Butonlar | `App.Inventory.Transfer.Action.Confirm`, `App.Inventory.Transfer.Action.Validate`, `App.Inventory.Transfer.Action.Cancel`, `App.Inventory.Transfer.Action.Return`, `App.Inventory.Transfer.Action.Print` |
| Onay akışı | Start 'Onaya Gönderildi' → Approval 'Kaynak Depo Onayı' → End 'Onaylandı' → End 'Reddedildi' |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `TransferNo` | Fiş No | dxTextBox | | ✓ | |
| `ScheduledDate` | Planlanan Tarih | dxDateBox | ✓ | ✓ | |
| `PartnerId` | Kontak | dxSelectBox | | ✓ | sorgu: Adm_T_Contact |
| `Status` | Durum | dxSelectBox | | ✓ | liste: Draft, Waiting, Ready, Done, Cancelled |
| `BranchId` | Şube | dxSelectBox | ✓ | ✓ | sorgu: Sas_T_Branch |
| `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse (← BranchId) |
| `OperationTypeId` | Operasyon Türü | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_OperationType (← WarehouseId) · script |
| `EffectiveDate` | Geçerlilik Tarihi | dxDateBox | | ✓ | |
| `SourceLocationId` | Kaynak Konum | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Location (← WarehouseId) |
| `DestinationLocationId` | Hedef Konum | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Location (← WarehouseId) |
| `SourceDocument` | Kaynak Belge | dxTextBox | | ✓ | |
| `OperationKind` | OperationKind | dxSelectBox | | | liste: Receipt, Delivery, InternalTransfer, Manufacturing, Repair |
| `PendingAction` | PendingAction | dxTextBox | | | |
| `LineSummary` | LineSummary | dxTextBox | | | |
| `ApprovalStatus` | Kaynak Depo Onayı | dxTextBox | | | |
| `ApprovalUserName` | Onaylayan | dxTextBox | | | |
| `ApprovalDate` | Onay Tarihi | dxDateBox | | | |
| `ApprovalDescription` | Onay Açıklaması | dxTextBox | | | |
| `SourceApproverUserNames` | SourceApproverUserNames | dxTextBox | | | |
#### Lot/Seri Numaraları — `App.Inventory.TransferLineLot`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_TransferLineLot.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.TransferLineLot` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import` |
| Açıklama | Lot/Seri Numaraları — stoğa giren satırın (alım, teslimat iadesi) lot ya da seri numaraları; satırdaki Detaylar butonuyla açılır. |
| Kaynak | `Inv_V_TransferLineLot` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Komutlar | InsertBefore: SQL · InsertAfter: `Inv_P_TransferRecalc` · UpdateBefore: SQL · UpdateAfter: `Inv_P_TransferRecalc` · DeleteBefore: SQL · DeleteAfter: `Inv_P_TransferRecalc` |
| Form varsayılanları | Quantity=1 |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `BaseId` | BaseId | dxTextBox | | | |
| `LotNo` | Lot/Seri No | dxTextBox | ✓ | ✓ | |
| `Quantity` | Miktar | dxNumberBox | ✓ | ✓ | |
#### Stoktan Lot Seçimi — `App.Inventory.TransferLineLotStock`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_TransferLineLotStock.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.TransferLineLotStock` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import` |
| Açıklama | Stoktan Lot Seçimi — stoktan çıkan satırın (teslimat, iç transfer, alım iadesi) kaynak konumundaki bütün lot/seriler; satırdaki Detaylar butonuyla açılır. |
| Kaynak | `Inv_V_TransferLineLotStock` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · batch |
| Kapsam | Kiracı |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `BaseId` | BaseId | dxTextBox | | | |
| `IsSelected` | Seç | dxCheckBox | | ✓ | script |
| `LotNo` | Lot/Seri No | dxTextBox | | | |
| `InDate` | Giriş Tarihi | dxDateBox | | | |
| `OnHand` | Eldeki Miktar | dxNumberBox | | | |
| `SelectedQuantity` | Seçilen Miktar | dxNumberBox | | ✓ | script |
| `UomId` | Birim | dxTextBox | | | |
#### Transfer Satırları — `App.Inventory.TransferLine`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_TransferLine.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.TransferLine` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Transfer Satırları — alım, teslimat ve iç transferlerin ürün satırları. |
| Kaynak | `Inv_T_TransferLine` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Komutlar | InsertBefore: SQL · InsertAfter: `Inv_P_TransferRecalc` · UpdateBefore: SQL · UpdateAfter: `Inv_P_TransferLineAfterSave` · DeleteBefore: SQL · DeleteAfter: `Inv_P_TransferRecalc` |
| Form varsayılanları | DemandQuantity=1, UomId=Adet |
| Butonlar | `App.Inventory.TransferLine.GenerateLots`, `App.Inventory.TransferLine.AssignLots`, `App.Inventory.TransferLine.Details` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `TransferId` | TransferId | dxTextBox | | | |
| `ProductId` | Ürün | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Product · script |
| `DemandQuantity` | Talep | dxNumberBox | ✓ | ✓ | |
| `Quantity` | Miktar | dxNumberBox | | ✓ | |
| `UomId` | Birim | dxSelectBox | ✓ | ✓ | sorgu: Adm_T_Uom |
| `Description` | Açıklama | dxTextArea | | ✓ | |
| `LotNumbers` | Lotlar | dxTextBox | | | |
| `PurchaseOrderLineId` | PurchaseOrderLineId | dxTextBox | | | |
| `MaterialRequestItemId` | MaterialRequestItemId | dxTextBox | | | |
| `PendingAction` | PendingAction | dxTextBox | | | |
| `TrackingMethod` | Takip Yöntemi | dxTextBox | | | |
| `LotFromStock` | Lot Stoktan | dxCheckBox | | | |
#### Ek Bilgi — `App.Inventory.TransferOther`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_TransferOther.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.TransferOther` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Ek Bilgi — transfer belgesinin nakliye ve diğer bilgileri (alım, teslimat ve iç transferlerin Ek Bilgi sekmesi). |
| Kaynak | `Inv_T_Transfer` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Komutlar | UpdateBefore: SQL |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `CarrierId` | Nakliyeci | dxSelectBox | | ✓ | sorgu: Adm_T_Contact |
| `ResponsibleUserId` | Sorumlu | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `TrackingReference` | Takip Referansı | dxTextBox | | ✓ | |
| `ProjectId` | Proje | dxSelectBox | | ✓ | sorgu: Prj_T_Project |
| `Weight` | Ağırlık (kg) | dxNumberBox | | ✓ | |
| `ShippingWeight` | Nakliye Ağırlığı (kg) | dxNumberBox | | ✓ | |
#### Not — `App.Inventory.TransferNote`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_TransferNote.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.TransferNote` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Not — transfer belgesinin serbest notu (alım, teslimat ve iç transferlerin Not sekmesi). |
| Kaynak | `Inv_T_Transfer` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Komutlar | UpdateBefore: SQL |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `Note` | Not | dxHtmlEditor | | ✓ | |
#### Onay ve Teslim — `App.Inventory.TransferApproval`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_TransferApproval.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.TransferApproval` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Onay ve Teslim — iç transferin kaynak depo onayı ve teslimi (İç Transferler'in Onay ve Teslim sekmesi; salt okunur). |
| Kaynak | `Inv_T_Transfer` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Komutlar | UpdateBefore: SQL |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `ApprovalStatus` | Kaynak Depo Onayı | dxTextBox | | ✓ | |
| `ReceivedByUserId` | Teslim Alan | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `ApprovalUserName` | Onaylayan | dxTextBox | | ✓ | |
| `ReceivedDate` | Teslim Alma Tarihi | dxDateBox | | ✓ | |
| `ApprovalDate` | Onay Tarihi | dxDateBox | | ✓ | |
| `ApprovalDescription` | Onay Açıklaması | dxTextBox | | ✓ | |
### Stok, Hareketler ve Ürün Hareketleri (`App.Inventory.Stock`, `App.Inventory.Transfer`, `App.Inventory.StockMove`)
#### Stok — `App.Inventory.Stock`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_Stock.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory` › `App.Inventory.Stock` (sıra 3) |
| Yetki | `App.Inventory.Stock` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Stok — şube › depo › konum › ürün › lot bazında eldeki miktar, ürünün biriminde (salt okunur). |
| Kaynak | `Inv_T_Stock` · 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.Inventory.Widget.Products`, `App.Inventory.Widget.Lots`, `App.Inventory.Widget.ZeroStock` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `BranchId` | Şube | dxSelectBox | | | sorgu: Sas_T_Branch |
| `WarehouseId` | Depo | dxSelectBox | | | sorgu: Inv_T_Warehouse |
| `LocationId` | Konum | dxSelectBox | | | sorgu: Inv_T_Location |
| `ProductId` | Ürün | dxSelectBox | | | sorgu: Inv_T_Product |
| `LotNo` | Lot/Seri No | dxTextBox | | | |
| `Quantity` | Miktar | dxNumberBox | | | |
| `UomId` | Birim | dxSelectBox | | | sorgu: Adm_T_Uom |
| `InDate` | Giriş Tarihi | dxDateBox | | | |
| `LastMoveDate` | Son Hareket | dxDateBox | | | |
#### Hareketler — `App.Inventory.Transfer`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_Transfer.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory` › `App.Inventory.Transfer` (sıra 4) |
| Yetki | `App.Inventory.Transfer` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Hareketler — alım, teslimat ve iç transfer belgeleri tek, salt okunur listede. |
| Kaynak | `Inv_T_Transfer` · 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.TransferLine` (Id → TransferId) |
| Widget'lar | `App.Inventory.Widget.OpenReceipts`, `App.Inventory.Widget.OpenDeliveries`, `App.Inventory.Widget.OpenInternal`, `App.Inventory.Widget.Late` |
| Butonlar | `App.Inventory.Transfer.Open`, `App.Inventory.Transfer.Open`, `App.Inventory.Transfer.Open` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `TransferNo` | Fiş No | dxTextBox | | ✓ | |
| `OperationKind` | Tür | dxSelectBox | | ✓ | liste: Receipt, Delivery, InternalTransfer, Manufacturing, Repair |
| `OperationTypeId` | Operasyon Türü | dxSelectBox | | ✓ | sorgu: Inv_T_OperationType |
| `PartnerId` | Kontak | dxSelectBox | | ✓ | sorgu: Adm_T_Contact |
| `BranchId` | Şube | dxSelectBox | | ✓ | sorgu: Sas_T_Branch |
| `WarehouseId` | Depo | dxSelectBox | | ✓ | sorgu: Inv_T_Warehouse |
| `SourceLocationId` | Kaynak Konum | dxSelectBox | | ✓ | sorgu: Inv_T_Location |
| `DestinationLocationId` | Hedef Konum | dxSelectBox | | ✓ | sorgu: Inv_T_Location |
| `ScheduledDate` | Planlanan Tarih | dxDateBox | | ✓ | |
| `EffectiveDate` | Geçerlilik Tarihi | dxDateBox | | ✓ | |
| `SourceDocument` | Kaynak Belge | dxTextBox | | ✓ | |
| `Status` | Durum | dxSelectBox | | ✓ | liste: Draft, Waiting, Ready, Done, Cancelled |
#### Ürün Hareketleri — `App.Inventory.StockMove`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_StockMove.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Inventory` › `App.Inventory.StockMove` (sıra 5) |
| Yetki | `App.Inventory.StockMove` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import` |
| Açıklama | Ürün Hareketleri — alım, teslimat ve iç transferlerin bütün ürün satırları ortak kolonlarla; satırın lot dağılımı varsa lot başına bir satır (salt okunur). |
| Kaynak | `Inv_V_StockMove` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✗ · sil ✗ · popup |
| Kapsam | Kiracı |
| Widget'lar | `App.Inventory.Widget.DoneToday`, `App.Inventory.Widget.DoneReceipts`, `App.Inventory.Widget.DoneDeliveries`, `App.Inventory.Widget.OpenMoves` |
| Butonlar | `App.Inventory.Transfer.Open`, `App.Inventory.Transfer.Open`, `App.Inventory.Transfer.Open` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `PartnerId` | Kontak | dxSelectBox | | | sorgu: Adm_T_Contact |
| `TransferId` | TransferId | dxTextBox | | | |
| `MoveDate` | Tarih | dxDateBox | | | |
| `TransferNo` | Fiş No | dxTextBox | | | |
| `OperationKind` | Tür | dxSelectBox | | | liste: Receipt, Delivery, InternalTransfer, Manufacturing, Repair |
| `OperationTypeId` | Operasyon Türü | dxSelectBox | | | sorgu: Inv_T_OperationType |
| `Status` | Durum | dxSelectBox | | | liste: Draft, Waiting, Ready, Done, Cancelled |
| `ProductId` | Ürün | dxSelectBox | | | sorgu: Inv_T_Product |
| `DemandQuantity` | Talep | dxNumberBox | | | |
| `LotNo` | Lot/Seri No | dxTextBox | | | |
| `Quantity` | Miktar | dxNumberBox | | | |
| `UomId` | Birim | dxSelectBox | | | sorgu: Adm_T_Uom |
| `BranchId` | Şube | dxSelectBox | | | sorgu: Sas_T_Branch |
| `WarehouseId` | Depo | dxSelectBox | | | sorgu: Inv_T_Warehouse |
| `SourceLocationId` | Kaynak Konum | dxSelectBox | | | sorgu: Inv_T_Location |
| `DestinationLocationId` | Hedef Konum | dxSelectBox | | | sorgu: Inv_T_Location |
| `SourceDocument` | Kaynak Belge | dxTextBox | | | |
<!-- module-doc:auto:end -->