# 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. ## 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. Ekipman sekmesi (2026-10-18): - Ürünler'e Reçeteler'in soluna "Ekipman" sekmesi eklendi. Ekipman ayrı bir kayıt değil, ürünün kendisidir (Bakım › Ekipman Kategorileri "ekipman olan ürünler" kararı); sekme Muhasebe/Stok gibi ürün satırını düzenleyen Form sekmesidir (`Id → Id`). - Alanlar görseldeki gibi: tedarikçi, tedarikçi referansı, model, seri numarası, geçerlilik tarihi, maliyet, garanti bitiş tarihi; ek olarak ekipman kategorisi (`Mm_T_EquipmentCategory`), ekipmanın ait olduğu departman (`Hr_T_Department`) ve masraf merkezi (`Mm_T_CostCenter`, Bakım › Tanımlamalar › Masraf Merkezleri; yalnız aktifler, "Üst / Ad" olarak). - Kolonlar `Equipment` önekiyle `Inv_T_Product`'a eklendi; ekipman maliyeti (`EquipmentCost`, edinim değeri) ürünün stok maliyetinden (`Cost`) ayrıdır. - Kategori ve departman şube kapsamlı olduğundan seçimde "Şube / Kategori" ve "Şube / Departman" gösterilir; listeler kiracının bütün şubelerini getirir, çünkü ürün şubeye bağlı değildir. 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, Ekipman (aynı satır), Nitelik & Varyantlar, Varyantlar (menülü, salt okunur), Satınalma, Reçeteler (menülü); Ekipman Reçeteler'in solundadır 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, çıkış stratejisi (`RemovalStrategy`: `FIFO` / `LIFO`, varsayılan FIFO), 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/Ekipman sekmelerinin alanları; ekipman kolonları `Equipment*` önekli (tedarikçi → `Adm_T_Contact`, kategori → `Mm_T_EquipmentCategory`, departman → `Hr_T_Department`, masraf merkezi → `Mm_T_CostCenter`) | | `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. - **Çıkış stratejisi** (ürün kategorisi, 2026-10-14): `FIFO` ilk giren ilk çıkar (en eski `InDate`), `LIFO` son giren ilk çıkar (en yeni `InDate`); aynı alımla aynı anda giren lot/serilerde lot/seri no belirler (FIFO küçükten, LIFO büyükten — SN000005 önce), tarihi boş stok en sona, kategorisiz ürün FIFO, üst kategoriden devralınmaz. Satınalma › Planlama'nın İç Transfer sırası, Öner ve Seçilenleri Planla ile İç Transferler'in Otomatik Ata'sı bu sırayı izler. Yeni kategori FIFO ile açılır (kolonun `DEFAULT`'u). - **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. Ürünün Ekipman sekmesi kategoriyi Bakım modülünün Ekipman Kategorileri'nden okur. 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. - **Ekipman sekmesi neden boş görünüyor?** Sekmenin yetkisi (`App.Inventory.ProductEquipment`) role verilmelidir. Var olan veritabanında kolonlar migrate ile eklenmez; tablo tasarımcısıyla eklenmelidir (bkz. 10). - **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, ProductEquipment, 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. - **Ekipman kolonları:** `Inv_T_Product` scriptleri `CREATE` olduğundan yalnızca yeni veritabanında kolonla kurulur. Kurulu veritabanında on `Equipment*` kolonu Tablo Tasarımcısı'ndan (düzenleme modu `ALTER`) eklenir. Geri almak için `Inventory_ProductEquipment` wizard'ı silinir ve Ürünler'in alt form listesinden sekme çıkarılır; kolonlar düşürülmez. - **Sorgu bağımlılığı:** Sorgular SQL Server'a özgüdür (`STRING_SPLIT`, `CONCAT_WS`, `STRING_AGG`, `CROSS APPLY`). ## 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 teslim alan, malzeme talebinden iç transfer, transfer fişi yazdırma (iç transfer onayı 2026-10-14'te kaldırıldı). - 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. Kaynak ve hedefi aynı iç konum olan iç transfer stoğu taşımaz (2026-10-14, Satınalma'nın Stoktan kararı): Doğrula yeterliliği denetler, stoğa yazmaz, teslimi kaydeder. 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ç). - İç transferde onay akışı yoktur (2026-10-14, kullanıcı kararı): alım ve teslimat gibi satırdaki durum butonlarıyla (Yapılacak olarak işaretle › Doğrula) ilerler. Kaynak depo onayı, iş akışı kolonları (`ApprovalStatus`, `ApprovalUserName`, `ApprovalDate`, `ApprovalDescription`), `SourceApproverUserNames` ve Onay ve Teslim sekmesi kaldırıldı; teslim alan ve teslim alma tarihi (Doğrula yazar) Ek Bilgi sekmesindedir. - 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. Tamamlanmış belgenin başlığı kayıt sonrası operasyon türünden yeniden türetilmez (kilitli alanlar; sonradan değişen tür İade Et'i 50328'e düşürürdü). - Malzeme talebi kalemleri iç transfere yalnız Satınalma › Talepler › Planlama'daki İç Transfer ya da Stoktan kararıyla gelir (`Prc_P_MaterialRequestPlan`, [App.Prc.md](App.Prc.md)): aynı kaynak → hedef konum için taslak transfer varsa satır ona eklenir, yoksa yeni taslak açılır — tür kaynak deponun İç Transferler türüdür (numaratörü `….InternalTransfer` ile biten; sarf türleri seçilmez), taslak da yalnız o türde aranır; Stoktan kararında kaynak = hedef = talebin teslim konumudur. Satırın Miktar'ı (yapılan) planlanan miktarla açılır: lot/seri takipli üründe planlanan lotlar lot dağılımına yazılır, miktar takipli üründe plan miktarı doğrudan yazılır; Hazırla stok kontrolüyle yeniden hesaplar. Siparişten açılan alımın satırı talep kalemini taşı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–50328 (2026-10-14'te kaldırılanlar: 50325 aynı konum yasağı, 50304 kaynak depo onayı). ### 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). İç transferin teslim alanı ve teslim alma tarihi Ek Bilgi'de salt okunurdur. 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 ve Bekleyen), Doğrula (Hazır), İptal Et (Taslak, Bekleyen, Hazır), İade Et (Tamamlandı; iade belgesinde görünmez — gizli `ReturnOfId` alanı, 50327), Yazdır (her durumda). 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, ReceivedByUserId, ReceivedDate (iç transferde Doğrula yazar) | | `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 (çıkış stratejisinin — FIFO/LIFO — sıralama tarihi), 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,LineLotStockSave}` | | Tetikleyici | `Inv_TR_TransferLock`: tamamlanmış belgenin durumu, şube, depo, operasyon türü, konumlar ve kontağı değiştirilemez (50328) | ### 5. İş kuralları ve hesaplar - **Yapılacak olarak işaretle** (taslak, satırlı, konumları dolu): dış konumdan girişte yapılan miktar talep kadar dolar ve belge Hazır olur. Hazırla ve stok kontrolünden sonra belge yeniden hesaplanır (lotlu satırda yapılan miktar lot toplamı, fiş özeti, talep kalemi). İç 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 (kaynak = hedef olan belgede de). Stok güncellenir (kaynak = hedefte stok yerinde kalır), 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 ve talebin durumu yenilenir (bütün kalemleri teslim edilen talep Tamamlandı). 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. İade belgesi yeniden iade edilemez (50327 — sipariş ve talep kalemindeki işaret zinciri bozulurdu). Tamamlanmış iadenin miktarı talep kaleminin transfer payından düşer, kalem Planlama'ya döner. - **İptal Et**: Tamamlandı ya da İptal dışındaki belgede. İptal edilmiş belge düzenlenemez; tamamlanmış belgenin stoğu belirleyen başlık alanları kilitlidir (`Inv_TR_TransferLock`, 50328 — açıklama, nakliye ve not serbest); 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ı ürün kategorisinin çıkış stratejisiyle atar (FIFO: ilk giren ilk çıkar, LIFO: son giren ilk çıkar — stok kaydının `InDate`'i, tarihi boş stok en sona; kategorisiz ürün FIFO; Planlama'nın Öner'iyle aynı sıra). Satınalma › Planlama'da lotla planlanan iç transferin lotları onayda satıra yazılır ([App.Prc.md](App.Prc.md)); Otomatik Ata onları stratejiye göre yeniden kurar. - **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 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. Bütün kiracı tablosu lookup'ları (şube, depo, konum, ürün, kategori, nitelik, kontak, kullanıcı, departman) `TenantId = '@TENANTID'` ile süzülür. ### 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 başka bir iç konuma 2 Adet; Yapılacak olarak işaretle, lotlar seçilir, Doğrula; Ek Bilgi sekmesinde teslim alan ve teslim alma tarihi görünür. 5. Satınalma Planlama'da Ana Depo'yu teslim konumu olan bir talebin 1 Adet sensörünü Stoktan karşılar: Ana Depo → Ana Depo iç transfer LOT000001 (1) ile açılır; Yapılacak olarak işaretle › Doğrula stoğu 4'te bırakır (4. adım 2 adet taşıdı), talep kalemine teslim edilen 1 yazılı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. - **İç transferde sıra nedir?** Satırlar › Yapılacak olarak işaretle (stok kontrolü) › lot seçimi › Doğrula; alım ve teslimatla aynıdır, onay adımı yoktur. Planlamadan açılan belge de Taslak gelir, Yapılacak olarak işaretle elle basılır. - **İç transferde dış konum seçilemiyor?** İç transfer depo içinde taşımadır: Kaynak ve Hedef Konum listeleri yalnız iç konumları gösterir (Yapılacak olarak işaretle/Doğrula'da 50326). Kaynak ve hedef aynı olabilir: Satınalma'nın Stoktan kararı bu belgeyi açar, Doğrula stoğu taşımadan teslimi kaydeder. İade belgesi bu kuraldan muaftır. - **Tamamlanmış belgenin konumunu düzeltmek?** Kilitlidir (50328); İade Et ile geri alıp doğru konumla yeni belge açın. - **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. Alım siparişin onayında bir kez açılır; tedarikçiye iadeden sonra eksik kalan miktar için yeni alım elle açılır. ### 10. Dosyalar ve geri alma - **SQL (sql + postgres):** `Inv_T_{Transfer,TransferLine,TransferLineLot,Stock}`, `Inv_TR_TransferLock`, `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}.json` (`Inventory_TransferApproval` 2026-10-14'te kaldırıldı); 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). ## 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 Üç ekranın yetkisi menüyle aynı sırada `App.Inventory` izin grubunun kökündedir (`App.Inventory.Stock` sıra 3, `App.Inventory.Transfer` sıra 4, `App.Inventory.StockMove` sıra 5); 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. ## 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` | | Form varsayılanları | RemovalStrategy=FIFO, IsActive=true | | 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 | | `RemovalStrategy` | Çıkış Stratejisi | dxSelectBox | ✓ | ✓ | liste: FIFO, LIFO | | `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.ProductEquipment` (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, 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) | | Form varsayılanları | UomId=Adet, IsActive=true, Quantity=1 | | 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, BranchId= | | 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, BranchId= | | 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, BranchId= | | 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ı | | Form varsayılanları | Quantity=1 | | 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ı | | Form varsayılanları | DurationMin=60 | | 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 | | ✓ | | #### Ekipman — `App.Inventory.ProductEquipment` | Özellik | Değer | | --- | --- | | Wizard | `wizard/Inventory_ProductEquipment.json` | | Yol | Liste (Wizard) | | Menü | Menüsüz (alt form) | | Yetki | `App.Inventory.ProductEquipment` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` | | Açıklama | Ürün Ekipman — makine, cihaz ya da taşıt olarak kullanılan ürünlerin ekipman bilgileri. | | 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 | | --- | --- | --- | --- | --- | --- | | `EquipmentDepartmentId` | Departman | dxSelectBox | | ✓ | sorgu: Hr_T_Department | | `EquipmentCategoryId` | Ekipman Kategorisi | dxSelectBox | | ✓ | sorgu: Mm_T_EquipmentCategory | | `EquipmentCostCenterId` | Masraf Merkezi | dxSelectBox | | ✓ | sorgu: Mm_T_CostCenter | | `EquipmentSupplierId` | Tedarikçi | dxSelectBox | | ✓ | sorgu: Adm_T_Contact | | `EquipmentValidityDate` | Geçerlilik Tarihi | dxDateBox | | ✓ | | | `EquipmentSupplierRef` | Tedarikçi Referansı | dxTextBox | | ✓ | | | `EquipmentCost` | Maliyet | dxNumberBox | | ✓ | | | `EquipmentModel` | Model | dxTextBox | | ✓ | | | `EquipmentWarrantyEndDate` | Garanti Bitiş Tarihi | dxDateBox | | ✓ | | | `EquipmentSerialNo` | Seri Numarası | 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 | | --- | --- | --- | --- | --- | --- | | `TransferNo` | Fiş No | dxTextBox | | ✓ | | | `PartnerId` | Tedarikçi Adı | dxSelectBox | | ✓ | sorgu: Adm_T_Contact | | `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 | | ✓ | | | `ReturnOfId` | İade Edilen 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 | | | | | `ReturnOfId` | İade Edilen Belge | 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) | | 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` | | 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 | | | | | `ReturnOfId` | İade Edilen Belge | 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. Tablo: Inv_T_Transfer (belgenin kendi satırı) · tenant ve şube kapsamlı · Alım, Teslimat ve İç Transfer ekranlarının Ek Bilgi sekmesi olarak açılır; kendi menüsü yoktur. | | 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 | | ✓ | | | `ReceivedByUserId` | Teslim Alan | dxSelectBox | | ✓ | sorgu: AbpUsers | | `ReceivedDate` | Teslim Alma Tarihi | dxDateBox | | ✓ | | #### 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 metin notu. Tablo: Inv_T_Transfer (belgenin kendi satırı) · tenant ve şube kapsamlı · Alım, Teslimat ve İç Transfer ekranlarının Not sekmesi olarak açılır; kendi menüsü yoktur. | | 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 | | ✓ | | ### 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 | | | |