Genel düzenlemeler -> Satınalma ve Inventory

This commit is contained in:
Sedat ÖZTÜRK 2026-10-14 22:26:03 +03:00
parent 60992800a8
commit c0c90174d5
149 changed files with 4510 additions and 4376 deletions

View file

@ -869,6 +869,10 @@ Rules:
- Do not require user to explicitly request these columns each time.
- If user explicitly says "no tenant" or "no audit", then respect that override.
- A non-definition (transaction/document) table also gets `BranchId uniqueidentifier NOT NULL`
next to `TenantId`, and its screens (including views reading it) use `IsBranch: true`; detail/line
tables carry the column too: Branch is picked first and the header lookup cascades on it (`CascadeParentFields: BranchId`), subform relation `BranchId → BranchId`. Override only on "no branch". Details:
`lowcode.instructions.md` §8.1 (İşlem tablosu → `BranchId`).
- Primary key strategy must remain compatible with existing index/key policy.
### 32.2 Wizard menu parent fallback behavior

View file

@ -65,7 +65,7 @@ ama hiçbirini görmeden bırakma; kullanıcı "şunu da yapabilir miydik?" dedi
| 10 | **Özet** | Toplam/adet satırı, grup özetleri, pivot | §9.5 · §6 |
| 11 | **Biçimlendirme** | Koşullu satır/hücre rengi, CSS sınıfı | `lowcode` §4.3.7 |
| 12 | **Düzenleme deneyimi** | Popup/satır/hücre/batch, form grupları, kopyalama, toplu silme | §3 |
| 13 | **Aksiyonlar** | Hazır toolbar/satır butonları, URL parametreleri, not/ek/geçmiş, içe-dışa aktarma; özel butonlar: adres, diyalog, script, yetki, koşullu görünürlük | §5.8 · `lowcode` §4.9 |
| 13 | **Aksiyonlar** | Hazır toolbar/satır butonları, URL parametreleri, not/ek/geçmiş, içe-dışa aktarma; özel butonlar: adres, diyalog, script, yetki, koşullu görünürlük (satır) ve seçime göre aktiflik (toolbar) | §5.8 · `lowcode` §4.9 |
| 14 | **Yazma mantığı** | Özel SQL, before/after kancaları, farklı servis adresi | §4 |
| 15 | **Ana-detay** | Alt form sekmeleri ve ilişki alanları | §5.2 |
| 16 | **Gösterge** | Üstte KPI kartları, grafik | §5.3 · §8 |

View file

@ -256,6 +256,7 @@ bildirilir:
| --- | --- |
| Tenant + audit kolonları (`Id`, `TenantId`, `CreationTime`, `CreatorId`, `LastModificationTime`, `LastModifierId`, `IsDeleted`, `DeletionTime`, `DeleterId`) | Yeni tabloda varsayılan; kullanıcı "audit yok" demedikçe eklenir |
| Tanım tablosunda `IsActive` | Yeni **tanım** tablosunda varsayılan (aşağıda); kullanıcı "aktif/pasif yok" demedikçe eklenir |
| İşlem tablosunda `BranchId` | Tanım **olmayan** yeni tabloda `TenantId` gibi varsayılan; ekran `IsBranch: true` (§8.1) |
| `IsActive` varsayılan değeri | Her tabloda `DEFAULT 1`, formda `true` (§8.1) |
| Metinlerin EN + TR olması, dil anahtarı üzerinden verilmesi | Platform sözleşmesi |
| İsimlendirme (`ListFormCode`, menü kodu, yetki adları, dosya adları) | §2'den türer |
@ -796,6 +797,8 @@ Kısa ve karar odaklı yaz; talebi tekrar anlatma.
olmasa da — ve madde 8 (form alanı + Aktif/Pasif widget'ı) ile madde 10 (`create_table` kolonu,
demo veride `IsActive: true`) bunu taşır. Tanım olmayan tabloda da `IsActive` kolonu varsa
varsayılanı aynıdır: `bit NOT NULL DEFAULT 1`, formda `true` (§8.1).
Hayır ise (işlem/belge tablosu) kolon tablosunda `TenantId`'nin yanında `BranchId`
(uniqueidentifier, zorunlu) yer alır ve ekran `IsBranch: true` ile kurulur (§8.1 İşlem tablosu).
**Görsel kolonu:** görsel tutan her kolon (fotoğraf, resim, logo, avatar kopyası, belge
görüntüsü) `nvarchar(MAX)`'tir ve editörü `dxImageUpload`'dır — değer başka bir kayıttan
kopyalanıyor olsa da. Görsel base64 metin olarak saklanır; `nvarchar(512)` gibi sınırlı boy
@ -1607,7 +1610,7 @@ Adres zincirinin hazır örneği Kiracılar ekranıdır: Ülke › İl › İlç
| Tip | Biçim | Not |
| --- | --- | --- |
| `1` StaticData | `[{"key":"Wares","name":"App.StaticLookup.Wares"},{"key":"Service","name":"App.StaticLookup.Service"}]` | `name` **her zaman dil anahtarıdır** (§4.3.4.1), düz metin yazılmaz. Kolon **sayı** tipindeyse `key` sayı, **metin** tipindeyse `key` metin olmalıdır; aksi hâlde seçim eşleşmez. Cascade gerekiyorsa her öğeye `group` eklenir. |
| `2` Query | `SELECT Id AS [Key], Name AS [Name] FROM ... WHERE IsDeleted = 0` | Cascade'de ebeveyn değerleri `@param0…` ile gelir; boş ebeveyn tüm listeyi göstersin diye `(Kolon = @param0 OR @param0 IS NULL)` kalıbı kullanılır. Sorgu ekranın veri kaynağında/tenant bağlamında çalışır, `@USERID` gibi token'lar çözülür. |
| `2` Query | `SELECT Id AS [Key], Name AS [Name] FROM ... WHERE TenantId = '@TENANTID' AND IsDeleted = 0` | Cascade'de ebeveyn değerleri `@param0…` ile gelir; boş ebeveyn tüm listeyi göstersin diye `(Kolon = @param0 OR @param0 IS NULL)` kalıbı kullanılır. Sorgu ekranın veri kaynağında çalışır, `@USERID` gibi token'lar çözülür. **Lookup ekranın kiracı süzgecinden geçmez:** kaynağın en dış tablosu kiracı tablosuysa (`IMultiTenant` entity ya da `TenantId` kolonlu seed tablosu — `_T_` önekliler, `AbpUsers`/`AbpRoles`/`AbpOrganizationUnits`) sorgu `TenantId = '@TENANTID'` taşır (host'ta `IS NULL` çözülür). Host tanımları (`Sas_H_*`) ve anahtarla bağlanan alt sorgu/join filtre istemez. C# seeder'da `LookupQueryValues.DefaultLookupQueryJson` filtreyi tablonun kapsamından (`TableNameResolver.IsTenantTable`) kendisi ekler; elle yazılan sorgu `TenantFilter` kalıbını kullanır. |
| `3` WebService | `METHOD;url;bodyJson;keySelector;nameSelector;groupSelector` | Noktalı virgülle **altı parça**. Selector'lar her satır `a` üzerinde çalışan JS ifadeleridir (`a.id`, `a.name`, `null`). Gövdedeki `@param0`, `@param1`… cascade filtre değerleriyle doldurulur. Örnek: `GET;notification-rule/notification-types;{};a.id;a.name;null`. Eksik ya da boş seçici `a.id` / `a.name` / `a.group`'a düşer; seçici ifade (`a.id`) ya da ok fonksiyonu (`a => a.id`) olabilir. Store anahtarı `valueExpr`'in küçük harflisidir; boş ebeveyn gövdeye `null` metni olarak yazılır (tırnak içindeyse `"null"`) |
Cascade örneği — Ülke → İl → İlçe (aşağıdaki nesneler `LookupJson` kolonuna **tek satır,
@ -1643,7 +1646,7 @@ Wizard öğesi olarak (Eğitim Tipi → Eğitim Konusu; ebeveyn StaticData, çoc
"ValueExpr": "key", "DisplayExpr": "name",
"CascadeEmptyFields": "TrainingTopicId" },
{ "FieldName": "TrainingTopicId", "EditorType": "dxSelectBox", "LookupDataSourceType": 2,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Hr_T_TrainingTopic WHERE (TrainingType = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' ORDER BY Name",
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Hr_T_TrainingTopic WHERE TenantId = '@TENANTID' AND (TrainingType = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' ORDER BY Name",
"ValueExpr": "Key", "DisplayExpr": "Name",
"CascadeParentFields": "TrainingType" }
```
@ -1757,7 +1760,7 @@ Wizard ve MCP ile üretilen **her** liste ekranında yeni kayıt şu değerlerle
| Kolon | Form varsayılanı | Tablodaki `DEFAULT` |
| --- | --- | --- |
| `IsActive` | `true` | `bit NOT NULL DEFAULT 1` |
| Ölçü birimi (`UomId`, `*UomId`; lookup `Adm_T_Uom`) | `Adet` | `DEFAULT 'Adet'` |
| Ölçü birimi (`UomId`, `*UomId`; lookup `Adm_T_Uom` — kiracı tablosudur (`Uom : IMultiTenant`), lookup `TenantId = '@TENANTID'` taşır) | `Adet` | `DEFAULT 'Adet'` |
| Para birimi (`CurrencyId`, `*Currency`; lookup `Sas_H_Currency`) | `TRY` (lookup'ın anahtarı adsa onun karşılığı) | `DEFAULT 'TRY'` |
| Talepte sabit varsayılanı olan her kolon (ör. Süre = 60) | o değer | `DEFAULT 60` |
@ -1844,7 +1847,7 @@ koşulu `DefaultFilter`'a token'la yazılır (`"CreatorId" = '@USERID'`).
{ "FieldName": "CreationTime", "FieldDbType": 6, "Value": "@NOW", "CustomValueType": 2 },
{ "FieldName": "CreatorId", "FieldDbType": 9, "Value": "@USERID", "CustomValueType": 2 }
],
// App.Prc.MaterialRequestPlanTrack — UpdateCommand: EXEC Prc_P_MaterialRequestStockUndo @Id, @TenantId, @LastModifierId
// App.Prc.MaterialRequestPlan — UpdateCommand: EXEC Prc_P_MaterialRequestPlanConfirm @Id, @TenantId, @LastModifierId
"UpdateFieldsDefaultValueDto": [
{ "FieldName": "LastModificationTime", "FieldDbType": 6, "Value": "@NOW", "CustomValueType": 2 },
{ "FieldName": "LastModifierId", "FieldDbType": 9, "Value": "@USERID", "CustomValueType": 2 },
@ -2005,7 +2008,7 @@ cevaba yazılmaz.
"EditorType": "dxSelectBox", "DbSourceType": 9,
"IsRequired": true, "IncludeInEditingForm": true, "ColSpan": 1,
"LookupDataSourceType": 2,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Crm_T_Customer WHERE IsDeleted = 0 ORDER BY Name",
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Crm_T_Customer WHERE TenantId = '@TENANTID' AND IsDeleted = 0 ORDER BY Name",
"ValueExpr": "Key", "DisplayExpr": "Name"
},
{
@ -2707,10 +2710,15 @@ Kurallar:
butonları form araç çubuğuna taşınır (satır bağlamı enjekte edilir). Gantt, Scheduler, Pivot ve
Chart'ta özel buton çizilmez. Buton anahtarı `Hint`'tir — aynı `Hint`'li iki buton yazma.
- Satır bazlı aksiyon istiyorsan `ButtonPosition: 0` kullan; buton komut sütununda görünür.
- **`IsVisible` ve `VisibleExpression` yalnızca satır butonlarında (`ButtonPosition: 0`)
çalışır**; toolbar butonu her zaman görünür (görünürlüğü `AuthName` belirler).
`VisibleExpression` bir ok fonksiyonudur ve `eval` edilir:
`"(e) => e.row.data.Status === 'Taslak'"`.
- `VisibleExpression` bir ok fonksiyonudur ve `eval` edilir:
`"(e) => e.row.data.Status === 'Taslak'"`. **Satır butonunda** (`ButtonPosition: 0`) `false` butonu
gizler (`IsVisible` de yalnız satır butonunda okunur). **Toolbar butonunda** buton gizlenmez, **pasif**
olur: ifade seçili her satır için ayrı çalışır (`e.row.data` = o satır), biri `false` dönerse ya da
seçim yoksa buton tıklanamaz; seçim değişince yeniden hesaplanır (Grid, Tree, Card ve form sayfası —
`isToolbarItemDisabled` / `updateSelectionToolbarItems`, `useToolbar.tsx`). İfadesi olmayan toolbar
butonu her zaman tıklanabilir (görünürlüğü `AuthName` belirler). Durum adımı butonları
(Onayla, İptal, Taslağa al …) izin verilen durumları buraya yazar; sunucudaki durum kontrolü yine
kalır. Örnek: Satınalma › Teklif Talepleri ve Siparişler (`App.Prc.md`).
- URL token'ları: satır butonunda `@LISTFORMCODE` ve **grid sütunu olarak tanımlı** her alan için
`@FieldName`; toolbar butonunda seçili ilk satırın tüm kolonları (`@LISTFORMCODE` yok). Sütun
listesinde olmayan bir alan adı satır butonunda değiştirilmez. Her token yalnızca **ilk geçtiği yerde**
@ -4073,6 +4081,23 @@ kolonu üretilmez.
Pasife alma silmenin yerine geçmez; silme açık kalır. Analiz bunu **Kararlar**'a değil **Veri
modeli**'ne yazar (§0.12 madde 5); tanım tablosu olduğunu da orada belirtir. Var olan tabloya kolon eklenmez (şema değişikliği ayrı iştir).
**İşlem tablosu → `BranchId` otomatik.** Tanım olmayan her yeni tablo (sipariş, talep, proje, hareket,
günlük gibi işlem/belge kayıtları) `TenantId` nasıl sorulmadan geliyorsa şubeyi de öyle taşır. Karar
yukarıdaki tanım kararının tersidir; ayrı sorulmaz.
| Katman | `BranchId` |
| --- | --- |
| Tablo | `[BranchId] uniqueidentifier NOT NULL` (PG `"BranchId" uuid NOT NULL`), `TenantId`'den hemen sonra |
| Ekran | `IsBranch: true` — liste yalnızca kullanıcıya atanmış şubelerin (`Sas_T_BranchUsers`) satırlarını getirir (`lowcode-reference.instructions.md` — Örtük filtreler) |
| Alan | Şube (`App.Listform.ListformField.BranchId`, var olan anahtar), `dxSelectBox`, zorunlu; lookup kullanıcının şubeleri: `SELECT b.Id AS [Key], b.Name AS [Name] FROM Sas_T_Branch b INNER JOIN Sas_T_BranchUsers bu ON bu.BranchId = b.Id AND bu.UserId = '@USERID' WHERE b.IsDeleted = 'false' AND b.IsActive = 1 AND b.TenantId = '@TENANTID' ORDER BY b.Name` |
| Form varsayılanı | `FormFieldsDefaultValueJson`'da `CustomValueType: 3` (`DbQuery`): kullanıcının departmanının şubesi, kullanıcının şubeleri arasındaysa (örnek: `App.Prc.PurchaseOrder`, `App.Prj.Project`) |
| View / rapor | Tablodan okuyan view `BranchId`'yi taşır (PG `CREATE OR REPLACE VIEW` kolon ekleyemediği için listenin **sonuna**); ekran `IsBranch: true`, Şube kolonu salt okunur lookup (`Sas_T_Branch`) |
| Ana kayda bağlı tablo (satır, alt form, kendi menüsü olan iş paketi/günce gibi) | Aynı kolonu taşır; form **cascade** ile kurulur: Şube alanı ana kayıttan önce gelir (kullanıcının şubeleri lookup'ı + departman şubesi `DbQuery` varsayılanı, `CascadeEmptyFields` = ana kayıt alanı), ana kayıt lookup'ı şubeye göre süzülür (`CascadeParentFields: BranchId`, sorguda `(p.BranchId = @param0 OR @param0 IS NULL)`); ana ekranın `SubFormsDto` ilişkisine `BranchId → BranchId` satırı eklenir (sekmeden açılan yeni kayıt şubeyi oradan alır). Ekran yine `IsBranch: true`; ana kaydın şubesini `DefaultFilter` alt sorgusuyla süzme (örnek: `App.Prj.WorkPackage`, `App.Prj.Diary`) |
| Widget | Widget SQL'i `IsBranch` filtresinden geçmez; şube kırılımı gerekiyorsa sorguya yazılır |
Kullanıcı "şube yok" derse kolon ve `IsBranch` çıkarılır. Var olan işlem tablosuna kolon eklemek
şema değişikliğidir; istekle yapılır (yama betiği yazılmaz, kolon `CREATE` içine konur).
### 8.2 View tasarımcısı (`SqlViewDesignerDialog`) — çalışma mantığı
Bir ekran birden fazla tablodan besleniyorsa, `SelectCommandType: 4` (Query) yerine **tasarlanmış

View file

@ -1,4 +1,5 @@
using System.Text.Json;
using System.Collections.Generic;
using System.Text.Json;
using Sozsoft.Platform.Enums;
using Sozsoft.Platform.ListForms;
using static Sozsoft.Platform.PlatformConsts;
@ -7,14 +8,23 @@ namespace Sozsoft.Platform;
public static class LookupQueryValues
{
private const string defaultDomain = "Sozsoft";
// Lookup sorgusu ekranin kiraci suzgecinden gecmez; kiraci tablosunda filtre sorguya yazilir (host'ta IS NULL cozulur).
private const string TenantFilter = $"\"TenantId\" = '{DefaultValues.TenantId}'";
public static string DefaultLookupQueryJson(
string TableName,
string ValueExpr,
string DisplayExpr,
bool isTable = true,
bool isDeleted = false) => JsonSerializer.Serialize(new LookupDto
bool isDeleted = false)
{
var conditions = new List<string>();
if (TableNameResolver.IsTenantTable(TableName))
conditions.Add(TenantFilter);
if (isDeleted)
conditions.Add("\"IsDeleted\" = 'false'");
return JsonSerializer.Serialize(new LookupDto
{
DataSourceType = UiLookupDataSourceTypeEnum.Query,
ValueExpr = "Key",
@ -23,23 +33,9 @@ public static class LookupQueryValues
$"\"{ValueExpr}\" AS \"Key\", " +
$"\"{DisplayExpr}\" AS \"Name\" " +
$"FROM \"{(isTable ? TableNameResolver.GetFullTableName($"{TableName}") : TableNameResolver.GetFullViewName($"{TableName}"))}\" " +
(!isDeleted ? "" : $"WHERE \"IsDeleted\" = 'false'") +
(conditions.Count == 0 ? "" : $"WHERE {string.Join(" AND ", conditions)} ") +
$"ORDER BY \"{DisplayExpr}\";"
});
public static string DefaultLookupQuery(
string TableName,
string ValueExpr,
string DisplayExpr,
bool isTable = true,
bool isDeleted = false)
{
return $"SELECT " +
$"\"{ValueExpr}\" AS \"Key\", " +
$"\"{DisplayExpr}\" AS \"Name\" " +
$"FROM \"{(isTable ? TableNameResolver.GetFullTableName($"{TableName}") : TableNameResolver.GetFullViewName($"{TableName}"))}\" " +
(!isDeleted ? "" : $"WHERE \"IsDeleted\" = 'false'") +
$"ORDER BY \"{DisplayExpr}\";";
}
public static string TenantValues(bool alwaysName = false)
@ -139,13 +135,6 @@ public static class LookupQueryValues
$"GROUP BY \"Township\", \"PostalCode\" " +
$"ORDER BY \"Township\";";
public static string RoleValues =
$"SELECT " +
$"\"Id\" AS \"Key\", " +
$"\"Name\" AS \"Name\" " +
$"FROM \"AbpRoles\"" +
$"ORDER BY \"Name\"";
/// <summary>
/// Manuel bildirim alicilari: yalnizca oturumun kiracisindaki aktif kullanicilar. Kiraci
/// filtresi '@TENANTID' ile kurulur, host baglaminda "IS NULL" olarak cozulur.
@ -158,7 +147,7 @@ public static class LookupQueryValues
$"WHERE " +
$"\"IsDeleted\" = 'false' " +
$"AND \"IsActive\" = 'true' " +
$"AND \"TenantId\" = '@TENANTID' " +
$"AND {TenantFilter} " +
$"ORDER BY \"Name\";";
/// <summary>
@ -175,7 +164,7 @@ public static class LookupQueryValues
$"WHERE " +
$"\"IsDeleted\" = 'false' " +
$"AND \"IsActive\" = 'true' " +
$"AND \"TenantId\" = '@TENANTID' " +
$"AND {TenantFilter} " +
$"ORDER BY \"Name\";";
/// <summary>
@ -189,7 +178,7 @@ public static class LookupQueryValues
$"FROM \"{FullNameTable(TableNameEnum.Sector)}\" " +
$"WHERE " +
$"\"IsDeleted\" = 'false' " +
$"AND \"TenantId\" = '@TENANTID' " +
$"AND {TenantFilter} " +
$"ORDER BY \"Name\";";
/// <summary>
@ -209,30 +198,17 @@ public static class LookupQueryValues
$"WHERE " +
$"\"IsDeleted\" = 'false' " +
$"AND \"IsActive\" = 'true' " +
$"AND \"TenantId\" = '@TENANTID' " +
$"AND {TenantFilter} " +
$"ORDER BY \"FullName\";";
public static string UserValues =
$"SELECT " +
$"\"Id\" AS \"Key\", " +
$"\"UserName\" AS \"Name\" " +
$"FROM \"AbpUsers\"" +
$"FROM \"AbpUsers\" " +
$"WHERE {TenantFilter} " +
$"ORDER BY \"Name\"";
public static string BranchValues =
$"SELECT \"Id\" AS \"Key\", " +
$"\"Name\" AS \"Name\" " +
$"FROM \"{defaultDomain}\".\"dbo\".\"{FullNameTable(TableNameEnum.Branch)}\" " +
$"WHERE " +
$"\"TenantId\" = '@TENANTID' " + // 🔹 Bu form doğru — Replace hedefi bu.
$"AND \"IsDeleted\" = 'false' " +
$"AND \"Id\" IN ( " +
$"SELECT \"BranchId\" " +
$"FROM \"{FullNameTable(TableNameEnum.BranchUsers)}\" " +
$"WHERE \"UserId\" = '@USERID' " + // 🔹 Bu da doğru.
$") " +
$"ORDER BY \"Name\";";
public static string PermissionNameValues =
$"SELECT \"Name\" AS \"Key\", " +
$"CONCAT(\"Name\", ' (', \"DisplayName\", ')') AS \"Name\" " +
@ -272,14 +248,6 @@ public static class LookupQueryValues
$"WHERE \"IsDisabled\" = 'false' " +
$"ORDER BY \"ParentCode\", \"Order\";";
public static string OrganizationUnitSalesTeamValues =
$"SELECT " +
$"\"Code\" AS \"Key\", " +
$"\"DisplayName\" AS \"Name\" " +
$"FROM \"AbpOrganizationUnits\"" +
$"WHERE \"Code\" LIKE '00001%' " +
$"ORDER BY \"DisplayName\"";
public static string RouteKeyValues =
$@"SELECT
""Path"" AS ""Key"",
@ -299,6 +267,7 @@ public static class LookupQueryValues
$"\"Name\" AS \"Name\" " +
$"FROM \"{TableNameResolver.GetFullTableName(nameof(TableNameEnum.Department))}\" " +
$"WHERE \"IsDeleted\" = 'false' " +
$"AND {TenantFilter} " +
$"ORDER BY \"Name\";";
// Lookup sorgusu ekranın tenant filtresinden geçmez; kiracı kırılımı token ile sorguda yazılır.
@ -308,7 +277,7 @@ public static class LookupQueryValues
$"\"Name\" AS \"Name\" " +
$"FROM \"{TableNameResolver.GetFullTableName(nameof(TableNameEnum.Branch))}\" " +
$"WHERE " +
$"\"TenantId\" = '{DefaultValues.TenantId}' " +
$"{TenantFilter} " +
$"AND \"IsDeleted\" = 'false' " +
$"ORDER BY \"Name\";";
@ -320,7 +289,7 @@ public static class LookupQueryValues
$"\"Name\" AS \"Name\" " +
$"FROM \"Hr_T_BenefitType\" " +
$"WHERE " +
$"\"TenantId\" = '{DefaultValues.TenantId}' " +
$"{TenantFilter} " +
$"AND \"IsActive\" = 'true' " +
$"AND \"IsDeleted\" = 'false' " +
$"ORDER BY \"Name\";";
@ -333,6 +302,7 @@ public static class LookupQueryValues
$"WHERE " +
$"(\"BranchId\" = @param0 OR @param0 IS NULL) " +
$"AND \"IsDeleted\" = 'false' " +
$"AND {TenantFilter} " +
$"ORDER BY \"Name\";";
public static string JobPositionValues =
@ -343,6 +313,7 @@ public static class LookupQueryValues
$"WHERE " +
$"(\"DepartmentId\" = @param0 OR @param0 IS NULL) " +
$"AND \"IsDeleted\" = 'false' " +
$"AND {TenantFilter} " +
$"ORDER BY \"Name\";";
public static string JobPositionFullValues =
@ -366,6 +337,7 @@ public static class LookupQueryValues
$"FROM \"{TableNameResolver.GetFullTableName(nameof(TableNameEnum.JobPosition))}\" jp " +
$"WHERE " +
$"jp.\"IsDeleted\" = 'false' " +
$"AND jp.{TenantFilter} " +
$"AND " +
$"( " +
$"jp.\"DepartmentId\" IN (SELECT \"Id\" FROM \"DepartmentTree\") " +
@ -379,6 +351,7 @@ public static class LookupQueryValues
$"\"QuestionText\" AS \"Name\" " +
$"FROM \"{TableNameResolver.GetFullTableName(nameof(TableNameEnum.SurveyQuestion))}\" " +
$"WHERE \"IsDeleted\" = 'false' " +
$"AND {TenantFilter} " +
$"ORDER BY \"QuestionText\";";
/// <summary>Hr_T_Shift wizard ile uretilen bir tablodur (entity'si yoktur); kullanici bir vardiyaya baglanir.</summary>
@ -390,7 +363,7 @@ public static class LookupQueryValues
$"WHERE " +
$"\"IsDeleted\" = 'false' " +
$"AND \"IsActive\" = 'true' " +
$"AND \"TenantId\" = '@TENANTID' " +
$"AND {TenantFilter} " +
$"ORDER BY \"StartTime\";";
/// <summary>SGK cikis kodlari host tanimidir; kiraci filtresi yoktur, kod adla birlikte gosterilir.</summary>
@ -413,7 +386,7 @@ public static class LookupQueryValues
$"WHERE " +
$"\"IsDeleted\" = 'false' " +
$"AND \"IsActive\" = 'true' " +
$"AND \"TenantId\" = '@TENANTID' " +
$"AND {TenantFilter} " +
$"ORDER BY \"Name\";";
// Diller de bir yetenek tipidir (Languages); dil listesi o tipe, yetenek listesi diger tiplere suzulur.
@ -428,7 +401,7 @@ public static class LookupQueryValues
$"WHERE " +
$"s.\"IsDeleted\" = 'false' " +
$"AND t.\"Name\" = '{LanguageSkillTypeName}' " +
$"AND s.\"TenantId\" = '@TENANTID' " +
$"AND s.{TenantFilter} " +
$"ORDER BY s.\"Name\";";
/// <summary>Secilen dilin tipine ait seviyeler (A1-C2); <c>@param0</c> dilin <c>SkillId</c>'sidir.</summary>
@ -441,7 +414,7 @@ public static class LookupQueryValues
$"WHERE " +
$"(s.\"Id\" = @param0 OR @param0 IS NULL) " +
$"AND l.\"IsDeleted\" = 'false' " +
$"AND l.\"TenantId\" = '@TENANTID' " +
$"AND l.{TenantFilter} " +
$"ORDER BY l.\"Progress\";";
public static string TenantNonLanguageSkillValues =
@ -453,33 +426,26 @@ public static class LookupQueryValues
$"WHERE " +
$"s.\"IsDeleted\" = 'false' " +
$"AND t.\"Name\" <> '{LanguageSkillTypeName}' " +
$"AND s.\"TenantId\" = '@TENANTID' " +
$"AND s.{TenantFilter} " +
$"ORDER BY t.\"Name\", s.\"Name\";";
public static string TechnicalSkillsValues =
$"SELECT " +
$"\"Name\" AS \"Key\", " +
$"\"Name\" AS \"Name\" " +
$"FROM \"{FullNameTable(TableNameEnum.Skill)}\" " +
$"WHERE \"TenantId\" = '{DefaultValues.TenantId}' " +
$"AND \"IsDeleted\" = 'false' " +
$"AND \"SkillTypeId\" IN (SELECT \"Id\" FROM \"{FullNameTable(TableNameEnum.SkillType)}\" WHERE \"TenantId\" = '{DefaultValues.TenantId}' AND \"Name\"='Technical Skills' ) " +
$"ORDER BY \"Name\"";
public static string NotificationIdentityValues =
$"SELECT " +
$"\"Id\" AS \"Key\", " +
$"\"Name\" AS \"Name\" " +
$"FROM \"AbpRoles\"" +
$"FROM \"AbpRoles\" " +
$"WHERE {TenantFilter} " +
$"UNION ALL " +
$"SELECT " +
$"\"Id\" AS \"Key\", " +
$"\"UserName\" AS \"Name\" " +
$"FROM \"AbpUsers\"" +
$"FROM \"AbpUsers\" " +
$"WHERE {TenantFilter} " +
$"UNION ALL " +
$"SELECT " +
$"\"Id\" AS \"Key\", " +
$"\"DisplayName\" AS \"Name\" " +
$"FROM \"AbpOrganizationUnits\"" +
$"FROM \"AbpOrganizationUnits\" " +
$"WHERE {TenantFilter} " +
$"ORDER BY \"Name\"";
}

View file

@ -6202,7 +6202,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
DataSourceType = UiLookupDataSourceTypeEnum.Query,
DisplayExpr = "Name",
ValueExpr = "Key",
LookupQuery = $"SELECT \"UserName\" AS \"Key\", \"UserName\" AS \"Name\" FROM \"AbpUsers\" UNION SELECT \"Name\" AS \"Key\", \"Name\" AS \"Name\" FROM \"AbpRoles\"",
LookupQuery = $"SELECT \"UserName\" AS \"Key\", \"UserName\" AS \"Name\" FROM \"AbpUsers\" WHERE \"TenantId\" = '{DefaultValues.TenantId}' UNION SELECT \"Name\" AS \"Key\", \"Name\" AS \"Name\" FROM \"AbpRoles\" WHERE \"TenantId\" = '{DefaultValues.TenantId}'",
}),
ColumnCustomizationJson = DefaultColumnCustomizationJson,
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
@ -6370,7 +6370,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
DataSourceType = UiLookupDataSourceTypeEnum.Query,
DisplayExpr = "Name",
ValueExpr = "Key",
LookupQuery = $"SELECT \"Id\" AS \"Key\", \"UserName\" AS \"Name\" FROM \"AbpUsers\"",
LookupQuery = $"SELECT \"Id\" AS \"Key\", \"UserName\" AS \"Name\" FROM \"AbpUsers\" WHERE \"TenantId\" = '{DefaultValues.TenantId}'",
}),
ColumnCustomizationJson = DefaultColumnCustomizationJson,
PermissionJson = DefaultFieldPermissionJson(listForm.Name),

View file

@ -139,6 +139,12 @@ public static class TableNameResolver
return entry.Method(entry.PrefixGroup, tableEnum);
}
/// <summary>
/// Tablo kiraciya ait mi (host tanimi degil): sorgu yazan yer kiraci filtresini ('@TENANTID') buna gore ekler.
/// </summary>
public static bool IsTenantTable(string tableName) =>
_map.TryGetValue(tableName, out var entry) && entry.Method.Method.Name != nameof(TablePrefix.PlatformByName);
public static string GetFullViewName(string tableName)
{
if (!Enum.TryParse<TableNameEnum>(tableName, out var tableEnum))

View file

@ -123,6 +123,13 @@ Bir çelişki varsa sıra: `ai.instructions.md` → `dotnet.instructions.md` →
1. **Yeni tablo** → tenant + tam audit kolonları varsayılan gelir (`Id`, `TenantId`,
`CreationTime`, `CreatorId`, `LastModificationTime`, `LastModifierId`, `IsDeleted`,
`DeletionTime`, `DeleterId`). Kullanıcı açıkça "tenant yok / audit yok" demedikçe çıkarma.
Tanım **olmayan** (işlem/belge) yeni tablo `TenantId` gibi `BranchId uniqueidentifier NOT NULL`
(PG `uuid NOT NULL`) da taşır; ekranı `IsBranch: true`, Şube alanı kullanıcının şubelerinden
(`Sas_T_BranchUsers`) seçilir ve yeni kayıtta kullanıcının departman şubesiyle (`DbQuery`) açılır.
Bu tablodan okuyan view/rapor ekranı da `BranchId`'yi taşır ve `IsBranch: true` olur. Ana kayda
bağlı tablo da kolonu taşır; formda önce Şube seçilir, ana kayıt lookup'ı şubeye göre süzülür
(`CascadeParentFields: BranchId`) + alt form ilişkisi `BranchId → BranchId`. Ayrıntı:
`lowcode.instructions.md` §8.1 (İşlem tablosu → `BranchId`).
Yeni **tanım** tablosu (tanım olup olmadığına talebin içeriğine göre analizde karar verilir;
sabit ad listesi yoktur) buna ek olarak `IsActive bit NOT NULL DEFAULT 1` ile gelir; liste + form alanı, varsayılan
`true`, Aktif/Pasif widget'ı. Tanım olmasa da MCP ile (ya da wizard ile) üretilen her ekranda

View file

@ -16819,7 +16819,7 @@
"Name": "App.Prc.MaterialRequestPlanStock",
"ParentName": "App.Prc.MaterialRequestPlan",
"DisplayName": "App.Prc.MaterialRequestPlanStock",
"Order": 7,
"Order": 6,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
@ -16889,7 +16889,7 @@
"Name": "App.Prc.MaterialRequestPlanSupplier",
"ParentName": "App.Prc.MaterialRequestPlan",
"DisplayName": "App.Prc.MaterialRequestPlanSupplier",
"Order": 8,
"Order": 7,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
@ -16959,7 +16959,7 @@
"Name": "App.Prc.MaterialRequestPlanLastPurchase",
"ParentName": "App.Prc.MaterialRequestPlan",
"DisplayName": "App.Prc.MaterialRequestPlanLastPurchase",
"Order": 9,
"Order": 8,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
@ -17019,7 +17019,7 @@
"Name": "App.Prc.MaterialRequestPlanSource",
"ParentName": "App.Prc.MaterialRequestPlan",
"DisplayName": "App.Prc.MaterialRequestPlanSource",
"Order": 10,
"Order": 9,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
@ -17079,7 +17079,7 @@
"Name": "App.Prc.MaterialRequestPlanVendor",
"ParentName": "App.Prc.MaterialRequestPlan",
"DisplayName": "App.Prc.MaterialRequestPlanVendor",
"Order": 11,
"Order": 10,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
@ -17139,7 +17139,7 @@
"Name": "App.Prc.MaterialRequestPlanLine",
"ParentName": "App.Prc.MaterialRequestPlan",
"DisplayName": "App.Prc.MaterialRequestPlanLine",
"Order": 12,
"Order": 11,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
@ -17389,7 +17389,7 @@
"Name": "App.Prc.Orders",
"ParentName": null,
"DisplayName": "App.Prc.Orders",
"Order": 5,
"Order": 4,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
@ -17399,7 +17399,7 @@
"Name": "App.Prc.PurchaseAgreement",
"ParentName": null,
"DisplayName": "App.Prc.PurchaseAgreement",
"Order": 4,
"Order": 2,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
@ -18479,7 +18479,7 @@
"Name": "App.Inventory.TransferLine",
"ParentName": "App.Inventory.Operations",
"DisplayName": "App.Inventory.TransferLine",
"Order": 5,
"Order": 4,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Inventory"
@ -18669,7 +18669,7 @@
"Name": "App.Inventory.TransferOther",
"ParentName": "App.Inventory.Operations",
"DisplayName": "App.Inventory.TransferOther",
"Order": 6,
"Order": 5,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Inventory"
@ -18739,7 +18739,7 @@
"Name": "App.Inventory.TransferNote",
"ParentName": "App.Inventory.Operations",
"DisplayName": "App.Inventory.TransferNote",
"Order": 7,
"Order": 6,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Inventory"
@ -18804,76 +18804,6 @@
"MultiTenancySide": 3,
"Modules": "Inventory"
},
{
"GroupName": "App.Inventory",
"Name": "App.Inventory.TransferApproval",
"ParentName": "App.Inventory.InternalTransfer",
"DisplayName": "App.Inventory.TransferApproval",
"Order": 7,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Inventory"
},
{
"GroupName": "App.Inventory",
"Name": "App.Inventory.TransferApproval.Create",
"ParentName": "App.Inventory.TransferApproval",
"DisplayName": "App.Platform.Create",
"Order": 1,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Inventory"
},
{
"GroupName": "App.Inventory",
"Name": "App.Inventory.TransferApproval.Update",
"ParentName": "App.Inventory.TransferApproval",
"DisplayName": "App.Platform.Update",
"Order": 2,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Inventory"
},
{
"GroupName": "App.Inventory",
"Name": "App.Inventory.TransferApproval.Delete",
"ParentName": "App.Inventory.TransferApproval",
"DisplayName": "App.Platform.Delete",
"Order": 3,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Inventory"
},
{
"GroupName": "App.Inventory",
"Name": "App.Inventory.TransferApproval.Export",
"ParentName": "App.Inventory.TransferApproval",
"DisplayName": "App.Platform.Export",
"Order": 4,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Inventory"
},
{
"GroupName": "App.Inventory",
"Name": "App.Inventory.TransferApproval.Import",
"ParentName": "App.Inventory.TransferApproval",
"DisplayName": "App.Platform.Import",
"Order": 5,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Inventory"
},
{
"GroupName": "App.Inventory",
"Name": "App.Inventory.TransferApproval.Note",
"ParentName": "App.Inventory.TransferApproval",
"DisplayName": "App.Platform.Note",
"Order": 6,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Inventory"
},
{
"GroupName": "App.Inventory",
"Name": "App.Inventory.Transfer",

View file

@ -23,10 +23,10 @@
"Code": "VEN",
"Name": "Tedarikçiler",
"DepartmentId": null,
"ResponsibleUserName": null,
"LocationType": "External",
"ParentId": null,
"IsActive": true,
"ResponsibleUserName": "system@sozsoft.com"
"IsActive": true
},
{
"Id": "0178f19c-5f8c-5506-8d36-4fa5a4688124",
@ -35,10 +35,10 @@
"Code": "CUS",
"Name": "Müşteriler",
"DepartmentId": null,
"ResponsibleUserName": null,
"LocationType": "External",
"ParentId": null,
"IsActive": true,
"ResponsibleUserName": "system@sozsoft.com"
"IsActive": true
},
{
"Id": "15ceb858-663f-406e-b5a8-92c1fb3b361b",

View file

@ -5,73 +5,61 @@
"Order": 0,
"Rows": [
{
"Id": "c2afde78-e0ff-31e7-12ec-3a2429f022bf",
"Name": "(40X40mm) Mamül Sepeti Üst Geçme Kepi",
"IsFavorite": true,
"CanBeSold": true,
"CanBeExpensed": false,
"CanBePurchased": false,
"ProductType": "Wares",
"CategoryId": "ac5ef4ce-aa21-0bcd-db9d-3a2429dfe211",
"TrackInventory": true,
"TrackingMethod": "Quantity",
"UomId": "Adet",
"PurchaseUomId": "Adet",
"SalesPrice": 1,
"Cost": 0,
"IsActive": true,
"Id": "c2afde78-e0ff-31e7-12ec-3a2429f022bf"
},
{
"Name": "(K.M.G) AUTONİCS PR12-4DN Sensör",
"InternalReference": "060104763",
"IsFavorite": false,
"CanBeSold": false,
"CanBeExpensed": false,
"CanBePurchased": true,
"ProductType": "Wares",
"TrackInventory": true,
"TrackingMethod": "Quantity",
"UomId": "Adet",
"PurchaseUomId": "Adet",
"SalesPrice": 1,
"Cost": 0,
"IsActive": true,
"Id": "9df0e297-3601-2d31-1b1e-3a2429f022bf"
},
{
"Name": "(K.M.G) 2A Cam Sigorta (5*20)",
"InternalReference": "060104796",
"IsFavorite": false,
"CanBeSold": false,
"CanBeExpensed": false,
"CanBePurchased": true,
"ProductType": "Wares",
"TrackInventory": true,
"TrackingMethod": "Serial",
"UomId": "Adet",
"PurchaseUomId": "Adet",
"SalesPrice": 1,
"Cost": 0,
"IsActive": true,
"Id": "4de8b328-a0bf-3b36-96d9-3a2429f022bf"
},
{
"Id": "eb0ce687-3014-4f8b-9482-469f3e6d3993",
"Name": "Deneme",
"IsFavorite": false,
"CanBeSold": true,
"CanBeExpensed": false,
"CanBePurchased": false,
"ProductType": "Service",
"CategoryId": "eb9eed73-a7e1-5b5b-c31b-3a2429dfe211",
"TrackInventory": false,
"TrackingMethod": "Quantity",
"SalesPrice": 0.0000,
"SalesPrice": 1.0000,
"Cost": 0.0000,
"InternalReference": null,
"UomId": "Adet",
"PurchaseUomId": "Adet",
"IsActive": true,
"Image": null
},
{
"Id": "9df0e297-3601-2d31-1b1e-3a2429f022bf",
"Name": "(K.M.G) AUTONİCS PR12-4DN Sensör",
"IsFavorite": false,
"CanBeSold": false,
"CanBeExpensed": false,
"CanBePurchased": true,
"ProductType": "Wares",
"CategoryId": "ac5ef4ce-aa21-0bcd-db9d-3a2429dfe211",
"TrackInventory": true,
"TrackingMethod": "Quantity",
"SalesPrice": 1.0000,
"Cost": 0.0000,
"InternalReference": "060104763",
"UomId": "Adet",
"PurchaseUomId": "Adet",
"IsActive": true,
"Image": null
},
{
"Id": "4de8b328-a0bf-3b36-96d9-3a2429f022bf",
"Name": "(K.M.G) 2A Cam Sigorta (5*20)",
"IsFavorite": false,
"CanBeSold": false,
"CanBeExpensed": false,
"CanBePurchased": true,
"ProductType": "Wares",
"CategoryId": "eb9eed73-a7e1-5b5b-c31b-3a2429dfe211",
"TrackInventory": true,
"TrackingMethod": "Serial",
"SalesPrice": 1.0000,
"Cost": 0.0000,
"InternalReference": "060104796",
"UomId": "Adet",
"PurchaseUomId": "Adet",
"IsActive": true,
"Image": null
}
]
}

View file

@ -37258,6 +37258,20 @@
"Key": "App.Listform.ListformField.ReceivedDate",
"Value": "Alınma Tarihi"
},
{
"Id": "3714a98e-855b-5576-909d-4c3a3fde5164",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.ReturnOfId",
"Value": "Return Of"
},
{
"Id": "2682cd41-3f88-5fcd-87dd-0111fc362651",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.ReturnOfId",
"Value": "İade Edilen Belge"
},
{
"Id": "b3dc5cf5-79e2-5ece-bdbb-2c531f5d9570",
"CultureName": "en",
@ -87299,14 +87313,14 @@
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Inventory.ProductCategory.Desc",
"Value": "Product Categories — groups products for reporting, filtering and default accounting (e.g. Electrical & Electronic Materials, Finished Wares).\nWhere: Inventory › Definitions › Product Categories.\nFields: name, parent category (optional, builds a hierarchy), active.\nUsed by: Products › Category field. Passive categories are hidden in lookups; existing products keep their category."
"Value": "Product Categories — groups products for reporting, filtering and default accounting (e.g. Electrical & Electronic Materials, Finished Wares).\nWhere: Inventory › Definitions › Product Categories.\nFields: name, parent category (optional, builds a hierarchy), removal strategy, active.\nThe removal strategy decides which lot/location leaves stock first (each category carries its own value, it is not inherited from the parent): FIFO — first in, first out (oldest receipt date), LIFO — last in, first out (newest receipt date). The order in the Internal Transfer tab of Purchasing › Planning, Suggest and Plan Selected, and Auto Assign in Internal Transfers follow it; a product without a category uses FIFO.\nUsed by: Products › Category field. Passive categories are hidden in lookups; existing products keep their category."
},
{
"Id": "b7555a39-509a-57b0-842c-222eee6055dd",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Inventory.ProductCategory.Desc",
"Value": "Ürün Kategorileri — ürünleri raporlama, filtreleme ve varsayılan muhasebe için gruplar (ör. Elektrik ve Elektronik Malzemeler, Mamuller).\nNerede: Envanter › Tanımlamalar › Ürün Kategorileri.\nAlanlar: ad, üst kategori (isteğe bağlı, hiyerarşi kurar), aktif.\nKullanıldığı yer: Ürünler › Kategori alanı. Pasif kategoriler lookup'ta görünmez; mevcut ürünler kategorisini korur."
"Value": "Ürün Kategorileri — ürünleri raporlama, filtreleme ve varsayılan muhasebe için gruplar (ör. Elektrik ve Elektronik Malzemeler, Mamuller).\nNerede: Envanter › Tanımlamalar › Ürün Kategorileri.\nAlanlar: ad, üst kategori (isteğe bağlı, hiyerarşi kurar), çıkış stratejisi, aktif.\nÇıkış stratejisi stoktan hangi lotun/konumun önce çıkacağını belirler (her kategori kendi değerini taşır, üst kategoriden devralınmaz): FIFO — ilk giren ilk çıkar (en eski giriş tarihi), LIFO — son giren ilk çıkar (en yeni giriş tarihi). Satınalma › Planlama'nın İç Transfer sekmesindeki sıra, Öner ve Seçilenleri Planla ile İç Transferler'deki Otomatik Ata bu stratejiyi izler; kategorisi olmayan ürün FIFO çalışır.\nKullanıldığı yer: Ürünler › Kategori alanı. Pasif kategoriler lookup'ta görünmez; mevcut ürünler kategorisini korur."
},
{
"Id": "c581da6c-4d74-5334-8617-bcb606082d75",
@ -91947,14 +91961,14 @@
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prj.Project.Desc",
"Value": "Projects — R&D and supported projects (TÜBİTAK, KOSGEB, R&D centre, EU, internal) with their team, work packages, costs and diary.\nWhere: Project › Projects.\nCard: project no, name, type, status, start/end date, manager, coloured tags (from Tags).\nTabs: Project Summary, Support, Needs, Activities, Innovative Aspect, Outputs and Benefits (all edit this record), Team (tree), Work Packages (Gantt), Man-Month and Detailed Cost Report (read-only), Diary."
"Value": "Projects — R&D and supported projects (TÜBİTAK, KOSGEB, R&D centre, EU, internal) with their team, work packages, costs and diary.\nWhere: Project › Projects.\nCard: project no, name, type, status, start/end date, manager, branch, coloured tags (from Tags).\nOnly projects of the branches assigned to the user are listed; a new project opens with the user's department branch.\nTabs: Project Summary, Support, Needs, Activities, Innovative Aspect, Outputs and Benefits (all edit this record), Team (tree), Work Packages (Gantt), Man-Month and Detailed Cost Report (read-only), Diary."
},
{
"Id": "99549244-22cc-5b57-9b39-5924edcbbef9",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prj.Project.Desc",
"Value": "Proje Listesi — Ar-Ge ve destekli projeler (TÜBİTAK, KOSGEB, Ar-Ge Merkezi, AB, iç proje); takım, iş paketleri, maliyetler ve günce ile birlikte.\nNerede: Proje › Projeler.\nKart: proje no, ad, tip, durum, başlangıç/bitiş tarihi, yönetici, renkli etiketler (Etiketler tanımından).\nSekmeler: Proje Özeti, Destek, İhtiyaçlar, Faaliyetler, Yenilikçi Yönü, Çıktı ve Faydaları (hepsi bu kaydı düzenler), Takım (ağaç), İş Paketleri (Gantt), Adam / Ay ve Detaylı Maliyet Raporu (salt okunur), Günce."
"Value": "Proje Listesi — Ar-Ge ve destekli projeler (TÜBİTAK, KOSGEB, Ar-Ge Merkezi, AB, iç proje); takım, iş paketleri, maliyetler ve günce ile birlikte.\nNerede: Proje › Projeler.\nKart: proje no, ad, tip, durum, başlangıç/bitiş tarihi, yönetici, şube, renkli etiketler (Etiketler tanımından).\nYalnızca kullanıcıya atanmış şubelerin projeleri listelenir; yeni proje kullanıcının departman şubesiyle açılır.\nSekmeler: Proje Özeti, Destek, İhtiyaçlar, Faaliyetler, Yenilikçi Yönü, Çıktı ve Faydaları (hepsi bu kaydı düzenler), Takım (ağaç), İş Paketleri (Gantt), Adam / Ay ve Detaylı Maliyet Raporu (salt okunur), Günce."
},
{
"Id": "2c6114bb-f8bf-5b63-83d7-73da8cee2cca",
@ -95797,14 +95811,14 @@
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Inventory.InternalTransfer.Desc",
"Value": "Internal Transfers — moves between locations of the same warehouse.\nWhere: Inventory › Operations › Internal Transfers; extra tab Approval & Delivery.\nFields: contact, branch › warehouse › operation type (internal transfer types only), source and destination location (internal locations only, different from each other), scheduled date, source document.\nOrder: enter the lines › Start Workflow › the warehouse responsible of the source location gives Source Warehouse Approval › the document is made ready automatically (Ready/Waiting) › select lots › Validate. A location without a responsible has no approval step (No Approval Needed) and Mark as To Do is pressed by hand. Approval comes before the stock move; Validate writes the receiving user and date.\nImport from Requests (draft transfer) adds the approved material request lines to be fulfilled by transfer; Validate writes the delivered quantity to the request line.\nStatuses: Draft › Waiting / Ready › Done; Cancelled. Row buttons appear according to the document status. Mark as To Do checks stock and fills the done quantity; Validate posts stock by branch › warehouse › location › product › lot; the remainder of lines done below demand moves to a new document (backorder). Return opens a reverse draft document from a done one; Print prints the transfer slip.\nTabs: Operations (product lines; Details for lots/serials, Generate Lot/Serial and Auto Assign), Additional Info (shipping, responsible, project), Note.\nProducts with inventory tracking off create no stock move; products tracked by lot or serial need a lot distribution before Validate. The number comes from the operation type's sequence. Related screens: Inventory › Stock, Moves and Product Moves."
"Value": "Internal Transfers — moves between internal locations (within a warehouse or between warehouses).\nWhere: Inventory › Operations › Internal Transfers.\nFields: contact, branch › warehouse › operation type (internal transfer types only), source and destination location (internal locations only), scheduled date, source document.\nOrder: enter the lines › Mark as To Do (stock check, Ready/Waiting) › select lots › Validate. There is no approval step; like receipts and deliveries the document moves on with the status buttons on its row. Validate writes the receiving user and date (Additional Info tab).\nMaterial request lines come to a transfer through the Internal Transfer or From Stock decision in Purchasing › Requests › Planning: the line is added to the draft transfer for the same source → destination location, otherwise a new draft is opened with the source warehouse's Internal Transfers type; with From Stock the source and destination are the request's delivery location and Validate records the delivery without moving stock. Validate writes the delivered quantity to the request line; cancelling the transfer or deleting its line returns the quantity to Planning.\nStatuses: Draft › Waiting / Ready › Done; Cancelled. Mark as To Do checks stock and fills the done quantity; Validate posts stock by branch › warehouse › location › product › lot; the remainder of lines done below demand moves to a new document (backorder). Return opens a reverse draft document from a done one; Print prints the transfer slip.\nTabs: Operations (product lines; Details for lots/serials, Generate Lot/Serial and Auto Assign), Additional Info (shipping, responsible, project, received by), Note.\nProducts with inventory tracking off create no stock move; products tracked by lot or serial need a lot distribution before Validate. The number comes from the operation type's sequence. Related screens: Inventory › Stock, Moves and Product Moves."
},
{
"Id": "607d1ef7-46dc-5c82-a5e9-c3b08b43ff6d",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Inventory.InternalTransfer.Desc",
"Value": "İç Transferler — aynı deponun konumları arasında taşıma.\nNerede: Envanter › Operasyonlar › İç Transferler; ek sekme Onay ve Teslim.\nAlanlar: kontak, şube › depo › operasyon türü (yalnız iç transfer türleri), kaynak ve hedef konum (yalnız iç konumlar, birbirinden farklı), planlanan tarih, kaynak belge.\nSıra: satırlar girilir › Onayla › kaynak konumun depo sorumlusu Kaynak Depo Onayı verir › belge kendiliğinden hazırlanır (Hazır/Bekleyen) › lotlar seçilir › Doğrula. Sorumlusu olmayan konumda onay adımı yoktur (Onay Gerekmez) ve Yapılacak olarak işaretle elle basılır. Onay stok hareketinden önce gelir; Doğrula teslim alanı ve teslim alma tarihini yazar.\nTalepten Aktar (taslak transferde) transferle karşılanacak onaylı malzeme talebi kalemlerini ekler; Doğrula teslim edilen miktarı talep kalemine yazar.\nDurumlar: Taslak › Bekleyen / Hazır › Tamamlandı; İptal. Satırdaki butonlar belgenin durumuna göre görünür. Yapılacak olarak işaretle stoğu kontrol eder ve yapılacak miktarı doldurur; Doğrula stoğu şube › depo › konum › ürün › lot bazında günceller, talepten az yapılan satırların kalanı aynı türde yeni belgeye (backorder) geçer. İade Et, tamamlanmış belgeden ters yönlü taslak belge açar; Yazdır transfer fişini basar.\nSekmeler: Operasyonlar (ürün satırları; Detaylar ile lot/seri, Lot/Seri Oluştur ve Otomatik Ata), Ek Bilgi (nakliye, sorumlu, proje), Not.\nÜrünün Envanter Takibi kapalıysa stok hareketi oluşmaz; Takip Yöntemi Lot ya da Seri ise Doğrula'dan önce lot dağılımı girilmelidir. Numara operasyon türünün numaratöründen verilir. İlişkili ekranlar: Envanter › Stok, Hareketler ve Ürün Hareketleri."
"Value": "İç Transferler — iç konumlar arasında taşıma (aynı depo ya da depolar arası).\nNerede: Envanter › Operasyonlar › İç Transferler.\nAlanlar: kontak, şube › depo › operasyon türü (yalnız iç transfer türleri), kaynak ve hedef konum (yalnız iç konumlar), planlanan tarih, kaynak belge.\nSıra: satırlar girilir › Yapılacak olarak işaretle (stok kontrolü, Hazır/Bekleyen) › lotlar seçilir › Doğrula. Onay adımı yoktur; alım ve teslimat gibi satırdaki durum butonlarıyla ilerler. Doğrula teslim alanı ve teslim alma tarihini yazar (Ek Bilgi sekmesi).\nMalzeme talebi kalemleri transfere Satınalma › Talepler › Planlama'daki İç Transfer ya da Stoktan kararıyla gelir: aynı kaynak → hedef konum için taslak transfer varsa satır ona eklenir, yoksa kaynak deponun İç Transferler türüyle yeni taslak açılır; Stoktan kararında kaynak ve hedef talebin teslim konumudur, Doğrula stoğa dokunmadan teslimi kaydeder. Doğrula teslim edilen miktarı talep kalemine yazar; transfer iptal edilir ya da satırı silinirse miktar Planlama'ya döner.\nDurumlar: Taslak › Bekleyen / Hazır › Tamamlandı; İptal. Yapılacak olarak işaretle stoğu kontrol eder ve yapılacak miktarı doldurur; Doğrula stoğu şube › depo › konum › ürün › lot bazında günceller, talepten az yapılan satırların kalanı aynı türde yeni belgeye (backorder) geçer. İade Et, tamamlanmış belgeden ters yönlü taslak belge açar; Yazdır transfer fişini basar.\nSekmeler: Operasyonlar (ürün satırları; Detaylar ile lot/seri, Lot/Seri Oluştur ve Otomatik Ata), Ek Bilgi (nakliye, sorumlu, proje, teslim alan), Not.\nÜrünün Envanter Takibi kapalıysa stok hareketi oluşmaz; Takip Yöntemi Lot ya da Seri ise Doğrula'dan önce lot dağılımı girilmelidir. Numara operasyon türünün numaratöründen verilir. İlişkili ekranlar: Envanter › Stok, Hareketler ve Ürün Hareketleri."
},
{
"Id": "7c613a76-67c4-5c0c-a419-2c86a69451da",
@ -95820,48 +95834,6 @@
"Key": "App.Inventory.InternalTransfer.PartnerId",
"Value": "Kontak"
},
{
"Id": "324c39f3-510a-5726-a0e7-a1d78c19523a",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Inventory.TransferApproval.ApprovalStatus",
"Value": "Source Warehouse Approval"
},
{
"Id": "5292b5cf-35dd-504a-b02a-6ebe282a30ba",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Inventory.TransferApproval.ApprovalStatus",
"Value": "Kaynak Depo Onayı"
},
{
"Id": "794c4f77-ce12-5cb0-a46b-f3731669e119",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.SourceApproverUserNames",
"Value": "SourceApproverUserNames"
},
{
"Id": "c02c8dec-1538-5d28-b893-b5a0f06885dd",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.SourceApproverUserNames",
"Value": "SourceApproverUserNames"
},
{
"Id": "e359487a-2cc2-55e0-b076-eb0e2931e383",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Inventory.Transfer.Tab.Approval",
"Value": "Approval & Delivery"
},
{
"Id": "741e07c5-a60f-5914-afbb-5cf06499457d",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Inventory.Transfer.Tab.Approval",
"Value": "Onay ve Teslim"
},
{
"Id": "b2400766-1d59-57a4-b98e-de79e6910904",
"CultureName": "en",
@ -95895,14 +95867,14 @@
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Inventory.TransferLine.Desc",
"Value": "Transfer Lines — product lines of receipts, deliveries and internal transfers.\nWhere: Operations tab of Inventory › Operations › Receipts, Deliveries and Internal Transfers.\nFields: product (unit comes from the product), description, demand, done quantity (filled by Mark as To Do, editable before Validate), unit.\nRow buttons — shown only on lines of lot/serial tracked products: Details opens the lot/serial distribution (incoming lines type new numbers, outgoing lines select from the stock of the source location); Generate Lot/Serial (incoming lines of lot/serial tracked products, from the Inventory.LotNumber / Inventory.SerialNumber sequences) and Auto Assign (outgoing lines, first-in first-out from the source location). On lot/serial tracked lines the done quantity follows the total of the entered lots, and the Lots column lists them. Lines of done or cancelled documents cannot be changed."
"Value": "Transfer Lines — product lines of receipts, deliveries and internal transfers.\nWhere: Operations tab of Inventory › Operations › Receipts, Deliveries and Internal Transfers.\nFields: product (unit comes from the product), description, demand, done quantity (filled by Mark as To Do, editable before Validate), unit.\nRow buttons — shown only on lines of lot/serial tracked products: Details opens the lot/serial distribution (incoming lines type new numbers, outgoing lines select from the stock of the source location); Generate Lot/Serial (incoming lines of lot/serial tracked products, from the Inventory.LotNumber / Inventory.SerialNumber sequences) and Auto Assign (outgoing lines, from the source location in the product category's removal strategy — FIFO or LIFO). On lot/serial tracked lines the done quantity follows the total of the entered lots, and the Lots column lists them. Lines of done or cancelled documents cannot be changed."
},
{
"Id": "5dd858a1-e562-5fd9-adb7-e8406c90cf5d",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Inventory.TransferLine.Desc",
"Value": "Transfer Satırları — alım, teslimat ve iç transferlerin ürün satırları.\nNerede: Envanter › Operasyonlar › Alımlar, Teslimatlar ve İç Transferler ekranlarının Operasyonlar sekmesi.\nAlanlar: ürün (birim üründen gelir), açıklama, talep, yapılan miktar (Yapılacak olarak işaretle doldurur, Doğrula'dan önce değiştirilebilir), birim.\nSatır butonları — yalnız lot/seri takipli ürünün satırında görünür: Detaylar lot/seri dağılımını açar (giren satırda numara yazılır, çıkan satırda kaynak konumun stoğundan seçilir); Lot/Seri Oluştur (lot/seri takipli ürünün giriş satırı; Inventory.LotNumber / Inventory.SerialNumber numaratöründen) ve Otomatik Ata (çıkış satırı; kaynak konumdan ilk giren ilk çıkar). Lot/seri takipli satırda yapılan miktar girilen lotların toplamını izler; Lotlar kolonu seçilen lotları listeler. Tamamlanmış ya da iptal edilmiş belgenin satırı değiştirilemez."
"Value": "Transfer Satırları — alım, teslimat ve iç transferlerin ürün satırları.\nNerede: Envanter › Operasyonlar › Alımlar, Teslimatlar ve İç Transferler ekranlarının Operasyonlar sekmesi.\nAlanlar: ürün (birim üründen gelir), açıklama, talep, yapılan miktar (Yapılacak olarak işaretle doldurur, Doğrula'dan önce değiştirilebilir), birim.\nSatır butonları — yalnız lot/seri takipli ürünün satırında görünür: Detaylar lot/seri dağılımını açar (giren satırda numara yazılır, çıkan satırda kaynak konumun stoğundan seçilir); Lot/Seri Oluştur (lot/seri takipli ürünün giriş satırı; Inventory.LotNumber / Inventory.SerialNumber numaratöründen) ve Otomatik Ata (çıkış satırı; kaynak konumdan ürün kategorisinin çıkış stratejisiyle — FIFO ya da LIFO). Lot/seri takipli satırda yapılan miktar girilen lotların toplamını izler; Lotlar kolonu seçilen lotları listeler. Tamamlanmış ya da iptal edilmiş belgenin satırı değiştirilemez."
},
{
"Id": "ae8cdf0d-5895-5570-8d32-7d15e9f1dbeb",
@ -96175,14 +96147,14 @@
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Inventory.TransferOther.Desc",
"Value": "Additional Info — shipping and other information of a transfer document (Additional Info tab of receipts, deliveries and internal transfers).\nFields: carrier (contact), tracking reference, weight (calculated from the lines: product weight × quantity), shipping weight, responsible, project."
"Value": "Additional Info — shipping and other information of a transfer document (Additional Info tab of receipts, deliveries and internal transfers).\nFields: carrier (contact), tracking reference, weight (calculated from the lines: product weight × quantity), shipping weight, responsible, project; for internal transfers received by and receipt date (written by Validate, read only)."
},
{
"Id": "23261dbf-c29f-5fb4-93b2-ec4d3f19962c",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Inventory.TransferOther.Desc",
"Value": "Ek Bilgi — transfer belgesinin nakliye ve diğer bilgileri (alım, teslimat ve iç transferlerin Ek Bilgi sekmesi).\nAlanlar: nakliyeci (kontak), takip referansı, ağırlık (satırlardan hesaplanır: ürün ağırlığı × miktar), nakliye ağırlığı, sorumlu, proje."
"Value": "Ek Bilgi — transfer belgesinin nakliye ve diğer bilgileri (alım, teslimat ve iç transferlerin Ek Bilgi sekmesi).\nAlanlar: nakliyeci (kontak), takip referansı, ağırlık (satırlardan hesaplanır: ürün ağırlığı × miktar), nakliye ağırlığı, sorumlu, proje; iç transferde teslim alan ve teslim alma tarihi (Doğrula yazar, salt okunur)."
},
{
"Id": "818cd5de-1982-52fa-bdb9-f828b5fbb7e2",
@ -96282,48 +96254,6 @@
"Key": "App.Inventory.TransferNote.Desc",
"Value": "Not — transfer belgesinin serbest notu (alım, teslimat ve iç transferlerin Not sekmesi).\nAlan: not (zengin metin)."
},
{
"Id": "2e546bba-e534-519f-9758-5fe36806e4c4",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Inventory.TransferApproval",
"Value": "Approval & Delivery"
},
{
"Id": "753464aa-9981-5ce3-9d29-27035440b72c",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Inventory.TransferApproval",
"Value": "Onay ve Teslim"
},
{
"Id": "99bac7e9-f3d0-5c28-b90f-0eeb505f1b78",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Inventory.TransferApproval.Title",
"Value": "Approval & Delivery"
},
{
"Id": "3addc479-7476-5ce8-9e4b-1f157f9db89f",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Inventory.TransferApproval.Title",
"Value": "Onay ve Teslim"
},
{
"Id": "48711261-e1f5-53a2-8caf-c603817a95f6",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Inventory.TransferApproval.Desc",
"Value": "Approval & Delivery — source warehouse approval and receipt of an internal transfer (Approval & Delivery tab of Internal Transfers; read only).\nFields: source warehouse approval (No Approval Needed when the source location has no responsible), approval user / date / description (written by the workflow), received by and receipt date (written by Validate)."
},
{
"Id": "6e98e0c5-d9d7-5c2f-9137-f0c9c84efc43",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Inventory.TransferApproval.Desc",
"Value": "Onay ve Teslim — iç transferin kaynak depo onayı ve teslimi (İç Transferler'in Onay ve Teslim sekmesi; salt okunur).\nAlanlar: kaynak depo onayı (kaynak konumun sorumlusu yoksa Onay Gerekmez), onaylayan / onay tarihi / açıklaması (iş akışı yazar), teslim alan ve teslim alma tarihi (Doğrula yazar)."
},
{
"Id": "be937f76-123b-5b7e-9f33-805aac3c6d32",
"CultureName": "en",
@ -96408,20 +96338,6 @@
"Key": "App.Inventory.Transfer.Open",
"Value": "Aç"
},
{
"Id": "131fd91d-5c9b-5161-8c0b-e5b22f51a8de",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Inventory.Transfer.SameLocation",
"Value": "Source and destination location cannot be the same."
},
{
"Id": "344c9e63-fa99-547d-9e64-c9aa67035dd9",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Inventory.Transfer.SameLocation",
"Value": "Kaynak ve hedef konum aynı olamaz."
},
{
"Id": "88108bff-37d4-5e69-9e11-d9a1e7e30a1e",
"CultureName": "en",
@ -97085,14 +97001,14 @@
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanTrack.Desc",
"Value": "Plan Tracking — every decision made in Planning with the document it produced and how far it has progressed; each row is one decision.\nWhere: Purchasing › Requests › Plan Tracking. Purchasing rows are the request lines on RFQs (the root RFQ of a tender; copies on alternative suppliers are not repeated), transfer rows are internal transfer lines; returns are not listed.\nFields: plan date and purchasing responsible (the user who planned), request no, department, product, decision (Purchasing / Internal Transfer / From Stock), document no and status (RFQ: Draft / Sent / Converted / Cancelled; transfer: Draft / Waiting / Ready / Done / Cancelled), supplier (the winning supplier once ordered) or source location, destination location, order no and status, planned quantity, done quantity (received on the order or moved by the completed transfer), unit, required date, warehouse, branch.\nUsage: the list is read-only. Row buttons open the RFQ, the purchase order or the internal transfer on its detail page; Undo on a From Stock row reverses the fulfilment from stock: the quantity is taken off the line's delivered quantity, the line returns to Waiting and can be planned again in Planning. Purchasing and transfer decisions are undone on their document: cancelling the RFQ or the internal transfer, or deleting its line, returns the line to Planning.\nCards: total decisions, purchasing, internal transfer, completed.\nRelated: Planning, Requests for Quotation, Purchase Orders, Inventory › Internal Transfers."
"Value": "Plan Tracking — every decision made in Planning with the document it produced and how far it has progressed; each row is one decision.\nWhere: Purchasing › Requests › Plan Tracking. Purchasing rows are the request lines on RFQs (the root RFQ of a tender; copies on alternative suppliers are not repeated), transfer rows are internal transfer lines; From Stock rows are internal transfers too — source and destination are the request's delivery location, the warehouse's Validate records the hand-over (no stock movement); returns are not listed.\nFields: plan date and purchasing responsible (the user who planned), request no, department, product, decision (Purchasing / Internal Transfer / From Stock), document no and status (RFQ: Draft / Sent / Converted / Cancelled; transfer: Draft / Waiting / Ready / Done / Cancelled), supplier (the winning supplier once ordered) or source location, destination location, order no and status, planned quantity, done quantity (received on the order or moved by the completed transfer), unit, required date, warehouse, branch.\nUsage: the list is read-only. Row buttons open the RFQ, the purchase order or the internal transfer (From Stock included) on its detail page. Every decision is undone on its document: cancelling the RFQ or the internal transfer, or deleting its line, returns the line to Planning. A request whose lines are all delivered becomes Completed.\nCards: total decisions, purchasing, internal transfer, completed.\nRelated: Planning, Requests for Quotation, Purchase Orders, Inventory › Internal Transfers."
},
{
"Id": "eb2c2035-1e3a-554b-810d-6486c72d0398",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanTrack.Desc",
"Value": "Plan Takibi — Planlama'da verilen her karar, ürettiği belge ve belgenin geldiği aşamayla; her satır bir karardır.\nNerede: Satınalma › Talepler › Plan Takibi. Satınalma satırları teklif taleplerindeki talep kalemleridir (ihalenin kök teklif talebi; alternatif tedarikçilere kopyalanan satırlar tekrar listelenmez), transfer satırları iç transfer satırlarıdır, Stoktan satırları talebin teslim konumundaki stoktan belgesiz karşılanan miktardır; iade belgeleri listelenmez.\nAlanlar: plan tarihi ve satınalma sorumlusu (planlayan kullanıcı), talep no, departman, ürün, karar (Satınalma / İç Transfer / Stoktan), belge no ve durumu (teklif: Taslak / Gönderildi / Siparişe Dönüştü / İptal; transfer: Taslak / Bekleyen / Hazır / Tamamlandı / İptal), tedarikçi (siparişe dönüştüyse kazanan tedarikçi) ya da kaynak konum, hedef konum, sipariş no ve durumu, planlanan miktar, gerçekleşen (siparişte alınan ya da tamamlanan transferde taşınan), birim, termin tarihi, depo, şube.\nKullanım: liste salt okunurdur. Satırdaki butonlar teklif talebini, satınalma siparişini ya da iç transferi detay sayfasında açar; Stoktan satırındaki Geri Al stoktan karşılamayı geri alır: miktar kalemin teslim edilen miktarından düşer, kalem Bekliyor'a döner ve Planlama'da yeniden planlanır. Satınalma ve transfer kararı belgesinden geri alınır: teklif talebi ya da iç transfer iptal edilince ya da satırı silinince kalem Planlama'ya döner.\nKartlar: toplam karar, satınalma, iç transfer, tamamlanan.\nİlişkili: Planlama, Teklif Talepleri, Satınalma Siparişleri, Envanter › İç Transferler."
"Value": "Plan Takibi — Planlama'da verilen her karar, ürettiği belge ve belgenin geldiği aşamayla; her satır bir karardır.\nNerede: Satınalma › Talepler › Plan Takibi. Satınalma satırları teklif taleplerindeki talep kalemleridir (ihalenin kök teklif talebi; alternatif tedarikçilere kopyalanan satırlar tekrar listelenmez), transfer satırları iç transfer satırlarıdır; Stoktan satırları da iç transferdir — kaynağı ve hedefi talebin teslim konumu olan, depo Doğrula'sında teslimi kaydeden (stok hareketi oluşmaz) belge; iade belgeleri listelenmez.\nAlanlar: plan tarihi ve satınalma sorumlusu (planlayan kullanıcı), talep no, departman, ürün, karar (Satınalma / İç Transfer / Stoktan), belge no ve durumu (teklif: Taslak / Gönderildi / Siparişe Dönüştü / İptal; transfer: Taslak / Bekleyen / Hazır / Tamamlandı / İptal), tedarikçi (siparişe dönüştüyse kazanan tedarikçi) ya da kaynak konum, hedef konum, sipariş no ve durumu, planlanan miktar, gerçekleşen (siparişte alınan ya da tamamlanan transferde taşınan), birim, termin tarihi, depo, şube.\nKullanım: liste salt okunurdur. Satırdaki butonlar teklif talebini, satınalma siparişini ya da iç transferi (Stoktan dahil) detay sayfasında açar. Her karar belgesinden geri alınır: teklif talebi ya da iç transfer iptal edilince ya da satırı silinince kalem Planlama'ya döner. Bütün kalemleri teslim edilen talebin durumu Tamamlandı olur.\nKartlar: toplam karar, satınalma, iç transfer, tamamlanan.\nİlişkili: Planlama, Teklif Talepleri, Satınalma Siparişleri, Envanter › İç Transferler."
},
{
"Id": "43e6afa9-b6ec-5e70-9afd-3f2d6b8b2db2",
@ -97295,14 +97211,14 @@
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanSource.Desc",
"Value": "Internal Transfer — the Internal Transfer tab of the Plan dialog: internal locations holding stock of the line's product.\nWhere: Purchasing › Material Requests › Planning › Plan button (no menu of its own); filtered by the line being planned. The request's own delivery location is listed too and ticked as Delivery Location.\nFields: branch, warehouse, location, delivery location, on hand, reserved (requested from that location by open internal transfers), free (on hand − reserved), max (upper limit for the row), plan quantity, unit — all in the line's unit.\nUsage: type into the highlighted Plan Quantity cell (saved when leaving the cell), press Plan All (takes Max) or select rows and press Plan Selected (each row takes its Max in turn) on one or more locations; the quantities go to the Fulfilment Plan as a draft (0 removes the row). A row cannot exceed its free stock, the draft total cannot exceed the remaining quantity. Confirm in the dialog creates the internal transfers; a quantity on the delivery location opens no transfer — it is fulfilled from stock and closes the line when nothing is left to plan and nothing is being purchased."
"Value": "Internal Transfer — the Internal Transfer tab of the Plan dialog: internal locations holding stock of the line's product. If the product is tracked by lot/serial number every lot of every location (every serial when tracked by serial) is a separate row; a product tracked by quantity has one row per location.\nWhere: Purchasing › Material Requests › Planning › Plan button (no menu of its own); filtered by the line being planned. The request's own delivery location is listed too and ticked as Delivery Location.\nFields: branch, warehouse, location, lot/serial no (tracked products only), delivery location, on hand, reserved (requested from that location by open internal transfers; on a lot row, assigned to that lot), free (on hand − reserved; on a lot row limited by the location's free stock), max (upper limit for the row), removal order, plan quantity, unit — all in the line's unit.\nRemoval order: the delivery location first, then the removal strategy of the product's category (Inventory › Definitions › Product Categories; FIFO: oldest receipt first, LIFO: newest receipt first; products without a category use FIFO). The list comes in this order; Suggest and Plan Selected distribute stock in this order.\nUsage: type into the highlighted Plan Quantity cell (saved when leaving the cell), press Plan All (takes Max for that row) or select rows and press Plan Selected (each row takes its Max in removal order); the quantities go to the Fulfilment Plan as a draft (0 removes the row). A row cannot exceed its free stock, the draft total cannot exceed the remaining quantity. Confirm in the dialog creates the internal transfers and writes the planned lots into the transfer line's lot distribution (the warehouse can change them with Details or Auto Assign in Internal Transfers); a quantity on the delivery location is a From Stock decision: it opens an internal transfer whose source and destination are the delivery location; when the warehouse validates it (stock stays in place) the line is delivered."
},
{
"Id": "c5a496f4-2dfb-5067-ab90-1771eab3cf02",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanSource.Desc",
"Value": "İç Transfer — Planla diyaloğunun İç Transfer sekmesi: talep kaleminin ürününün stoğu olan iç konumlar.\nNerede: Satınalma › Talepler › Planlama › Planla butonu (kendi menüsü yoktur); planlanan kaleme süzülür. Talebin kendi teslim konumu da listelenir, Teslim Konumu işaretiyle.\nAlanlar: şube, depo, konum, teslim konumu, eldeki, ayrılan (açık iç transferlerde o konumdan istenen), serbest (eldeki − ayrılan), en fazla (satıra yazılabilecek üst sınır), plan miktarı, birim — hepsi kalemin biriminde.\nKullanım: bir ya da birkaç konumun vurgulu Plan Miktarı hücresine miktar yazılır (hücreden çıkınca kaydedilir), satırdaki Tümünü Planla ile En Fazla değeri atanır ya da satırlar seçilip Seçilenleri Planla ile her birine sırayla En Fazla yazılır; miktarlar taslak olarak Karşılama Planı'na geçer (0 satırı çıkarır). Satır serbest stoğu, taslak toplamı planlanacak kalanı aşamaz. Diyalogdaki Onayla iç transferleri oluşturur; teslim konumuna yazılan miktar transfer açmaz, stoktan karşılanır ve planlanacak kalanı kalmayan, satınalma payı olmayan kalemi kapatır."
"Value": "İç Transfer — Planla diyaloğunun İç Transfer sekmesi: talep kaleminin ürününün stoğu olan iç konumlar. Ürün lot/seri numarasıyla takip ediliyorsa her konumun her lotu (seri takipte her seri) ayrı satırdır; miktarla takip edilen üründe konum başına tek satır vardır.\nNerede: Satınalma › Talepler › Planlama › Planla butonu (kendi menüsü yoktur); planlanan kaleme süzülür. Talebin kendi teslim konumu da listelenir, Teslim Konumu işaretiyle.\nAlanlar: şube, depo, konum, lot/seri no (yalnız takipli üründe), teslim konumu, eldeki, ayrılan (açık iç transferlerde o konumdan istenen; lot satırında o lota atanmış), serbest (eldeki − ayrılan; lot satırında konumun serbest stoğuyla sınırlı), en fazla (satıra yazılabilecek üst sınır), çıkış sırası, plan miktarı, birim — hepsi kalemin biriminde.\nÇıkış sırası: teslim konumu önce, sonra ürünün kategorisindeki çıkış stratejisi (Envanter › Tanımlamalar › Ürün Kategorileri; FIFO: en eski giriş önce, LIFO: en yeni giriş önce; kategorisiz ürün FIFO). Liste bu sırayla gelir; Öner ve Seçilenleri Planla stoğu bu sırayla dağıtır.\nKullanım: vurgulu Plan Miktarı hücresine miktar yazılır (hücreden çıkınca kaydedilir), satırdaki Tümünü Planla ile o satıra En Fazla değeri atanır ya da satırlar seçilip Seçilenleri Planla ile çıkış sırasıyla her birine En Fazla yazılır; miktarlar taslak olarak Karşılama Planı'na geçer (0 satırı çıkarır). Satır serbest stoğu, taslak toplamı planlanacak kalanı aşamaz. Diyalogdaki Onayla iç transferleri oluşturur ve planlanan lotları transfer satırının lot dağılımına yazar (depo İç Transferler'de Detaylar ya da Otomatik Ata ile değiştirebilir); teslim konumuna yazılan miktar Stoktan kararıdır: kaynağı ve hedefi teslim konumu olan bir iç transfer açar; depo Doğrula'ya basınca (stok yerinde kalır) kalem teslim edilmiş olur."
},
{
"Id": "5cbff28f-1336-5777-8a29-7593c54123cc",
@ -97379,14 +97295,14 @@
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanLine.Desc",
"Value": "Fulfilment Plan — the draft distribution of the line in the Plan dialog, waiting for Confirm.\nWhere: Purchasing › Requests › Planning › Plan button, below the Internal Transfer and Purchasing tabs (no menu of its own); filtered by the line being planned.\nFields: decision (internal transfer / from stock / purchasing), supplier or source location, quantity and unit, unit price and currency for purchasing (the price the RFQ line will get).\nUsage: rows are written from the Plan Quantity of the two tabs; a row can be deleted here (applied at once); Reset Draft in the dialog clears the whole draft. Confirm turns every row into a document in one go (internal transfers first, then fulfilment from stock, then RFQs) and empties the plan; if a row is rejected (stock, remaining quantity, operation type) no document is created and the draft stays. The draft total is shown in Planning as Draft Plan."
"Value": "Fulfilment Plan — the draft distribution of the line in the Plan dialog, waiting for Confirm.\nWhere: Purchasing › Requests › Planning › Plan button, below the Internal Transfer and Purchasing tabs (no menu of its own); filtered by the line being planned.\nFields: decision (internal transfer / from stock / purchasing), supplier or source location, lot/serial no (for a lot/serial tracked product in internal transfer and from-stock decisions), quantity and unit, unit price and currency for purchasing (the price the RFQ line will get).\nUsage: rows are written from the Plan Quantity of the two tabs; a row can be deleted here (applied at once); Reset Draft in the dialog clears the whole draft. Confirm turns every row into a document in one go (internal transfers first, then fulfilment from stock, then RFQs) and empties the plan; if a row is rejected (stock, remaining quantity, operation type) no document is created and the draft stays. The draft total is shown in Planning as Draft Plan."
},
{
"Id": "e970b541-a224-5fe5-aa3a-5fdfca725385",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanLine.Desc",
"Value": "Karşılama Planı — kalemin Planla diyaloğundaki, onay bekleyen taslak dağıtımı.\nNerede: Satınalma › Talepler › Planlama › Planla butonu, İç Transfer ve Satınalma sekmelerinin altında (kendi menüsü yoktur); planlanan kaleme süzülür.\nAlanlar: karar (iç transfer / stoktan / satınalma), tedarikçi ya da kaynak konum, miktar ve birim, satınalmada birim fiyat ve para birimi (teklif kalemine yazılacak fiyat).\nKullanım: satırlar iki sekmenin Plan Miktarı'ndan yazılır; burada satır silinebilir (silme hemen uygulanır), diyalogdaki Taslağı Sıfırla bütün taslağı siler. Onayla bütün satırları tek seferde belgeye çevirir (önce iç transferler, sonra stoktan karşılama, en son teklif talepleri) ve planı boşaltır; bir satır reddedilirse (stok, kalan, operasyon türü) hiçbir belge açılmaz, taslak yerinde kalır. Taslak toplamı Planlama'da Taslak Plan kolonunda görünür."
"Value": "Karşılama Planı — kalemin Planla diyaloğundaki, onay bekleyen taslak dağıtımı.\nNerede: Satınalma › Talepler › Planlama › Planla butonu, İç Transfer ve Satınalma sekmelerinin altında (kendi menüsü yoktur); planlanan kaleme süzülür.\nAlanlar: karar (iç transfer / stoktan / satınalma), tedarikçi ya da kaynak konum, lot/seri no (lot/seri takipli üründe iç transfer ve stoktan kararında), miktar ve birim, satınalmada birim fiyat ve para birimi (teklif kalemine yazılacak fiyat).\nKullanım: satırlar iki sekmenin Plan Miktarı'ndan yazılır; burada satır silinebilir (silme hemen uygulanır), diyalogdaki Taslağı Sıfırla bütün taslağı siler. Onayla bütün satırları tek seferde belgeye çevirir (önce iç transferler, sonra stoktan karşılama, en son teklif talepleri) ve planı boşaltır; bir satır reddedilirse (stok, kalan, operasyon türü) hiçbir belge açılmaz, taslak yerinde kalır. Taslak toplamı Planlama'da Taslak Plan kolonunda görünür."
},
{
"Id": "4545d7aa-f424-5115-9ae2-59b8f40b6e6c",
@ -97407,14 +97323,14 @@
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlan.Info",
"Value": "1) Suggest builds the plan for you: stock first (the delivery location, then the location with the most free stock), the rest as purchasing from the best supplier (lowest price, else the latest purchase); Suggest & Confirm also confirms it at once. Nothing is planned until you press a button. 2) To change it, type into the highlighted Plan Quantity cell (saved when you leave the cell), press Plan All on a row, or select rows and press Plan Selected; each row takes the most it allows (Max). Stock on the request's own delivery location is fulfilled from stock without a transfer. 3) Check the Fulfilment Plan below (a row can be deleted there) and press Confirm: internal transfers and RFQs are created."
"Value": "1) Suggest builds the plan for you: stock first (the delivery location, then the other locations in the product category's removal order — FIFO or LIFO), the rest as purchasing from the best supplier (lowest price, else the latest purchase); Suggest & Confirm also confirms it at once. Nothing is planned until you press a button. 2) To change it, type into the highlighted Plan Quantity cell (saved when you leave the cell), press Plan All on a row, or select rows and press Plan Selected; each row takes the most it allows (Max). Stock on the request's own delivery location is planned as From Stock: an internal transfer with the same source and destination records the delivery without moving stock. 3) Check the Fulfilment Plan below (a row can be deleted there) and press Confirm: internal transfers and RFQs are created."
},
{
"Id": "e1f4b24a-b3ce-54d3-a43c-04bc28916b9a",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlan.Info",
"Value": "1) Öner planı sizin için kurar: önce stok (talebin teslim konumu, sonra serbest stoğu en çok olan konum), kalan kısım en uygun tedarikçiden (en düşük fiyat, fiyat yoksa en son alım) satınalma; Öner ve Onayla bunu hemen onaylar. Siz bir butona basmadan hiçbir şey planlanmaz. 2) Değiştirmek için vurgulu Plan Miktarı hücresine yazın (hücreden çıkınca kaydedilir), satırdaki Tümünü Planla'ya basın ya da satırları seçip Seçilenleri Planla'ya basın; her satır alabileceği en fazla miktarı (En Fazla) alır. Talebin kendi teslim konumundaki stok transfer açmadan stoktan karşılanır. 3) Alttaki Karşılama Planı'nı kontrol edin (satır oradan silinebilir) ve Onayla'ya basın: iç transferler ve teklif talepleri oluşur."
"Value": "1) Öner planı sizin için kurar: önce stok (talebin teslim konumu, sonra diğer konumlar ürün kategorisinin çıkış stratejisi — FIFO ya da LIFO — sırasıyla), kalan kısım en uygun tedarikçiden (en düşük fiyat, fiyat yoksa en son alım) satınalma; Öner ve Onayla bunu hemen onaylar. Siz bir butona basmadan hiçbir şey planlanmaz. 2) Değiştirmek için vurgulu Plan Miktarı hücresine yazın (hücreden çıkınca kaydedilir), satırdaki Tümünü Planla'ya basın ya da satırları seçip Seçilenleri Planla'ya basın; her satır alabileceği en fazla miktarı (En Fazla) alır. Talebin kendi teslim konumundaki stok Stoktan olarak planlanır: kaynağı ve hedefi aynı olan iç transfer stoğu taşımadan teslimi kaydeder. 3) Alttaki Karşılama Planı'nı kontrol edin (satır oradan silinebilir) ve Onayla'ya basın: iç transferler ve teklif talepleri oluşur."
},
{
"Id": "3919694f-1c14-54da-9de9-825d4502c4eb",
@ -97505,14 +97421,14 @@
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlan.TakeMax",
"Value": "Plan All"
"Value": "Plan"
},
{
"Id": "1dc9ad68-b979-536b-8169-e58d839dc665",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlan.TakeMax",
"Value": "Tümünü Planla"
"Value": "Planla"
},
{
"Id": "bc3ea62c-0946-54e0-9195-aad7ed08ab46",
@ -97570,34 +97486,6 @@
"Key": "App.Prc.MaterialRequestPlan.ResetDraft",
"Value": "Taslağı Sıfırla"
},
{
"Id": "8a88703a-5c0e-5fb8-897b-82c90c8c7187",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanTrack.UndoStock",
"Value": "Undo"
},
{
"Id": "5f8de940-b6cd-5435-a2f9-a562aaf345a4",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanTrack.UndoStock",
"Value": "Geri Al"
},
{
"Id": "a580aef2-8fa8-57a8-b00b-2eb05eb3d1d2",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanTrack.UndoStockConfirm",
"Value": "Undo this fulfilment from stock? The quantity returns to the line and it can be planned again in Planning."
},
{
"Id": "b271da70-3bc4-57c1-95d1-f1101e7b836f",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanTrack.UndoStockConfirm",
"Value": "Bu stoktan karşılama geri alınsın mı? Miktar kaleme geri döner ve Planlama ekranında yeniden planlanabilir."
},
{
"Id": "cbb23672-79f1-5c44-9402-07540e538f13",
"CultureName": "en",
@ -97653,6 +97541,62 @@
"ResourceName": "Platform",
"Key": "Abp.Identity.User.BranchDefaultLocationRequired",
"Value": "{0} şubesi için seçilen depoya ait bir varsayılan konum seçin."
},
{
"Id": "352db6a5-59bc-5621-86cb-c93c21a34a88",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.RemovalRank",
"Value": "Removal Order"
},
{
"Id": "e7b957fe-a08d-5697-9288-430fe218bfd2",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.RemovalRank",
"Value": "Çıkış Sırası"
},
{
"Id": "ff51cdea-a23d-5334-9762-802bea95b423",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.RemovalStrategy",
"Value": "Removal Strategy"
},
{
"Id": "97191139-4c32-5350-90a3-f4c7ed35a332",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.RemovalStrategy",
"Value": "Çıkış Stratejisi"
},
{
"Id": "cc8e876d-64f6-5d03-9623-1e247d42ff66",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.StaticLookup.Fifo",
"Value": "FIFO (First In, First Out)"
},
{
"Id": "8c7995f3-ed8c-5004-8c1e-2819fb0ce8a3",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.StaticLookup.Fifo",
"Value": "FIFO (İlk Giren İlk Çıkar)"
},
{
"Id": "f0d33731-151b-52b6-a8af-77434e9a09c9",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.StaticLookup.Lifo",
"Value": "LIFO (Last In, First Out)"
},
{
"Id": "45ccf971-2e2e-5f02-8048-2997a4987f5e",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.StaticLookup.Lifo",
"Value": "LIFO (Son Giren İlk Çıkar)"
}
]
}

View file

@ -309,7 +309,7 @@ Hiçbir yetki role otomatik atanmaz.
**Teknik yetenekler için seviye seçilemiyor.** Seed'de Technical Skills tipine seviye tanımlı değil; kullanıcı yetkinliği 1–5 ölçeğiyle girilir. Performans modülünde bu tipe seviye eklenmesi gerekir.
**"Languages" tipinin adını değiştirdim, dil listesi boşaldı.** Lookup'lar tip adını sabit kullanır (`TenantLanguageSkillValues`, `TechnicalSkillsValues`).
**"Languages" tipinin adını değiştirdim, dil listesi boşaldı.** Lookup'lar tip adını sabit kullanır (`TenantLanguageSkillValues`, `TenantNonLanguageSkillValues`).
Kontrol edilmeli (koddan tespit edilen tutarsızlıklar):
- Organizasyon Şeması API'si (`api/app/org-chart`) yalnız oturum ister, `App.Hr.OrgChart` yetkisini denetlemez; menü ve rota yetkiyle korunur.

View file

@ -54,7 +54,7 @@ Tüm tablolar kiracı + tam audit + soft delete, anahtar `Id uniqueidentifier`.
| Tablo | İçerik |
| --- | --- |
| `Inv_T_ProductCategory` | Ad, üst kategori, aktif |
| `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 sekmelerinin alanları |
| `Inv_T_ProductAttributeLine` | Ürün × nitelik, `ValueIds` (`|` ayrımlı değer Id) |
@ -70,6 +70,7 @@ Tüm tablolar kiracı + tam audit + soft delete, anahtar `Id uniqueidentifier`.
- **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.
@ -113,7 +114,6 @@ Dış entegrasyon yok. Reçete operasyonları iş merkezi ve operasyonu Üretim
- **Demo veri aynaları:** `data/App.Inventory.{ProductCategory,Attribute,Product,Warehouse}.json`.
- **Geri alma:** Wizard Manager'da ana ekranlar (Product, Bom, Attribute) önce, alt formları sonra silinir. Depolar/Konumlar/Operasyon Türleri bağımsızdır; tablo düşürülecekse sıra OperationType → Location → Warehouse (FK). Tablolar ancak açık onayla `dropTables` ile düşürülür.
- **Sorgu bağımlılığı:** Sorgular SQL Server'a özgüdür (`STRING_SPLIT`, `CONCAT_WS`, `STRING_AGG`, `CROSS APPLY`).
- **Açık nokta:** Eski ürün ekranlarının form varsayılanları (Aktif = true, Birim = Adet, Miktar = 1, Süre = 60, Kur = TRY) düz wizard biçimiyle dosyaya yazılmadı. ListForm düzenleyicisinden ya da `ListForm` bölümlü yeniden deploy ile eklenmelidir.
<!-- module-doc:section App.Inventory.Operations -->
## Operasyonlar (`App.Inventory.Operations`)
@ -130,7 +130,7 @@ Onaylanan analiz (talep "Envanter giriş ve çıkışları"):
- Stok bakiyesi ayrı tablodadır (`Inv_T_Stock`, kullanıcı kararı): yalnız Doğrula yordamı yazar.
- Stok yetmezse belge Bekleyen kalır, Doğrula yapılamaz (negatif stok yok). Rezervasyon yoktur; Doğrula stoğu yeniden kontrol eder.
- Kısmi işlemde kalan, aynı türde yeni belgeye (backorder) geçer.
- Ek kapsam: İade, iç transferde kaynak depo onayı ve teslim, malzeme talebinden iç transfer, transfer fişi yazdırma.
- 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.
@ -140,26 +140,25 @@ Onaylanan analiz (talep "Envanter giriş ve çıkışları"):
Üretimde verilen ek kararlar:
- Stok konum türüne göre işlenir: kaynak konum `Internal` ise stoktan düşer, hedef konum `Internal` ise stoğa eklenir. Tedarikçiler/Müşteriler gibi dış (`External`) konumlar stok tutmaz; alım türünün kaynağı ve teslimat türünün hedefi dış konumdur. Demo veride IKT deposuna "Tedarikçiler" ve "Müşteriler" dış konumları eklendi.
- 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ç).
- İç transfer onaycısı kaynak konumun depo sorumlusudur (`Inv_T_Location.ResponsibleUserName`, kullanıcı adı — iş akışı onaycıyı adla eşlediği için Guid tutulmaz (kullanıcı kararı); kayıt sonrası `SourceApproverUserNames`'e kullanıcı adı yazılır). Sorumlu yoksa `ApprovalStatus` "Onay Gerekmez" olur ve akış beklenmez. Ekranda belge durumu (`Status`) ile onay durumu (`ApprovalStatus`) birlikte bulunur: tablo bütün türler için ortak olduğundan durum akış düğümü değil belge yaşam döngüsüdür (standing default 24'ten bilinçli sapma).
- Teslim Alan / Teslim Alma Tarihi iç transferin Doğrula işleminde yazılır (Doğrula'ya basan kullanıcı).
- İç 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; iş akışı güncellemesi yalnız akış alanlarını gönderir.
- Malzeme talebi kalemleri iç transfere yalnız Satınalma › Talepler › Planlama'daki İç Transfer kararıyla gelir (`Prc_P_MaterialRequestPlan`, [App.Prc.md](App.Prc.md)): aynı kaynak → hedef konum için onaya girmemiş taslak transfer varsa satır ona eklenir, yoksa kaynak deponun iç transfer türüyle yeni taslak açılır. İç Transferler'deki Talepten Aktar butonu ve Transfer Talep Kalemleri ekranı 2026-10-13'te kaldırıldı.
- 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–50321.
- 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); yalnız İç Transferler'de Onay ve Teslim (`App.Inventory.TransferApproval`, aynı satır, salt okunur).
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; iç transferde onay tamamlanmışsa — ve Bekleyen), Doğrula (Hazır), İptal Et (Taslak, Bekleyen, Hazır), İade Et (Tamamlandı), Yazdır (her durumda); İç Transferler'de ayrıca iş akışı butonları. Buton adları durum adlarıyla eşleşir: Yapılacak olarak işaretle › Hazır, Doğrula › Tamamlandı, İptal Et › İptal. Satır butonları (yalnız ürünün takip yöntemi Lot ya da Seri olan satırda görünür): Lot/Seri Oluştur, Otomatik Ata, Detaylar; görünürlük satırın `TrackingMethod` kolonundan okunur. Hareketler'de (`App.Inventory.Transfer`) satırda Detay (salt okunur başlık + Operasyonlar sekmesi), Not ve belgeyi kendi ekranında açan Aç vardır; Ürün Hareketleri'nde de Aç hareketin belgesini açar (`/admin/form/App.Inventory.{Receipt|Delivery|InternalTransfer}/@TransferId`).
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
@ -167,30 +166,31 @@ Tüm tablolar kiracı + tam audit + soft delete, anahtar `Id uniqueidentifier`.
| Tablo / nesne | İçerik |
| --- | --- |
| `Inv_T_Transfer` | TransferNo, BranchId, WarehouseId, OperationTypeId, OperationKind, PartnerId (Kontak), Source/DestinationLocationId, ScheduledDate, EffectiveDate, SourceDocument, PurchaseOrderId, BackorderOfId, ReturnOfId, CarrierId, TrackingReference, Weight (hesap), ShippingWeight, ResponsibleUserId, ProjectId, DeliveryPolicy (`Direct`/`OneTime`, yalnız teslimat), Note, LineSummary (fiş özeti), Status (`Draft`/`Waiting`/`Ready`/`Done`/`Cancelled`), PendingAction, SourceApproverUserNames, iş akışı dörtlüsü, ReceivedByUserId, ReceivedDate |
| `Inv_T_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 (FIFO), LastMoveDate; tekil (TenantId, LocationId, ProductId, LotNo) |
| `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}` |
| 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; iç transferde onaylı ya da Onay Gerekmez): dış konumdan girişte yapılan miktar talep kadar dolar ve belge Hazır olur. İç konumdan çıkışta satırlar ürün bazında sırayla stoktan karşılanır; tümü karşılanırsa Hazır, değilse Bekleyen. Teslimatta "Mümkün olduğunca kısa sürede" kısmi karşılamada da Hazır yapar, "Tüm ürünler hazır olduğunda" bütün satırları bekler.
- **Yapılacak olarak işaretle** (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. Stok güncellenir, belge Tamamlandı olur, Geçerlilik Tarihi yazılır. Sipariş kaleminin `ReceivedQuantity`'si ve talep kaleminin `DeliveredQuantity`'si artar (iadede azalır); talep kalemi tam karşılanınca `Done` olur. Siparişten açılan alımda ürünün tedarikçi fiyat listesi siparişin birim fiyatı ve son alım tarihiyle yenilenir (`Inv_P_TransferSupplierPrice`; kural [App.Prc.md](App.Prc.md) Talepler bölümünde). Recalc ve İptal Et talep kaleminin satır durumunu plana eşler (`Prc_P_MaterialRequestItemSync`): transferle tamamen planlanmış kalem kapanır, transfer iptal edilir ya da satırı silinirse yeniden açılır ve miktar Planlama'ya döner. Talepten az yapılan satırların kalanı backorder belgesine geçer ve stok kontrolüyle Hazır/Bekleyen açılır.
- **İade Et** (Tamamlandı): kaynak/hedef yer değiştirmiş, yapılan miktarlar ve lotlarıyla taslak belge; iadeden backorder açılmaz.
- **İptal Et**: Tamamlandı ya da İptal dışındaki belgede. İptal edilmiş belge düzenlenemez; tamamlanmış ya da iptal edilmiş belgenin satırı ve lotu değiştirilemez. Yalnız elle açılmış taslak (siparişten, backorder ya da iadeden gelmeyen) silinebilir.
- **Lot/Seri Oluştur**: yalnız giriş satırında; lot takipte kalan miktar için `Inventory.LotNumber`'tan tek lot, seri takipte kalan her birim için `Inventory.SerialNumber`'dan seri (miktar tam sayı olmalı). **Otomatik Ata**: yalnız çıkış satırında; mevcut lotları siler, kaynak konumdaki lotları ilk giren ilk çıkar sırasıyla atar.
- **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, Onay ve Teslim İç Transferler'in altındadır. Durum butonları ekranın `.Update`, satır butonları Transfer Satırları'nın `.Update`, Detaylar Lot/Seri Numaraları'nın okuma yetkisini ister. Belge ekranını kullanan role sekme ve diyalog yetkileri de verilmelidir. Yetkiler hiçbir role otomatik atanmaz. Kiracı kapsamlı; şube kolonla tutulur.
İ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
@ -201,7 +201,8 @@ Satınalma Siparişleri (onayda taslak alım, alınan miktar), Malzeme Talepleri
1. Satınalma'da P00012 (10 Adet sensör, lot takipli) onaylanır; Alımlar'da IKT/IN/00001 taslak açılır (Tedarikçiler › Ana Depo).
2. Yapılacak olarak işaretle: belge Hazır, yapılan 10. Satırda Lot/Seri Oluştur LOT000001 (10) üretir; Doğrula Ana Depo'ya 10 Adet LOT000001 ekler, P00012 kalemine Alınan 10 yazılır.
3. Teslimatlar'da 4 Adet sensör için belge açılır; Yapılacak olarak işaretle Hazır yapar, Otomatik Ata LOT000001 (4) atar, Doğrula stoğu 6'ya düşürür.
4. İç Transferler'de Ana Depo'dan (sorumlusu var) başka bir iç konuma 2 Adet; Onayla, sorumlu onaylar (belge kendiliğinden hazırlanır), lotlar seçilir, Doğrula; Onay ve Teslim sekmesinde onaylayan ve teslim alan görünür.
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
@ -209,16 +210,15 @@ Satınalma Siparişleri (onayda taslak alım, alınan miktar), Malzeme Talepleri
- **Doğrula "lot/seri miktarı eşit değil" diyor?** Ürün lot/seri takiplidir; satırdaki Detaylar'dan lot girin ya da Lot/Seri Oluştur (giriş) / Otomatik Ata (çıkış) kullanın.
- **Ürün stokta görünmüyor?** Ürünün Envanter Takibi kapalıysa hareket stoğa işlenmez.
- **"Numaratör bulunamadı"?** Operasyon türünün numaratörü Diziler'de bu kiracı için tanımlı ve aktif olmalıdır.
- **İç transfer hazırlanamıyor?** Kaynak konumun sorumlusu varsa önce Onayla ile onay alınmalıdır; onay verilince belge kendiliğinden hazırlanır.
- **İç transferde sıra nedir?** Satırlar › Onayla › Kaynak Depo Onayı › (otomatik Yapılacak olarak işaretle) › lot seçimi › Doğrula. Onay stok hareketinden önce gelir, çünkü malın kaynak depodan çıkmasına verilen izindir (kullanıcı kararı: onay sonrası Yapılacak olarak işaretle otomatik). Otomatik Yapılacak olarak işaretle şartları sağlanmazsa (satır yok, konum kuralı) belge Taslak kalır ve Yapılacak olarak işaretle elle basılır.
- **İç transfer onay istemiyor, "Onay Gerekmez" yazıyor?** Onaycı kaynak konumun Sorumlu'sudur (kullanıcı adı); Konumlar'da sorumlu girilmemişse belge onay beklemez. Seed'deki konumların sorumlusu `system@sozsoft.com`'dur. Onay akışı için konuma sorumlu atanır (yeni ve taslak belgelerde geçerli olur).
- **İç transferde dış konum ya da aynı konum seçilemiyor?** İç transfer depo içinde taşımadır: Kaynak ve Hedef Konum listeleri yalnız iç konumları gösterir, hedef kaynaktan farklı olmalıdır (formda kural, Yapılacak olarak işaretle/Doğrula'da 50325 ve 50326). İade belgesi bu kuraldan muaftır; yanlışlıkla dış konuma yapılmış eski transfer İade Et ile geri alınır.
- **Siparişten alım açılmadı?** Siparişte envanter takipli ürün kalemi olmalı; siparişin iptal olmayan bir alımı zaten varsa yenisi açılmaz.
- **İç 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_V_{StockMove,TransferLineLot,TransferLineLotStock}`, `Inv_F_UomConvert`, `Inv_P_Transfer*`; değişen: `Inv_T_OperationType` (SequenceName), `Prc_T_PurchaseOrderLine` (ReceivedQuantity), `Prc_P_PurchaseOrderSetStatus`, `Prc_P_PurchaseRfqAward`.
- **Wizard'lar:** `Inventory_{Receipt,Delivery,InternalTransfer,Transfer,TransferLine,TransferLineLot,TransferLineLotStock,TransferOther,TransferNote,TransferApproval}.json`; değişen `Inventory_OperationType.json`, `Prc_PurchaseOrderLine.json`.
- **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).
@ -251,7 +251,7 @@ Ayrı bir Raporlama dalı yoktur (kullanıcı kararı): Stok (`App.Inventory.Sto
### 6. Yetki ve görünürlük
İki ekranın yetkisi menüyle aynı sırada `App.Inventory` izin grubunun kökündedir (`App.Inventory.Stock` sıra 3, `App.Inventory.StockMove` sıra 4); yetkiler hiçbir role otomatik atanmaz. Kiracı kapsamlı.
Üç 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
@ -292,12 +292,14 @@ Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_S
| 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`
@ -342,7 +344,7 @@ Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_S
| Kapsam | Kiracı |
| Alt formlar | `App.Inventory.ProductGeneral` (Id → Id), `App.Inventory.ProductAttributeLine` (Id → ProductId), `App.Inventory.ProductSupplier` (Id → ProductId), `App.Inventory.ProductStock` (Id → Id), `App.Inventory.ProductAccounting` (Id → Id), `App.Inventory.Bom` (Id → ProductId) |
| Widget'lar | `App.Widget.Total`, `App.Widget.Saleable`, `App.Widget.Purchasable`, `App.Widget.Service` |
| Form varsayılanları | IsActive=true, IsFavorite=false, CanBeSold=true, CanBeExpensed=false, CanBePurchased=false, IsFavorite=false, UomId=Adet, PurchaseUomId=Adet, SalesPrice=0, Cost=0, TrackInventory=true, TrackingMethod=Quantity, ProductType=Wares |
| 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 |
@ -408,7 +410,7 @@ Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_S
| Kapsam | Kiracı |
| Alt formlar | `App.Inventory.BomComponent` (Id → BomId), `App.Inventory.BomOperation` (Id → BomId), `App.Inventory.BomOther` (Id → Id), `App.Inventory.BomOverview` (Id → BomId) |
| Widget'lar | `App.Widget.Total`, `App.Widget.VariantBased`, `App.Widget.Active` |
| Form varsayılanları | UomId=Adet, IsActive=true, Quantity=0 |
| Form varsayılanları | UomId=Adet, IsActive=true, Quantity=1 |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
@ -572,6 +574,7 @@ Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_S
| 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 |
| --- | --- | --- | --- | --- | --- |
@ -597,6 +600,7 @@ Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_S
| 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 |
| --- | --- | --- | --- | --- | --- |
@ -773,8 +777,8 @@ Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_S
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `PartnerId` | Tedarikçi Adı | dxSelectBox | | ✓ | sorgu: Adm_T_Contact |
| `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 | | ✓ | |
@ -787,6 +791,7 @@ Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_S
| `PendingAction` | PendingAction | dxTextBox | | | |
| `LineSummary` | LineSummary | dxTextBox | | | |
| `SourceDocument` | Kaynak Belge | dxTextBox | | ✓ | |
| `ReturnOfId` | İade Edilen Belge | dxTextBox | | | |
#### Teslimatlar — `App.Inventory.Delivery`
@ -824,6 +829,7 @@ Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_S
| `OperationKind` | OperationKind | dxSelectBox | | | liste: Receipt, Delivery, InternalTransfer, Manufacturing, Repair |
| `PendingAction` | PendingAction | dxTextBox | | | |
| `LineSummary` | LineSummary | dxTextBox | | | |
| `ReturnOfId` | İade Edilen Belge | dxTextBox | | | |
#### İç Transferler — `App.Inventory.InternalTransfer`
@ -838,12 +844,11 @@ Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_S
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Inventory.TransferLine` (Id → TransferId), `App.Inventory.TransferOther` (Id → Id), `App.Inventory.TransferNote` (Id → Id), `App.Inventory.TransferApproval` (Id → Id) |
| 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` |
| Onay akışı | Start 'Onaya Gönderildi' → Approval 'Kaynak Depo Onayı' → End 'Onaylandı' → End 'Reddedildi' |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
@ -861,11 +866,7 @@ Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_S
| `OperationKind` | OperationKind | dxSelectBox | | | liste: Receipt, Delivery, InternalTransfer, Manufacturing, Repair |
| `PendingAction` | PendingAction | dxTextBox | | | |
| `LineSummary` | LineSummary | dxTextBox | | | |
| `ApprovalStatus` | Kaynak Depo Onayı | dxTextBox | | | |
| `ApprovalUserName` | Onaylayan | dxTextBox | | | |
| `ApprovalDate` | Onay Tarihi | dxDateBox | | | |
| `ApprovalDescription` | Onay Açıklaması | dxTextBox | | | |
| `SourceApproverUserNames` | SourceApproverUserNames | dxTextBox | | | |
| `ReturnOfId` | İade Edilen Belge | dxTextBox | | | |
#### Lot/Seri Numaraları — `App.Inventory.TransferLineLot`
@ -968,6 +969,8 @@ Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_S
| `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`
@ -988,30 +991,6 @@ Wizard'lar `Inventory_Stock.json`, `Inventory_StockMove.json`; nesneler `Inv_T_S
| --- | --- | --- | --- | --- | --- |
| `Note` | Not | dxHtmlEditor | | ✓ | |
#### Onay ve Teslim — `App.Inventory.TransferApproval`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Inventory_TransferApproval.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Inventory.TransferApproval` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Onay ve Teslim — iç transferin kaynak depo onayı ve teslimi (İç Transferler'in Onay ve Teslim sekmesi; salt okunur). |
| Kaynak | `Inv_T_Transfer` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Komutlar | UpdateBefore: SQL |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `ApprovalStatus` | Kaynak Depo Onayı | dxTextBox | | ✓ | |
| `ReceivedByUserId` | Teslim Alan | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `ApprovalUserName` | Onaylayan | dxTextBox | | ✓ | |
| `ReceivedDate` | Teslim Alma Tarihi | dxDateBox | | ✓ | |
| `ApprovalDate` | Onay Tarihi | dxDateBox | | ✓ | |
| `ApprovalDescription` | Onay Açıklaması | dxTextBox | | ✓ | |
### Stok, Hareketler ve Ürün Hareketleri (`App.Inventory.Stock`, `App.Inventory.Transfer`, `App.Inventory.StockMove`)
#### Stok — `App.Inventory.Stock`

View file

@ -71,34 +71,33 @@ Yok. Tanımlar Yönetim › Tanımlamalar › Kontaklar'ın Satış ve Satınalm
### 1. Amaç ve kapsam
Departmanların iç ve dış ihtiyaç duydukları malzemeleri satınalmaya iletmesi ve satınalmanın her kalemin nasıl karşılanacağına karar vermesi. Talep eden personel talebi ve satırlarını girer, onaya gönderir; talep önce talep edenin departman onaycısına, sonra satınalmaya düşer. Onaylanan talebin kalemleri **Planlama**'ya düşer: satınalmacı son alımlara, depo stoklarına ve tedarikçi fiyatlarına bakarak her kalemi (gerekirse miktarla bölerek) satın almaya (taslak teklif talebi) ya da stoktan iç transfere (taslak iç transfer) ayırır; verilen kararlar **Plan Takibi**'nde izlenir. Teklif toplama, sipariş ve mal kabul Siparişler dalında ve Envanter'dedir; transferin hazırlanıp tamamlanması Envanter › İç Transferler'dedir.
Departmanların iç ve dış ihtiyaç duydukları malzemeleri satınalmaya iletmesi ve satınalmanın her kalemin nasıl karşılanacağına karar vermesi. Talep eden personel talebi ve satırlarını girer, onaya gönderir; talep önce talep edenin departman onaycısına, sonra satınalmaya düşer. Onaylanan talebin kalemleri **Planlama**'ya düşer: satınalmacı son alımlara, depo stoklarına ve tedarikçi fiyatlarına bakarak her kalemi (gerekirse miktarla bölerek) satın almaya (taslak teklif talebi), başka konumdan iç transfere ya da teslim konumundaki stoktan teslime (Stoktan) ayırır; verilen kararlar **Plan Takibi**'nde izlenir. Teklif toplama, sipariş ve mal kabul Siparişler dalında ve Envanter'dedir; transferin hazırlanıp tamamlanması Envanter › İç Transferler'dedir. Bütün kalemleri teslim edilen talep **Tamamlandı** olur.
### 2. Analiz ve kararlar
- Wizard List ekranları + menüsüz satır alt formu + Grid Workflow. Taleplerim ve iki onay listesi aynı tabloyu (`Prc_T_MaterialRequest`) filtreyle gösterir; Tüm Talepler başlık × kalem görünümünden (`Prc_V_MaterialRequestLine`) okur, her kalem bir satırdır.
- Belge no numaratörden: `MaterialRequest` (MT-YYYY-00001, yıllık sıfırlanır). Şirket alanı açılmadı (kiracı kapsamı).
- Departman onaycısı: `Adm_T_Approver`'da Onay Yeri = Satınalma (`Purchase`) ve talebin departmanı. Satınalma onaycısı Onaycılar'da tanımlanmaz: Satınalma Onayı Bekleyenler ekranında karar verebilen, yani `App.Prc.MaterialRequestPurchaseApproval.Update` yetkisi doğrudan ya da rolüyle verilmiş aktif kullanıcılardır (satınalma ekibinin rolüne bu yetki verilir). Herhangi bir onaycının onayı yeterli.
- Taslak aşaması: kayıt Taslak açılır; akış platformun Onaya Gönder işlemiyle başlar (`WorkflowDto.ApprovalIsManualStart: true` — yoksa yeni kayıt akışı kendiliğinden başlatır ve satır girilemez).
- **Karşılama kararı satınalmanındır** (2026-10-13). Satınalma onayı belge açmaz; onaylanan kalem Planlama'ya düşer. Talep eden karşılama şekli ve satınalma sorumlusu seçmez (2026-10-13 kararı; talep satırındaki Önerilen Karşılama ve Satınalma Sorumlusu kaldırıldı): ikisi Planlama'da belirlenir — planlamayı onaylayan kullanıcı satınalma sorumlusudur (teklif talebinin alıcısı, iç transferin sorumlusu, Plan Takibi'nde Satınalma Sorumlusu). Planla diyaloğu ürünün stoğu varsa İç Transfer, yoksa Satınalma sekmesiyle açılır. Teklif talebi, sipariş ve iç transferdeki "Talepten Aktar" / "Talep Kalemleri" sekmeleri kaldırıldı: talep kalemi bu belgelere yalnız Planlama'dan girer (tek kapı; aynı kalemin iki yoldan iki kez karşılanması önlenir).
- Planlama Wizard List'tir (görseldeki çalışma masası düzeni Custom Component ile değil, platformun grid'i ile): satır seçilince ürünün Depo Stokları, Tedarikçiler ve Son Alımlar sekmeleri listenin altında açılır (`SubFormsListFormType: List`, ilişki `ProductId → ProductId`). Satırda Düzenle yoktur; **Planla** butonu Core diyaloğunu (`MaterialRequestPlan`, `ui/src/views/purchasing/MaterialRequestPlanDialog.tsx`) açar (kullanıcı kararı 2026-10-13: bir kalem birden çok yöntemle karşılanabilmeli, dağıtım ekranda görünmeli, onayla belgeler kendiliğinden oluşmalı). Diyalogda İç Transfer (stoğu olan konumlar) ve Satınalma (tedarikçiler) sekmeleri teslimatlardaki Stoktan Lot Seçimi gibi batch düzenlenen ListForm ızgaralarıdır: Plan Miktarı yazılan her satır taslak plana (`Prc_T_MaterialRequestPlanLine`) yazılır, taslak alttaki Karşılama Planı ızgarasında görünür; Onayla Planlama ekranının `UpdateCommand`'ını (`Prc_P_MaterialRequestPlanConfirm`) çalıştırır ve taslağı belgelere çevirir. Ekran kodları butonun `OnClick` yapılandırmasındadır, bileşene yazılmaz.
- Kalem miktarla bölünebilir (ör. 4 transfer + 6 satınalma); kalan bitene kadar listede kalır. Onaylanmış karar ayrı bir tabloda tutulmaz: paylar belgelerin kendisinden hesaplanır (`Prc_V_MaterialRequestItemPlan`) — teklif ya da transfer iptal edilir, kalemi silinir ya da miktarı değişirse kalan kendiliğinden güncellenir.
- Satınalma kararı tedarikçiye taslak teklif talebi üretir (doğrudan sipariş değil): teklif toplama, ihale ve kıyas mevcut akışla sürer; sipariş onaylanınca taslak alım açılır.
- İç transferin kaynak konumunu planlamacı seçer (stoğu olan iç konumlar önce, miktarıyla listelenir); serbest stok (eldeki − açık transferlerde o konumdan istenen) planlanan miktarı karşılamalıdır. Kalanın tamamı transferle planlanan ve satınalma payı olmayan kalem **kapanır** (Satır Durumu = Tamamlandı); transfer iptal edilir ya da satırı silinirse yeniden Bekliyor olur.
- **Stoktan karşılama** (kullanıcı kararı 2026-10-13): stok talebin kendi teslim konumundaysa İç Transfer sekmesinde o konum da "Teslim Konumu" işaretiyle listelenir; oraya yazılan Plan Miktarı transfer açmaz, karar Stoktan'dır (`PlanMethod = Stock`). Onayda miktar kalemin `FromStockQuantity` ve `DeliveredQuantity` değerine eklenir, kalandan düşer; satınalma payı olmayan ve kalanı biten kalem kapanır. Stok hareketi oluşmaz: malzemenin depodan çıkışı Envanter'de ayrıca kaydedilir, teslim konumunun serbest stoğu stoktan karşılananı ayırmaz.
- Satınalma sekmesi kiracının bütün aktif kontaklarını listeler (kullanıcı kararı 2026-10-13): ürünün fiyat listesindekiler fiyatıyla önce, diğerleri fiyatsız sonra; fiyatsız tedarikçinin teklif kalemi 0 fiyatla açılır.
- İki sekmede de satırın En Fazla kolonu (`MaxQuantity`) yazılabilecek üst sınırı gösterir: planlanacak kalandan kalemin diğer taslak satırları düşülür, İç Transfer'de serbest stok da sınırdır. Plan Miktarı bunu aşarsa ızgara kaydetmez (`compare` kuralı); aynı anda birden çok satır düzenlenirse toplam yine kayıt yordamında denetlenir.
- **Hız yardımları** (kullanıcı kararı 2026-10-13: her satırla tek tek uğraşılmamalı):
- **Öner** (diyalogun üstünde; yalnız basınca — diyalog açılışta hiçbir şey planlamaz, plan kullanıcının butonlarıyla kurulur): `Prc_P_MaterialRequestPlanSuggest` taslağı sıfırlayıp kurar — önce stok (teslim konumu, sonra serbest stoğu en çok olan konum), kalan kısım en uygun tedarikçiden satınalma. Tedarikçi `Prc_V_MaterialRequestPlanVendor.SuggestRank` sırasıyla seçilir (fiyatlılar ucuzdan pahalıya, sonra son alım tarihi, sonra ad; para birimi farkı gözetilmez) ve yalnız fiyat listesinde ya da alım geçmişinde bulunan tedarikçi önerilir; yoksa kalan planlanmadan kalır. Diyalog yordamı Karşılama Planı ekranının ekleme komutuyla çağırır (`BaseId` = kalem; Karşılama Planı + Create yetkisi).
- **Taslağı Sıfırla** (diyalogun üstünde): kalemin bütün taslak satırlarını Karşılama Planı'nın silme komutuyla siler (Karşılama Planı + Delete yetkisi); Karşılama Planı'ndaki Sil de hemen uygulanır (hücre düzenleme). Onaydan önce plan istenildiği kadar geri alınıp yeniden kurulur. Onaydan sonra: iç transfer ya da teklif talebi kendi ekranında iptal edilince ya da satırı silinince kalem Planlama'ya döner; Stoktan karşılama Plan Takibi'ndeki **Geri Al** ile geri alınır (`Prc_P_MaterialRequestStockUndo`: stoktan karşılanan miktar teslim edilenden düşülür ve sıfırlanır, kapanmış kalem Bekliyor'a döner; Plan Takibi + Update yetkisi).
- **Öner ve Onayla** (diyalogun üstünde, Öner'in yanında): öneriyi kurar ve taslak oluştuysa hemen Onayla'yı çalıştırır; önerilecek kaynak yoksa onay denenmez.
- **Tümünü Planla** (İç Transfer / Satınalma satır butonu): satıra En Fazla değerini yazar. **Seçilenleri Planla** (aynı ızgaraların araç çubuğu, çoklu seçim): seçilen satırları sırayla en fazla miktarla planlar: Plan Miktarı eksi (-1) gönderilir, `Prc_P_MaterialRequestPlanLineSave` bunu kalanın diğer taslak satırlardan arta kalanı (iç transferde konumun serbest stoğuyla sınırlı) olarak yazar; alınacak bir şey kalmayan satır değişmez. Planlama listesinin kendisinde seçim tektir (kullanıcı kararı). Plan Miktarı hücresi vurguludur ve hücre düzenlemede değer hücreden çıkınca kaydedilir (Değişiklikleri Kaydet yoktur).
- Plan Takibi ayrı menü ekranıdır (görseldeki "Takip" sekmesi): her satır bir karar, belge ve sipariş bağlantılı.
- İş akışı kolonları tablo tasarımcısının Workflow şablonundaki dörtlüdür: `ApprovalUserName` nvarchar(256) (onaycı kullanıcı adları), `ApprovalStatus` nvarchar(50) (bulunulan düğümün başlığı), `ApprovalDate` datetime, `ApprovalDescription` nvarchar(200); dört ekranın `WorkflowDto`'su bunlara bağlıdır. Departman ve satınalma kararları ayrı kolonda tutulmaz; her karar (karar veren, açıklama, red nedeni) iş akışı notlarına yazılır.
- Onay ve red bilgileri popup düzenleme formunda yer almaz (iş akışı yazar); listede kolon olarak görünür.
- Red nedeni ayrı kolonda tutulmaz: onay düğümleri red sırasında Red Nedenleri listesinden (`Prc_T_RejectReason`, zorunlu) seçim ister; seçilen neden ve not `ApprovalDescription`'a ve iş akışı notuna yazılır.
- Satır tablosu `Prc_T_MaterialRequestItem` adıyla açıldı (birim kolonu `Adm_T_Uom.Id` ile aynı tipte, nvarchar). İlk açılan `Prc_T_MaterialRequestLine` scripti 2026-10-13'te ölü artefakt olarak silindi.
- Talep satırı formu: Ürün; Miktar – Birim; Termin Tarihi – Satır Durumu; Talep Nedeni (en sonda). Termin başlığı talep ekranlarında ayrı anahtardır (`App.Listform.ListformField.RequiredDate`), ortak "Bitiş Tarihi" anahtarı başka modüllerde kullanıldığı için değiştirilmedi.
- Talebin durumu iş akışından gelir: `ApprovalStatus` boş (taslak) › Departman Onayı › Satınalma Onayı › Onaylandı ya da Reddedildi. Onaylanan talep satınalmada aynı alanda ilerler: kalemi taslak teklif talebindeyse Teklif Talebi, gönderilmiş (ya da siparişe dönüşmüş) teklif talebindeyse Teklif Talebi Gönderildi, iptal olmayan bir siparişteyse Satınalma Siparişi; kalemler belgelerden çıkarılır ya da belgeler iptal edilirse Onaylandı'ya döner. Kalemler farklı aşamadaysa en ileri aşama yazılır (`Prc_P_MaterialRequestSyncStatus`). Transfer kararı bu alanı değiştirmez. Ayrı `Status` kolonu yoktur; karşılama satır durumundan (Bekliyor / Tamamlandı / İptal) izlenir.
- Departman onaycısı: `Adm_T_Approver`'da Onay Yeri = Satınalma (`Purchase`) ve talebin departmanı. Satınalma onaycısı Onaycılar'da tanımlanmaz: Satınalma Onayı Bekleyenler ekranında karar verebilen, yani `App.Prc.MaterialRequestPurchaseApproval.Update` yetkisi doğrudan ya da rolüyle verilmiş aktif kullanıcılardır. Herhangi bir onaycının onayı yeterli.
- Taslak aşaması: kayıt Taslak açılır; akış platformun Onaya Gönder işlemiyle başlar (`WorkflowDto.ApprovalIsManualStart: true`).
- **Karşılama kararı satınalmanındır** (2026-10-13). Satınalma onayı belge açmaz; onaylanan kalem Planlama'ya düşer. Talep eden karşılama şekli ve satınalma sorumlusu seçmez; ikisi Planlama'da belirlenir — planlamayı onaylayan kullanıcı satınalma sorumlusudur (teklif talebinin alıcısı, iç transferin sorumlusu, Plan Takibi'nde Satınalma Sorumlusu). Talep kalemi teklif talebine, siparişe ve iç transfere yalnız Planlama'dan girer (tek kapı; aynı kalem iki yoldan iki kez karşılanmaz).
- Planlama Wizard List'tir: satır seçilince ürünün Depo Stokları, Tedarikçiler ve Son Alımlar sekmeleri listenin altında açılır (`SubFormsListFormType: List`, ilişki `ProductId → ProductId`). Satırda Düzenle yoktur; **Planla** butonu Core diyaloğunu (`MaterialRequestPlan`, `ui/src/views/purchasing/MaterialRequestPlanDialog.tsx`) açar. Diyalogun İç Transfer ve Satınalma sekmeleri batch düzenlenen ListForm ızgaralarıdır: Plan Miktarı yazılan her satır taslak plana (`Prc_T_MaterialRequestPlanLine`) yazılır, taslak alttaki Karşılama Planı'nda görünür; Onayla Planlama ekranının `UpdateCommand`'ını (`Prc_P_MaterialRequestPlanConfirm`) çalıştırıp taslağı belgelere çevirir. Diyalog ürünün stoğu varsa İç Transfer, yoksa Satınalma sekmesiyle açılır.
- Kalem miktarla bölünebilir (ör. 4 transfer + 6 satınalma); kalan bitene kadar listede kalır. Onaylanmış karar ayrı tabloda tutulmaz: paylar belgelerin kendisinden hesaplanır (`Prc_V_MaterialRequestItemPlan`) — belge iptal edilir, kalemi silinir, miktarı değişir ya da iade edilirse kalan kendiliğinden güncellenir.
- Satınalma kararı tedarikçiye taslak teklif talebi üretir (doğrudan sipariş değil); teklif toplama, ihale ve kıyas Siparişler dalında sürer, sipariş onaylanınca taslak alım açılır.
- **Lot/seri ile planlama** (2026-10-14): iç transfer planı ürünün envanter takibine göre yapılır. Lot ya da seri takipli üründe İç Transfer sekmesinin satırı konum × lottur (seride her seri 1 adetlik ayrı satır), plan lotla yazılır (`LotNo`) ve Onayla lotu transfer satırının lot dağılımına (`Inv_T_TransferLineLot`) ekler; depo Detaylar ya da Otomatik Ata ile değiştirebilir. Miktarla takip edilen (ya da takipsiz) üründe konum başına tek satır vardır, yalnız miktar yazılır.
- **Çıkış stratejisi** (2026-10-14): ürün kategorisinin Çıkış Stratejisi (`Inv_T_ProductCategory.RemovalStrategy`: `FIFO` ilk giren ilk çıkar, `LIFO` son giren ilk çıkar; stok kaydının `InDate`'i, aynı anda girenlerde lot/seri no — LIFO'da büyükten, tarihi boş stok en sona; kategorisiz ürün FIFO, üst kategoriden devralınmaz) İç Transfer sekmesinin sırasını (`RemovalRank`, Çıkış Sırası kolonu; teslim konumu önce) belirler. Öner ve Seçilenleri Planla stoğu bu sırayla dağıtır; Tümünü Planla yalnız kendi satırını doldurur. İç Transferler'deki Otomatik Ata da aynı kuralla atar.
- **Stoktan** (2026-10-14 kararı; 2026-10-13'teki belgesiz karşılamanın yerine): stok talebin teslim konumundaysa İç Transfer sekmesinde o konum "Teslim Konumu" işaretiyle listelenir; oraya yazılan plan Stoktan kararıdır (`PlanMethod = Stock`). Onayda yeni operasyon türü açılmadan İç Transferler türüyle, kaynağı ve hedefi teslim konumu olan bir iç transfer açılır; belge Yapılacak olarak işaretle ve Doğrula akışından geçer, Doğrula stoğa dokunmaz (yeterliliği yine denetler) ve kalemin teslim edilen miktarını yazar. Belge no ve durumu Plan Takibi'ne yansır.
- **Talep tamamlanması** (2026-10-14): iptal olmayan bütün kalemlerinin teslim edilen miktarı talep edilene ulaşınca talep Tamamlandı olur — iç transfer, Stoktan ya da siparişten açılan alımın Doğrula'sıyla (alım satırı talep kalemini taşır). İade teslimi geri alırsa durum yeniden hesaplanır.
- Satınalma sekmesi kiracının bütün aktif kontaklarını listeler: ürünün fiyat listesindekiler fiyatıyla önce, diğerleri fiyatsız sonra; fiyatsız tedarikçinin teklif kalemi 0 fiyatla açılır.
- İki sekmede de En Fazla kolonu (`MaxQuantity`) yazılabilecek üst sınırı gösterir: planlanacak kalandan kalemin diğer taslak satırları düşülür, İç Transfer'de kullanılabilir stok da sınırdır. Plan Miktarı bunu aşarsa ızgara kaydetmez (`compare` kuralı); toplam kayıt yordamında yeniden denetlenir.
- **Hız yardımları** (2026-10-13: her satırla tek tek uğraşılmamalı):
- **Öner**: `Prc_P_MaterialRequestPlanSuggest` taslağı sıfırlayıp kurar — önce stok, çıkış sırasıyla (her satır alabileceği en fazlayı alır), kalan kısım en uygun tedarikçiden satınalma. Tedarikçi `Prc_V_MaterialRequestPlanVendor.SuggestRank` sırasıyla seçilir (fiyatlılar ucuzdan pahalıya, sonra son alım tarihi yeniden eskiye, sonra ad; para birimi farkı gözetilmez) ve yalnız fiyat listesinde ya da alım geçmişinde bulunan tedarikçi önerilir; yoksa kalan planlanmadan kalır. Diyalog yordamı Karşılama Planı'nın ekleme komutuyla çağırır. Diyalog açılışta hiçbir şey planlamaz.
- **Öner ve Onayla**: öneriyi kurar ve taslak oluştuysa hemen Onayla'yı çalıştırır.
- **Taslağı Sıfırla**: kalemin bütün taslak satırlarını Karşılama Planı'nın silme komutuyla siler; Karşılama Planı'ndaki Sil de hemen uygulanır.
- **Tümünü Planla** (satır butonu): satıra En Fazla değerini yazar. **Seçilenleri Planla** (araç çubuğu, çoklu seçim): seçilen satırları sırayla (İç Transfer'de çıkış sırasıyla) en fazla miktarla planlar — Plan Miktarı eksi (-1) gönderilir, kayıt yordamı bunu alınabilecek en fazla miktar olarak yazar.
- Onaydan sonra her karar kendi belgesinden geri alınır: teklif talebi ya da iç transfer (Stoktan dahil) iptal edilince ya da satırı silinince kalem Planlama'ya döner.
- İş akışı kolonları Workflow şablonundaki dörtlüdür (`ApprovalUserName`, `ApprovalStatus`, `ApprovalDate`, `ApprovalDescription`); onay ve red bilgileri popup formda yer almaz, listede görünür. Red nedeni ayrı kolonda tutulmaz: onay düğümü red sırasında Red Nedenleri listesinden (`Prc_T_RejectReason`) seçim ister, seçilen neden ve not `ApprovalDescription`'a yazılır.
- Talebin durumu `ApprovalStatus`'tadır: boş (taslak) › Departman Onayı › Satınalma Onayı › Onaylandı ya da Reddedildi; onaydan sonra satınalmada ilerler: Teklif Talebi (kalem taslak teklifte), Teklif Talebi Gönderildi (gönderilmiş ya da siparişe dönüşmüş teklifte), Satınalma Siparişi (iptal olmayan siparişte), Tamamlandı (bütün kalemler teslim edildi); belgeler iptal edilirse Onaylandı'ya döner (`Prc_P_MaterialRequestSyncStatus`). Ayrı `Status` kolonu yoktur; kalem durumu Bekliyor / Tamamlandı / İptal'dir.
- Talep satırı formu: Ürün; Miktar – Birim; Termin Tarihi – Satır Durumu; Talep Nedeni. Termin başlığı ayrı anahtardır (`App.Listform.ListformField.RequiredDate`).
### 3. Menü ve ekranlar
@ -106,136 +105,148 @@ Satınalma (`App.Prc`) › Talepler (`App.Prc.MaterialRequests`):
| Ekran | Kod | Filtre / not |
| --- | --- | --- |
| Taleplerim | `App.Prc.MyMaterialRequest` | talep eden = oturumdaki kullanıcı; ekle/sil açık, akış |
| Taleplerim | `App.Prc.MyMaterialRequest` | talep eden = oturumdaki kullanıcı; ekle/sil açık, akış; şube yetkili |
| Departman Onayı Bekleyenler | `App.Prc.MaterialRequestDeptApproval` | ApprovalStatus = Departman Onayı; yalnız kendine düşenler |
| Satınalma Onayı Bekleyenler | `App.Prc.MaterialRequestPurchaseApproval` | ApprovalStatus = Satınalma Onayı; yalnız kendine düşenler |
| Planlama | `App.Prc.MaterialRequestPlan` | onaylı talebin Bekliyor ve planlanacak miktarı kalan kalemleri; satırda Planla (diyalog), Düzenle yok; alt sekmeler Depo Stokları, Tedarikçiler, Son Alımlar |
| Plan Takibi | `App.Prc.MaterialRequestPlanTrack` | verilen kararlar (teklif kalemi / iç transfer satırı); salt okunur; satırda Teklif, Sipariş, Transfer butonları, Stoktan satırında Geri Al |
| Tüm Talepler | `App.Prc.MaterialRequest` | filtresiz, kalem kalem; ekle/sil kapalı, yalnız kalemin sorumlusu ve durumu düzenlenir, akış yok |
| Planlama | `App.Prc.MaterialRequestPlan` | onaylı talebin Bekliyor ve planlanacak miktarı kalan kalemleri; satırda Planla (diyalog); alt sekmeler Depo Stokları, Tedarikçiler, Son Alımlar |
| Plan Takibi | `App.Prc.MaterialRequestPlanTrack` | verilen kararlar (teklif kalemi / iç transfer satırı, Stoktan dahil); salt okunur; satırda Teklif, Sipariş, Transfer butonları |
| Tüm Talepler | `App.Prc.MaterialRequest` | filtresiz, kalem kalem; ekle/sil kapalı, yalnız kalemin satır durumu düzenlenir |
Talep Satırları (`App.Prc.MaterialRequestLine`) menüsüz alt formdur; Taleplerim ve iki onay listesinde sekmedir (Tüm Talepler kalemleri kolon olarak gösterir). Planlama'nın sekmeleri menüsüz alt formlardır: Depo Stokları (`App.Prc.MaterialRequestPlanStock`, `Inv_T_Stock`), Tedarikçiler (`App.Prc.MaterialRequestPlanSupplier`, `Inv_T_ProductSupplier`), Son Alımlar (`App.Prc.MaterialRequestPlanLastPurchase`, `Prc_V_PurchaseReceiptLine`: Envanter'de tamamlanan alımların satırları, siparişsiz alım dahil, iade hariç; fiyat ve sipariş no yalnız siparişli alımda dolar). Planla diyaloğunun üç ekranı da menüsüzdür: İç Transfer (`App.Prc.MaterialRequestPlanSource`, `Prc_V_MaterialRequestPlanSource`), Satınalma (`App.Prc.MaterialRequestPlanVendor`, `Prc_V_MaterialRequestPlanVendor`), Karşılama Planı (`App.Prc.MaterialRequestPlanLine`, `Prc_V_MaterialRequestPlanLine`). Red Nedenleri (`App.Prc.RejectReason`) Satınalma › Tanımlamalar altındadır (bkz. Tanımlamalar).
Talep Satırları (`App.Prc.MaterialRequestLine`) menüsüz alt formdur; Taleplerim ve iki onay listesinde sekmedir. Planlama'nın sekmeleri menüsüz alt formlardır: Depo Stokları (`App.Prc.MaterialRequestPlanStock`, `Inv_T_Stock`), Tedarikçiler (`App.Prc.MaterialRequestPlanSupplier`, `Inv_T_ProductSupplier`), Son Alımlar (`App.Prc.MaterialRequestPlanLastPurchase`, `Prc_V_PurchaseReceiptLine`). Planla diyaloğunun üç ekranı menüsüzdür: İç Transfer (`App.Prc.MaterialRequestPlanSource`), Satınalma (`App.Prc.MaterialRequestPlanVendor`), Karşılama Planı (`App.Prc.MaterialRequestPlanLine`). Red Nedenleri (`App.Prc.RejectReason`) Satınalma › Tanımlamalar altındadır.
### 4. Veri modeli
Tüm tablolar kiracı + tam audit + soft delete taşır.
- `Prc_T_MaterialRequest`: RequestNo, Priority (0–3), RequesterUserId, BranchId (`Sas_T_Branch`), DepartmentId, WarehouseId, LocationId, RequestDate, Description, ApprovalUserName, ApprovalStatus, ApprovalDate, ApprovalDescription (iş akışı), DeptApproverUserNames / PurchaseApproverUserNames (`|` ayrılmış kullanıcı adları).
- `Prc_T_MaterialRequestItem`: MaterialRequestId (FK, cascade), ProductId, Quantity, UomId (nvarchar, `Adm_T_Uom`), DueDate (termin), RequestReason, DeliveredQuantity, FromStockQuantity (stoktan karşılanan), LineStatus (Waiting / Done / Cancelled).
- `Prc_T_MaterialRequest`: RequestNo, Priority (0–3), RequesterUserId, BranchId, DepartmentId, WarehouseId, LocationId (teslim konumu), RequestDate, Description, iş akışı dörtlüsü, DeptApproverUserNames / PurchaseApproverUserNames (`|` ayrılmış kullanıcı adları).
- `Prc_T_MaterialRequestItem`: MaterialRequestId (FK cascade), ProductId, Quantity, UomId, DueDate (termin), RequestReason, DeliveredQuantity (Doğrula yazar), LineStatus (Waiting / Done / Cancelled).
- `Prc_T_MaterialRequestPlanLine`: MaterialRequestItemId (FK cascade), PlanMethod (Purchase / Transfer / Stock), SupplierId ya da SourceLocationId, LotNo (lot/seri takipli üründe, aksi hâlde boş), Quantity — onaylanmamış dağıtım; onay satırları siler.
- `Prc_T_RejectReason`: Name, SortOrder, IsActive.
- Görünüm `Prc_V_MaterialRequestLine`: talep başlığı LEFT JOIN silinmemiş kalemler; `Id` kalemin Id'si (kalemi olmayan talepte talebin Id'si), `MaterialRequestId` talep. Tüm Talepler'in kaynağıdır.
- Görünüm `Prc_V_MaterialRequestItemPlan`: kalem başına PurchaseQuantity (satınalma payı), TransferQuantity (transfer payı), RemainingQuantity (planlanacak), kalemin biriminde.
- Görünüm `Prc_V_MaterialRequestPlan`: Planlama'nın kaynağı; kalem + talep başlığı + paylar + StockQuantity (bütün iç konumlar) + DueState (Late / Week / Later) + DraftQuantity (onay bekleyen taslak plan toplamı).
- Tablo `Prc_T_MaterialRequestPlanLine` (tenant + audit): MaterialRequestItemId (FK cascade), PlanMethod, SupplierId ya da SourceLocationId, Quantity — kalemin onaylanmamış dağıtımı; onay satırları siler.
- Görünümler `Prc_V_MaterialRequestPlanSource` (kalem × stoğu olan iç konum, teslim konumu dahil — IsDestination; OnHand, ReservedQuantity = açık transferlerde o konumdan istenen, FreeQuantity, taslak PlanQuantity; `Id` = kalem:konum — iç transfer kararının stok kuralı da budur), `Prc_V_MaterialRequestPlanVendor` (kalem × kiracının aktif kontağı; fiyat listesindeyse fiyat satırı, SortKey = fiyatlılar önce + ad, son alım tarihi, taslak PlanQuantity, tedarikçinin bu kalemi taşıyan taslak teklifi RfqId/RfqNo/RfqQuantity; `Id` = kalem:tedarikçi), `Prc_V_MaterialRequestPlanLine` (taslak satırı + kalemin birimi + satınalmada fiyat); üçü de `BaseId` = kalem.
- Görünüm `Prc_V_PurchaseReceiptLine`: Son Alımlar'ın kaynağı; tamamlanan alımın (iade hariç) yapılan satırı × sipariş kalemi; sipariş birim fiyatı alım satırının birimine çevrilir, `UntaxedAmount` = miktar × fiyat.
- Görünüm `Prc_V_MaterialRequestPlanTrack`: Plan Takibi'nin kaynağı; ihalenin kök teklif talebindeki talep kalemleri ∪ iç transfer satırları (iade hariç); `DocumentId`/`DocumentNo`/`DocumentStatus`, sipariş (`PurchaseOrderId`, `PurchaseOrderNo`, `OrderStatus`), `DoneQuantity`.
- Yordamlar `Prc_P_MaterialRequestAfterSave(@Id)`, `Prc_P_MaterialRequestSyncStatus(@DocId)` (teklif/sipariş Recalc'i, durum işlemi ve belge silme sonrasında; `@DocId` boşsa onaylanmış bütün talepler), `Prc_P_MaterialRequestPlanLineSave(@Id, @PlanMethod, @PlanQuantity, @TenantId, @LastModifierId)` (diyalog ızgaralarının batch kaydı; `@Id` = kalem:hedef), `Prc_P_MaterialRequestPlanConfirm(@Id, @TenantId, @LastModifierId)` (Onayla), `Prc_P_MaterialRequestPlanSuggest(@Id, @TenantId, @LastModifierId)` (Öner), `Prc_P_MaterialRequestStockUndo(@Id, @TenantId, @LastModifierId)` (Plan Takibi'nin Geri Al'ı; stoktan karşılama yoksa ya da kalem kapatılmışsa 50202), `Prc_P_MaterialRequestPlan(@Id, @PlanMethod, @PlanQuantity, @PlanSupplierId, @PlanSourceLocationId, @TenantId, @LastModifierId)` (onayın her taslak satırı için çağırdığı karar), `Prc_P_MaterialRequestItemSync(@TransferId)` (transferin kalemlerinin satır durumu; `Inv_P_TransferRecalc` ve transfer iptali çağırır).
- Görünümler:
- `Prc_V_MaterialRequestLine`: başlık LEFT JOIN kalemler; Tüm Talepler'in kaynağı.
- `Prc_V_MaterialRequestItemPlan`: kalem başına PurchaseQuantity, TransferQuantity, RemainingQuantity (kalemin biriminde).
- `Prc_V_MaterialRequestPlan`: Planlama'nın kaynağı; kalem + başlık + paylar + StockQuantity + DueState (Late / Week / Later) + DraftQuantity.
- `Prc_V_MaterialRequestPlanSource`: kalem × stoğu olan iç konum (takipli üründe × lot), teslim konumu dahil (IsDestination); LotNo, OnHand, ReservedQuantity (açık transferlerde o konumdan istenen; lot satırında o lota atanan), FreeQuantity (lot satırında konumun serbest stoğuyla sınırlı), AvailableQuantity (taslakta kullanılabilir), MaxQuantity, RemovalRank, PlanQuantity; `Id` = kalem:konum:lot. İç transfer ve Stoktan kararının stok kuralı buradadır.
- `Prc_V_MaterialRequestPlanVendor`: kalem × aktif kontak; fiyat satırı, SuggestRank (fiyat ↑, son alım ↓, ad), PlanQuantity, tedarikçinin bu kalemi taşıyan taslak teklifi (RfqId/RfqNo/RfqQuantity); `Id` = kalem:tedarikçi.
- `Prc_V_MaterialRequestPlanLine`: taslak satırı + lot + birim + satınalmada fiyat.
- `Prc_V_PurchaseReceiptLine`: Son Alımlar; tamamlanan alımın (iade hariç) satırı × sipariş kalemi.
- `Prc_V_MaterialRequestPlanTrack`: Plan Takibi; ihalenin kök teklif talebindeki talep kalemleri ∪ iç transfer satırları (iade hariç; kaynağı ve hedefi aynı olan transfer `Stock` kararıdır); belge, sipariş ve `DoneQuantity`.
- Yordamlar: `Prc_P_MaterialRequestAfterSave(@Id)`, `Prc_P_MaterialRequestSyncStatus(@DocId)` (talep durumu; `@DocId` teklif, sipariş ya da transfer — boşsa onaylanmış bütün talepler), `Prc_P_MaterialRequestPlanLineSave(@Id, @PlanMethod, @PlanQuantity, @TenantId, @LastModifierId)`, `Prc_P_MaterialRequestPlanSuggest(@Id, @TenantId, @LastModifierId)`, `Prc_P_MaterialRequestPlanConfirm(@Id, @TenantId, @LastModifierId)`, `Prc_P_MaterialRequestPlan(@Id, @PlanMethod, @PlanQuantity, @PlanSupplierId, @PlanSourceLocationId, @PlanLotNo, @TenantId, @LastModifierId)`, `Prc_P_MaterialRequestItemSync(@TransferId)` (transferin kalemlerinin satır durumu, ardından talep durumu); tetikleyici `Prc_TR_MaterialRequestLock`.
### 5. İş kuralları ve hesaplar
- `Prc_P_MaterialRequestAfterSave` talep kaydı/güncellemesi sonrasında çalışır ve onaycı kullanıcı listelerini (`DeptApproverUserNames`, `PurchaseApproverUserNames`) Onaycılar'dan yeniden yazar. Onaycılar sonradan değişirse talep yeniden kaydedilene kadar liste eski kalır. İki liste formda ve listede gizlidir; iş akışı onaycıyı bu alanlardan okur (`@DeptApproverUserNames`, `@PurchaseApproverUserNames`).
- Talep ve satırları yalnız Taslak'ta (`ApprovalStatus` boş) değiştirilir (2026-10-13 kararı): onaya gönderilmiş talebe satır eklenemez, satırı değiştirilemez ve silinemez (alt form Insert/Update/Delete Before komutu; 50001/50005/50002); başlığın iş alanları (öncelik, talep eden, şube, departman, depo, konum, talep tarihi, açıklama) `Prc_TR_MaterialRequestLock` tetikleyicisiyle kilitlidir (50004) — kural ekran komutunda değil tetikleyicidedir, çünkü onay akışı da başlığı aynı güncelleme yolundan yazar; onay alanları, onaycı listeleri ve silme bayrağı serbesttir. Değişiklik için talep Taslak adımına alınır, düzenlenir ve yeniden onaya gönderilir. Planlama/teslim yordamlarının yazdığı kalem alanları (teslim edilen, stoktan karşılanan, satır durumu) kilide girmez. Onay sürecindeki ya da onaylanmış talep silinemez; reddedilen talep silinebilir.
- Ürün listesi yalnız aktif ve satın alınabilir ürünleri gösterir; birim ürünün satınalma biriminden (yoksa biriminden) kopyalanır, salt okunurdur.
- Şube ayrı alandır ve iki zinciri süzer: Şube › Departman, Şube › Depo › Konum; şube değişince departman, depo ve konum, depo değişince konum temizlenir. Talep eden değişince şubesi ve departmanı kullanıcının departmanından gelir; yeni kayıtta şube ve departman oturumdaki kullanıcınınkidir. Açıklama HTML editörüdür, formda tam satırdır.
- Tüm Talepler'de düzenleme `UpdateCommand` ile yalnız `Prc_T_MaterialRequestItem`'ın `LineStatus` kolonunu yazar; başlık alanları salt okunurdur. Kartlar kalemi değil talebi sayar (tablodan okur).
- Onaycı listesi boşsa akış o adımda hata verir: Onaycılar'a ilgili departman için Satınalma satırı tanımlanmalı ve en az bir kullanıcıya (ya da rolüne) Satınalma Onayı Bekleyenler güncelleme yetkisi verilmelidir.
- **Paylar** (`Prc_V_MaterialRequestItemPlan`, kalemin birimine `Inv_F_UomConvert` ile çevrilir): satınalma payı = teklif aşamasındaki (Taslak/Gönderildi) teklif talebindeki ya da iptal olmayan siparişe geçmiş teklif kalemindeki miktar; ihale kalemi bütün tedarikçilere kopyalandığı için ihale × ihale kalemi başına bir kez (en büyüğü) sayılır. Transfer payı = iptal olmayan iç transfer satırı; tamamlanan belgede yapılan, açık belgede istenen miktar (eksik tamamlamanın kalanı backorder'da istenir); iade belgesi sayılmaz. Planlanacak = talep − satınalma payı − transfer payı.
- **Taslak** (`Prc_P_MaterialRequestPlanLineSave`, kalem kilitlenerek — batch kaydı satırları eşzamanlı gönderir): talep onaylı (ya da satınalmada ilerleyen) ve kalem Bekliyor olmalı; miktar 0 ya da boşsa satır taslaktan çıkar. Taslak toplamı planlanacak kalanı (hata 50200), iç transfer / stoktan satırı konumun serbest stoğunu aşamaz; teslim konumuna yazılan satır Stock kararıdır; satınalmada tedarikçi aktif kontak olmalıdır. Taslak satırı Karşılama Planı'ndan da silinebilir.
- **Onayla** (`Prc_P_MaterialRequestPlanConfirm`, tek transaction): taslak boşsa reddedilir (50201); satırlar iç transfer, stoktan, satınalma sırasıyla `Prc_P_MaterialRequestPlan`'a gider, ardından taslak silinir. Bir satır reddedilirse hiçbir belge açılmaz, taslak yerinde kalır.
- **Karar** (`Prc_P_MaterialRequestPlan`, kalem kilitlenerek): talep onaylı ve kalem Bekliyor olmalı; plan miktarı > 0 ve ≤ planlanacak.
- Satınalma: tedarikçi zorunlu. Tedarikçinin talebin şubesi ve deposu için taslak teklif talebi varsa (en yenisi) kalem ona eklenir — kalem zaten oradaysa miktarı artar; yoksa yeni taslak teklif talebi açılır: numara `Prc.PurchaseRfq`, alım operasyon türü talebin deposunun ilk aktif alım türü, para birimi ve ödeme/teslimat koşulları kontak kartından, alıcı (satınalma sorumlusu) planlayan. Birim fiyat tedarikçinin fiyat listesinden (en düşük minimum miktar; listede yoksa 0), KDV ürünün alış oranı, teslim tarihi kalemin termini. Teklifin yeniden hesabı talebin durumunu Teklif Talebi yapar.
- İç Transfer: kaynak konum zorunlu; konum ve serbest stok `Prc_V_MaterialRequestPlanSource`'tan okunur (iç konum, teslim konumundan farklı, ürünün stoğu var; serbest stok yetmeli).
- Stoktan: belge açılmaz; teslim konumunun serbest stoğu yetmeli (50198). Miktar kalemin FromStockQuantity ve DeliveredQuantity değerine eklenir; satınalma payı olmayan, kalanı biten kalem Tamamlandı olur. Plan Takibi'nde belgesiz Stoktan satırı olarak görünür; satırdaki Geri Al kararı geri alır. Aynı kaynak → hedef için onaya girmemiş (Onay durumu boş ya da Onay Gerekmez) taslak iç transfer varsa satır ona eklenir ve kaynak belgeye talep no yazılır; yoksa kaynak deponun ilk aktif iç transfer türüyle yeni taslak açılır (sorumlu planlayan, kaynak belge talep no). Satırın istenen miktarı plan miktarıdır; belge `Inv_P_TransferAfterSave` ile numaralanır ve kaynak depo onaycısı yazılır — onay akışı İç Transferler'de başlatılır.
- **Kalem kapanışı** (`Prc_P_MaterialRequestItemSync`, transferin her yeniden hesabında ve iptalinde): satınalma payı olmayan, planlanacağı kalmayan Bekliyor kalem Tamamlandı olur; Tamamlandı kalem planlanacak miktar yeniden doğarsa (transfer iptal, satır silme) ve teslim edilen miktar talebe ulaşmamışsa Bekliyor'a döner. Transferin Doğrula'sı teslim edilen miktarı kaleme yazar (Envanter).
- **Tedarikçi fiyatı** (`Inv_P_TransferSupplierPrice`, alımın Doğrula'sında): siparişten açılan alım tamamlanınca ürünün tedarikçi fiyat listesi (`Inv_T_ProductSupplier`) siparişin birim fiyatıyla yenilenir (kullanıcı kararı 2026-10-13). Tedarikçi × ürün × birim × para birimi başına tek satır tutulur: alınan miktara uyan kademe (min. miktar ≤ alınan miktar olan en büyüğü) fiyat ve Son Alım Tarihi ile güncellenir, uyan satır yoksa yeni satır açılır (min. miktar 1 — 1'in altındaki alımda alınan miktar —, temin süresi siparişin onayından alıma geçen gün). Fiyatı sipariş verir: siparişsiz alım, iade ve fiyatı 0 olan kalem yazmaz. Planlama'nın varsayılan tedarikçisi ve teklif kalemi fiyatı bu listeden okunduğu için sonraki karar son alım fiyatıyla açılır.
- Planlama kartları: planlanacak kalem, geciken (termin geçmiş), 7 gün içinde, taslak planlı (onay bekleyen taslağı olan kalem). Plan Takibi kartları: toplam karar, satınalma, iç transfer, tamamlanan (gerçekleşen ≥ planlanan).
- `Prc_P_MaterialRequestAfterSave` kayıt sonrasında onaycı listelerini Onaycılar'dan yeniden yazar; Onaycılar sonradan değişirse talep yeniden kaydedilene kadar liste eski kalır. Liste boşsa akış o adımda hata verir.
- Talep ve satırları yalnız Taslak'ta değiştirilir: onaya gönderilmiş talebe satır eklenemez, satırı değiştirilemez ve silinemez (alt form Before komutları; 50001/50005/50002); başlığın iş alanları `Prc_TR_MaterialRequestLock` tetikleyicisiyle kilitlidir (50004) — kural tetikleyicidedir, çünkü onay akışı da başlığı aynı güncelleme yolundan yazar. Planlama/teslim yordamlarının yazdığı kalem alanları kilide girmez. Onay sürecindeki ya da onaylanmış talep silinemez; reddedilen talep silinebilir.
- Ürün listesi aktif ve satın alınabilir ürünlerdir; birim ürünün satınalma biriminden (yoksa biriminden) gelir, salt okunurdur. Şube iki zinciri süzer: Şube › Departman, Şube › Depo › Konum.
- Tüm Talepler'de düzenleme yalnız kalemin `LineStatus`'unu yazar ve ardından talep durumunu yeniler (iptal edilen son açık kalem talebi Tamamlandı yapabilir).
- **Paylar** (`Prc_V_MaterialRequestItemPlan`, kalemin birimine çevrilir): satınalma payı = teklif aşamasındaki (Taslak/Gönderildi) ya da iptal olmayan siparişe geçmiş teklif kalemi (ihale × ihale kalemi başına bir kez); transfer payı = iptal olmayan iç transfer satırı (Stoktan dahil) — tamamlanmış belgede yapılan, açık belgede istenen; tamamlanmış iade belgesinin yapılan miktarı düşülür. Planlanacak = talep − satınalma payı − transfer payı.
- **Taslak** (`Prc_P_MaterialRequestPlanLineSave`, kalem kilitlenerek): talep onaylı (ya da satınalmada ilerleyen) ve kalem Bekliyor olmalı; 0 ya da boş miktar satırı taslaktan çıkarır. Taslak toplamı planlanacak kalanı (50200), iç transfer / Stoktan satırı kullanılabilir stoğu (lot ve konum; 50198) aşamaz; teslim konumuna yazılan satır Stoktan kararıdır.
- **Onayla** (`Prc_P_MaterialRequestPlanConfirm`, tek transaction): taslak boşsa 50201; satırlar önce iç transfer ve Stoktan, sonra satınalma sırasıyla karara gider, ardından taslak silinir. Bir satır reddedilirse hiçbir belge açılmaz.
- **Karar** (`Prc_P_MaterialRequestPlan`, kalem kilitlenerek): plan miktarı > 0 ve ≤ planlanacak.
- Satınalma: tedarikçinin talebin şubesi ve deposu için taslak teklif talebi varsa kalem ona eklenir (zaten oradaysa miktarı artar); yoksa yeni taslak açılır (numara `Prc.PurchaseRfq`, talebin deposunun aktif alım türü — numaratörü `….Receipt` ile biten öncelikli, para birimi ve koşullar kontak kartından, alıcı planlayan). Birim fiyat tedarikçinin fiyat listesinden (en düşük minimum miktar; yoksa 0), KDV ürünün alış oranı, teslim tarihi termin.
- İç Transfer: kaynak konum zorunlu, teslim konumundan farklı ve ürünün (takipli üründe lotun) serbest stoğu yetmeli (50197/50198). Belge kaynak deponun **İç Transferler** türüyle açılır: depoda birden çok iç transfer türü (Bakım Sarf Tüketimi, Departman Sarf Çıkışı …) olabildiği için numaratörü `….InternalTransfer` ile biten aktif tür seçilir, yoksa adına göre ilki. Bu türde aynı kaynak → teslim konumu için taslak varsa satır ona eklenir (kaynak belgeye talep no yazılır), yoksa yeni taslak açılır (sorumlu planlayan). Satırın yapılan miktarı planla açılır: lot planlandıysa lot dağılımına eklenir (miktar lot toplamıdır), miktar takipli üründe plan miktarı doğrudan yazılır; belge `Inv_P_TransferAfterSave` ile numaralanır ve Taslak açılır; İç Transferler'de onay adımı yoktur.
- Stoktan: İç Transfer'in aynısı, kaynak = hedef = teslim konumu.
- **Kalem kapanışı** (`Prc_P_MaterialRequestItemSync`, transferin her yeniden hesabında ve iptalinde): satınalma payı olmayan, planlanacağı kalmayan Bekliyor kalem Tamamlandı olur; planlanacak miktar yeniden doğarsa (iptal, satır silme, iade) ve teslim tamamlanmamışsa Bekliyor'a döner. Ardından talep durumu yenilenir.
- **Tedarikçi fiyatı** (`Inv_P_TransferSupplierPrice`, siparişli alımın Doğrula'sında): tedarikçi × ürün × birim × para birimi başına tek satır; alınan miktara uyan kademe fiyat ve Son Alım Tarihi ile güncellenir, yoksa yeni satır açılır. Siparişsiz alım, iade ve 0 fiyat yazmaz.
- Kartlar: Planlama — planlanacak, geciken, 7 gün içinde, taslak planlı; Plan Takibi — toplam, satınalma, iç transfer (Stoktan dahil), tamamlanan; talep listeleri — onaylanan (onaydan sonraki bütün durumlar dahil).
### 6. Yetki ve görünürlük
Yetki ağacı: `App.Prc` › `App.Prc.MaterialRequests` › her liste (+ Create/Update/Delete/Export/Import; Note yalnızca tablo kaynaklı listede — view kaynaklı Taleplerim, Planlama, Plan Takibi ve diyalog ekranlarında Not yoktur); alt form `App.Prc.MaterialRequestLine` listenin altında, Planlama'nın sekmeleri ve diyalog ekranları (`App.Prc.MaterialRequestPlan{Stock,Supplier,LastPurchase,Source,Vendor,Line}`) `App.Prc.MaterialRequestPlan` altında. Talep edenlere Taleplerim (+Create, +Update), onaycılara ilgili onay listesi (+Update), satınalma ekibine Planlama (+Update — Planla butonu ve Onayla), sekmeleri, diyalog ekranları (İç Transfer ve Satınalma +Update — taslak yazma, Karşılama Planı +Delete — taslak silme), Plan Takibi ve Tüm Talepler verilir; diyalogdaki Teklif butonu Teklif Talepleri okuma yetkisini ister; Plan Takibi'nin butonları hedef ekranın okuma yetkisini ister (Teklif Talepleri, Satınalma Siparişleri, İç Transferler). Onay listeleri yalnız kullanıcının onayına düşen kayıtları gösterir. Yetkiler hiçbir role otomatik atanmaz. Kiracı kapsamlı; Taleplerim şube yetkilidir (`IsBranch`, 2026-10-14 kararı): kullanıcı yalnız atandığı şubelerin taleplerini görür ve formda yalnız onları seçer; şube seçilince kullanıcının o şubedeki varsayılan deposu ve konumu (Kullanıcılar › Yetkiler › Şube Yönetimi, `Sas_T_BranchUsers.DefaultWarehouseId/DefaultLocationId`) gelir, yeni talep departmanın şubesiyle (kullanıcı o şubeye atanmışsa) ve onun varsayılan depo/konumuyla açılır. Diğer talep listelerinde şube filtresi yok.
Yetki ağacı: `App.Prc` › `App.Prc.MaterialRequests` › her liste (+ Create/Update/Delete/Export/Import; Note yalnız tablo kaynaklı listede — Taleplerim ve onay listeleri; view kaynaklı Tüm Talepler, Planlama, Plan Takibi ve diyalog ekranlarında Not yoktur); alt form `App.Prc.MaterialRequestLine` listenin altında, Planlama'nın sekmeleri ve diyalog ekranları `App.Prc.MaterialRequestPlan` altında. Talep edenlere Taleplerim (+Create, +Update), onaycılara ilgili onay listesi (+Update), satınalma ekibine Planlama (+Update), sekmeleri, diyalog ekranları (İç Transfer ve Satınalma +Update, Karşılama Planı +Create/+Delete), Plan Takibi ve Tüm Talepler verilir; Plan Takibi'nin butonları hedef ekranın okuma yetkisini ister. Yetkiler hiçbir role otomatik atanmaz. Kiracı kapsamlı; lookup'lar (şube, kontak, kullanıcı) kiracıya süzülür. Taleplerim şube yetkilidir (`IsBranch`): kullanıcı yalnız atandığı şubelerin taleplerini görür; şube seçilince kullanıcının o şubedeki varsayılan deposu ve konumu gelir.
### 7. Entegrasyonlar
Yönetim › Tanımlamalar › Onaycılar (onay yeri Satınalma); Yönetim › Roller (Satınalma Onayı Bekleyenler yetkisi); Envanter › Tanımlamalar › Ürünler (tedarikçi fiyat listesi), Depolar, Konumlar, Operasyon Türleri (deponun alım ve iç transfer türü); Envanter › Stok (Depo Stokları); Envanter › Operasyonlar › İç Transferler (transfer kararı, teslim edilen miktar, kalem kapanışı); Envanter › Operasyonlar › Alımlar (Son Alımlar; tamamlanan siparişli alım tedarikçi fiyatını yazar); Satınalma › Siparişler (satınalma kararı → teklif talebi); İK departmanları; Yönetim › Tanımlamalar › Diziler (`MaterialRequest`, `Prc.PurchaseRfq`). Akış e-posta bildirimi platformun iş akışı altyapısındadır.
Yönetim › Onaycılar (onay yeri Satınalma) ve Roller; Envanter › Ürünler (tedarikçi fiyat listesi, kategori çıkış stratejisi, takip yöntemi), Depolar, Konumlar, Operasyon Türleri (deponun alım ve iç transfer türü), Stok; Envanter › İç Transferler (iç transfer ve Stoktan kararı, teslim edilen miktar, kalem kapanışı); Envanter › Alımlar (Son Alımlar, teslim edilen miktar, tedarikçi fiyatı); Satınalma › Siparişler; İK departmanları; Diziler (`MaterialRequest`, `Prc.PurchaseRfq`).
### 8. Akış örneği
1. Onaycılar'da BT departmanı için Satınalma yerinde Ayşe tanımlıdır; Mehmet'in rolünde Satınalma Onayı Bekleyenler, Planlama ve diyalog ekranlarının güncelleme yetkisi vardır.
2. BT'den Ali Taleplerim'de yeni talep açar (MT-2026-00001), depo/konum (WH/Stock) seçer, Talep Satırları'na 10 adet ürün, termin ve neden girer; Onaya Gönder der.
3. Ayşe Departman Onayı Bekleyenler'de talebi onaylar; talep Satınalma Onayı Bekleyenler'e geçer.
4. Mehmet onaylar; talep Onaylandı olur, Ali'ye bilgi gider; kalem Planlama'da 10 planlanacak olarak görünür.
5. Mehmet satırı seçer: Depo Stokları'nda Depo-2/Raf A'da 4 adet, Son Alımlar'da 3K Kutu'dan 200 ₺'lik son alım, Tedarikçiler'de 3K Kutu ve 5 Mutlu Gıda fiyatları görünür.
6. Planla: diyalog İç Transfer sekmesiyle açılır (öneri Transfer); Depo-2/Raf A satırına 4 yazar, Kaydet. Satınalma sekmesinde 3K Kutu'ya 6 yazar, Kaydet. Karşılama Planı'nda iki satır görünür, listede Taslak Plan 10 olur.
7. Onayla: Raf A → talebin konumuna taslak iç transfer açılır, 3K Kutu'nun taslak teklif talebine (yoksa yeni RFQ) 6 adet eklenir; kalem listeden çıkar, talep Teklif Talebi olur. Satınalma sekmesindeki Teklif butonu teklif talebini yeni sekmede açar.
8. Plan Takibi'nde iki karar görünür; transfer Envanter'de onaylanıp tamamlanınca gerçekleşen 4 olur, teklif ihale/sipariş/alım akışıyla ilerler.
1. BT departmanı için Onaycılar'da Satınalma yerinde Ayşe tanımlıdır; Mehmet'in rolünde Satınalma Onayı Bekleyenler, Planlama ve diyalog ekranlarının yetkileri vardır.
2. Ali Taleplerim'de MT-2026-00001'i açar (teslim konumu 0001/Ana Depo), 10 adet sensör ve 2 adet sigorta girer, Onaya Gönder der; Ayşe, sonra Mehmet onaylar.
3. Planla (sensör, lot takipli, kategori FIFO): İç Transfer sekmesinde Ek Depo'nun LOT-0012 ve LOT-0015 satırları çıkış sırasıyla listelenir; Öner LOT-0012'den 4 yazar, kalan 6'yı 3K Kutu'ya ayırır. Onayla: Ek Depo → Ana Depo taslak iç transfer (LOT-0012 × 4) ve 3K Kutu'ya taslak teklif talebi açılır; talep Teklif Talebi olur.
4. Planla (sigorta, Ana Depo'da stoğu var): teslim konumu satırına 2 yazılır, Onayla Ana Depo → Ana Depo iç transfer (Stoktan) açar.
5. Depo iki transferi hazırlar (Yapılacak olarak işaretle), Doğrula'ya basar: Stoktan belgesi stoğa dokunmaz, iki kalemin teslim edilen miktarı yazılır.
6. Teklif siparişe döner, alım Doğrula'lanınca sensörün kalan 6'sı da teslim edilmiş olur; talep Tamamlandı.
### 9. Sık sorulanlar
- **Talebim onay listesinde görünmüyor?** Onaycılar'da talebin departmanı için aktif Satınalma satırı olmalı; satınalma adımı için en az bir aktif kullanıcının (doğrudan ya da rolüyle) Satınalma Onayı Bekleyenler güncelleme yetkisi olmalıdır. Onaycılar ya da yetkiler talep açıldıktan sonra değiştiyse talebi bir kez kaydedin.
- **Onaya gönderdikten sonra satır ekleyebilir miyim?** Hayır; talep reddedilirse ya da akış başa dönerse yeniden düzenlenir.
- **Son Alımlar boş?** Sekme yalnız Doğrula ile stoğa girmiş alımları gösterir; taslak/hazır alım ve onaylanmış ama teslim alınmamış sipariş listelenmez. Siparişsiz alım listelenir ama fiyatı boştur.
- **Tedarikçi fiyatı alımdan sonra değişmedi?** Fiyatı yalnız siparişten açılan alım yazar; elle açılan alımın fiyatı yoktur.
- **Onaylanan kalem Planlama'da yok?** Kalem Bekliyor olmalı ve planlanacak miktarı kalmalı; tamamı teklife/transfere ayrılmış ya da Tüm Talepler'de Tamamlandı/İptal yapılmış kalem listelenmez.
- **"Alım operasyon türü tanımlı değil" / "iç transfer operasyon türü tanımlı değil"?** Envanter › Tanımlamalar › Operasyon Türleri'nde talebin deposu için aktif Alım, kaynak konumun deposu için aktif İç Transfer türü tanımlanmalıdır.
- **"Yeterli serbest stok yok"?** Kaynak konumdaki eldeki miktardan açık (Taslak/Bekleyen/Hazır) transferlerde o konumdan istenen miktar düşülür; başka konum seçin ya da miktarı azaltın.
- **Onaylamadan diyaloğu kapattım?** Taslak plan kalır; Planlama'da Taslak Plan kolonunda görünür, Planla ile açıp onaylayabilir ya da Karşılama Planı'ndan silebilirsiniz.
- **Onayla reddedildi?** Mesaj sebebi söyler (serbest stok taslak yazıldıktan sonra azalmış, kalan değişmiş ya da deponun operasyon türü yok); hiçbir belge açılmamıştır, taslağı düzeltip yeniden onaylayın.
- **Planladığım miktarı geri almak?** Teklif talebindeki kalemi silin ya da teklifi iptal edin; transferde satırı silin ya da transferi iptal edin — miktar Planlama'ya döner, transferle kapanan kalem yeniden açılır.
- **Red nedeni nereden seçilir?** Reddet düğmesinin açtığı karar penceresinde, Satınalma › Tanımlamalar › Red Nedenleri listesinden; neden ve not Onay Açıklaması kolonunda görünür.
- **Talebim onay listesinde görünmüyor?** Onaycılar'da talebin departmanı için aktif Satınalma satırı olmalı; satınalma adımı için en az bir aktif kullanıcının Satınalma Onayı Bekleyenler güncelleme yetkisi olmalıdır. Onaycılar ya da yetkiler talep açıldıktan sonra değiştiyse talebi bir kez kaydedin.
- **Stoktan karşıladım, İç Transferler'de belge neden kaynak ve hedefi aynı?** Stok zaten teslim konumundadır; belge malın talep edene teslimini kaydeder. Hazırlama ve Doğrula diğer transferler gibidir, Doğrula stoğu taşımaz.
- **Talep neden Tamamlandı olmadı?** İptal olmayan her kalemin teslim edilen miktarı talep edilene ulaşmalıdır: iç transfer / Stoktan belgesi ya da siparişin alımı Doğrula'lanmış olmalı.
- **İade ettim, kalem nerede?** Tamamlanmış iadenin miktarı transfer payından düşer; kalem Bekliyor'a döner ve Planlama'da yeniden görünür, talep durumu geri alınır.
- **Onaylanan kalem Planlama'da yok?** Kalem Bekliyor olmalı ve planlanacak miktarı kalmalı; tamamı belgelere ayrılmış ya da Tüm Talepler'de Tamamlandı/İptal yapılmış kalem listelenmez.
- **"Operasyon türü tanımlı değil"?** Envanter › Operasyon Türleri'nde talebin deposu için aktif Alım, kaynak konumun deposu için aktif İç Transfer türü tanımlanmalıdır.
- **"Yeterli serbest stok yok"?** Eldeki miktardan açık transferlerde o konumdan (lot satırında o lottan) istenen ve diğer taslak satırlar düşülür; başka konum/lot seçin ya da miktarı azaltın.
- **Onayla reddedildi?** Mesaj sebebi söyler; hiçbir belge açılmamıştır, taslağı düzeltip yeniden onaylayın.
- **Planladığım miktarı geri almak?** Teklif talebindeki kalemi silin ya da teklifi iptal edin; iç transferde (Stoktan dahil) satırı silin ya da transferi iptal edin — miktar Planlama'ya döner.
### 10. Dosyalar ve geri alma
- Tablolar: `sql/object/Prc_T_MaterialRequest.sql`, `Prc_T_MaterialRequestItem.sql`, `Prc_T_RejectReason.sql` (+ postgres eşleri); `Prc_T_MaterialRequestPlanLine.sql`.
- Görünümler: `Prc_V_MaterialRequestLine`, `Prc_V_MaterialRequestItemPlan`, `Prc_V_MaterialRequestPlan`, `Prc_V_MaterialRequestPlanTrack`, `Prc_V_PurchaseReceiptLine` (sql + postgres object); Envanter'de `Inv_P_TransferSupplierPrice` (Doğrula'dan).
- Tablo: `Prc_T_MaterialRequestPlanLine`; görünümler `Prc_V_MaterialRequestPlan{Source,Vendor,Line}` (sql + postgres).
- Yordamlar: `Prc_P_MaterialRequestAfterSave`, `Prc_P_MaterialRequestSyncStatus`, `Prc_P_MaterialRequestPlan`, `Prc_P_MaterialRequestPlanLineSave`, `Prc_P_MaterialRequestPlanConfirm`, `Prc_P_MaterialRequestItemSync` (sql + postgres); değişen `Inv_P_TransferRecalc`, `Inv_P_TransferSetStatus` (kalem eşlemesi çağrısı).
- Wizard'lar: `Prc_MaterialRequestLine.json`, `Prc_MyMaterialRequest.json`, `Prc_MaterialRequestDeptApproval.json`, `Prc_MaterialRequestPurchaseApproval.json`, `Prc_MaterialRequestPlan.json`, `Prc_MaterialRequestPlan{Stock,Supplier,LastPurchase}.json`, `Prc_MaterialRequestPlanTrack.json`, `Prc_MaterialRequest.json`, `Prc_RejectReason.json`; güncellenen `Adm_Approver.json`.
- Kaldırılan (2026-10-13): `Prc_PurchaseRfqImportItem.json`, `Prc_PurchaseOrderImportItem.json`, `Inventory_TransferImportItem.json` ve `Prc_V_MaterialRequestAvailableItem`, `Prc_V_PurchaseImportItem`, `Prc_P_PurchaseImportItem`, `Prc_V_MaterialRequestTransferItem`, `Inv_P_TransferImportItem`; ekranlar üst wizard'ların `Pending.ListFormCodes` kaydıyla migrate'te silinir.
- Tablolar: `Prc_T_MaterialRequest`, `Prc_T_MaterialRequestItem`, `Prc_T_MaterialRequestPlanLine`, `Prc_T_RejectReason`; tetikleyici `Prc_TR_MaterialRequestLock` (sql + postgres object).
- Görünümler: `Prc_V_MaterialRequestLine`, `Prc_V_MaterialRequestItemPlan`, `Prc_V_MaterialRequestPlan`, `Prc_V_MaterialRequestPlan{Source,Vendor,Line}`, `Prc_V_MaterialRequestPlanTrack`, `Prc_V_PurchaseReceiptLine`.
- Yordamlar: `Prc_P_MaterialRequestAfterSave`, `Prc_P_MaterialRequestSyncStatus`, `Prc_P_MaterialRequestItemSync`, `Prc_P_MaterialRequestPlan`, `Prc_P_MaterialRequestPlan{LineSave,Suggest,Confirm}`; Envanter'de çağrılan `Inv_P_TransferAfterSave`, `Inv_P_TransferRecalc`, `Inv_P_TransferSetStatus`, `Inv_P_TransferValidate`, `Inv_P_TransferSupplierPrice`.
- Wizard'lar: `Prc_MyMaterialRequest`, `Prc_MaterialRequestLine`, `Prc_MaterialRequestDeptApproval`, `Prc_MaterialRequestPurchaseApproval`, `Prc_MaterialRequestPlan`, `Prc_MaterialRequestPlan{Stock,Supplier,LastPurchase,Source,Vendor,Line,Track}`, `Prc_MaterialRequest`, `Prc_RejectReason`.
- Kaldırılanlar: 2026-10-13 — Talepten Aktar ekranları ve nesneleri (`Prc_PurchaseRfqImportItem`, `Prc_PurchaseOrderImportItem`, `Inventory_TransferImportItem`, `Prc_V_MaterialRequestAvailableItem`, `Prc_V_PurchaseImportItem`, `Prc_P_PurchaseImportItem`, `Prc_V_MaterialRequestTransferItem`, `Inv_P_TransferImportItem`); 2026-10-14 — belgesiz Stoktan karşılama (`FromStockQuantity` kolonu, `Prc_P_MaterialRequestStockUndo`, Plan Takibi'nin Geri Al butonu ve dil anahtarları). Kurulu veritabanında `Prc_P_MaterialRequestStockUndo` yordamı elle düşürülür.
- Numaratör: `App.Definitions.Sequence` › `MaterialRequest`.
- Geri alma: Wizard Manager'da talep bazlı silme (alt form en son değil, önce listeler); tablolar yalnız açık onayla düşürülür.
- Geri alma: Wizard Manager'da talep bazlı silme (önce listeler, alt form en son); tablolar yalnız açık onayla düşürülür.
<!-- module-doc:section App.Prc.PurchaseAgreement -->
## Sözleşmeler (`App.Prc.PurchaseAgreement`)
### 1. Amaç ve kapsam
_Henüz yazılmadı._ <!-- module-doc:todo -->
Tedarikçiyle yapılan çerçeve anlaşmaların (Kapsamlı Sipariş / İhale) anlaşılan ürün, miktar ve birim fiyatlarıyla tutulması; teklif talebi ve siparişin bu fiyatlarla açılması ve sözleşmeden ne kadar sipariş edildiğinin izlenmesi. Kullanıcılar satınalma personelidir. Teklif ve sipariş akışı Siparişler bölümündedir.
### 2. Analiz ve kararlar
_Henüz yazılmadı._ <!-- module-doc:todo -->
- Sözleşme ayrı belgedir (`Prc_T_PurchaseAgreement` + `Prc_T_PurchaseAgreementLine`), numarası `Prc.PurchaseAgreement` numaratöründen (BO00001).
- Durum elle seçilir: Taslak › Doğrulanmış › Kapanmış / İptal. Teklif talebi ve siparişte yalnız **Doğrulanmış** sözleşme seçilebilir; seçim tedarikçi ve şubeye göre süzülür.
- Sözleşmeye bağlanan **kalemsiz** teklif talebi kaydedilince sözleşmenin kalan (henüz siparişe dönüşmemiş) miktarlarıyla ve anlaşılan fiyatlarla dolar (`Prc_P_PurchaseRfqFromAgreement`, `Prc_P_PurchaseRfqAfterSave`'den); kalemi olan belgeye dokunulmaz.
- Şube › Depo › Operasyon Türü zinciri teklif ve siparişteki gibidir; para birimi sözleşmede tutulur.
### 3. Menü ve ekranlar
_Henüz yazılmadı._ <!-- module-doc:todo -->
Satınalma (`App.Prc`) › Sözleşmeler (`App.Prc.PurchaseAgreement`, Siparişler'in üstünde). Sekme: Ürünler (`App.Prc.PurchaseAgreementLine`, menüsüz alt form). Listedeki Yeni Teklif butonu Teklif Talepleri'ni açar.
### 4. Veri modeli
_Henüz yazılmadı._ <!-- module-doc:todo -->
Kiracı + tam audit + soft delete.
- `Prc_T_PurchaseAgreement`: AgreementNo, SupplierId, BranchId, BuyerUserId, AgreementType (`Blanket` / `Tender`), CurrencyId, StartDate, EndDate, WarehouseId, OperationTypeId, Terms, Status (`Draft` / `Confirmed` / `Closed` / `Cancelled`).
- `Prc_T_PurchaseAgreementLine`: AgreementId (FK cascade), ProductId, Description, Quantity (anlaşılan), UomId, UnitPrice.
- Görünüm `Prc_V_PurchaseAgreementLine`: kalem + aynı sözleşmeye bağlı siparişlerde o ürün için sipariş edilen miktar.
- Teklif ve siparişte `AgreementId`.
### 5. İş kuralları ve hesaplar
_Henüz yazılmadı._ <!-- module-doc:todo -->
- Bitiş tarihi başlangıçtan önce olamaz (50131).
- Kalan miktar = anlaşılan − sözleşmeye bağlı siparişlerde sipariş edilen; boş teklif talebi bu kalanla dolar, fiyat kalemin anlaşılan birim fiyatıdır.
- Ürün listesi aktif ve satın alınabilir ürünlerdir; birim ürünün satınalma biriminden gelir.
### 6. Yetki ve görünürlük
_Henüz yazılmadı._ <!-- module-doc:todo -->
`App.Prc` › `App.Prc.PurchaseAgreement` (+ Create/Update/Delete/Export/Import/Note); Ürünler sekmesinin yetkisi sözleşmenin altındadır. Yetkiler hiçbir role otomatik atanmaz. Kiracı kapsamlı.
### 7. Entegrasyonlar
_Henüz yazılmadı._ <!-- module-doc:todo -->
Siparişler (teklif talebi ve siparişte sözleşme seçimi, sipariş edilen miktar); Kontaklar (tedarikçi); Envanter (Ürünler, Depolar, Operasyon Türleri); Para Birimleri; Diziler (`Prc.PurchaseAgreement`).
### 8. Akış örneği
_Henüz yazılmadı._ <!-- module-doc:todo -->
1. Satınalma 3K Kutu ile 2026 yılı için 1.000 adet koli kapsamlı sipariş sözleşmesi açar (BO00001), Ürünler'e 1.000 × 12 ₺ yazar, durumu Doğrulanmış yapar.
2. Teklif Talepleri'nde 3K Kutu ve BO00001 seçilerek kalemsiz belge kaydedilir; belge 1.000 adet × 12 ₺ ile dolar.
3. Teklif siparişe döndükçe sözleşmenin Ürünler sekmesinde sipariş edilen miktar artar; sonraki boş teklif kalanla dolar.
### 9. Sık sorulanlar
_Henüz yazılmadı._ <!-- module-doc:todo -->
- **Sözleşme teklifte görünmüyor?** Durumu Doğrulanmış olmalı; tedarikçi ve şube teklifle aynı olmalı.
- **Teklif sözleşmeden dolmadı?** Yalnız kalemsiz teklif talebi kaydedilirken dolar; önceden kalem eklenmişse dokunulmaz.
### 10. Dosyalar ve geri alma
_Henüz yazılmadı._ <!-- module-doc:todo -->
- Tablolar: `Prc_T_PurchaseAgreement`, `Prc_T_PurchaseAgreementLine`; görünüm `Prc_V_PurchaseAgreementLine`; yordam `Prc_P_PurchaseRfqFromAgreement` (sql + postgres object).
- Wizard'lar: `Prc_PurchaseAgreement.json`, `Prc_PurchaseAgreementLine.json`.
- Numaratör: `App.Definitions.Sequence` › `Prc.PurchaseAgreement`.
- Geri alma: önce `Prc_PurchaseAgreement`, sonra `Prc_PurchaseAgreementLine` `delete_wizard` ile; tablolar yalnız açık onayla düşürülür.
<!-- module-doc:section App.Prc.Orders -->
## Siparişler (`App.Prc.Orders`)
@ -294,8 +305,10 @@ Tüm tablolar kiracı + tam audit + soft delete.
- Alternatif (`Prc_P_PurchaseRfqCreateAlternative @Key, @UserId`, `@Key` = teklif|kontak, seçilen her satır için): belge teklif aşamasında olmalı; tedarikçinin ihalede iptal olmayan belgesi varsa hata.
- Kalem Tutarı KDV dahildir: Tutar = yuvarla(yuvarla(Miktar × Birim Fiyat) × (1 + Oran/100)); Vergi Hariç = Σ yuvarla(Miktar × Birim Fiyat); KDV = Σ(Tutar − kalemin vergi hariç tutarı); Toplam = Vergi Hariç + KDV = Σ Tutar. Formdaki script ve `Prc_P_Purchase{Rfq,Order}Recalc` aynı formülü kullanır; kalem her eklenip/değişip/silindiğinde yeniden hesaplanır.
- Teklif işlemleri: E-posta ile Gönder (taslak ya da gönderilmiş; kalem ve tedarikçi e-postası şart; Taslak → Gönderildi) · İhaleyi Gönder (ihalenin bütün taslak belgeleri) · Siparişe Dönüştür (taslak ya da gönderilmiş; ihale daha önce dönüştürülmemiş olmalı) · İptal (siparişe dönüşmüş teklif iptal edilemez) · Taslak olarak ayarla (yalnız iptalden; ihale siparişe dönüşmüşse olmaz).
- Sipariş işlemleri: Siparişi Onayla (taslak, kalemli) · E-posta ile Gönder (iptal dışında) · İptal · Taslak olarak ayarla (yalnız iptalden).
- **Alım:** Siparişi Onayla ve Siparişe Dönüştür (onaylı açılan sipariş) siparişin operasyon türünde taslak alım açar (`Inv_P_TransferFromPurchaseOrder`): konumlar operasyon türünden, satırlar envanter takipli kalemlerin alınmamış miktarı, Kaynak Belge = sipariş no. Siparişin iptal olmayan alımı varsa yenisi açılmaz. Yapılmış alımı olan sipariş iptal edilemez; iptal edilen siparişin yapılmamış alımları da iptal olur.
- Sipariş işlemleri: Siparişi Onayla (taslak, kalemli) · E-posta ile Gönder (iptal dışında) · İptal · Taslak olarak ayarla (yalnız iptalden). İptal: taslak ya da onaylı sipariş; yapılmış alımı olan sipariş iptal edilemez.
- Araç çubuğu butonları seçili belgenin durumuna göre aktif/pasif olur (`VisibleExpression`): teklifte Alternatif Oluştur, Fiyat Girişi, E-posta ile Gönder, İhaleyi Gönder, Siparişe Dönüştür ve İptal yalnız Teklif Talebi / Gönderildi'de, Taslak olarak ayarla yalnız İptal'de; siparişte Siparişi Onayla yalnız Taslak'ta, E-posta ile Gönder ve İptal Taslak / Onaylandı'da, Taslak olarak ayarla yalnız İptal'de. Satırdan okunamayan şartları (kalem, alım, ihale durumu) sunucu denetler.
- **Alım:** Siparişi Onayla ve Siparişe Dönüştür (onaylı açılan sipariş) siparişin operasyon türünde taslak alım açar (`Inv_P_TransferFromPurchaseOrder`): konumlar operasyon türünden, satırlar envanter takipli kalemlerin alınmamış miktarı, Kaynak Belge = sipariş no. Siparişin iptal olmayan alımı varsa yenisi açılmaz. Alım satırı sipariş kaleminin talep kalemini taşır: alımın Doğrula'sı talep kaleminin teslim edilen miktarını yazar, bütün kalemleri teslim edilen talep Tamamlandı olur (iade geri alır). Yapılmış alımı olan sipariş iptal edilemez; iptal edilen siparişin yapılmamış alımları da iptal olur.
- Siparişe Dönüştür tek transaction'dır: bir teklif ya da alım açılamazsa hiçbir sipariş açılmaz. Teklif talebi ya da sipariş silinince talep durumları yeniden hesaplanır (`Prc_P_MaterialRequestSyncStatus`).
- Siparişe dönüşmüş ya da iptal edilmiş teklif ve kalemleri değiştirilemez; iptal edilmiş siparişin kalemi değiştirilemez. Gönderilmiş ya da dönüşmüş teklif silinemez; yalnız teklifsiz yazılmış taslak sipariş silinebilir.
- Fiyat Karşılaştırması sekmesinde birim fiyat, teslim tarihi ve Seçili düzenlenir (ilgili teklifin toplamı yeniden hesaplanır). Siparişe dönüşte kazanan satırlar Seçili olarak işaretlenir.
- Sözleşmede bitiş tarihi başlangıçtan önce olamaz; sözleşme seçilen boş teklif kalan (siparişe dönüşmemiş) miktarlarla dolar.
@ -319,7 +332,7 @@ Yönetim › Tanımlamalar › Kontaklar (tedarikçi, e-posta, Satınalma sekmes
### 9. Sık sorulanlar
- **Butonlar nerede?** Listede bir belge seçilir; işlemler araç çubuğundadır (detay sayfasının araç çubuğunda da görünür). Buton yetkisi: durum işlemleri ekranın Update, Alternatif Oluştur Teklifler ekranının Create yetkisi.
- **Butonlar nerede?** Listede bir belge seçilir; işlemler araç çubuğundadır (detay sayfasının araç çubuğunda da görünür). Belgenin durumunda yapılamayan işlemin butonu pasiftir. Buton yetkisi: durum işlemleri ekranın Update, Alternatif Oluştur Teklifler ekranının Create yetkisi.
- **Talep kalemini teklife nasıl eklerim?** Satınalma › Talepler › Planlama'da satırdaki Planla ile Satınalma sekmesinde tedarikçiye miktar yazıp Onayla'ya basın; kalem tedarikçinin taslak teklif talebine eklenir.
- **Alternatif Oluştur / Fiyat Girişi modalı nasıl kullanılır?** Alternatif Oluştur'da ihaleye eklenecek tedarikçiler satır başındaki kutuyla seçilip Seçilenler İçin Oluştur'a basılır (modal iş bitince kendiliğinden kapanır). Fiyat Girişi ayrı butondur: bütün tedarikçilerin fiyat ve terminleri yazılıp tablonun Kaydet'ine basılır, modal Kapat ile kapanır.
- **Alternatif ekledim, kalemleri eksik?** Alternatif, açıldığı andaki kalemleri kopyalar; sonradan eklenen kalem yalnız eklendiği belgededir.
@ -630,7 +643,7 @@ Yönetim › Tanımlamalar › Kontaklar (tedarikçi, e-posta, Satınalma sekmes
| Düzenleme | ekle ✗ · düzenle ✗ · sil ✗ · popup |
| Kapsam | Kiracı |
| Widget'lar | `App.Widget.Total`, `App.StaticLookup.Purchase`, `App.StaticLookup.InternalTransfer`, `App.StaticLookup.Done` |
| Butonlar | `App.Prc.MaterialRequestPlanTrack.OpenRfq`, `App.Prc.MaterialRequestPlanTrack.OpenOrder`, `App.Prc.MaterialRequestPlanTrack.OpenTransfer`, `App.Prc.MaterialRequestPlanTrack.UndoStock` |
| Butonlar | `App.Prc.MaterialRequestPlanTrack.OpenRfq`, `App.Prc.MaterialRequestPlanTrack.OpenOrder`, `App.Prc.MaterialRequestPlanTrack.OpenTransfer` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
@ -643,9 +656,9 @@ Yönetim › Tanımlamalar › Kontaklar (tedarikçi, e-posta, Satınalma sekmes
| `PlanMethod` | Karar | dxSelectBox | | | liste: Purchase, Transfer, Stock |
| `DocumentNo` | Belge No | dxTextBox | | | |
| `DocumentStatus` | Durum | dxSelectBox | | | liste: Draft, Sent, Purchase, Waiting, Ready, Done, Cancelled |
| `SupplierId` | Tedarikçi | dxSelectBox | | | sorgu: Adm_T_Contact |
| `SourceLocationId` | Kaynak Konum | dxSelectBox | | | sorgu: Inv_T_Location |
| `LocationId` | Hedef Konum | dxSelectBox | | | sorgu: Inv_T_Location |
| `SupplierId` | Tedarikçi | dxSelectBox | | | sorgu: Adm_T_Contact |
| `PurchaseOrderNo` | Sipariş No | dxTextBox | | | |
| `OrderStatus` | Sipariş Durumu | dxSelectBox | | | liste: Draft, Purchase, Cancelled |
| `Quantity` | Miktar | dxNumberBox | | | |
@ -671,6 +684,7 @@ Yönetim › Tanımlamalar › Kontaklar (tedarikçi, e-posta, Satınalma sekmes
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Widget'lar | `App.Prc.MaterialRequest.Status.DeptApproval`, `App.Prc.MaterialRequest.Status.PurchaseApproval`, `App.Prc.MaterialRequest.Status.Approved`, `App.Prc.MaterialRequest.Status.Rejected` |
| Komutlar | UpdateAfter: `Prc_P_MaterialRequestSyncStatus` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
@ -773,6 +787,7 @@ Yönetim › Tanımlamalar › Kontaklar (tedarikçi, e-posta, Satınalma sekmes
| `PlanMethod` | Karar | dxSelectBox | | | liste: Purchase, Transfer, Stock |
| `SupplierId` | Tedarikçi | dxSelectBox | | | sorgu: Adm_T_Contact |
| `SourceLocationId` | Kaynak Konum | dxSelectBox | | | sorgu: Inv_T_Location |
| `LotNo` | Lot/Seri No | dxTextBox | | | |
| `Quantity` | Miktar | dxNumberBox | | | |
| `UomId` | Birim | dxSelectBox | | | sorgu: Adm_T_Uom |
| `Price` | Birim Fiyat | dxNumberBox | | | |
@ -786,7 +801,7 @@ Yönetim › Tanımlamalar › Kontaklar (tedarikçi, e-posta, Satınalma sekmes
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Prc.MaterialRequestPlanSource` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import` |
| Açıklama | İç Transfer — Planla diyaloğunun İç Transfer sekmesi: talep kaleminin ürününün stoğu olan iç konumlar. |
| Açıklama | İç Transfer — Planla diyaloğunun İç Transfer sekmesi: talep kaleminin ürününün stoğu olan iç konumlar. Ürün lot/seri numarasıyla takip ediliyorsa her konumun her lotu (seri takipte her seri) ayrı satırdır; miktarla takip edilen üründe konum başına tek satır vardır. |
| Kaynak | `Prc_V_MaterialRequestPlanSource` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · cell |
@ -799,12 +814,15 @@ Yönetim › Tanımlamalar › Kontaklar (tedarikçi, e-posta, Satınalma sekmes
| `BranchId` | Şube Adı | dxSelectBox | | | sorgu: Sas_T_Branch |
| `WarehouseId` | Depo | dxSelectBox | | | sorgu: Inv_T_Warehouse |
| `LocationId` | Konum | dxSelectBox | | | sorgu: Inv_T_Location |
| `LotNo` | Lot/Seri No | dxTextBox | | | |
| `UomId` | Birim | dxTextBox | | | |
| `PlanQuantity` | Plan Miktarı | dxNumberBox | | | |
| `OnHand` | Eldeki Miktar | dxNumberBox | | | |
| `ReservedQuantity` | Rezerve Miktar | dxNumberBox | | | |
| `FreeQuantity` | Serbest Miktar | dxNumberBox | | | |
| `IsDestination` | Teslim Konumu | dxCheckBox | | | |
| `MaxQuantity` | En Fazla | dxNumberBox | | | |
| `RemovalRank` | Çıkış Sırası | dxNumberBox | | | |
#### Depo Stokları — `App.Prc.MaterialRequestPlanStock`
@ -968,7 +986,7 @@ Yönetim › Tanımlamalar › Kontaklar (tedarikçi, e-posta, Satınalma sekmes
| Kapsam | Kiracı |
| Alt formlar | `App.Prc.PurchaseRfqLine` (Id → PurchaseRfqId), `App.Prc.PurchaseRfqQuote` (Id → Id), `App.Prc.PurchaseRfqOther` (Id → Id), `App.Prc.PurchaseRfqAlternative` (Id → BaseId), `App.Prc.PurchaseRfqComparison` (Id → BaseId) |
| Widget'lar | `App.Widget.Draft`, `App.Widget.Sent`, `App.Widget.Expired`, `App.Widget.Completed` |
| Komutlar | InsertAfter: `Prc_P_PurchaseRfqAfterSave` · UpdateBefore: SQL · UpdateAfter: `Prc_P_PurchaseRfqAfterSave` · DeleteBefore: SQL |
| Komutlar | InsertAfter: `Prc_P_PurchaseRfqAfterSave` · UpdateBefore: SQL · UpdateAfter: `Prc_P_PurchaseRfqAfterSave` · DeleteBefore: SQL · DeleteAfter: `Prc_P_MaterialRequestSyncStatus` |
| Form varsayılanları | RfqNo=Prc.PurchaseRfq, BuyerUserId=@USERID, CurrencyId=TRY, Status=Draft, BranchId=, WarehouseId= |
| Butonlar | `App.Prc.PurchaseRfq.CreateAlternative`, `App.Prc.PurchaseRfq.PriceEntry`, `App.Prc.PurchaseOrder.Action.Send`, `App.Prc.PurchaseRfq.Action.SendTender`, `App.Prc.PurchaseRfq.Action.Award`, `App.Prc.PurchaseOrder.Action.Cancel`, `App.Prc.PurchaseOrder.Action.Draft` |

View file

@ -74,7 +74,7 @@ Projelerin hiyerarşik iş planı (1 → 1.01, 1.02 …) ay ölçeğinde Gantt o
### 4. Veri modeli
- `Prj_T_WorkPackage`: ProjectId → Prj_T_Project, ParentId, Code (proje içinde benzersiz), Name, StartDate, EndDate, Months, Progress, Color, Note.
- `Prj_T_WorkPackage`: ProjectId → Prj_T_Project, BranchId (zorunlu, formda önce seçilir; proje listesi şubeye göre süzülür), ParentId, Code (proje içinde benzersiz), Name, StartDate, EndDate, Months, Progress, Color, Note.
- `Prj_T_WorkPackageMember`: WorkPackageId, UserId (paket+personel benzersiz).
- `Prj_T_WorkPackageMonthRate`: WorkPackageId, UserId, Year, Month, Rate.
- `Prj_T_WorkPackageResource`: WorkPackageId, Kind, ResourceType, UserId, ResourceName, OrganizationType/Name, WorkDone, WorkDescription, DocumentDate/No, Unit (Adet), Price, Quantity (1), VatRate (0), Cost.
@ -87,7 +87,7 @@ Projelerin hiyerarşik iş planı (1 → 1.01, 1.02 …) ay ölçeğinde Gantt o
### 6. Yetki ve görünürlük
`App.Prj › App.Prj.WorkPackage` (+ C/U/D/E/I/N); alt formlar `… › App.Prj.WorkPackage › App.Prj.WorkPackage{Member|MonthRate|Planned|Actual}`.
`App.Prj › App.Prj.WorkPackage` (+ C/U/D/E/I/N); alt formlar `… › App.Prj.WorkPackage › App.Prj.WorkPackage{Member|MonthRate|Planned|Actual}`. Şube kırılımı (`IsBranch`): tablo `BranchId` taşır. Formda önce Şube seçilir (kullanıcının şubeleri, varsayılan departman şubesi), Proje listesi seçilen şubeye göre süzülür (`CascadeParentFields: BranchId`, şube değişince proje temizlenir). Proje kartının sekmesinden eklenen kayıt şubeyi alt form ilişkisinden (`BranchId → BranchId`) alır. Liste kullanıcıya atanmış şubelerle (`Sas_T_BranchUsers`) sınırlıdır.
### 7. Entegrasyonlar
@ -167,7 +167,7 @@ Intranet › Dashboard'daki **Güncem** kutusu (`diary`, builtin `ui/src/views/i
### 4. Veri modeli
`Prj_T_Diary`: ProjectId, WorkPackageId (projeye göre süzülür), UserId, StartTime, EndTime, Minutes, Content (nvarchar(MAX), HTML). Kiracı + audit + soft delete.
`Prj_T_Diary`: ProjectId, BranchId (zorunlu, formda önce seçilir; proje listesi şubeye göre süzülür), WorkPackageId (projeye göre süzülür), UserId, StartTime, EndTime, Minutes, Content (nvarchar(MAX), HTML). Kiracı + audit + soft delete.
### 5. İş kuralları ve hesaplar
@ -175,7 +175,7 @@ Dakika = (Bitiş − Başlangıç) saat × 60, yuvarlanır, negatif olamaz; form
### 6. Yetki ve görünürlük
`App.Prj › App.Prj.Diary` (+ C/U/D/E/I/N, `.Widget`). Kayıtlar kiracı içinde tüm yetkililere görünür. `App.Prj.Diary.Widget` panodaki Günce kutusunu gösterir; modalda kaydetmek ekran yetkisini (`App.Prj.Diary` + `.Create`) ister, yoksa modal yetki uyarısı gösterir.
`App.Prj › App.Prj.Diary` (+ C/U/D/E/I/N, `.Widget`). Şube kırılımı (`IsBranch`): tablo `BranchId` taşır. Formda önce Şube seçilir (kullanıcının şubeleri, varsayılan departman şubesi), Proje listesi seçilen şubeye göre süzülür (`CascadeParentFields: BranchId`, şube değişince proje temizlenir). Proje kartının sekmesinden eklenen kayıt şubeyi alt form ilişkisinden (`BranchId → BranchId`) alır. Liste kullanıcıya atanmış şubelerle (`Sas_T_BranchUsers`) sınırlıdır. `App.Prj.Diary.Widget` panodaki Günce kutusunu gösterir; modalda kaydetmek ekran yetkisini (`App.Prj.Diary` + `.Create`) ister, yoksa modal yetki uyarısı gösterir.
### 7. Entegrasyonlar
@ -222,6 +222,7 @@ Widget'lar: toplam, aktif, tamamlanan proje sayısı ve toplam bütçe.
`Prj_T_Project` alanları:
- Kimlik: ProjectNo (kiracı içinde benzersiz), Name, ProjectType, Status (varsayılan Draft), StartDate, EndDate, ManagerId, Tags.
- Şube: BranchId (zorunlu, `Sas_T_Branch`) — işlem tablosu olduğu için kiracı gibi şubeyi de taşır.
- HTML metinler: Summary, Needs, Activities, Innovation, Outputs (hepsi nvarchar(MAX)).
- Destek: NationalSupportOrg, InternationalSupportOrg, OwnFundedAmount, SupportAmount, TotalBudget, ServicePurchaseSubject, ServicePurchasePlace.
@ -240,7 +241,7 @@ View'lar: `Prj_V_ProjectMember` (takım hesapları) ve `Prj_V_ProjectCostSummary
### 6. Yetki ve görünürlük
`App.Prj › App.Prj.Project` (+ C/U/D/E/I/N). Menüsüz sekmelerin yetkisi `… › App.Prj.Project › App.Prj.Project{Summary|Support|Needs|Activities|Innovation|Outputs|Member|CostSummary}` altındadır. Metin sekmelerinde silme kapalıdır.
`App.Prj › App.Prj.Project` (+ C/U/D/E/I/N). Liste şube kırılımlıdır (`IsBranch`): yalnızca kullanıcıya atanmış şubelerin projeleri görünür; Şube seçimi kullanıcının şubeleriyle sınırlıdır, yeni proje kullanıcının departman şubesiyle açılır (`DbQuery`). Proje menüsündeki diğer listeler (İş Paketleri, Günce, Adam/Ay, Kaynak Listesi, Personel Adam/Ay, Bütçe Raporu) aynı şube kapsamını projeden alır. Menüsüz sekmelerin yetkisi `… › App.Prj.Project › App.Prj.Project{Summary|Support|Needs|Activities|Innovation|Outputs|Member|CostSummary}` altındadır. Metin sekmelerinde silme kapalıdır.
### 7. Entegrasyonlar
@ -344,7 +345,7 @@ Her satırda şu kolonlar bulunur: Title, StartDate, EndDate, Progress, AvgRate
### 6. Yetki ve görünürlük
`App.Prj › App.Prj.ManMonth`. Ekleme, düzenleme ve silme kapalıdır.
`App.Prj › App.Prj.ManMonth`. Ekleme, düzenleme ve silme kapalıdır. Şube kırılımı (`IsBranch`): view projenin `BranchId`'sini taşır, Şube kolonu görünür ve yalnızca kullanıcıya atanmış şubelerin (`Sas_T_BranchUsers`) projeleri listelenir; Proje seçimi de bu şubelerle sınırlıdır.
### 7. Entegrasyonlar
@ -398,7 +399,7 @@ Ekranda ayrıca bir hesap yapılmaz. Maliyet değeri, giriş sırasında iş pak
### 6. Yetki ve görünürlük
Yetki dalı `App.Prj › App.Prj.ResourceList` altındadır. Ekran yalnızca okuma ve dışa aktarma için kullanılır.
Yetki dalı `App.Prj › App.Prj.ResourceList` altındadır. Ekran yalnızca okuma ve dışa aktarma için kullanılır. Şube kırılımı (`IsBranch`): view projenin `BranchId`'sini taşır, Şube kolonu görünür ve yalnızca kullanıcıya atanmış şubelerin (`Sas_T_BranchUsers`) projeleri listelenir; Proje seçimi de bu şubelerle sınırlıdır.
### 7. Entegrasyonlar
@ -453,7 +454,7 @@ Kaynak `Prj_V_PersonnelManMonth` view'ıdır. Satır anahtarı oran kaydının I
### 6. Yetki ve görünürlük
Yetki yolu `App.Prj › App.Prj.PersonnelManMonth` şeklindedir. Ekran salt okunurdur.
Yetki yolu `App.Prj › App.Prj.PersonnelManMonth` şeklindedir. Ekran salt okunurdur. Şube kırılımı (`IsBranch`): view projenin `BranchId`'sini taşır, Şube kolonu görünür ve yalnızca kullanıcıya atanmış şubelerin (`Sas_T_BranchUsers`) projeleri listelenir; Proje seçimi de bu şubelerle sınırlıdır.
### 7. Entegrasyonlar
@ -515,7 +516,7 @@ Kolonlar: Title, StartDate, EndDate, Year, Month, Planned, Actual, Ratio, Progre
### 6. Yetki ve görünürlük
Yetki dalı `App.Prj › App.Prj.BudgetReport`'tur. Rapor salt okunurdur.
Yetki dalı `App.Prj › App.Prj.BudgetReport`'tur. Rapor salt okunurdur. Şube kırılımı (`IsBranch`): view projenin `BranchId`'sini taşır, Şube kolonu görünür ve yalnızca kullanıcıya atanmış şubelerin (`Sas_T_BranchUsers`) projeleri listelenir; Proje seçimi de bu şubelerle sınırlıdır.
### 7. Entegrasyonlar
@ -633,11 +634,12 @@ Talep, raporun yalnızca ay bazında gösterilmesini istiyor. Çeyrek bazlı top
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Prj.WorkPackageMember` (Id → WorkPackageId), `App.Prj.WorkPackageMonthRate` (Id → WorkPackageId), `App.Prj.WorkPackagePlanned` (Id → WorkPackageId), `App.Prj.WorkPackageActual` (Id → WorkPackageId) |
| Form varsayılanları | Progress=0 |
| Form varsayılanları | Progress=0, BranchId= |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `ProjectId` | Proje | dxSelectBox | ✓ | ✓ | sorgu: Prj_T_Project |
| `BranchId` | Şube Adı | dxSelectBox | ✓ | ✓ | sorgu: Sas_T_Branch |
| `ProjectId` | Proje | dxSelectBox | ✓ | ✓ | sorgu: Prj_T_Project (← BranchId) |
| `Code` | İş Paket No | dxTextBox | ✓ | ✓ | |
| `Name` | İş Paketi | dxTextBox | ✓ | ✓ | |
| `ParentId` | Üst İş Paketi | dxSelectBox | | ✓ | sorgu: Prj_T_WorkPackage (← ProjectId) |
@ -777,11 +779,12 @@ Talep, raporun yalnızca ay bazında gösterilmesini istiyor. Çeyrek bazlı top
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Widget'lar | `App.Widget.Total`, `App.Widget.Today`, `App.Widget.TotalHours` |
| Form varsayılanları | UserId=@USERID |
| Form varsayılanları | UserId=@USERID, BranchId= |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `ProjectId` | Proje | dxSelectBox | ✓ | ✓ | sorgu: Prj_T_Project |
| `BranchId` | Şube Adı | dxSelectBox | ✓ | ✓ | sorgu: Sas_T_Branch |
| `ProjectId` | Proje | dxSelectBox | ✓ | ✓ | sorgu: Prj_T_Project (← BranchId) |
| `WorkPackageId` | İş Paketi | dxSelectBox | | ✓ | sorgu: Prj_T_WorkPackage (← ProjectId) |
| `StartTime` | Başlangıç Tarihi | dxDateBox | ✓ | ✓ | script |
| `EndTime` | Bitiş Tarihi | dxDateBox | | ✓ | script |
@ -805,20 +808,21 @@ Talep, raporun yalnızca ay bazında gösterilmesini istiyor. Çeyrek bazlı top
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Prj.ProjectSummary` (Id → Id), `App.Prj.ProjectSupport` (Id → Id), `App.Prj.ProjectNeeds` (Id → Id), `App.Prj.ProjectActivities` (Id → Id), `App.Prj.ProjectInnovation` (Id → Id), `App.Prj.ProjectOutputs` (Id → Id), `App.Prj.ProjectMember` (Id → ProjectId), `App.Prj.WorkPackage` (Id → ProjectId), `App.Prj.ProjectCostSummary` (Id → ProjectId), `App.Prj.Diary` (Id → ProjectId) |
| Alt formlar | `App.Prj.ProjectSummary` (Id → Id), `App.Prj.ProjectSupport` (Id → Id), `App.Prj.ProjectNeeds` (Id → Id), `App.Prj.ProjectActivities` (Id → Id), `App.Prj.ProjectInnovation` (Id → Id), `App.Prj.ProjectOutputs` (Id → Id), `App.Prj.ProjectMember` (Id → ProjectId), `App.Prj.WorkPackage` (Id → ProjectId, BranchId → BranchId), `App.Prj.ProjectCostSummary` (Id → ProjectId), `App.Prj.Diary` (Id → ProjectId, BranchId → BranchId) |
| Widget'lar | `App.Widget.Total`, `App.Widget.Active`, `App.Widget.Completed`, `App.Widget.TotalBudget` |
| Form varsayılanları | Status=Draft, ProjectNo=Prj.Project |
| Form varsayılanları | Status=Draft, ProjectNo=Prj.Project, BranchId= |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `BranchId` | Şube Adı | dxSelectBox | ✓ | ✓ | sorgu: Sas_T_Branch |
| `ProjectNo` | Proje No | dxTextBox | ✓ | ✓ | |
| `Name` | Proje Adı | dxTextBox | ✓ | ✓ | |
| `ProjectType` | Proje Tipi | dxSelectBox | | ✓ | liste: TUBITAK, KOSGEB, ArgeCenter, EU, Internal |
| `Status` | Durum | dxSelectBox | ✓ | ✓ | liste: Draft, Active, Completed, Cancelled |
| `StartDate` | Başlangıç Tarihi | dxDateBox | | ✓ | |
| `EndDate` | Bitiş Tarihi | dxDateBox | | ✓ | |
| `ManagerId` | Proje Yöneticisi | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `Tags` | Etiketler | dxTagBox | | ✓ | sorgu: Prj_T_Tag |
| `Status` | Durum | dxSelectBox | ✓ | ✓ | liste: Draft, Active, Completed, Cancelled |
#### Proje Özeti — `App.Prj.ProjectSummary`
@ -1018,6 +1022,7 @@ Talep, raporun yalnızca ay bazında gösterilmesini istiyor. Çeyrek bazlı top
| --- | --- | --- | --- | --- | --- |
| `ParentId` | Üst | dxTextBox | | | |
| `ProjectId` | Proje | dxSelectBox | | | sorgu: Prj_T_Project |
| `BranchId` | Şube Adı | dxSelectBox | | | sorgu: Sas_T_Branch |
| `Title` | Personel / İş Adı | dxTextBox | | | |
| `StartDate` | Başlangıç | dxDateBox | | | |
| `EndDate` | Bitiş | dxDateBox | | | |
@ -1048,6 +1053,7 @@ Talep, raporun yalnızca ay bazında gösterilmesini istiyor. Çeyrek bazlı top
| --- | --- | --- | --- | --- | --- |
| `ProjectNo` | Proje No | dxTextBox | | | |
| `ProjectName` | Proje Adı | dxTextBox | | | |
| `BranchId` | Şube Adı | dxSelectBox | | | sorgu: Sas_T_Branch |
| `WorkPackageCode` | İş Paket No | dxTextBox | | | |
| `WorkPackageName` | İş Adı | dxTextBox | | | |
| `ResourceType` | Tipi | dxSelectBox | | | liste: Personnel, Travel, Equipment, Consulting, Service, Material, Other |
@ -1084,6 +1090,7 @@ Talep, raporun yalnızca ay bazında gösterilmesini istiyor. Çeyrek bazlı top
| --- | --- | --- | --- | --- | --- |
| `ProjectNo` | Proje No | dxTextBox | | | |
| `ProjectName` | Proje Adı | dxTextBox | | | |
| `BranchId` | Şube Adı | dxSelectBox | | | sorgu: Sas_T_Branch |
| `WorkPackageCode` | İş Paket No | dxTextBox | | | |
| `WorkPackageName` | İş Adı | dxTextBox | | | |
| `PeriodDate` | Tarih | dxDateBox | | | |
@ -1114,6 +1121,7 @@ Talep, raporun yalnızca ay bazında gösterilmesini istiyor. Çeyrek bazlı top
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `ProjectId` | Proje | dxSelectBox | | | sorgu: Prj_T_Project |
| `BranchId` | Şube Adı | dxSelectBox | | | sorgu: Sas_T_Branch |
| `ParentId` | Üst | dxTextBox | | | |
| `Title` | Gider Kalemi | dxTextBox | | | |
| `ResourceType` | Kaynak Tipi | dxSelectBox | | | liste: Personnel, Travel, Equipment, Consulting, Service, Material, Other |

View file

@ -1,6 +1,6 @@
-- Transfer belgesi kaydı (ve iş akışı adımları) sonrası: tür, şube, depo ve boş konumlar operasyon türünden gelir (formda olmayan alımın
-- kaynağı ve teslimatın hedefi her zaman, iade belgesi hariç); teslimat politikası
-- yalnız teslimatta tutulur; iç transferin onaycısı kaynak konumun depo sorumlusudur (kullanıcı adı; iş akışı onaycıyı adla eşler), sorumlusu olmayan konumdan transfer onay beklemez.
-- Transfer belgesi kaydı sonrası: tür, şube, depo ve boş konumlar operasyon türünden gelir (formda olmayan alımın
-- kaynağı ve teslimatın hedefi her zaman, iade belgesi hariç); teslimat politikası yalnız teslimatta tutulur. Tamamlanmış belgenin başlığı
-- yeniden türetilmez: stoğu belirleyen alanlar kilitlidir (Inv_TR_TransferLock) ve sonradan değişen operasyon türü İade Et'i 50328'e düşürürdü.
-- Numara, özet ve durum butonunun işlemi (PendingAction) buradan çalışır.
CREATE OR REPLACE PROCEDURE public."Inv_P_TransferAfterSave"(p_id uuid, p_user_id uuid DEFAULT NULL)
LANGUAGE plpgsql AS $$
@ -18,35 +18,13 @@ BEGIN
THEN COALESCE(ot."DestinationLocationId", t."DestinationLocationId") ELSE t."DestinationLocationId" END,
"DeliveryPolicy" = CASE WHEN ot."OperationKind" = 'Delivery' THEN COALESCE(t."DeliveryPolicy", 'Direct') END
FROM "Inv_T_OperationType" ot
WHERE t."Id" = p_id AND ot."Id" = t."OperationTypeId";
UPDATE "Inv_T_Transfer" t SET
"SourceApproverUserNames" = a."UserName",
"ApprovalStatus" = CASE WHEN a."UserName" IS NULL AND t."ApprovalStatus" IS NULL THEN 'Onay Gerekmez'
WHEN a."UserName" IS NOT NULL AND t."ApprovalStatus" = 'Onay Gerekmez' THEN NULL
ELSE t."ApprovalStatus" END
FROM (SELECT x."Id", NULLIF(l."ResponsibleUserName", '') AS "UserName"
FROM "Inv_T_Transfer" x
LEFT JOIN "Inv_T_Location" l ON l."Id" = x."SourceLocationId"
WHERE x."Id" = p_id) a
WHERE t."Id" = a."Id" AND t."OperationKind" = 'InternalTransfer' AND t."Status" = 'Draft';
WHERE t."Id" = p_id AND ot."Id" = t."OperationTypeId" AND t."Status" <> 'Done';
CALL public."Inv_P_TransferNumber"(p_id);
CALL public."Inv_P_TransferRecalc"(p_id);
-- Durum butonları işlemi PendingAction alanına yazıp ekranın güncelleme ucuyla kaydeder.
IF v_act IS NOT NULL THEN
CALL public."Inv_P_TransferSetStatus"(p_id, v_act, p_user_id);
-- Kaynak depo onayı verilen taslak iç transfer kendiliğinden hazırlanır (kullanıcı kararı: onay → Hazırla tek adım).
-- Hazırla'nın şartları (satır, farklı iki iç konum) sağlanmıyorsa denenmez: onay kaydı bozulmaz, belge taslak kalır ve
-- Hazırla elle basılınca hatayı gösterir.
ELSIF EXISTS (SELECT 1
FROM "Inv_T_Transfer" t
INNER JOIN "Inv_T_Location" s ON s."Id" = t."SourceLocationId" AND s."LocationType" = 'Internal'
INNER JOIN "Inv_T_Location" d ON d."Id" = t."DestinationLocationId" AND d."LocationType" = 'Internal'
WHERE t."Id" = p_id AND t."OperationKind" = 'InternalTransfer' AND t."Status" = 'Draft' AND t."ApprovalStatus" = 'Onaylandı'
AND s."Id" <> d."Id"
AND EXISTS (SELECT 1 FROM "Inv_T_TransferLine" l WHERE l."TransferId" = t."Id" AND l."IsDeleted" = false)) THEN
CALL public."Inv_P_TransferSetStatus"(p_id, 'Confirm', p_user_id);
END IF;
END;
$$;

View file

@ -1,5 +1,5 @@
-- Belgeden yeni belge açar. Backorder: talepten az yapılan satırların kalanı, aynı konumlarla; stok kontrolüyle Hazır/Bekleyen olur.
-- Return (İade): yapılan miktarlar lotlarıyla, kaynak ve hedef yer değiştirerek Taslak açılır. İkisi de onay durumunu ve bağları taşır.
-- Return (İade): yapılan miktarlar lotlarıyla, kaynak ve hedef yer değiştirerek Taslak açılır. İkisi de bağları taşır.
CREATE OR REPLACE PROCEDURE public."Inv_P_TransferCopy"(p_source_id uuid, p_mode varchar, p_user_id uuid, INOUT p_new_id uuid DEFAULT NULL)
LANGUAGE plpgsql AS $$
DECLARE v_is_return boolean := p_mode = 'Return';
@ -8,7 +8,7 @@ BEGIN
INSERT INTO "Inv_T_Transfer" ("Id", "TenantId", "BranchId", "WarehouseId", "OperationTypeId", "OperationKind", "PartnerId", "SourceLocationId", "DestinationLocationId",
"ScheduledDate", "SourceDocument", "PurchaseOrderId", "BackorderOfId", "ReturnOfId", "CarrierId", "ResponsibleUserId", "ProjectId", "DeliveryPolicy",
"Status", "SourceApproverUserNames", "ApprovalUserName", "ApprovalStatus", "ApprovalDate", "ApprovalDescription", "CreationTime", "CreatorId", "IsDeleted")
"Status", "CreationTime", "CreatorId", "IsDeleted")
SELECT p_new_id, t."TenantId", t."BranchId", t."WarehouseId", t."OperationTypeId", t."OperationKind", t."PartnerId",
CASE WHEN v_is_return THEN t."DestinationLocationId" ELSE t."SourceLocationId" END,
CASE WHEN v_is_return THEN t."SourceLocationId" ELSE t."DestinationLocationId" END,
@ -16,7 +16,7 @@ BEGIN
CASE WHEN v_is_return THEN t."TransferNo" ELSE t."SourceDocument" END, t."PurchaseOrderId",
CASE WHEN v_is_return THEN NULL ELSE p_source_id END, CASE WHEN v_is_return THEN p_source_id END,
t."CarrierId", t."ResponsibleUserId", t."ProjectId", t."DeliveryPolicy",
'Draft', t."SourceApproverUserNames", t."ApprovalUserName", t."ApprovalStatus", t."ApprovalDate", t."ApprovalDescription", NOW() AT TIME ZONE 'UTC', p_user_id, false
'Draft', NOW() AT TIME ZONE 'UTC', p_user_id, false
FROM "Inv_T_Transfer" t
WHERE t."Id" = p_source_id;

View file

@ -23,8 +23,8 @@ BEGIN
RETURN;
END IF;
INSERT INTO "Inv_T_TransferLine" ("Id", "TenantId", "TransferId", "ProductId", "Description", "DemandQuantity", "Quantity", "UomId", "PurchaseOrderLineId", "CreationTime", "CreatorId", "IsDeleted")
SELECT gen_random_uuid(), l."TenantId", v_new, l."ProductId", l."Description", l."Quantity" - l."ReceivedQuantity", 0, l."UomId", l."Id", NOW() AT TIME ZONE 'UTC', p_user_id, false
INSERT INTO "Inv_T_TransferLine" ("Id", "TenantId", "TransferId", "ProductId", "Description", "DemandQuantity", "Quantity", "UomId", "PurchaseOrderLineId", "MaterialRequestItemId", "CreationTime", "CreatorId", "IsDeleted")
SELECT gen_random_uuid(), l."TenantId", v_new, l."ProductId", l."Description", l."Quantity" - l."ReceivedQuantity", 0, l."UomId", l."Id", l."MaterialRequestItemId", NOW() AT TIME ZONE 'UTC', p_user_id, false
FROM "Prc_T_PurchaseOrderLine" l
INNER JOIN "Inv_T_Product" p ON p."Id" = l."ProductId"
WHERE l."PurchaseOrderId" = p_order_id AND l."IsDeleted" = false AND p."TrackInventory" = true AND l."Quantity" > l."ReceivedQuantity";

View file

@ -1,17 +1,19 @@
-- Otomatik Ata: stoktan çıkan satırın lot dağılımını kaynak konumun stoğundan ilk giren ilk çıkar (InDate) sırasıyla yeniden kurar.
-- Otomatik Ata: stoktan çıkan satırın lot dağılımını kaynak konumun stoğundan ürün kategorisinin çıkış stratejisiyle yeniden kurar
-- (FIFO: ilk giren ilk çıkar, LIFO: son giren ilk çıkar — InDate, aynı anda girenlerde lot/seri no; kategorisiz ürün FIFO). Planlama'nın Öner'i aynı kuralı izler.
-- Stok yetmezse karşılanabilen kadar atanır; eksik Tamamla'da bildirilir.
CREATE OR REPLACE PROCEDURE public."Inv_P_TransferLineLotAssign"(p_id uuid, p_user_id uuid DEFAULT NULL)
LANGUAGE plpgsql AS $$
DECLARE v_tenant uuid; v_method varchar(16); v_src uuid; v_src_internal boolean; v_product uuid;
v_line_uom varchar(64); v_product_uom varchar(64); v_need numeric(18, 4);
v_line_uom varchar(64); v_product_uom varchar(64); v_need numeric(18, 4); v_strategy varchar(16);
BEGIN
SELECT l."TenantId", CASE WHEN p."TrackInventory" THEN p."TrackingMethod" END, t."SourceLocationId",
COALESCE(src."LocationType" = 'Internal', false), l."ProductId", l."UomId", p."UomId",
COALESCE(src."LocationType" = 'Internal', false), l."ProductId", l."UomId", p."UomId", COALESCE(pc."RemovalStrategy", 'FIFO'),
public."Inv_F_UomConvert"(CASE WHEN l."Quantity" > 0 THEN l."Quantity" ELSE l."DemandQuantity" END, l."UomId", p."UomId")
INTO v_tenant, v_method, v_src, v_src_internal, v_product, v_line_uom, v_product_uom, v_need
INTO v_tenant, v_method, v_src, v_src_internal, v_product, v_line_uom, v_product_uom, v_strategy, v_need
FROM "Inv_T_TransferLine" l
INNER JOIN "Inv_T_Transfer" t ON t."Id" = l."TransferId"
INNER JOIN "Inv_T_Product" p ON p."Id" = l."ProductId"
LEFT JOIN "Inv_T_ProductCategory" pc ON pc."Id" = p."CategoryId"
LEFT JOIN "Inv_T_Location" src ON src."Id" = t."SourceLocationId"
WHERE l."Id" = p_id;
@ -30,7 +32,11 @@ BEGIN
public."Inv_F_UomConvert"(LEAST(s."Quantity", v_need - s."Before"), v_product_uom, v_line_uom),
NOW() AT TIME ZONE 'UTC', p_user_id, false
FROM (SELECT "LotNo", "Quantity",
SUM("Quantity") OVER (ORDER BY "InDate", "LotNo" ROWS UNBOUNDED PRECEDING) - "Quantity" AS "Before"
SUM("Quantity") OVER (ORDER BY CASE WHEN v_strategy = 'LIFO' THEN NULL ELSE COALESCE("InDate", '9999-12-31') END NULLS FIRST,
CASE WHEN v_strategy = 'LIFO' THEN COALESCE("InDate", '1900-01-01') END DESC NULLS LAST,
CASE WHEN v_strategy = 'LIFO' THEN NULL ELSE "LotNo" END,
CASE WHEN v_strategy = 'LIFO' THEN "LotNo" END DESC NULLS LAST
ROWS UNBOUNDED PRECEDING) - "Quantity" AS "Before"
FROM "Inv_T_Stock"
WHERE "LocationId" = v_src AND "ProductId" = v_product AND "LotNo" <> '' AND "Quantity" > 0
AND "TenantId" IS NOT DISTINCT FROM v_tenant) s

View file

@ -1,20 +1,18 @@
-- Transfer belgesinin durum butonları: Confirm (Hazırla, taslakta), Check (Hazırla, bekleyende), Validate (Tamamla), Cancel (İptal Et), Return (İade Et).
CREATE OR REPLACE PROCEDURE public."Inv_P_TransferSetStatus"(p_id uuid, p_action varchar, p_user_id uuid DEFAULT NULL)
LANGUAGE plpgsql AS $$
DECLARE v_status varchar(16); v_kind varchar(32); v_approval varchar(50); v_src uuid; v_dst uuid; v_new uuid;
DECLARE v_status varchar(16); v_kind varchar(32); v_src uuid; v_dst uuid; v_new uuid;
BEGIN
SELECT "Status", "OperationKind", "ApprovalStatus", "SourceLocationId", "DestinationLocationId"
INTO v_status, v_kind, v_approval, v_src, v_dst
SELECT "Status", "OperationKind", "SourceLocationId", "DestinationLocationId"
INTO v_status, v_kind, v_src, v_dst
FROM "Inv_T_Transfer" WHERE "Id" = p_id;
UPDATE "Inv_T_Transfer" SET "PendingAction" = NULL WHERE "Id" = p_id;
-- İç transfer depo içinde taşımadır: iki uç da stok tutan iç konum ve birbirinden farklı olmalı (dış konuma giden mal stoktan düşer, hiçbir yere girmez).
-- İç transfer depo içinde taşımadır: iki uç da stok tutan iç konum olmalı (dış konuma giden mal stoktan düşer, hiçbir yere girmez).
-- Kaynak ve hedef aynı olabilir: stok zaten teslim konumundaki talebin teslimidir (Planlama'nın Stoktan kararı), Doğrula stoğa dokunmaz.
-- İade belgesi muaftır: yanlışlıkla dış konuma yapılmış transfer İade Et ile geri alınabilmeli.
IF v_kind = 'InternalTransfer' AND p_action IN ('Confirm', 'Check', 'Validate')
AND NOT EXISTS (SELECT 1 FROM "Inv_T_Transfer" WHERE "Id" = p_id AND "ReturnOfId" IS NOT NULL) THEN
IF v_src = v_dst THEN
RAISE EXCEPTION 'Kaynak ve hedef konum aynı olamaz.' USING ERRCODE = 'P0001', DETAIL = '50325';
END IF;
IF EXISTS (SELECT 1 FROM "Inv_T_Location" WHERE "Id" IN (v_src, v_dst) AND "LocationType" <> 'Internal') THEN
RAISE EXCEPTION 'İç transferde kaynak ve hedef konum iç konum olmalıdır.' USING ERRCODE = 'P0001', DETAIL = '50326';
END IF;
@ -30,15 +28,14 @@ BEGIN
IF v_src IS NULL OR v_dst IS NULL THEN
RAISE EXCEPTION 'Kaynak ve hedef konum seçilmelidir.' USING ERRCODE = 'P0001', DETAIL = '50303';
END IF;
IF v_kind = 'InternalTransfer' AND COALESCE(v_approval, '') NOT IN ('Onaylandı', 'Onay Gerekmez') THEN
RAISE EXCEPTION 'Kaynak depo onayı tamamlanmadan iç transfer hazırlanamaz.' USING ERRCODE = 'P0001', DETAIL = '50304';
END IF;
CALL public."Inv_P_TransferCheckAvailability"(p_id);
CALL public."Inv_P_TransferRecalc"(p_id);
ELSIF p_action = 'Check' THEN
IF v_status NOT IN ('Waiting', 'Ready') THEN
RAISE EXCEPTION 'Stok kontrolü yalnız bekleyen ya da hazır belgede yapılır.' USING ERRCODE = 'P0001', DETAIL = '50305';
END IF;
CALL public."Inv_P_TransferCheckAvailability"(p_id);
CALL public."Inv_P_TransferRecalc"(p_id);
ELSIF p_action = 'Validate' THEN
IF v_status <> 'Ready' THEN
RAISE EXCEPTION 'Yalnız hazır belge tamamlanabilir.' USING ERRCODE = 'P0001', DETAIL = '50306';
@ -55,6 +52,9 @@ BEGIN
IF v_status <> 'Done' THEN
RAISE EXCEPTION 'Yalnız tamamlanmış belge iade edilebilir.' USING ERRCODE = 'P0001', DETAIL = '50308';
END IF;
IF EXISTS (SELECT 1 FROM "Inv_T_Transfer" WHERE "Id" = p_id AND "ReturnOfId" IS NOT NULL) THEN
RAISE EXCEPTION 'İade belgesi yeniden iade edilemez; asıl belgeden yeni bir hareket açın.' USING ERRCODE = 'P0001', DETAIL = '50327';
END IF;
CALL public."Inv_P_TransferCopy"(p_id, 'Return', p_user_id, v_new);
END IF;
END;

View file

@ -1,5 +1,5 @@
-- Tamamla: yapılan miktarlar stoğa işlenir (Inv_T_Stock, ürün biriminde, lot kırılımlı). İç konumdan çıkışta stok yetmezse
-- işlem durur; dış konumlar stok tutmaz. Envanter takibi kapalı ürün stoğa girmez. Lot/seri takipli üründe lot toplamı
-- işlem durur; dış konumlar stok tutmaz. Kaynak ve hedefi aynı konum olan belge stoğa dokunmaz (teslim kaydıdır). Envanter takibi kapalı ürün stoğa girmez. Lot/seri takipli üründe lot toplamı
-- yapılan miktara eşit olmalıdır. Sipariş kalemlerinin alınan, talep kalemlerinin teslim edilen miktarı güncellenir (iadede düşülür);
-- siparişli alım ürün–tedarikçi fiyatını yazar (Inv_P_TransferSupplierPrice).
-- Talepten az yapılan satırların kalanı aynı türde yeni belgeye (backorder) geçer.
@ -83,12 +83,15 @@ BEGIN
RAISE EXCEPTION 'Kaynak konumda yeterli stok yok: %', v_msg USING ERRCODE = 'P0001', DETAIL = '50312';
END IF;
UPDATE "Inv_T_Stock" s SET "Quantity" = s."Quantity" - m."Quantity", "LastMoveDate" = v_now, "LastModificationTime" = v_now, "LastModifierId" = p_user_id
FROM tmp_inv_move m
WHERE m."ProductId" = s."ProductId" AND m."LotNo" = s."LotNo" AND s."LocationId" = v_src AND s."TenantId" IS NOT DISTINCT FROM v_tenant;
-- Kaynak ve hedef aynıysa stok yerinde kalır: belge teslimi kaydeder (yeterlilik yine denetlenir).
IF v_src <> v_dst THEN
UPDATE "Inv_T_Stock" s SET "Quantity" = s."Quantity" - m."Quantity", "LastMoveDate" = v_now, "LastModificationTime" = v_now, "LastModifierId" = p_user_id
FROM tmp_inv_move m
WHERE m."ProductId" = s."ProductId" AND m."LotNo" = s."LotNo" AND s."LocationId" = v_src AND s."TenantId" IS NOT DISTINCT FROM v_tenant;
END IF;
END IF;
IF v_dst_internal THEN
IF v_dst_internal AND v_src <> v_dst THEN
UPDATE "Inv_T_Stock" s SET "Quantity" = s."Quantity" + m."Quantity", "LastMoveDate" = v_now, "LastModificationTime" = v_now, "LastModifierId" = p_user_id,
"InDate" = CASE WHEN s."Quantity" <= 0 THEN v_now ELSE s."InDate" END
FROM tmp_inv_move m

View file

@ -0,0 +1,23 @@
-- Tamamlanmış hareket belgesinin stoğu belirleyen başlık alanları değiştirilemez (Alımlar, Teslimatlar, İç Transferler ve ortak sekmeleri):
-- stok eski konumda kalır, İade Et yeni konumdan düşmeye çalışırdı. Kural ekranın UpdateBeforeCommand'ında değil burada, çünkü durum
-- butonları yalnız PendingAction ile aynı güncelleme yolundan yazar. Açıklama, nakliye ve not alanları serbesttir;
-- satırların kuralı Transfer Satırları'nın Update/DeleteBeforeCommand'ındadır (50313).
CREATE OR REPLACE FUNCTION public."Inv_TR_TransferLock"() RETURNS trigger
LANGUAGE plpgsql AS $$
BEGIN
IF OLD."Status" = 'Done'
AND (NEW."Status", NEW."BranchId", NEW."WarehouseId", NEW."OperationTypeId", NEW."OperationKind", NEW."SourceLocationId",
NEW."DestinationLocationId", NEW."PartnerId", NEW."IsDeleted")
IS DISTINCT FROM
(OLD."Status", OLD."BranchId", OLD."WarehouseId", OLD."OperationTypeId", OLD."OperationKind", OLD."SourceLocationId",
OLD."DestinationLocationId", OLD."PartnerId", OLD."IsDeleted") THEN
RAISE EXCEPTION 'Tamamlanmış belgenin konumu, türü ve durumu değiştirilemez; düzeltme için İade Et kullanın.'
USING ERRCODE = 'P0001', DETAIL = '50328';
END IF;
RETURN NEW;
END;
$$;
DROP TRIGGER IF EXISTS "Inv_TR_TransferLock" ON public."Inv_T_Transfer";
CREATE TRIGGER "Inv_TR_TransferLock" BEFORE UPDATE ON public."Inv_T_Transfer"
FOR EACH ROW EXECUTE FUNCTION public."Inv_TR_TransferLock"();

View file

@ -4,6 +4,7 @@ CREATE TABLE IF NOT EXISTS public."Inv_T_ProductCategory"
"TenantId" uuid NULL,
"Name" varchar(128) NOT NULL,
"ParentId" uuid NULL,
"RemovalStrategy" varchar(16) NOT NULL DEFAULT 'FIFO',
"IsActive" boolean NOT NULL DEFAULT TRUE,
"CreationTime" timestamp NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'),
"CreatorId" uuid NULL,

View file

@ -28,11 +28,6 @@ CREATE TABLE IF NOT EXISTS public."Inv_T_Transfer"
"LineSummary" text NULL,
"Status" varchar(16) NOT NULL DEFAULT 'Draft',
"PendingAction" varchar(16) NULL,
"SourceApproverUserNames" varchar(512) NULL,
"ApprovalUserName" varchar(256) NULL,
"ApprovalStatus" varchar(50) NULL,
"ApprovalDate" timestamp NULL,
"ApprovalDescription" varchar(200) NULL,
"ReceivedByUserId" uuid NULL,
"ReceivedDate" timestamp NULL,
"CreationTime" timestamp NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'),

View file

@ -1,6 +1,7 @@
-- Transfer belgesinin talep kalemlerinin satır durumunu planla eşler (yeniden hesap ve iptal sonrası): kalanın tamamı iç transferle
-- planlanmış, satınalma payı olmayan bekleyen kalem kapanır (Tamamlandı); transfer iptal edilir, satırı silinir ya da eksik tamamlanıp kalanı
-- yeniden açılırsa kapalı kalem Bekliyor'a döner ve Planlama'da görünür. Silinmiş satırların kalemleri de kapsamdadır.
-- yeniden açılırsa kapalı kalem Bekliyor'a döner ve Planlama'da görünür. Silinmiş satırların kalemleri de kapsamdadır. Ardından
-- kalemlerin taleplerinin durumu yenilenir (teslim tamamlandıysa Tamamlandı; alım belgesi de buradan geçer).
CREATE OR REPLACE PROCEDURE public."Prc_P_MaterialRequestItemSync"(p_transfer_id uuid)
LANGUAGE plpgsql AS $$
BEGIN
@ -12,5 +13,7 @@ BEGIN
AND p."PurchaseQuantity" = 0
AND ((i."LineStatus" = 'Waiting' AND p."RemainingQuantity" <= 0)
OR (i."LineStatus" = 'Done' AND p."RemainingQuantity" > 0 AND i."DeliveredQuantity" < i."Quantity"));
CALL public."Prc_P_MaterialRequestSyncStatus"(p_transfer_id);
END;
$$;

View file

@ -3,17 +3,21 @@
-- Purchase: tedarikçinin talebin şubesi ve deposu için taslak teklif talebi varsa kalem ona eklenir (kalem zaten oradaysa miktarı artar), yoksa
-- talebin deposunun alım operasyon türüyle yeni taslak teklif talebi açılır (para birimi ve koşullar kontak kartından; alıcı — satınalma sorumlusu —
-- planlayan). Fiyat tedarikçinin fiyat listesinden gelir; teklif → sipariş → alım akışı oradan sürer.
-- Transfer: kaynak konumun serbest stoğu (Prc_V_MaterialRequestPlanSource) yetmelidir; aynı kaynak → talebin konumu için onaya
-- girmemiş taslak iç transfer varsa satır ona, yoksa kaynak deponun iç transfer operasyon türüyle yeni taslak açılır. Kalanın tamamı transferle
-- Transfer: kaynak konumun (lot/seri takipli üründe p_plan_lot_no lotunun) serbest stoğu (Prc_V_MaterialRequestPlanSource) yetmelidir; aynı
-- kaynak → talebin konumu için taslak iç transfer varsa satır ona, yoksa kaynak deponun iç transfer operasyon türüyle yeni
-- taslak açılır. Depoda aynı türden birkaç operasyon türü olabilir (Bakım Sarf Tüketimi, Departman Sarf Çıkışı …); türün kendi
-- numaratörünü taşıyanı (SequenceName '….InternalTransfer' / '….Receipt' ile biter) seçilir, taslak da yalnız o türde aranır. Lot planlandıysa transfer satırının lot dağılımına (Inv_T_TransferLineLot, satırın biriminde) eklenir; depo Detaylar ya da
-- Otomatik Ata ile değiştirebilir. Kalanın tamamı transferle
-- planlanan, satınalma payı olmayan kalem transfer belgesinin yeniden hesabında kapanır (Prc_P_MaterialRequestItemSync).
-- Stock: stok talebin teslim konumundadır; belge açılmaz, serbest stok yetmelidir. Miktar kalemin stoktan karşılanan ve teslim edilen
-- miktarına eklenir; satınalma payı olmayan ve kalanı biten kalem kapanır.
-- Stock: stok talebin teslim konumundadır; Transfer gibi iç transfer açılır, kaynak ve hedef teslim konumudur (Doğrula stoğa dokunmaz,
-- teslimi kaydeder: kalemin teslim edilen miktarı artar). Belge numarası ve durumu Plan Takibi'ne transferden yansır.
CREATE OR REPLACE PROCEDURE public."Prc_P_MaterialRequestPlan"(
p_id uuid,
p_plan_method varchar,
p_plan_quantity numeric(18, 4),
p_plan_supplier_id uuid,
p_plan_source_location_id uuid,
p_plan_lot_no varchar,
p_tenant_id uuid,
p_last_modifier_id uuid
)
@ -59,7 +63,8 @@ BEGIN
SELECT "Id" INTO v_op_type
FROM "Inv_T_OperationType"
WHERE "IsDeleted" = false AND "IsActive" = true AND "OperationKind" = 'Receipt' AND "WarehouseId" = v_warehouse
ORDER BY "Name"
AND "TenantId" IS NOT DISTINCT FROM p_tenant_id
ORDER BY CASE WHEN "SequenceName" LIKE '%.' || "OperationKind" THEN 0 ELSE 1 END, "Name"
LIMIT 1;
IF v_op_type IS NULL THEN
RAISE EXCEPTION 'Talebin deposu için aktif bir alım operasyon türü tanımlı değil.' USING ERRCODE = 'P0001', DETAIL = '50195';
@ -98,40 +103,43 @@ BEGIN
END IF;
CALL public."Prc_P_PurchaseRfqRecalc"(v_doc);
ELSIF p_plan_method = 'Transfer' THEN
ELSIF p_plan_method IN ('Transfer', 'Stock') THEN
IF p_plan_method = 'Stock' THEN
p_plan_source_location_id := v_location;
END IF;
IF p_plan_source_location_id IS NULL THEN
RAISE EXCEPTION 'İç transfer kararında kaynak konum seçilmelidir.' USING ERRCODE = 'P0001', DETAIL = '50196';
END IF;
-- Konum ve serbest stok kuralı diyaloğun İç Transfer ızgarasıyla aynıdır.
SELECT "WarehouseId", "FreeQuantity" INTO v_src_warehouse, v_free
FROM public."Prc_V_MaterialRequestPlanSource"
WHERE "BaseId" = p_id AND "LocationId" = p_plan_source_location_id;
IF v_src_warehouse IS NULL OR p_plan_source_location_id = v_location THEN
RAISE EXCEPTION 'Kaynak konum, talebin teslim konumundan farklı ve ürünün stoğu olan bir iç konum olmalıdır.' USING ERRCODE = 'P0001', DETAIL = '50197';
WHERE "BaseId" = p_id AND "LocationId" = p_plan_source_location_id AND COALESCE("LotNo", '') = COALESCE(p_plan_lot_no, '');
IF v_src_warehouse IS NULL OR (p_plan_method = 'Transfer' AND p_plan_source_location_id = v_location) THEN
RAISE EXCEPTION 'Kaynak konum, talebin teslim konumundan farklı ve ürünün (lot/seri takipli üründe lotun) stoğu olan bir iç konum olmalıdır.' USING ERRCODE = 'P0001', DETAIL = '50197';
END IF;
IF p_plan_quantity > v_free THEN
RAISE EXCEPTION 'Kaynak konumda yeterli serbest stok yok (serbest: % %).', trim_scale(GREATEST(v_free, 0)), v_uom USING ERRCODE = 'P0001', DETAIL = '50198';
END IF;
SELECT "Id" INTO v_op_type
FROM "Inv_T_OperationType"
WHERE "IsDeleted" = false AND "IsActive" = true AND "OperationKind" = 'InternalTransfer' AND "WarehouseId" = v_src_warehouse
AND "TenantId" IS NOT DISTINCT FROM p_tenant_id
ORDER BY CASE WHEN "SequenceName" LIKE '%.' || "OperationKind" THEN 0 ELSE 1 END, "Name"
LIMIT 1;
IF v_op_type IS NULL THEN
RAISE EXCEPTION 'Kaynak depo için aktif bir iç transfer operasyon türü tanımlı değil.' USING ERRCODE = 'P0001', DETAIL = '50199';
END IF;
SELECT "Id" INTO v_doc
FROM "Inv_T_Transfer"
WHERE "IsDeleted" = false AND "OperationKind" = 'InternalTransfer' AND "Status" = 'Draft' AND "ReturnOfId" IS NULL AND "BackorderOfId" IS NULL
WHERE "IsDeleted" = false AND "OperationTypeId" = v_op_type AND "Status" = 'Draft' AND "ReturnOfId" IS NULL AND "BackorderOfId" IS NULL
AND "SourceLocationId" = p_plan_source_location_id AND "DestinationLocationId" = v_location
AND COALESCE("ApprovalStatus", 'Onay Gerekmez') = 'Onay Gerekmez'
AND "TenantId" IS NOT DISTINCT FROM p_tenant_id
ORDER BY "CreationTime" DESC
LIMIT 1;
IF v_doc IS NULL THEN
SELECT "Id" INTO v_op_type
FROM "Inv_T_OperationType"
WHERE "IsDeleted" = false AND "IsActive" = true AND "OperationKind" = 'InternalTransfer' AND "WarehouseId" = v_src_warehouse
ORDER BY "Name"
LIMIT 1;
IF v_op_type IS NULL THEN
RAISE EXCEPTION 'Kaynak depo için aktif bir iç transfer operasyon türü tanımlı değil.' USING ERRCODE = 'P0001', DETAIL = '50199';
END IF;
v_doc := gen_random_uuid();
INSERT INTO "Inv_T_Transfer" ("Id", "TenantId", "BranchId", "WarehouseId", "OperationTypeId", "OperationKind", "SourceLocationId", "DestinationLocationId",
"SourceDocument", "ResponsibleUserId", "Status", "CreationTime", "CreatorId", "IsDeleted")
@ -145,34 +153,39 @@ BEGIN
WHERE "Id" = v_doc AND strpos(COALESCE("SourceDocument", ''), v_request_no) = 0;
END IF;
-- Planlanan miktar yapılacak miktardır: lotsuz satırda doğrudan yazılır, lotlu satırda lot dağılımından (Inv_P_TransferRecalc) gelir.
SELECT "Id" INTO v_line FROM "Inv_T_TransferLine" WHERE "TransferId" = v_doc AND "MaterialRequestItemId" = p_id AND "IsDeleted" = false LIMIT 1;
IF v_line IS NOT NULL THEN
UPDATE "Inv_T_TransferLine"
SET "DemandQuantity" = "DemandQuantity" + public."Inv_F_UomConvert"(p_plan_quantity, v_uom, "UomId"),
"Quantity" = "Quantity" + CASE WHEN COALESCE(p_plan_lot_no, '') = '' THEN public."Inv_F_UomConvert"(p_plan_quantity, v_uom, "UomId") ELSE 0 END,
"LastModificationTime" = NOW() AT TIME ZONE 'UTC', "LastModifierId" = p_last_modifier_id
WHERE "Id" = v_line;
ELSE
v_line := gen_random_uuid();
INSERT INTO "Inv_T_TransferLine" ("Id", "TenantId", "TransferId", "ProductId", "Description", "DemandQuantity", "Quantity", "UomId", "MaterialRequestItemId",
"CreationTime", "CreatorId", "IsDeleted")
VALUES (gen_random_uuid(), p_tenant_id, v_doc, v_product, v_reason, p_plan_quantity, 0, v_uom, p_id, NOW() AT TIME ZONE 'UTC', p_last_modifier_id, false);
VALUES (v_line, p_tenant_id, v_doc, v_product, v_reason, p_plan_quantity, CASE WHEN COALESCE(p_plan_lot_no, '') = '' THEN p_plan_quantity ELSE 0 END, v_uom, p_id,
NOW() AT TIME ZONE 'UTC', p_last_modifier_id, false);
END IF;
-- Numara, kaynak depo onaycısı ve yeniden hesap (kalemin kapanması dahil) belge kaydı sonrasıyla aynıdır.
IF COALESCE(p_plan_lot_no, '') <> '' THEN
UPDATE "Inv_T_TransferLineLot" ll
SET "Quantity" = ll."Quantity" + public."Inv_F_UomConvert"(p_plan_quantity, v_uom, tl."UomId"),
"LastModificationTime" = NOW() AT TIME ZONE 'UTC', "LastModifierId" = p_last_modifier_id
FROM "Inv_T_TransferLine" tl
WHERE tl."Id" = ll."TransferLineId" AND ll."TransferLineId" = v_line AND ll."LotNo" = p_plan_lot_no AND ll."IsDeleted" = false;
IF NOT FOUND THEN
INSERT INTO "Inv_T_TransferLineLot" ("Id", "TenantId", "TransferLineId", "LotNo", "Quantity", "CreationTime", "CreatorId", "IsDeleted")
SELECT gen_random_uuid(), p_tenant_id, tl."Id", p_plan_lot_no, public."Inv_F_UomConvert"(p_plan_quantity, v_uom, tl."UomId"),
NOW() AT TIME ZONE 'UTC', p_last_modifier_id, false
FROM "Inv_T_TransferLine" tl
WHERE tl."Id" = v_line;
END IF;
END IF;
-- Numara ve yeniden hesap (kalemin kapanması dahil) belge kaydı sonrasıyla aynıdır.
CALL public."Inv_P_TransferAfterSave"(v_doc, p_last_modifier_id);
ELSIF p_plan_method = 'Stock' THEN
SELECT "FreeQuantity" INTO v_free FROM public."Prc_V_MaterialRequestPlanSource" WHERE "BaseId" = p_id AND "LocationId" = v_location;
IF p_plan_quantity > COALESCE(v_free, 0) THEN
RAISE EXCEPTION 'Teslim konumunda yeterli serbest stok yok (serbest: % %).', trim_scale(GREATEST(COALESCE(v_free, 0), 0)), v_uom
USING ERRCODE = 'P0001', DETAIL = '50198';
END IF;
UPDATE "Prc_T_MaterialRequestItem"
SET "FromStockQuantity" = "FromStockQuantity" + p_plan_quantity, "DeliveredQuantity" = "DeliveredQuantity" + p_plan_quantity,
"LastModificationTime" = NOW() AT TIME ZONE 'UTC', "LastModifierId" = p_last_modifier_id
WHERE "Id" = p_id;
UPDATE "Prc_T_MaterialRequestItem" i SET "LineStatus" = 'Done'
FROM public."Prc_V_MaterialRequestItemPlan" p
WHERE p."Id" = i."Id" AND i."Id" = p_id AND p."PurchaseQuantity" = 0 AND p."RemainingQuantity" <= 0;
ELSE
RAISE EXCEPTION 'Karar Satınalma, İç Transfer ya da Stoktan olmalıdır.' USING ERRCODE = 'P0001', DETAIL = '50192';
END IF;

View file

@ -1,6 +1,5 @@
-- Planla diyaloğunun Onayla'sı (App.Prc.MaterialRequestPlan › UpdateCommand): talep kaleminin taslak planındaki her satırı
-- Prc_P_MaterialRequestPlan ile belgeye çevirir (iç transferler, stoktan karşılama, sonra teklif talepleri — stok payı kalemi transferlerden
-- sonra kapatabilsin) ve taslağı siler. Tek transaction'dır:
-- Prc_P_MaterialRequestPlan ile belgeye çevirir (önce iç transferler ve Stoktan, sonra teklif talepleri) ve taslağı siler. Tek transaction'dır:
-- bir satır reddedilirse (stok, kalan, operasyon türü) hiçbir belge açılmaz ve taslak yerinde kalır.
CREATE OR REPLACE PROCEDURE public."Prc_P_MaterialRequestPlanConfirm"(
p_id uuid,
@ -16,13 +15,13 @@ BEGIN
USING ERRCODE = 'P0001', DETAIL = '50201';
END IF;
FOR r IN SELECT "PlanMethod", "Quantity", "SupplierId", "SourceLocationId"
FOR r IN SELECT "PlanMethod", "Quantity", "SupplierId", "SourceLocationId", "LotNo"
FROM "Prc_T_MaterialRequestPlanLine"
WHERE "MaterialRequestItemId" = p_id AND "IsDeleted" = false
ORDER BY CASE "PlanMethod" WHEN 'Transfer' THEN 0 WHEN 'Stock' THEN 1 ELSE 2 END, "CreationTime"
LOOP
CALL public."Prc_P_MaterialRequestPlan"(p_id, r."PlanMethod", r."Quantity", r."SupplierId", r."SourceLocationId", p_tenant_id,
p_last_modifier_id);
CALL public."Prc_P_MaterialRequestPlan"(p_id, r."PlanMethod", r."Quantity", r."SupplierId", r."SourceLocationId", r."LotNo",
p_tenant_id, p_last_modifier_id);
END LOOP;
DELETE FROM "Prc_T_MaterialRequestPlanLine" WHERE "MaterialRequestItemId" = p_id;

View file

@ -1,10 +1,11 @@
-- Planla diyaloğunun İç Transfer (App.Prc.MaterialRequestPlanSource) ve Satınalma (App.Prc.MaterialRequestPlanVendor) ızgaralarının satır kaydı:
-- girilen Plan Miktarı kalemin taslak planına (Prc_T_MaterialRequestPlanLine) yazılır, 0 ya da boş satırı plandan çıkarır. p_id ızgara
-- satırının anahtarıdır: kalem + ':' + hedef (Transfer'de kaynak konum, Purchase'da tedarikçi). Kaynak talebin teslim konumuysa karar
-- Stock'tur (transfer açılmaz, stoktan karşılanır). Belge açılmaz; onay
-- Prc_P_MaterialRequestPlanConfirm'dedir. Taslak toplamı planlanacak kalanı, konumun satırı serbest stoğu aşamaz. Batch kaydı satırları
-- eşzamanlı gönderdiği için kalem kilitlenir. Eksi miktar "alabileceği en fazla"dır (Seçilenleri Planla): kalanın diğer taslak satırlardan
-- arta kalanı, konumda serbest stokla sınırlı; alınacak bir şey yoksa satır değişmez.
-- satırının anahtarıdır: kalem + ':' + hedef (Transfer'de kaynak konum + ':' + lot — takipsiz üründe lot boş —, Purchase'da tedarikçi).
-- Kaynak talebin teslim konumuysa karar Stock'tur (Stoktan: kaynağı ve hedefi aynı iç transfer açılır). Belge açılmaz; onay
-- Prc_P_MaterialRequestPlanConfirm'dedir. Taslak toplamı planlanacak kalanı, satır kullanılabilir stoğu (Prc_V_MaterialRequestPlanSource
-- .AvailableQuantity: lotun ve konumun serbest stoğu) aşamaz. Batch kaydı satırları eşzamanlı gönderdiği için kalem kilitlenir. Eksi miktar
-- "alabileceği en fazla"dır (Seçilenleri Planla, Öner): kalanın diğer taslak satırlardan arta kalanı, kullanılabilir stokla sınırlı;
-- alınacak bir şey yoksa satır değişmez.
CREATE OR REPLACE PROCEDURE public."Prc_P_MaterialRequestPlanLineSave"(
p_id varchar,
p_plan_method varchar,
@ -16,6 +17,7 @@ LANGUAGE plpgsql AS $$
DECLARE v_item uuid := left(p_id, 36)::uuid;
v_target uuid := substring(p_id from 38 for 36)::uuid;
v_qty numeric(18, 4) := COALESCE(p_plan_quantity, 0);
v_lot varchar(64) := CASE WHEN p_plan_method = 'Purchase' THEN '' ELSE COALESCE(substring(p_id from 75 for 64), '') END;
v_method varchar(16) := p_plan_method; v_location uuid;
v_uom varchar(64); v_remaining numeric(18, 4); v_other numeric(18, 4); v_free numeric(18, 4); v_line uuid;
BEGIN
@ -36,7 +38,7 @@ BEGIN
SELECT "Id" INTO v_line
FROM "Prc_T_MaterialRequestPlanLine"
WHERE "MaterialRequestItemId" = v_item AND "PlanMethod" = v_method AND "IsDeleted" = false
AND v_target = CASE WHEN v_method = 'Purchase' THEN "SupplierId" ELSE "SourceLocationId" END;
AND v_target = CASE WHEN v_method = 'Purchase' THEN "SupplierId" ELSE "SourceLocationId" END AND "LotNo" = v_lot;
IF v_qty = 0 THEN
DELETE FROM "Prc_T_MaterialRequestPlanLine" WHERE "Id" = v_line;
@ -50,7 +52,8 @@ BEGIN
IF v_qty < 0 THEN
v_qty := v_remaining - v_other;
IF v_method IN ('Transfer', 'Stock') THEN
SELECT "FreeQuantity" INTO v_free FROM public."Prc_V_MaterialRequestPlanSource" WHERE "BaseId" = v_item AND "LocationId" = v_target;
SELECT "AvailableQuantity" INTO v_free FROM public."Prc_V_MaterialRequestPlanSource"
WHERE "BaseId" = v_item AND "LocationId" = v_target AND COALESCE("LotNo", '') = v_lot;
IF v_free < v_qty THEN
v_qty := v_free;
END IF;
@ -65,12 +68,13 @@ BEGIN
END IF;
IF v_method IN ('Transfer', 'Stock') THEN
SELECT "FreeQuantity" INTO v_free FROM public."Prc_V_MaterialRequestPlanSource" WHERE "BaseId" = v_item AND "LocationId" = v_target;
SELECT "AvailableQuantity" INTO v_free FROM public."Prc_V_MaterialRequestPlanSource"
WHERE "BaseId" = v_item AND "LocationId" = v_target AND COALESCE("LotNo", '') = v_lot;
IF v_free IS NULL THEN
RAISE EXCEPTION 'Kaynak konum ürünün stoğu olan bir iç konum olmalıdır.' USING ERRCODE = 'P0001', DETAIL = '50197';
RAISE EXCEPTION 'Kaynak konum (lot/seri takipli üründe lot) ürünün stoğu olan bir iç konum olmalıdır.' USING ERRCODE = 'P0001', DETAIL = '50197';
END IF;
IF v_qty > v_free THEN
RAISE EXCEPTION 'Kaynak konumda yeterli serbest stok yok (serbest: % %).', trim_scale(GREATEST(v_free, 0)), v_uom USING ERRCODE = 'P0001', DETAIL = '50198';
RAISE EXCEPTION 'Kaynak konumda (lotta) yeterli serbest stok yok (kullanılabilir: % %).', trim_scale(GREATEST(v_free, 0)), v_uom USING ERRCODE = 'P0001', DETAIL = '50198';
END IF;
ELSIF v_method = 'Purchase' THEN
IF NOT EXISTS (SELECT 1 FROM public."Prc_V_MaterialRequestPlanVendor" WHERE "BaseId" = v_item AND "ContactId" = v_target) THEN
@ -86,9 +90,9 @@ BEGIN
WHERE "Id" = v_line;
ELSE
INSERT INTO "Prc_T_MaterialRequestPlanLine" ("Id", "TenantId", "MaterialRequestItemId", "PlanMethod", "SupplierId", "SourceLocationId",
"Quantity", "CreationTime", "CreatorId", "IsDeleted")
"LotNo", "Quantity", "CreationTime", "CreatorId", "IsDeleted")
VALUES (gen_random_uuid(), p_tenant_id, v_item, v_method, CASE WHEN v_method = 'Purchase' THEN v_target END,
CASE WHEN v_method <> 'Purchase' THEN v_target END, v_qty, NOW() AT TIME ZONE 'UTC', p_last_modifier_id, false);
CASE WHEN v_method <> 'Purchase' THEN v_target END, v_lot, v_qty, NOW() AT TIME ZONE 'UTC', p_last_modifier_id, false);
END IF;
END;
$$;

View file

@ -1,6 +1,7 @@
-- Planla diyaloğunun Öner'i (App.Prc.MaterialRequestPlanLine › InsertCommand):
-- kalemin taslak planını sıfırlayıp planlanacak kalanı dağıtır. Önce stok: teslim konumu (stoktan karşılama), sonra serbest stoğu en çok
-- olan konum (Prc_V_MaterialRequestPlanSource); kalan kısım satınalma: Prc_V_MaterialRequestPlanVendor'ın SuggestRank'ı ilk olan,
-- kalemin taslak planını sıfırlayıp planlanacak kalanı dağıtır. Önce stok, Prc_V_MaterialRequestPlanSource'un RemovalRank sırasıyla: teslim
-- konumu (stoktan karşılama), sonra ürün kategorisinin çıkış stratejisi (FIFO/LIFO); lot/seri takipli üründe lotlar da bu sırayla seçilir.
-- Her satır alabileceği en fazla miktarı alır (eksi miktar, kullanılabilir stok kuralı kayıt yordamındadır). Kalan kısım satınalma: Prc_V_MaterialRequestPlanVendor'ın SuggestRank'ı ilk olan,
-- fiyat listesinde ya da alım geçmişinde bulunan tedarikçi (hiç bilinmeyen kontak seçilmez, kalan planlanmadan kalır). Satırlar
-- Prc_P_MaterialRequestPlanLineSave ile yazılır; kalem, stok ve kalan kuralları oradadır.
CREATE OR REPLACE PROCEDURE public."Prc_P_MaterialRequestPlanSuggest"(
@ -9,21 +10,24 @@ CREATE OR REPLACE PROCEDURE public."Prc_P_MaterialRequestPlanSuggest"(
p_last_modifier_id uuid
)
LANGUAGE plpgsql AS $$
DECLARE v_left numeric(18, 4); v_qty numeric(18, 4); v_key varchar(80); s record;
DECLARE v_left numeric(18, 4); v_key varchar(160); s record;
BEGIN
DELETE FROM "Prc_T_MaterialRequestPlanLine" WHERE "MaterialRequestItemId" = p_id AND "TenantId" IS NOT DISTINCT FROM p_tenant_id;
SELECT COALESCE("RemainingQuantity", 0) INTO v_left FROM public."Prc_V_MaterialRequestItemPlan" WHERE "Id" = p_id;
v_left := COALESCE(v_left, 0);
FOR s IN SELECT "Id", "FreeQuantity"
FOR s IN SELECT "Id"
FROM public."Prc_V_MaterialRequestPlanSource"
WHERE "BaseId" = p_id AND "FreeQuantity" > 0
ORDER BY "IsDestination" DESC, "FreeQuantity" DESC
ORDER BY "RemovalRank"
LOOP
EXIT WHEN v_left <= 0;
v_qty := LEAST(s."FreeQuantity", v_left);
CALL public."Prc_P_MaterialRequestPlanLineSave"(s."Id", 'Transfer', v_qty, p_tenant_id, p_last_modifier_id);
v_left := v_left - v_qty;
CALL public."Prc_P_MaterialRequestPlanLineSave"(s."Id", 'Transfer', -1, p_tenant_id, p_last_modifier_id);
SELECT COALESCE(ip."RemainingQuantity", 0) - COALESCE((SELECT SUM(x."Quantity") FROM "Prc_T_MaterialRequestPlanLine" x
WHERE x."MaterialRequestItemId" = p_id AND x."IsDeleted" = false), 0)
INTO v_left
FROM public."Prc_V_MaterialRequestItemPlan" ip
WHERE ip."Id" = p_id;
END LOOP;
IF v_left > 0 THEN

View file

@ -1,24 +0,0 @@
-- Plan Takibi'nin Geri Al'ı (App.Prc.MaterialRequestPlanTrack › UpdateCommand): stoktan karşılamayı geri alır. Stoktan karşılama belge
-- açmadığı için geri dönüşü kalemin kendisidir: stoktan karşılanan miktar teslim edilenden düşülür ve sıfırlanır, kalanı yeniden açılan
-- kapalı kalem Bekliyor'a döner ve Planlama'da yeniden planlanır (Prc_P_MaterialRequestItemSync ile aynı kural).
CREATE OR REPLACE PROCEDURE public."Prc_P_MaterialRequestStockUndo"(
p_id uuid,
p_tenant_id uuid,
p_last_modifier_id uuid
)
LANGUAGE plpgsql AS $$
BEGIN
UPDATE "Prc_T_MaterialRequestItem"
SET "DeliveredQuantity" = GREATEST("DeliveredQuantity" - "FromStockQuantity", 0),
"FromStockQuantity" = 0, "LastModificationTime" = NOW() AT TIME ZONE 'UTC', "LastModifierId" = p_last_modifier_id
WHERE "Id" = p_id AND "IsDeleted" = false AND "FromStockQuantity" > 0 AND "LineStatus" IN ('Waiting', 'Done')
AND "TenantId" IS NOT DISTINCT FROM p_tenant_id;
IF NOT FOUND THEN
RAISE EXCEPTION 'Geri alınacak stoktan karşılama yok ya da kalem kapatılmış.' USING ERRCODE = 'P0001', DETAIL = '50202';
END IF;
UPDATE "Prc_T_MaterialRequestItem" i SET "LineStatus" = 'Waiting'
FROM public."Prc_V_MaterialRequestItemPlan" p
WHERE p."Id" = i."Id" AND i."Id" = p_id AND i."LineStatus" = 'Done' AND p."RemainingQuantity" > 0 AND i."DeliveredQuantity" < i."Quantity";
END;
$$;

View file

@ -1,8 +1,9 @@
-- Onaylanan talebin durumu satınalmada ilerledikçe iş akışının durum alanında devam eder: kalemlerinden biri
-- Onaylanan talebin durumu satınalmada ilerledikçe iş akışının durum alanında devam eder: iptal olmayan bütün kalemleri
-- teslim edildiyse (teslim edilen ≥ istenen: iç transfer, Stoktan ya da alım Doğrula'sıyla) Tamamlandı; değilse kalemlerinden biri
-- iptal olmayan bir siparişteyse Satınalma Siparişi, gönderilmiş teklif talebindeyse Teklif Talebi Gönderildi,
-- taslak teklif talebindeyse Teklif Talebi; hiçbirinde değilse Onaylandı'ya döner. Akış "Onaylandı"da bittiği
-- için bu değerler hiçbir onay düğümüyle eşleşmez ve akış butonları kapalı kalır. p_doc_id verilirse yalnız o
-- belgenin (teklifte bütün ihalenin) kalemlerine bağlı talepler; boşsa onaylanmış bütün talepler yeniden hesaplanır.
-- taslak teklif talebindeyse Teklif Talebi; hiçbirinde değilse Onaylandı'ya döner (iade teslimi geri alırsa Tamamlandı da geri döner).
-- Akış "Onaylandı"da bittiği için bu değerler hiçbir onay düğümüyle eşleşmez ve akış butonları kapalı kalır. p_doc_id verilirse yalnız o
-- belgenin (teklifte bütün ihalenin; transferde satırlarının) kalemlerine bağlı talepler; boşsa onaylanmış bütün talepler yeniden hesaplanır.
CREATE OR REPLACE PROCEDURE public."Prc_P_MaterialRequestSyncStatus"(p_doc_id uuid DEFAULT NULL)
LANGUAGE plpgsql AS $$
DECLARE v_group uuid;
@ -17,6 +18,11 @@ BEGIN
UPDATE "Prc_T_MaterialRequest" m SET "ApprovalStatus" = s.stage
FROM (SELECT r."Id", CASE
WHEN NOT EXISTS (SELECT 1 FROM "Prc_T_MaterialRequestItem" i
WHERE i."MaterialRequestId" = r."Id" AND i."IsDeleted" = false AND i."LineStatus" <> 'Cancelled'
AND i."DeliveredQuantity" < i."Quantity")
AND EXISTS (SELECT 1 FROM "Prc_T_MaterialRequestItem" i
WHERE i."MaterialRequestId" = r."Id" AND i."IsDeleted" = false AND i."LineStatus" <> 'Cancelled') THEN 'Tamamlandı'
WHEN EXISTS (SELECT 1 FROM "Prc_T_MaterialRequestItem" i
INNER JOIN "Prc_T_PurchaseOrderLine" ol ON ol."MaterialRequestItemId" = i."Id" AND ol."IsDeleted" = false
INNER JOIN "Prc_T_PurchaseOrder" o ON o."Id" = ol."PurchaseOrderId" AND o."IsDeleted" = false AND o."Status" <> 'Cancelled'
@ -32,7 +38,7 @@ BEGIN
ELSE 'Onaylandı' END AS stage
FROM "Prc_T_MaterialRequest" r
WHERE r."IsDeleted" = false
AND r."ApprovalStatus" IN ('Onaylandı', 'Teklif Talebi', 'Teklif Talebi Gönderildi', 'Satınalma Siparişi')
AND r."ApprovalStatus" IN ('Onaylandı', 'Teklif Talebi', 'Teklif Talebi Gönderildi', 'Satınalma Siparişi', 'Tamamlandı')
-- Silinen satır da kapsamda kalır: kalemi belgeden çıkarılan talep geri dönmelidir.
AND (p_doc_id IS NULL OR EXISTS (
SELECT 1 FROM "Prc_T_MaterialRequestItem" i
@ -41,7 +47,9 @@ BEGIN
INNER JOIN "Prc_T_PurchaseRfq" q ON q."Id" = rl."PurchaseRfqId"
WHERE rl."MaterialRequestItemId" = i."Id" AND COALESCE(q."TenderGroupId", q."Id") = v_group)
OR EXISTS (SELECT 1 FROM "Prc_T_PurchaseOrderLine" ol
WHERE ol."MaterialRequestItemId" = i."Id" AND ol."PurchaseOrderId" = p_doc_id))))) s
WHERE ol."MaterialRequestItemId" = i."Id" AND ol."PurchaseOrderId" = p_doc_id)
OR EXISTS (SELECT 1 FROM "Inv_T_TransferLine" tl
WHERE tl."MaterialRequestItemId" = i."Id" AND tl."TransferId" = p_doc_id))))) s
WHERE m."Id" = s."Id" AND m."ApprovalStatus" <> s.stage;
END;
$$;

View file

@ -9,7 +9,6 @@ CREATE TABLE IF NOT EXISTS public."Prc_T_MaterialRequestItem"
"DueDate" date NOT NULL,
"RequestReason" varchar(256) NOT NULL,
"DeliveredQuantity" numeric(18, 4) NOT NULL DEFAULT 0,
"FromStockQuantity" numeric(18, 4) NOT NULL DEFAULT 0,
"LineStatus" varchar(16) NOT NULL DEFAULT 'Waiting',
"CreationTime" timestamp NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'),
"CreatorId" uuid NULL,

View file

@ -1,5 +1,5 @@
-- Planla diyaloğunun taslak karşılama planı: talep kaleminin onaylanmamış dağıtımı (iç transfer: kaynak konum, satınalma: tedarikçi) ve
-- miktarı. Onay (Prc_P_MaterialRequestPlanConfirm) satırları teklif talebine ya da iç transfere çevirir ve siler.
-- miktarı. İç transferde lot/seri takipli ürünün satırı lotu da taşır (LotNo; takipsiz üründe boş). Onay (Prc_P_MaterialRequestPlanConfirm) satırları teklif talebine ya da iç transfere çevirir ve siler.
CREATE TABLE IF NOT EXISTS public."Prc_T_MaterialRequestPlanLine"
(
"Id" uuid NOT NULL DEFAULT gen_random_uuid(),
@ -8,6 +8,7 @@ CREATE TABLE IF NOT EXISTS public."Prc_T_MaterialRequestPlanLine"
"PlanMethod" varchar(16) NOT NULL,
"SupplierId" uuid NULL,
"SourceLocationId" uuid NULL,
"LotNo" varchar(64) NOT NULL DEFAULT '',
"Quantity" numeric(18, 4) NOT NULL DEFAULT 0,
"CreationTime" timestamp NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'),
"CreatorId" uuid NULL,

View file

@ -1,13 +1,11 @@
-- Talep kaleminin planlanmış payları ve planlanacak kalanı (Planlama, Plan Takibi, kalem durumu). Miktarlar kalemin birimine çevrilir.
-- Satınalma payı: teklif aşamasındaki teklif talebinde ya da iptal olmayan siparişe geçmiş teklif kaleminde duran miktar; ihale aynı kalemi
-- bütün tedarikçilere kopyaladığı için ihale × ihale kalemi başına bir kez (en büyüğü) sayılır.
-- Transfer payı: iptal olmayan iç transfer satırı — tamamlanmış belgede yapılan, açık belgede istenen miktar (eksik tamamlanan belgenin kalanı
-- backorder belgesinde istenir); iade belgesi sayılmaz.
-- Stok payı: stok talebin teslim konumundayken onaylanan, belgesiz karşılanan miktar (FromStockQuantity).
-- Transfer payı (Stoktan kararı dahil — kaynak ve hedefi teslim konumu olan transfer): iptal olmayan iç transfer satırı — tamamlanmış belgede yapılan, açık belgede istenen miktar (eksik tamamlanan belgenin kalanı
-- backorder belgesinde istenir); tamamlanmış iade belgesinin yapılan miktarı paydan düşer (iade edilen kalem yeniden planlanır).
CREATE OR REPLACE VIEW public."Prc_V_MaterialRequestItemPlan" AS
SELECT i."Id", i."TenantId", COALESCE(pq."Quantity", 0) AS "PurchaseQuantity", COALESCE(tq."Quantity", 0) AS "TransferQuantity",
i."Quantity" - COALESCE(pq."Quantity", 0) - COALESCE(tq."Quantity", 0) - i."FromStockQuantity" AS "RemainingQuantity",
i."FromStockQuantity"
i."Quantity" - COALESCE(pq."Quantity", 0) - COALESCE(tq."Quantity", 0) AS "RemainingQuantity"
FROM "Prc_T_MaterialRequestItem" i
LEFT JOIN LATERAL (
SELECT SUM(g."Quantity") AS "Quantity"
@ -23,9 +21,10 @@ SELECT i."Id", i."TenantId", COALESCE(pq."Quantity", 0) AS "PurchaseQuantity", C
AND o."IsDeleted" = false AND o."Status" <> 'Cancelled')))
GROUP BY COALESCE(q."TenderGroupId", q."Id"), COALESCE(rl."TenderLineId", rl."Id")) g) pq ON true
LEFT JOIN LATERAL (
SELECT SUM(public."Inv_F_UomConvert"(CASE WHEN t."Status" = 'Done' THEN tl."Quantity" ELSE tl."DemandQuantity" END, tl."UomId", i."UomId")) AS "Quantity"
SELECT SUM(public."Inv_F_UomConvert"(CASE WHEN t."ReturnOfId" IS NOT NULL THEN CASE WHEN t."Status" = 'Done' THEN -tl."Quantity" ELSE 0 END
WHEN t."Status" = 'Done' THEN tl."Quantity" ELSE tl."DemandQuantity" END, tl."UomId", i."UomId")) AS "Quantity"
FROM "Inv_T_TransferLine" tl
INNER JOIN "Inv_T_Transfer" t ON t."Id" = tl."TransferId"
WHERE tl."MaterialRequestItemId" = i."Id" AND tl."IsDeleted" = false AND t."IsDeleted" = false
AND t."OperationKind" = 'InternalTransfer' AND t."Status" <> 'Cancelled' AND t."ReturnOfId" IS NULL) tq ON true
AND t."OperationKind" = 'InternalTransfer' AND t."Status" <> 'Cancelled') tq ON true
WHERE i."IsDeleted" = false;

View file

@ -1,8 +1,8 @@
-- Planla diyaloğunun Karşılama Planı ızgarası (App.Prc.MaterialRequestPlanLine): talep kaleminin onay bekleyen taslak planı. Miktar kalemin
-- biriminde; satınalmada birim fiyat teklif kalemine yazılacak fiyattır (tedarikçinin en düşük minimum miktarlı satırı). BaseId kalemdir.
-- biriminde; iç transferde lot/seri takipli ürünün lotu (LotNo); satınalmada birim fiyat teklif kalemine yazılacak fiyattır (tedarikçinin en düşük minimum miktarlı satırı). BaseId kalemdir.
CREATE OR REPLACE VIEW public."Prc_V_MaterialRequestPlanLine" AS
SELECT pl."Id", pl."TenantId", pl."MaterialRequestItemId" AS "BaseId", pl."PlanMethod", pl."SupplierId", pl."SourceLocationId", pl."Quantity",
i."UomId", ps."Price", ps."CurrencyId", pl."CreationTime", pl."CreatorId", pl."IsDeleted"
i."UomId", ps."Price", ps."CurrencyId", pl."CreationTime", pl."CreatorId", pl."IsDeleted", NULLIF(pl."LotNo", '') AS "LotNo"
FROM "Prc_T_MaterialRequestPlanLine" pl
INNER JOIN "Prc_T_MaterialRequestItem" i ON i."Id" = pl."MaterialRequestItemId"
LEFT JOIN LATERAL (SELECT x."Price", x."CurrencyId"

View file

@ -1,34 +1,80 @@
-- Planla diyaloğunun İç Transfer ızgarası (App.Prc.MaterialRequestPlanSource) ve iç transfer / stoktan karşılama kararlarının stok kuralı:
-- talep kaleminin ürününün stoğu olan iç konumlar. Talebin teslim konumu da listelenir (IsDestination): oraya yazılan plan transfer açmaz,
-- stoktan karşılanır (PlanMethod = Stock). Miktarlar kalemin biriminde; ayrılan = açık (Taslak/Bekleyen/Hazır) transferlerde o
-- konumdan istenen, serbest = eldeki − ayrılan. Plan Miktarı kalemin bu konum için taslak planıdır. BaseId diyaloğun süzdüğü kalem, Id
-- kalem + ':' + konumdur (Prc_P_MaterialRequestPlanLineSave ayırır); taslak kaydı ve onay serbest stoğu buradan okur.
-- MaxQuantity satıra yazılabilecek en fazla plan miktarıdır: serbest stok ile planlanacak kalandan kalemin diğer taslak satırları
-- düşüldükten sonra kalanın küçüğü (ızgaranın doğrulaması; kayıt yordamı aynı kuralı yeniden denetler).
CREATE OR REPLACE VIEW public."Prc_V_MaterialRequestPlanSource" AS
SELECT CAST(i."Id" AS varchar(36)) || ':' || CAST(st."LocationId" AS varchar(36)) AS "Id", i."TenantId", i."Id" AS "BaseId",
l."BranchId", l."WarehouseId", st."LocationId", st."OnHand", COALESCE(rs."Quantity", 0) AS "ReservedQuantity",
st."OnHand" - COALESCE(rs."Quantity", 0) AS "FreeQuantity", i."UomId", pl."Quantity" AS "PlanQuantity", i."IsDeleted",
st."LocationId" = r."LocationId" AS "IsDestination",
GREATEST(0, LEAST(st."OnHand" - COALESCE(rs."Quantity", 0), ip."RemainingQuantity" - COALESCE(od."Quantity", 0))) AS "MaxQuantity"
FROM "Prc_T_MaterialRequestItem" i
INNER JOIN "Prc_T_MaterialRequest" r ON r."Id" = i."MaterialRequestId"
CROSS JOIN LATERAL (SELECT s."LocationId", SUM(public."Inv_F_UomConvert"(s."Quantity", s."UomId", i."UomId")) AS "OnHand"
FROM "Inv_T_Stock" s
WHERE s."ProductId" = i."ProductId" AND s."IsDeleted" = false
GROUP BY s."LocationId"
HAVING SUM(s."Quantity") > 0) st
INNER JOIN "Inv_T_Location" l ON l."Id" = st."LocationId" AND l."LocationType" = 'Internal' AND l."IsDeleted" = false
LEFT JOIN LATERAL (SELECT SUM(public."Inv_F_UomConvert"(tl."DemandQuantity", tl."UomId", i."UomId")) AS "Quantity"
FROM "Inv_T_TransferLine" tl
INNER JOIN "Inv_T_Transfer" t ON t."Id" = tl."TransferId"
WHERE t."SourceLocationId" = st."LocationId" AND tl."ProductId" = i."ProductId" AND tl."IsDeleted" = false
AND t."IsDeleted" = false AND t."Status" IN ('Draft', 'Waiting', 'Ready')) rs ON TRUE
-- talep kaleminin ürününün stoğu olan iç konumlar. Ürün lot/seri ile takip ediliyorsa satır konum × lottur (seride her seri ayrı satır), yoksa
-- konum başına tek satırdır (LotNo boş). Talebin teslim konumu da listelenir (IsDestination): oraya yazılan plan Stoktan kararıdır (PlanMethod =
-- Stock; kaynağı ve hedefi teslim konumu olan iç transfer açar). Miktarlar kalemin biriminde; ayrılan = açık (Taslak/Bekleyen/Hazır) transferlerde o konumdan istenen
-- (lot satırında o lota atanmış), serbest = eldeki − ayrılan, lot satırında konumun serbest stoğuyla sınırlı (lotu henüz atanmamış istek de
-- konumdan düşer). Plan Miktarı kalemin bu satır için taslak planıdır. BaseId diyaloğun süzdüğü kalem, Id kalem + ':' + konum + ':' + lottur
-- (Prc_P_MaterialRequestPlanLineSave ayırır); taslak kaydı ve onay serbest stoğu buradan okur.
-- AvailableQuantity satırın taslak planda kullanabileceği stoktur (aynı konumun diğer lotlarına yazılmış taslak konumdan düşer);
-- MaxQuantity bununla planlanacak kalandan kalemin diğer taslak satırları düşüldükten sonra kalanın küçüğüdür (ızgaranın doğrulaması; kayıt
-- yordamı aynı kuralı yeniden denetler). RemovalRank Öner'in ve Seçilenleri Planla'nın sırasıdır: teslim konumu önce, sonra ürün
-- kategorisinin çıkış stratejisi (FIFO: en eski giriş, LIFO: en yeni giriş; aynı anda girenlerde lot/seri no — LIFO'da büyükten; kategorisiz ürün FIFO).
DROP VIEW IF EXISTS public."Prc_V_MaterialRequestPlanSource";
CREATE VIEW public."Prc_V_MaterialRequestPlanSource" AS
WITH it AS (
SELECT i."Id", i."TenantId", i."ProductId", i."UomId", i."IsDeleted", r."LocationId" AS "DestinationId",
p."TrackInventory" AND p."TrackingMethod" IN ('Lot', 'Serial') AS "IsTracked",
COALESCE(pc."RemovalStrategy", 'FIFO') AS "RemovalStrategy"
FROM "Prc_T_MaterialRequestItem" i
INNER JOIN "Prc_T_MaterialRequest" r ON r."Id" = i."MaterialRequestId"
INNER JOIN "Inv_T_Product" p ON p."Id" = i."ProductId"
LEFT JOIN "Inv_T_ProductCategory" pc ON pc."Id" = p."CategoryId"
WHERE i."IsDeleted" = false),
st AS (
SELECT it."Id" AS "ItemId", s."LocationId", CASE WHEN it."IsTracked" THEN s."LotNo" ELSE '' END AS "LotNo",
SUM(public."Inv_F_UomConvert"(s."Quantity", s."UomId", it."UomId")) AS "OnHand", MIN(s."InDate") AS "FirstIn",
MAX(s."InDate") AS "LastIn"
FROM it
INNER JOIN "Inv_T_Stock" s ON s."ProductId" = it."ProductId" AND s."IsDeleted" = false
GROUP BY it."Id", s."LocationId", CASE WHEN it."IsTracked" THEN s."LotNo" ELSE '' END
HAVING SUM(s."Quantity") > 0),
rs AS (
SELECT it."Id" AS "ItemId", t."SourceLocationId" AS "LocationId",
SUM(public."Inv_F_UomConvert"(tl."DemandQuantity", tl."UomId", it."UomId")) AS "Quantity"
FROM it
INNER JOIN "Inv_T_TransferLine" tl ON tl."ProductId" = it."ProductId" AND tl."IsDeleted" = false
INNER JOIN "Inv_T_Transfer" t ON t."Id" = tl."TransferId" AND t."IsDeleted" = false AND t."Status" IN ('Draft', 'Waiting', 'Ready')
GROUP BY it."Id", t."SourceLocationId"),
lr AS (
SELECT it."Id" AS "ItemId", t."SourceLocationId" AS "LocationId", tll."LotNo",
SUM(public."Inv_F_UomConvert"(tll."Quantity", tl."UomId", it."UomId")) AS "Quantity"
FROM it
INNER JOIN "Inv_T_TransferLine" tl ON tl."ProductId" = it."ProductId" AND tl."IsDeleted" = false
INNER JOIN "Inv_T_Transfer" t ON t."Id" = tl."TransferId" AND t."IsDeleted" = false AND t."Status" IN ('Draft', 'Waiting', 'Ready')
INNER JOIN "Inv_T_TransferLineLot" tll ON tll."TransferLineId" = tl."Id" AND tll."IsDeleted" = false
WHERE it."IsTracked"
GROUP BY it."Id", t."SourceLocationId", tll."LotNo"),
b AS (
SELECT st."ItemId", st."LocationId", st."LotNo", st."OnHand", st."FirstIn", st."LastIn",
CASE WHEN it."IsTracked" THEN COALESCE(lr."Quantity", 0) ELSE COALESCE(rs."Quantity", 0) END AS "Reserved",
SUM(st."OnHand") OVER (PARTITION BY st."ItemId", st."LocationId") - COALESCE(rs."Quantity", 0) AS "LocationFree"
FROM st
INNER JOIN it ON it."Id" = st."ItemId"
LEFT JOIN rs ON rs."ItemId" = st."ItemId" AND rs."LocationId" = st."LocationId"
LEFT JOIN lr ON lr."ItemId" = st."ItemId" AND lr."LocationId" = st."LocationId" AND lr."LotNo" = st."LotNo")
SELECT CAST(it."Id" AS varchar(36)) || ':' || CAST(b."LocationId" AS varchar(36)) || ':' || b."LotNo" AS "Id", it."TenantId", it."Id" AS "BaseId",
l."BranchId", l."WarehouseId", b."LocationId", NULLIF(b."LotNo", '') AS "LotNo", b."OnHand", b."Reserved" AS "ReservedQuantity",
fr."Quantity" AS "FreeQuantity", it."UomId", pl."Quantity" AS "PlanQuantity", it."IsDeleted",
b."LocationId" = it."DestinationId" AS "IsDestination",
GREATEST(0, LEAST(av."Quantity", ip."RemainingQuantity" - COALESCE(od."Total", 0))) AS "MaxQuantity",
av."Quantity" AS "AvailableQuantity",
ROW_NUMBER() OVER (PARTITION BY it."Id"
ORDER BY CASE WHEN b."LocationId" = it."DestinationId" THEN 0 ELSE 1 END,
CASE WHEN it."RemovalStrategy" = 'LIFO' THEN NULL ELSE COALESCE(b."FirstIn", '9999-12-31') END,
CASE WHEN it."RemovalStrategy" = 'LIFO' THEN COALESCE(b."LastIn", '1900-01-01') END DESC NULLS LAST,
fr."Quantity" DESC,
CASE WHEN it."RemovalStrategy" = 'LIFO' THEN NULL ELSE b."LotNo" END,
CASE WHEN it."RemovalStrategy" = 'LIFO' THEN b."LotNo" END DESC NULLS LAST) AS "RemovalRank"
FROM b
INNER JOIN it ON it."Id" = b."ItemId"
INNER JOIN "Inv_T_Location" l ON l."Id" = b."LocationId" AND l."LocationType" = 'Internal' AND l."IsDeleted" = false
INNER JOIN public."Prc_V_MaterialRequestItemPlan" ip ON ip."Id" = it."Id"
LEFT JOIN "Prc_T_MaterialRequestPlanLine" pl
ON pl."MaterialRequestItemId" = i."Id" AND pl."PlanMethod" IN ('Transfer', 'Stock') AND pl."SourceLocationId" = st."LocationId" AND pl."IsDeleted" = false
INNER JOIN public."Prc_V_MaterialRequestItemPlan" ip ON ip."Id" = i."Id"
LEFT JOIN LATERAL (SELECT SUM(x."Quantity") AS "Quantity"
ON pl."MaterialRequestItemId" = it."Id" AND pl."PlanMethod" IN ('Transfer', 'Stock') AND pl."SourceLocationId" = b."LocationId"
AND pl."LotNo" = b."LotNo" AND pl."IsDeleted" = false
LEFT JOIN LATERAL (SELECT SUM(x."Quantity") AS "Total",
SUM(CASE WHEN x."SourceLocationId" = b."LocationId" THEN x."Quantity" ELSE 0 END) AS "SameLocation"
FROM "Prc_T_MaterialRequestPlanLine" x
WHERE x."MaterialRequestItemId" = i."Id" AND x."IsDeleted" = false
AND (x."SourceLocationId" IS NULL OR x."SourceLocationId" <> st."LocationId")) od ON TRUE
WHERE i."IsDeleted" = false;
WHERE x."MaterialRequestItemId" = it."Id" AND x."IsDeleted" = false AND x."Id" IS DISTINCT FROM pl."Id") od ON TRUE
CROSS JOIN LATERAL (SELECT LEAST(b."OnHand" - b."Reserved", b."LocationFree") AS "Quantity") fr
CROSS JOIN LATERAL (SELECT LEAST(fr."Quantity", b."LocationFree" - COALESCE(od."SameLocation", 0)) AS "Quantity") av;

View file

@ -1,7 +1,7 @@
-- Plan Takibi (App.Prc.MaterialRequestPlanTrack): talep kalemleri için verilen her karar — satınalmada ihalenin kök teklif talebindeki kalem
-- (alternatif tedarikçilere kopyalanan satırlar tekrar listelenmez; siparişe dönüştüyse ihale kaleminin siparişi ve tedarikçisi), iç
-- transferde transfer satırı, stoktan karşılamada kalemin kendisi (belgesiz; konum talebin teslim konumu). Gerçekleşen: siparişte alınan,
-- transferde tamamlanmış belgede yapılan, stokta karşılanan miktar.
-- transferde transfer satırı; kaynak ve hedefi aynı (teslim konumu) olan transfer Stoktan kararıdır. Gerçekleşen: siparişte alınan,
-- transferde tamamlanmış belgede yapılan miktar.
CREATE OR REPLACE VIEW public."Prc_V_MaterialRequestPlanTrack" AS
SELECT rl."Id", rl."TenantId", i."Id" AS "MaterialRequestItemId", i."MaterialRequestId", r."RequestNo", r."BranchId", r."DepartmentId", r."WarehouseId",
r."LocationId", i."ProductId", i."DueDate", CAST('Purchase' AS varchar(16)) AS "PlanMethod", q."Id" AS "DocumentId", q."RfqNo" AS "DocumentNo",
@ -23,7 +23,7 @@ SELECT rl."Id", rl."TenantId", i."Id" AS "MaterialRequestItemId", i."MaterialReq
WHERE rl."IsDeleted" = false
UNION ALL
SELECT tl."Id", tl."TenantId", i."Id", i."MaterialRequestId", r."RequestNo", r."BranchId", r."DepartmentId", r."WarehouseId",
r."LocationId", i."ProductId", i."DueDate", CAST('Transfer' AS varchar(16)), t."Id", t."TransferNo",
r."LocationId", i."ProductId", i."DueDate", CAST(CASE WHEN t."SourceLocationId" = t."DestinationLocationId" THEN 'Stock' ELSE 'Transfer' END AS varchar(16)), t."Id", t."TransferNo",
t."Status", NULL, t."SourceLocationId",
NULL, NULL, NULL, tl."DemandQuantity", tl."UomId",
CASE WHEN t."Status" = 'Done' THEN tl."Quantity" ELSE 0 END, tl."CreationTime", tl."CreatorId", tl."IsDeleted"
@ -31,13 +31,4 @@ SELECT tl."Id", tl."TenantId", i."Id", i."MaterialRequestId", r."RequestNo", r."
INNER JOIN "Inv_T_Transfer" t ON t."Id" = tl."TransferId" AND t."IsDeleted" = false AND t."OperationKind" = 'InternalTransfer' AND t."ReturnOfId" IS NULL
INNER JOIN "Prc_T_MaterialRequestItem" i ON i."Id" = tl."MaterialRequestItemId"
INNER JOIN "Prc_T_MaterialRequest" r ON r."Id" = i."MaterialRequestId"
WHERE tl."IsDeleted" = false
UNION ALL
SELECT i."Id", i."TenantId", i."Id", i."MaterialRequestId", r."RequestNo", r."BranchId", r."DepartmentId", r."WarehouseId",
r."LocationId", i."ProductId", i."DueDate", CAST('Stock' AS varchar(16)), NULL, NULL,
NULL, NULL, r."LocationId",
NULL, NULL, NULL, i."FromStockQuantity", i."UomId",
i."FromStockQuantity", i."LastModificationTime", i."LastModifierId", i."IsDeleted"
FROM "Prc_T_MaterialRequestItem" i
INNER JOIN "Prc_T_MaterialRequest" r ON r."Id" = i."MaterialRequestId"
WHERE i."FromStockQuantity" > 0;
WHERE tl."IsDeleted" = false;

View file

@ -2,6 +2,7 @@ CREATE TABLE IF NOT EXISTS public."Prj_T_Diary"
(
"Id" uuid NOT NULL DEFAULT gen_random_uuid(),
"TenantId" uuid NULL,
"BranchId" uuid NOT NULL,
"ProjectId" uuid NOT NULL,
"WorkPackageId" uuid NULL,
"UserId" uuid NOT NULL,

View file

@ -2,6 +2,7 @@ CREATE TABLE IF NOT EXISTS public."Prj_T_Project"
(
"Id" uuid NOT NULL DEFAULT gen_random_uuid(),
"TenantId" uuid NULL,
"BranchId" uuid NOT NULL,
"ProjectNo" varchar(32) NOT NULL,
"Name" varchar(512) NOT NULL,
"ProjectType" varchar(32) NULL,

View file

@ -2,6 +2,7 @@ CREATE TABLE IF NOT EXISTS public."Prj_T_WorkPackage"
(
"Id" uuid NOT NULL DEFAULT gen_random_uuid(),
"TenantId" uuid NULL,
"BranchId" uuid NOT NULL,
"ProjectId" uuid NOT NULL,
"ParentId" uuid NULL,
"Code" varchar(16) NOT NULL,

View file

@ -1,7 +1,7 @@
CREATE OR REPLACE VIEW public."Prj_V_BudgetMonthly"
AS
WITH base AS (
SELECT x."TenantId", w."ProjectId", x."ResourceType", x."Kind", COALESCE(x."Cost", 0) AS "Cost",
SELECT x."TenantId", p."BranchId", w."ProjectId", x."ResourceType", x."Kind", COALESCE(x."Cost", 0) AS "Cost",
date_trunc('month', COALESCE(x."DocumentDate", w."StartDate"))::date AS "PeriodDate"
FROM public."Prj_T_WorkPackageResource" x
INNER JOIN public."Prj_T_WorkPackage" w ON w."Id" = x."WorkPackageId" AND w."IsDeleted" = FALSE
@ -9,11 +9,11 @@ WITH base AS (
WHERE x."IsDeleted" = FALSE
),
monthly AS (
SELECT "TenantId", "ProjectId", "ResourceType", "PeriodDate",
SELECT "TenantId", "BranchId", "ProjectId", "ResourceType", "PeriodDate",
SUM(CASE WHEN "Kind" = 'Planned' THEN "Cost" ELSE 0 END) AS "Planned",
SUM(CASE WHEN "Kind" = 'Actual' THEN "Cost" ELSE 0 END) AS "Actual"
FROM base
GROUP BY "TenantId", "ProjectId", "ResourceType", "PeriodDate"
GROUP BY "TenantId", "BranchId", "ProjectId", "ResourceType", "PeriodDate"
)
SELECT
(m."ProjectId"::text || '|' || m."ResourceType")::varchar(120) AS "Id",
@ -26,9 +26,10 @@ SELECT
SUM(m."Planned")::numeric(18,4) AS "Planned",
SUM(m."Actual")::numeric(18,4) AS "Actual",
(CASE WHEN SUM(m."Planned") > 0 THEN SUM(m."Actual") * 100.0 / SUM(m."Planned") ELSE 0 END)::numeric(18,4) AS "Ratio",
(CASE WHEN SUM(m."Planned") > 0 THEN LEAST(SUM(m."Actual") * 100.0 / SUM(m."Planned"), 100) ELSE 0 END)::numeric(18,4) AS "Progress"
(CASE WHEN SUM(m."Planned") > 0 THEN LEAST(SUM(m."Actual") * 100.0 / SUM(m."Planned"), 100) ELSE 0 END)::numeric(18,4) AS "Progress",
m."BranchId"
FROM monthly m
GROUP BY m."TenantId", m."ProjectId", m."ResourceType"
GROUP BY m."TenantId", m."BranchId", m."ProjectId", m."ResourceType"
UNION ALL
SELECT
(m."ProjectId"::text || '|' || m."ResourceType" || '|' || to_char(m."PeriodDate", 'YYYY-MM'))::varchar(120),
@ -40,5 +41,6 @@ SELECT
EXTRACT(YEAR FROM m."PeriodDate")::integer, EXTRACT(MONTH FROM m."PeriodDate")::integer,
m."Planned"::numeric(18,4), m."Actual"::numeric(18,4),
(CASE WHEN m."Planned" > 0 THEN m."Actual" * 100.0 / m."Planned" ELSE 0 END)::numeric(18,4),
(CASE WHEN m."Planned" > 0 THEN LEAST(m."Actual" * 100.0 / m."Planned", 100) ELSE 0 END)::numeric(18,4)
(CASE WHEN m."Planned" > 0 THEN LEAST(m."Actual" * 100.0 / m."Planned", 100) ELSE 0 END)::numeric(18,4),
m."BranchId"
FROM monthly m;

View file

@ -1,7 +1,7 @@
CREATE OR REPLACE VIEW public."Prj_V_ManMonthGantt"
AS
WITH base AS (
SELECT r."TenantId", w."ProjectId", r."UserId", w."Id" AS "WorkPackageId",
SELECT r."TenantId", p."BranchId", w."ProjectId", r."UserId", w."Id" AS "WorkPackageId",
w."Code", w."Name", r."Rate", make_date(r."Year", r."Month", 1) AS "PeriodDate"
FROM public."Prj_T_WorkPackageMonthRate" r
INNER JOIN public."Prj_T_WorkPackage" w ON w."Id" = r."WorkPackageId" AND w."IsDeleted" = FALSE
@ -19,10 +19,11 @@ SELECT
AVG(b."Rate")::numeric(18,4) AS "Progress",
AVG(b."Rate")::numeric(18,4) AS "AvgRate",
SUM(b."Rate")::numeric(18,4) AS "TotalRate",
COUNT(DISTINCT b."PeriodDate")::integer AS "MonthCount"
COUNT(DISTINCT b."PeriodDate")::integer AS "MonthCount",
b."BranchId"
FROM base b
LEFT JOIN public."AbpUsers" u ON u."Id" = b."UserId"
GROUP BY b."TenantId", b."ProjectId", b."UserId"
GROUP BY b."TenantId", b."BranchId", b."ProjectId", b."UserId"
UNION ALL
SELECT
(b."ProjectId"::text || '|' || b."UserId"::text || '|' || b."WorkPackageId"::text)::varchar(120),
@ -35,6 +36,7 @@ SELECT
AVG(b."Rate")::numeric(18,4),
AVG(b."Rate")::numeric(18,4),
SUM(b."Rate")::numeric(18,4),
COUNT(DISTINCT b."PeriodDate")::integer
COUNT(DISTINCT b."PeriodDate")::integer,
b."BranchId"
FROM base b
GROUP BY b."TenantId", b."ProjectId", b."UserId", b."WorkPackageId";
GROUP BY b."TenantId", b."BranchId", b."ProjectId", b."UserId", b."WorkPackageId";

View file

@ -10,7 +10,8 @@ SELECT
COALESCE(u."Rate", 100)::numeric(18,4) AS "MonthlyRate",
(r."Rate" * COALESCE(u."Rate", 100) / 100.0)::numeric(18,4) AS "EffectiveRate",
COALESCE(pm."AvgMonthlyCost", 0)::numeric(18,4) AS "UnitCost",
(COALESCE(pm."AvgMonthlyCost", 0) * r."Rate" * COALESCE(u."Rate", 100) / 10000.0)::numeric(18,4) AS "TotalCost"
(COALESCE(pm."AvgMonthlyCost", 0) * r."Rate" * COALESCE(u."Rate", 100) / 10000.0)::numeric(18,4) AS "TotalCost",
p."BranchId"
FROM public."Prj_T_WorkPackageMonthRate" r
INNER JOIN public."Prj_T_WorkPackage" w ON w."Id" = r."WorkPackageId" AND w."IsDeleted" = FALSE
INNER JOIN public."Prj_T_Project" p ON p."Id" = w."ProjectId" AND p."IsDeleted" = FALSE

View file

@ -7,7 +7,8 @@ SELECT
x."Kind", x."ResourceType", x."UserId", x."ResourceName",
x."Quantity", x."Unit", x."Price", x."VatRate", x."Cost",
x."DocumentDate", x."DocumentNo", x."OrganizationType", x."OrganizationName",
x."WorkDone", x."WorkDescription"
x."WorkDone", x."WorkDescription",
p."BranchId"
FROM public."Prj_T_WorkPackageResource" x
INNER JOIN public."Prj_T_WorkPackage" w ON w."Id" = x."WorkPackageId" AND w."IsDeleted" = FALSE
INNER JOIN public."Prj_T_Project" p ON p."Id" = w."ProjectId" AND p."IsDeleted" = FALSE;

View file

@ -1,7 +1,6 @@
-- Transfer belgesi kaydı (ve iş akışı adımları) sonrası: tür, şube, depo ve boş konumlar operasyon türünden gelir (formda olmayan alımın
-- kaynağı ve teslimatın hedefi her zaman, iade belgesi hariç); teslimat politikası
-- yalnız teslimatta tutulur; iç transferin onaycısı kaynak konumun depo sorumlusudur (kullanıcı adı; iş akışı onaycıyı adla eşler),
-- sorumlusu olmayan konumdan transfer onay beklemez.
-- Transfer belgesi kaydı sonrası: tür, şube, depo ve boş konumlar operasyon türünden gelir (formda olmayan alımın
-- kaynağı ve teslimatın hedefi her zaman, iade belgesi hariç); teslimat politikası yalnız teslimatta tutulur. Tamamlanmış belgenin başlığı
-- yeniden türetilmez: stoğu belirleyen alanlar kilitlidir (Inv_TR_TransferLock) ve sonradan değişen operasyon türü İade Et'i 50328'e düşürürdü.
-- Numara, özet ve durum butonunun işlemi (PendingAction) buradan çalışır.
CREATE OR ALTER PROCEDURE [dbo].[Inv_P_TransferAfterSave]
@Id uniqueidentifier,
@ -22,31 +21,11 @@ BEGIN
DeliveryPolicy = CASE WHEN ot.OperationKind = 'Delivery' THEN COALESCE(t.DeliveryPolicy, 'Direct') END
FROM Inv_T_Transfer t
INNER JOIN Inv_T_OperationType ot ON ot.Id = t.OperationTypeId
WHERE t.Id = @Id;
UPDATE t SET
SourceApproverUserNames = NULLIF(l.ResponsibleUserName, ''),
ApprovalStatus = CASE WHEN NULLIF(l.ResponsibleUserName, '') IS NULL AND t.ApprovalStatus IS NULL THEN N'Onay Gerekmez'
WHEN NULLIF(l.ResponsibleUserName, '') IS NOT NULL AND t.ApprovalStatus = N'Onay Gerekmez' THEN NULL
ELSE t.ApprovalStatus END
FROM Inv_T_Transfer t
LEFT JOIN Inv_T_Location l ON l.Id = t.SourceLocationId
WHERE t.Id = @Id AND t.OperationKind = 'InternalTransfer' AND t.Status = 'Draft';
WHERE t.Id = @Id AND t.Status <> 'Done';
EXEC Inv_P_TransferNumber @Id;
EXEC Inv_P_TransferRecalc @Id;
-- Durum butonları işlemi PendingAction alanına yazıp ekranın güncelleme ucuyla kaydeder.
IF @Act IS NOT NULL
EXEC Inv_P_TransferSetStatus @Id, @Act, @UserId;
-- Kaynak depo onayı verilen taslak iç transfer kendiliğinden hazırlanır (kullanıcı kararı: onay → Hazırla tek adım).
-- Hazırla'nın şartları (satır, farklı iki iç konum) sağlanmıyorsa denenmez: onay kaydı bozulmaz, belge taslak kalır ve
-- Hazırla elle basılınca hatayı gösterir.
ELSE IF EXISTS (SELECT 1
FROM Inv_T_Transfer t
INNER JOIN Inv_T_Location s ON s.Id = t.SourceLocationId AND s.LocationType = 'Internal'
INNER JOIN Inv_T_Location d ON d.Id = t.DestinationLocationId AND d.LocationType = 'Internal'
WHERE t.Id = @Id AND t.OperationKind = 'InternalTransfer' AND t.Status = 'Draft' AND t.ApprovalStatus = N'Onaylandı'
AND s.Id <> d.Id
AND EXISTS (SELECT 1 FROM Inv_T_TransferLine l WHERE l.TransferId = t.Id AND l.IsDeleted = 0))
EXEC Inv_P_TransferSetStatus @Id, 'Confirm', @UserId;
END

View file

@ -1,5 +1,5 @@
-- Belgeden yeni belge açar. Backorder: talepten az yapılan satırların kalanı, aynı konumlarla; stok kontrolüyle Hazır/Bekleyen olur.
-- Return (İade): yapılan miktarlar lotlarıyla, kaynak ve hedef yer değiştirerek Taslak açılır. İkisi de onay durumunu ve bağları taşır.
-- Return (İade): yapılan miktarlar lotlarıyla, kaynak ve hedef yer değiştirerek Taslak açılır. İkisi de bağları taşır.
CREATE OR ALTER PROCEDURE [dbo].[Inv_P_TransferCopy]
@SourceId uniqueidentifier,
@Mode nvarchar(16),
@ -14,7 +14,7 @@ BEGIN
INSERT INTO Inv_T_Transfer (Id, TenantId, BranchId, WarehouseId, OperationTypeId, OperationKind, PartnerId, SourceLocationId, DestinationLocationId,
ScheduledDate, SourceDocument, PurchaseOrderId, BackorderOfId, ReturnOfId, CarrierId, ResponsibleUserId, ProjectId, DeliveryPolicy,
Status, SourceApproverUserNames, ApprovalUserName, ApprovalStatus, ApprovalDate, ApprovalDescription, CreationTime, CreatorId, IsDeleted)
Status, CreationTime, CreatorId, IsDeleted)
SELECT @NewId, t.TenantId, t.BranchId, t.WarehouseId, t.OperationTypeId, t.OperationKind, t.PartnerId,
CASE WHEN @IsReturn = 1 THEN t.DestinationLocationId ELSE t.SourceLocationId END,
CASE WHEN @IsReturn = 1 THEN t.SourceLocationId ELSE t.DestinationLocationId END,
@ -22,7 +22,7 @@ BEGIN
CASE WHEN @IsReturn = 1 THEN t.TransferNo ELSE t.SourceDocument END, t.PurchaseOrderId,
CASE WHEN @IsReturn = 1 THEN NULL ELSE @SourceId END, CASE WHEN @IsReturn = 1 THEN @SourceId END,
t.CarrierId, t.ResponsibleUserId, t.ProjectId, t.DeliveryPolicy,
'Draft', t.SourceApproverUserNames, t.ApprovalUserName, t.ApprovalStatus, t.ApprovalDate, t.ApprovalDescription, GETUTCDATE(), @UserId, 0
'Draft', GETUTCDATE(), @UserId, 0
FROM Inv_T_Transfer t
WHERE t.Id = @SourceId;

View file

@ -24,8 +24,8 @@ BEGIN
IF @@ROWCOUNT = 0
RETURN;
INSERT INTO Inv_T_TransferLine (Id, TenantId, TransferId, ProductId, Description, DemandQuantity, Quantity, UomId, PurchaseOrderLineId, CreationTime, CreatorId, IsDeleted)
SELECT NEWID(), l.TenantId, @New, l.ProductId, l.Description, l.Quantity - l.ReceivedQuantity, 0, l.UomId, l.Id, GETUTCDATE(), @UserId, 0
INSERT INTO Inv_T_TransferLine (Id, TenantId, TransferId, ProductId, Description, DemandQuantity, Quantity, UomId, PurchaseOrderLineId, MaterialRequestItemId, CreationTime, CreatorId, IsDeleted)
SELECT NEWID(), l.TenantId, @New, l.ProductId, l.Description, l.Quantity - l.ReceivedQuantity, 0, l.UomId, l.Id, l.MaterialRequestItemId, GETUTCDATE(), @UserId, 0
FROM Prc_T_PurchaseOrderLine l
INNER JOIN Inv_T_Product p ON p.Id = l.ProductId
WHERE l.PurchaseOrderId = @OrderId AND l.IsDeleted = 0 AND p.TrackInventory = 1 AND l.Quantity > l.ReceivedQuantity;

View file

@ -1,4 +1,5 @@
-- Otomatik Ata: stoktan çıkan satırın lot dağılımını kaynak konumun stoğundan ilk giren ilk çıkar (InDate) sırasıyla yeniden kurar.
-- Otomatik Ata: stoktan çıkan satırın lot dağılımını kaynak konumun stoğundan ürün kategorisinin çıkış stratejisiyle yeniden kurar
-- (FIFO: ilk giren ilk çıkar, LIFO: son giren ilk çıkar — InDate, aynı anda girenlerde lot/seri no; kategorisiz ürün FIFO). Planlama'nın Öner'i aynı kuralı izler.
-- Stok yetmezse karşılanabilen kadar atanır; eksik Tamamla'da bildirilir.
CREATE OR ALTER PROCEDURE [dbo].[Inv_P_TransferLineLotAssign]
@Id uniqueidentifier,
@ -7,15 +8,16 @@ AS
BEGIN
SET NOCOUNT ON;
DECLARE @Tenant uniqueidentifier, @Method nvarchar(16), @Src uniqueidentifier, @SrcInternal bit, @ProductId uniqueidentifier,
@LineUom nvarchar(64), @ProductUom nvarchar(64), @Need decimal(18, 4);
@LineUom nvarchar(64), @ProductUom nvarchar(64), @Need decimal(18, 4), @Strategy nvarchar(16);
SELECT @Tenant = l.TenantId, @Method = CASE WHEN p.TrackInventory = 1 THEN p.TrackingMethod END, @Src = t.SourceLocationId,
@SrcInternal = CASE WHEN src.LocationType = 'Internal' THEN 1 ELSE 0 END, @ProductId = l.ProductId,
@LineUom = l.UomId, @ProductUom = p.UomId,
@LineUom = l.UomId, @ProductUom = p.UomId, @Strategy = ISNULL(pc.RemovalStrategy, 'FIFO'),
@Need = dbo.Inv_F_UomConvert(CASE WHEN l.Quantity > 0 THEN l.Quantity ELSE l.DemandQuantity END, l.UomId, p.UomId)
FROM Inv_T_TransferLine l
INNER JOIN Inv_T_Transfer t ON t.Id = l.TransferId
INNER JOIN Inv_T_Product p ON p.Id = l.ProductId
LEFT JOIN Inv_T_ProductCategory pc ON pc.Id = p.CategoryId
LEFT JOIN Inv_T_Location src ON src.Id = t.SourceLocationId
WHERE l.Id = @Id;
@ -27,7 +29,11 @@ BEGIN
WITH s AS (
SELECT LotNo, Quantity,
SUM(Quantity) OVER (ORDER BY InDate, LotNo ROWS UNBOUNDED PRECEDING) - Quantity AS Before
SUM(Quantity) OVER (ORDER BY CASE WHEN @Strategy = 'LIFO' THEN NULL ELSE ISNULL(InDate, '9999-12-31') END,
CASE WHEN @Strategy = 'LIFO' THEN ISNULL(InDate, '1900-01-01') END DESC,
CASE WHEN @Strategy = 'LIFO' THEN NULL ELSE LotNo END,
CASE WHEN @Strategy = 'LIFO' THEN LotNo END DESC
ROWS UNBOUNDED PRECEDING) - Quantity AS Before
FROM Inv_T_Stock
WHERE LocationId = @Src AND ProductId = @ProductId AND LotNo <> '' AND Quantity > 0
AND (TenantId = @Tenant OR (TenantId IS NULL AND @Tenant IS NULL)))

View file

@ -6,18 +6,18 @@ CREATE OR ALTER PROCEDURE [dbo].[Inv_P_TransferSetStatus]
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Status nvarchar(16), @Kind nvarchar(32), @Approval nvarchar(50), @Src uniqueidentifier, @Dst uniqueidentifier, @New uniqueidentifier;
DECLARE @Status nvarchar(16), @Kind nvarchar(32), @Src uniqueidentifier, @Dst uniqueidentifier, @New uniqueidentifier;
SELECT @Status = Status, @Kind = OperationKind, @Approval = ApprovalStatus, @Src = SourceLocationId, @Dst = DestinationLocationId
SELECT @Status = Status, @Kind = OperationKind, @Src = SourceLocationId, @Dst = DestinationLocationId
FROM Inv_T_Transfer WHERE Id = @Id;
UPDATE Inv_T_Transfer SET PendingAction = NULL WHERE Id = @Id;
-- İç transfer depo içinde taşımadır: iki uç da stok tutan iç konum ve birbirinden farklı olmalı (dış konuma giden mal stoktan düşer, hiçbir yere girmez).
-- İç transfer depo içinde taşımadır: iki uç da stok tutan iç konum olmalı (dış konuma giden mal stoktan düşer, hiçbir yere girmez).
-- Kaynak ve hedef aynı olabilir: stok zaten teslim konumundaki talebin teslimidir (Planlama'nın Stoktan kararı), Doğrula stoğa dokunmaz.
-- İade belgesi muaftır: yanlışlıkla dış konuma yapılmış transfer İade Et ile geri alınabilmeli.
IF @Kind = 'InternalTransfer' AND @Action IN ('Confirm', 'Check', 'Validate')
AND NOT EXISTS (SELECT 1 FROM Inv_T_Transfer WHERE Id = @Id AND ReturnOfId IS NOT NULL)
BEGIN
IF @Src = @Dst THROW 50325, N'Kaynak ve hedef konum aynı olamaz.', 1;
IF EXISTS (SELECT 1 FROM Inv_T_Location WHERE Id IN (@Src, @Dst) AND LocationType <> 'Internal')
THROW 50326, N'İç transferde kaynak ve hedef konum iç konum olmalıdır.', 1;
END
@ -28,14 +28,14 @@ BEGIN
IF NOT EXISTS (SELECT 1 FROM Inv_T_TransferLine WHERE TransferId = @Id AND IsDeleted = 0)
THROW 50302, N'Ürün satırı olmayan belge hazırlanamaz.', 1;
IF @Src IS NULL OR @Dst IS NULL THROW 50303, N'Kaynak ve hedef konum seçilmelidir.', 1;
IF @Kind = 'InternalTransfer' AND ISNULL(@Approval, N'') NOT IN (N'Onaylandı', N'Onay Gerekmez')
THROW 50304, N'Kaynak depo onayı tamamlanmadan iç transfer hazırlanamaz.', 1;
EXEC Inv_P_TransferCheckAvailability @Id;
EXEC Inv_P_TransferRecalc @Id;
END
ELSE IF @Action = 'Check'
BEGIN
IF @Status NOT IN ('Waiting', 'Ready') THROW 50305, N'Stok kontrolü yalnız bekleyen ya da hazır belgede yapılır.', 1;
EXEC Inv_P_TransferCheckAvailability @Id;
EXEC Inv_P_TransferRecalc @Id;
END
ELSE IF @Action = 'Validate'
BEGIN
@ -52,6 +52,8 @@ BEGIN
ELSE IF @Action = 'Return'
BEGIN
IF @Status <> 'Done' THROW 50308, N'Yalnız tamamlanmış belge iade edilebilir.', 1;
IF EXISTS (SELECT 1 FROM Inv_T_Transfer WHERE Id = @Id AND ReturnOfId IS NOT NULL)
THROW 50327, N'İade belgesi yeniden iade edilemez; asıl belgeden yeni bir hareket açın.', 1;
EXEC Inv_P_TransferCopy @Id, 'Return', @UserId, @New OUTPUT;
END
END

View file

@ -1,5 +1,5 @@
-- Tamamla: yapılan miktarlar stoğa işlenir (Inv_T_Stock, ürün biriminde, lot kırılımlı). İç konumdan çıkışta stok yetmezse
-- işlem durur; dış konumlar stok tutmaz. Envanter takibi kapalı ürün stoğa girmez. Lot/seri takipli üründe lot toplamı
-- işlem durur; dış konumlar stok tutmaz. Kaynak ve hedefi aynı konum olan belge stoğa dokunmaz (teslim kaydıdır). Envanter takibi kapalı ürün stoğa girmez. Lot/seri takipli üründe lot toplamı
-- yapılan miktara eşit olmalıdır. Sipariş kalemlerinin alınan, talep kalemlerinin teslim edilen miktarı güncellenir (iadede düşülür);
-- siparişli alım ürün–tedarikçi fiyatını yazar (Inv_P_TransferSupplierPrice).
-- Talepten az yapılan satırların kalanı aynı türde yeni belgeye (backorder) geçer.
@ -87,13 +87,15 @@ BEGIN
THROW 50312, @Msg, 1;
END
UPDATE s SET Quantity = s.Quantity - m.Quantity, LastMoveDate = @Now, LastModificationTime = @Now, LastModifierId = @UserId
FROM Inv_T_Stock s
INNER JOIN @Move m ON m.ProductId = s.ProductId AND m.LotNo = s.LotNo
WHERE s.LocationId = @Src AND (s.TenantId = @Tenant OR (s.TenantId IS NULL AND @Tenant IS NULL));
-- Kaynak ve hedef aynıysa stok yerinde kalır: belge teslimi kaydeder (yeterlilik yine denetlenir).
IF @Src <> @Dst
UPDATE s SET Quantity = s.Quantity - m.Quantity, LastMoveDate = @Now, LastModificationTime = @Now, LastModifierId = @UserId
FROM Inv_T_Stock s
INNER JOIN @Move m ON m.ProductId = s.ProductId AND m.LotNo = s.LotNo
WHERE s.LocationId = @Src AND (s.TenantId = @Tenant OR (s.TenantId IS NULL AND @Tenant IS NULL));
END
IF @DstInternal = 1
IF @DstInternal = 1 AND @Src <> @Dst
BEGIN
UPDATE s SET Quantity = s.Quantity + m.Quantity, LastMoveDate = @Now, LastModificationTime = @Now, LastModifierId = @UserId,
InDate = CASE WHEN s.Quantity <= 0 THEN @Now ELSE s.InDate END

View file

@ -0,0 +1,22 @@
-- Tamamlanmış hareket belgesinin stoğu belirleyen başlık alanları değiştirilemez (Alımlar, Teslimatlar, İç Transferler ve ortak sekmeleri):
-- stok eski konumda kalır, İade Et yeni konumdan düşmeye çalışırdı. Kural ekranın UpdateBeforeCommand'ında değil burada, çünkü durum
-- butonları yalnız PendingAction ile aynı güncelleme yolundan yazar. Açıklama, nakliye ve not alanları serbesttir;
-- satırların kuralı Transfer Satırları'nın Update/DeleteBeforeCommand'ındadır (50313).
CREATE OR ALTER TRIGGER [dbo].[Inv_TR_TransferLock] ON [dbo].[Inv_T_Transfer]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (SELECT 1
FROM inserted i
INNER JOIN deleted d ON d.Id = i.Id
WHERE d.Status = 'Done'
AND (i.Status <> d.Status OR i.BranchId <> d.BranchId OR i.WarehouseId <> d.WarehouseId
OR i.OperationTypeId <> d.OperationTypeId OR i.OperationKind <> d.OperationKind
OR ISNULL(i.SourceLocationId, '00000000-0000-0000-0000-000000000000') <> ISNULL(d.SourceLocationId, '00000000-0000-0000-0000-000000000000')
OR ISNULL(i.DestinationLocationId, '00000000-0000-0000-0000-000000000000') <> ISNULL(d.DestinationLocationId, '00000000-0000-0000-0000-000000000000')
OR ISNULL(i.PartnerId, '00000000-0000-0000-0000-000000000000') <> ISNULL(d.PartnerId, '00000000-0000-0000-0000-000000000000')
OR i.IsDeleted <> d.IsDeleted))
THROW 50328, N'Tamamlanmış belgenin konumu, türü ve durumu değiştirilemez; düzeltme için İade Et kullanın.', 1;
END
GO

View file

@ -6,6 +6,7 @@ BEGIN
[TenantId] uniqueidentifier NULL,
[Name] nvarchar(128) NOT NULL,
[ParentId] uniqueidentifier NULL,
[RemovalStrategy] nvarchar(16) NOT NULL DEFAULT 'FIFO',
[IsActive] bit NOT NULL DEFAULT 1,
[CreationTime] datetime2 NOT NULL DEFAULT GETUTCDATE(),
[CreatorId] uniqueidentifier NULL,

View file

@ -30,11 +30,6 @@ BEGIN
[LineSummary] nvarchar(MAX) NULL,
[Status] nvarchar(16) NOT NULL DEFAULT 'Draft',
[PendingAction] nvarchar(16) NULL,
[SourceApproverUserNames] nvarchar(512) NULL,
[ApprovalUserName] nvarchar(256) NULL,
[ApprovalStatus] nvarchar(50) NULL,
[ApprovalDate] datetime NULL,
[ApprovalDescription] nvarchar(200) NULL,
[ReceivedByUserId] uniqueidentifier NULL,
[ReceivedDate] datetime NULL,
[CreationTime] datetime2 NOT NULL DEFAULT GETUTCDATE(),

View file

@ -1,6 +1,7 @@
-- Transfer belgesinin talep kalemlerinin satır durumunu planla eşler (yeniden hesap ve iptal sonrası): kalanın tamamı iç transferle
-- planlanmış, satınalma payı olmayan bekleyen kalem kapanır (Tamamlandı); transfer iptal edilir, satırı silinir ya da eksik tamamlanıp kalanı
-- yeniden açılırsa kapalı kalem Bekliyor'a döner ve Planlama'da görünür. Silinmiş satırların kalemleri de kapsamdadır.
-- yeniden açılırsa kapalı kalem Bekliyor'a döner ve Planlama'da görünür. Silinmiş satırların kalemleri de kapsamdadır. Ardından
-- kalemlerin taleplerinin durumu yenilenir (teslim tamamlandıysa Tamamlandı; alım belgesi de buradan geçer).
CREATE OR ALTER PROCEDURE [dbo].[Prc_P_MaterialRequestItemSync]
@TransferId uniqueidentifier
AS
@ -14,4 +15,6 @@ BEGIN
AND p.PurchaseQuantity = 0
AND ((i.LineStatus = 'Waiting' AND p.RemainingQuantity <= 0)
OR (i.LineStatus = 'Done' AND p.RemainingQuantity > 0 AND i.DeliveredQuantity < i.Quantity));
EXEC Prc_P_MaterialRequestSyncStatus @TransferId;
END

View file

@ -3,17 +3,21 @@
-- Purchase: tedarikçinin talebin şubesi ve deposu için taslak teklif talebi varsa kalem ona eklenir (kalem zaten oradaysa miktarı artar), yoksa
-- talebin deposunun alım operasyon türüyle yeni taslak teklif talebi açılır (para birimi ve koşullar kontak kartından; alıcı — satınalma sorumlusu —
-- planlayan). Fiyat tedarikçinin fiyat listesinden gelir; teklif → sipariş → alım akışı oradan sürer.
-- Transfer: kaynak konumun serbest stoğu (Prc_V_MaterialRequestPlanSource) yetmelidir; aynı kaynak → talebin konumu için onaya
-- girmemiş taslak iç transfer varsa satır ona, yoksa kaynak deponun iç transfer operasyon türüyle yeni taslak açılır. Kalanın tamamı transferle
-- Transfer: kaynak konumun (lot/seri takipli üründe @PlanLotNo lotunun) serbest stoğu (Prc_V_MaterialRequestPlanSource) yetmelidir; aynı
-- kaynak → talebin konumu için taslak iç transfer varsa satır ona, yoksa kaynak deponun iç transfer operasyon türüyle yeni
-- taslak açılır. Depoda aynı türden birkaç operasyon türü olabilir (Bakım Sarf Tüketimi, Departman Sarf Çıkışı …); türün kendi
-- numaratörünü taşıyanı (SequenceName '….InternalTransfer' / '….Receipt' ile biter) seçilir, taslak da yalnız o türde aranır. Lot planlandıysa transfer satırının lot dağılımına (Inv_T_TransferLineLot, satırın biriminde) eklenir; depo Detaylar ya da
-- Otomatik Ata ile değiştirebilir. Kalanın tamamı transferle
-- planlanan, satınalma payı olmayan kalem transfer belgesinin yeniden hesabında kapanır (Prc_P_MaterialRequestItemSync).
-- Stock: stok talebin teslim konumundadır; belge açılmaz, serbest stok yetmelidir. Miktar kalemin stoktan karşılanan ve teslim edilen
-- miktarına eklenir; satınalma payı olmayan ve kalanı biten kalem kapanır.
-- Stock: stok talebin teslim konumundadır; Transfer gibi iç transfer açılır, kaynak ve hedef teslim konumudur (Doğrula stoğa dokunmaz,
-- teslimi kaydeder: kalemin teslim edilen miktarı artar). Belge numarası ve durumu Plan Takibi'ne transferden yansır.
CREATE OR ALTER PROCEDURE [dbo].[Prc_P_MaterialRequestPlan]
@Id uniqueidentifier,
@PlanMethod nvarchar(16),
@PlanQuantity decimal(18, 4),
@PlanSupplierId uniqueidentifier,
@PlanSourceLocationId uniqueidentifier,
@PlanLotNo nvarchar(64),
@TenantId uniqueidentifier,
@LastModifierId uniqueidentifier
AS
@ -63,7 +67,8 @@ BEGIN
SELECT TOP 1 @OpType = Id
FROM Inv_T_OperationType
WHERE IsDeleted = 0 AND IsActive = 1 AND OperationKind = 'Receipt' AND WarehouseId = @Warehouse
ORDER BY Name;
AND (TenantId = @TenantId OR (TenantId IS NULL AND @TenantId IS NULL))
ORDER BY CASE WHEN SequenceName LIKE CONCAT('%.', OperationKind) THEN 0 ELSE 1 END, Name;
IF @OpType IS NULL
THROW 50195, N'Talebin deposu için aktif bir alım operasyon türü tanımlı değil.', 1;
@ -98,39 +103,41 @@ BEGIN
EXEC Prc_P_PurchaseRfqRecalc @Doc;
END
ELSE IF @PlanMethod = 'Transfer'
ELSE IF @PlanMethod IN ('Transfer', 'Stock')
BEGIN
IF @PlanMethod = 'Stock'
SET @PlanSourceLocationId = @Location;
IF @PlanSourceLocationId IS NULL
THROW 50196, N'İç transfer kararında kaynak konum seçilmelidir.', 1;
-- Konum ve serbest stok kuralı diyaloğun İç Transfer ızgarasıyla aynıdır.
SELECT @SrcWarehouse = WarehouseId, @Free = FreeQuantity
FROM Prc_V_MaterialRequestPlanSource
WHERE BaseId = @Id AND LocationId = @PlanSourceLocationId;
IF @SrcWarehouse IS NULL OR @PlanSourceLocationId = @Location
THROW 50197, N'Kaynak konum, talebin teslim konumundan farklı ve ürünün stoğu olan bir iç konum olmalıdır.', 1;
WHERE BaseId = @Id AND LocationId = @PlanSourceLocationId AND ISNULL(LotNo, '') = ISNULL(@PlanLotNo, '');
IF @SrcWarehouse IS NULL OR (@PlanMethod = 'Transfer' AND @PlanSourceLocationId = @Location)
THROW 50197, N'Kaynak konum, talebin teslim konumundan farklı ve ürünün (lot/seri takipli üründe lotun) stoğu olan bir iç konum olmalıdır.', 1;
IF @PlanQuantity > @Free
BEGIN
SET @Msg = CONCAT(N'Kaynak konumda yeterli serbest stok yok (serbest: ', FORMAT(CASE WHEN @Free > 0 THEN @Free ELSE 0 END, '0.####'), N' ', @UomId, N').');
THROW 50198, @Msg, 1;
END
SELECT TOP 1 @OpType = Id
FROM Inv_T_OperationType
WHERE IsDeleted = 0 AND IsActive = 1 AND OperationKind = 'InternalTransfer' AND WarehouseId = @SrcWarehouse
AND (TenantId = @TenantId OR (TenantId IS NULL AND @TenantId IS NULL))
ORDER BY CASE WHEN SequenceName LIKE CONCAT('%.', OperationKind) THEN 0 ELSE 1 END, Name;
IF @OpType IS NULL
THROW 50199, N'Kaynak depo için aktif bir iç transfer operasyon türü tanımlı değil.', 1;
SELECT TOP 1 @Doc = Id
FROM Inv_T_Transfer
WHERE IsDeleted = 0 AND OperationKind = 'InternalTransfer' AND Status = 'Draft' AND ReturnOfId IS NULL AND BackorderOfId IS NULL
WHERE IsDeleted = 0 AND OperationTypeId = @OpType AND Status = 'Draft' AND ReturnOfId IS NULL AND BackorderOfId IS NULL
AND SourceLocationId = @PlanSourceLocationId AND DestinationLocationId = @Location
AND ISNULL(ApprovalStatus, N'Onay Gerekmez') = N'Onay Gerekmez'
AND (TenantId = @TenantId OR (TenantId IS NULL AND @TenantId IS NULL))
ORDER BY CreationTime DESC;
IF @Doc IS NULL
BEGIN
SELECT TOP 1 @OpType = Id
FROM Inv_T_OperationType
WHERE IsDeleted = 0 AND IsActive = 1 AND OperationKind = 'InternalTransfer' AND WarehouseId = @SrcWarehouse
ORDER BY Name;
IF @OpType IS NULL
THROW 50199, N'Kaynak depo için aktif bir iç transfer operasyon türü tanımlı değil.', 1;
SET @Doc = NEWID();
INSERT INTO Inv_T_Transfer (Id, TenantId, BranchId, WarehouseId, OperationTypeId, OperationKind, SourceLocationId, DestinationLocationId,
SourceDocument, ResponsibleUserId, Status, CreationTime, CreatorId, IsDeleted)
@ -144,36 +151,40 @@ BEGIN
SET SourceDocument = LEFT(CONCAT(SourceDocument, CASE WHEN ISNULL(SourceDocument, '') = '' THEN '' ELSE N', ' END, @RequestNo), 128)
WHERE Id = @Doc AND CHARINDEX(@RequestNo, ISNULL(SourceDocument, '')) = 0;
-- Planlanan miktar yapılacak miktardır: lotsuz satırda doğrudan yazılır, lotlu satırda lot dağılımından (Inv_P_TransferRecalc) gelir.
SELECT @Line = Id FROM Inv_T_TransferLine WHERE TransferId = @Doc AND MaterialRequestItemId = @Id AND IsDeleted = 0;
IF @Line IS NOT NULL
UPDATE Inv_T_TransferLine
SET DemandQuantity = DemandQuantity + dbo.Inv_F_UomConvert(@PlanQuantity, @UomId, UomId), LastModificationTime = GETUTCDATE(), LastModifierId = @LastModifierId
SET DemandQuantity = DemandQuantity + dbo.Inv_F_UomConvert(@PlanQuantity, @UomId, UomId),
Quantity = Quantity + CASE WHEN ISNULL(@PlanLotNo, '') = '' THEN dbo.Inv_F_UomConvert(@PlanQuantity, @UomId, UomId) ELSE 0 END,
LastModificationTime = GETUTCDATE(), LastModifierId = @LastModifierId
WHERE Id = @Line;
ELSE
BEGIN
SET @Line = NEWID();
INSERT INTO Inv_T_TransferLine (Id, TenantId, TransferId, ProductId, Description, DemandQuantity, Quantity, UomId, MaterialRequestItemId,
CreationTime, CreatorId, IsDeleted)
VALUES (NEWID(), @TenantId, @Doc, @ProductId, @Reason, @PlanQuantity, 0, @UomId, @Id, GETUTCDATE(), @LastModifierId, 0);
-- Numara, kaynak depo onaycısı ve yeniden hesap (kalemin kapanması dahil) belge kaydı sonrasıyla aynıdır.
EXEC Inv_P_TransferAfterSave @Doc, @LastModifierId;
END
ELSE IF @PlanMethod = 'Stock'
BEGIN
SELECT @Free = FreeQuantity FROM Prc_V_MaterialRequestPlanSource WHERE BaseId = @Id AND LocationId = @Location;
IF @PlanQuantity > ISNULL(@Free, 0)
BEGIN
SET @Msg = CONCAT(N'Teslim konumunda yeterli serbest stok yok (serbest: ', FORMAT(CASE WHEN @Free > 0 THEN @Free ELSE 0 END, '0.####'), N' ', @UomId, N').');
THROW 50198, @Msg, 1;
VALUES (@Line, @TenantId, @Doc, @ProductId, @Reason, @PlanQuantity, CASE WHEN ISNULL(@PlanLotNo, '') = '' THEN @PlanQuantity ELSE 0 END, @UomId, @Id,
GETUTCDATE(), @LastModifierId, 0);
END
UPDATE Prc_T_MaterialRequestItem
SET FromStockQuantity = FromStockQuantity + @PlanQuantity, DeliveredQuantity = DeliveredQuantity + @PlanQuantity,
LastModificationTime = GETUTCDATE(), LastModifierId = @LastModifierId
WHERE Id = @Id;
UPDATE i SET LineStatus = 'Done'
FROM Prc_T_MaterialRequestItem i
INNER JOIN Prc_V_MaterialRequestItemPlan p ON p.Id = i.Id
WHERE i.Id = @Id AND p.PurchaseQuantity = 0 AND p.RemainingQuantity <= 0;
IF ISNULL(@PlanLotNo, '') <> ''
BEGIN
UPDATE ll
SET Quantity = ll.Quantity + dbo.Inv_F_UomConvert(@PlanQuantity, @UomId, tl.UomId), LastModificationTime = GETUTCDATE(),
LastModifierId = @LastModifierId
FROM Inv_T_TransferLineLot ll
INNER JOIN Inv_T_TransferLine tl ON tl.Id = ll.TransferLineId
WHERE ll.TransferLineId = @Line AND ll.LotNo = @PlanLotNo AND ll.IsDeleted = 0;
IF @@ROWCOUNT = 0
INSERT INTO Inv_T_TransferLineLot (Id, TenantId, TransferLineId, LotNo, Quantity, CreationTime, CreatorId, IsDeleted)
SELECT NEWID(), @TenantId, tl.Id, @PlanLotNo, dbo.Inv_F_UomConvert(@PlanQuantity, @UomId, tl.UomId), GETUTCDATE(), @LastModifierId, 0
FROM Inv_T_TransferLine tl
WHERE tl.Id = @Line;
END
-- Numara ve yeniden hesap (kalemin kapanması dahil) belge kaydı sonrasıyla aynıdır.
EXEC Inv_P_TransferAfterSave @Doc, @LastModifierId;
END
ELSE
THROW 50192, N'Karar Satınalma, İç Transfer ya da Stoktan olmalıdır.', 1;

View file

@ -1,6 +1,5 @@
-- Planla diyaloğunun Onayla'sı (App.Prc.MaterialRequestPlan › UpdateCommand): talep kaleminin taslak planındaki her satırı
-- Prc_P_MaterialRequestPlan ile belgeye çevirir (iç transferler, stoktan karşılama, sonra teklif talepleri — stok payı kalemi transferlerden
-- sonra kapatabilsin) ve taslağı siler. Tek transaction'dır:
-- Prc_P_MaterialRequestPlan ile belgeye çevirir (önce iç transferler ve Stoktan, sonra teklif talepleri) ve taslağı siler. Tek transaction'dır:
-- bir satır reddedilirse (stok, kalan, operasyon türü) hiçbir belge açılmaz ve taslak yerinde kalır.
CREATE OR ALTER PROCEDURE [dbo].[Prc_P_MaterialRequestPlanConfirm]
@Id uniqueidentifier,
@ -10,7 +9,7 @@ AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @Method nvarchar(16), @Quantity decimal(18, 4), @Supplier uniqueidentifier, @Location uniqueidentifier;
DECLARE @Method nvarchar(16), @Quantity decimal(18, 4), @Supplier uniqueidentifier, @Location uniqueidentifier, @Lot nvarchar(64);
BEGIN TRANSACTION;
@ -18,16 +17,16 @@ BEGIN
THROW 50201, N'Onaylanacak taslak plan yok: önce Öner butonunu kullanın ya da İç Transfer veya Satınalma sekmesinde Plan Miktarı girin.', 1;
DECLARE plan_lines CURSOR LOCAL FAST_FORWARD FOR
SELECT PlanMethod, Quantity, SupplierId, SourceLocationId
SELECT PlanMethod, Quantity, SupplierId, SourceLocationId, LotNo
FROM Prc_T_MaterialRequestPlanLine
WHERE MaterialRequestItemId = @Id AND IsDeleted = 0
ORDER BY CASE PlanMethod WHEN 'Transfer' THEN 0 WHEN 'Stock' THEN 1 ELSE 2 END, CreationTime;
OPEN plan_lines;
FETCH NEXT FROM plan_lines INTO @Method, @Quantity, @Supplier, @Location;
FETCH NEXT FROM plan_lines INTO @Method, @Quantity, @Supplier, @Location, @Lot;
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC Prc_P_MaterialRequestPlan @Id, @Method, @Quantity, @Supplier, @Location, @TenantId, @LastModifierId;
FETCH NEXT FROM plan_lines INTO @Method, @Quantity, @Supplier, @Location;
EXEC Prc_P_MaterialRequestPlan @Id, @Method, @Quantity, @Supplier, @Location, @Lot, @TenantId, @LastModifierId;
FETCH NEXT FROM plan_lines INTO @Method, @Quantity, @Supplier, @Location, @Lot;
END
CLOSE plan_lines;
DEALLOCATE plan_lines;

View file

@ -1,12 +1,13 @@
-- Planla diyaloğunun İç Transfer (App.Prc.MaterialRequestPlanSource) ve Satınalma (App.Prc.MaterialRequestPlanVendor) ızgaralarının satır kaydı:
-- girilen Plan Miktarı kalemin taslak planına (Prc_T_MaterialRequestPlanLine) yazılır, 0 ya da boş satırı plandan çıkarır. @Id ızgara
-- satırının anahtarıdır: kalem + ':' + hedef (Transfer'de kaynak konum, Purchase'da tedarikçi). Kaynak talebin teslim konumuysa karar
-- Stock'tur (transfer açılmaz, stoktan karşılanır). Belge açılmaz; onay
-- Prc_P_MaterialRequestPlanConfirm'dedir. Taslak toplamı planlanacak kalanı, konumun satırı serbest stoğu aşamaz. Batch kaydı satırları
-- eşzamanlı gönderdiği için kalem kilitlenir. Eksi miktar "alabileceği en fazla"dır (Seçilenleri Planla): kalanın diğer taslak satırlardan
-- arta kalanı, konumda serbest stokla sınırlı; alınacak bir şey yoksa satır değişmez.
-- satırının anahtarıdır: kalem + ':' + hedef (Transfer'de kaynak konum + ':' + lot — takipsiz üründe lot boş —, Purchase'da tedarikçi).
-- Kaynak talebin teslim konumuysa karar Stock'tur (Stoktan: kaynağı ve hedefi aynı iç transfer açılır). Belge açılmaz; onay
-- Prc_P_MaterialRequestPlanConfirm'dedir. Taslak toplamı planlanacak kalanı, satır kullanılabilir stoğu (Prc_V_MaterialRequestPlanSource
-- .AvailableQuantity: lotun ve konumun serbest stoğu) aşamaz. Batch kaydı satırları eşzamanlı gönderdiği için kalem kilitlenir. Eksi miktar
-- "alabileceği en fazla"dır (Seçilenleri Planla, Öner): kalanın diğer taslak satırlardan arta kalanı, kullanılabilir stokla sınırlı;
-- alınacak bir şey yoksa satır değişmez.
CREATE OR ALTER PROCEDURE [dbo].[Prc_P_MaterialRequestPlanLineSave]
@Id nvarchar(80),
@Id nvarchar(160),
@PlanMethod nvarchar(16),
@PlanQuantity decimal(18, 4),
@TenantId uniqueidentifier,
@ -17,6 +18,7 @@ BEGIN
SET XACT_ABORT ON;
DECLARE @ItemId uniqueidentifier = TRY_CAST(LEFT(@Id, 36) AS uniqueidentifier),
@Target uniqueidentifier = TRY_CAST(SUBSTRING(@Id, 38, 36) AS uniqueidentifier),
@Lot nvarchar(64) = CASE WHEN @PlanMethod = 'Purchase' THEN '' ELSE ISNULL(SUBSTRING(@Id, 75, 64), '') END,
@UomId nvarchar(64), @Location uniqueidentifier, @Remaining decimal(18, 4), @Other decimal(18, 4), @Free decimal(18, 4), @Line uniqueidentifier,
@Qty decimal(18, 4) = ISNULL(@PlanQuantity, 0), @Msg nvarchar(400);
@ -36,7 +38,7 @@ BEGIN
SELECT @Line = Id
FROM Prc_T_MaterialRequestPlanLine
WHERE MaterialRequestItemId = @ItemId AND PlanMethod = @PlanMethod AND IsDeleted = 0
AND @Target = CASE WHEN @PlanMethod = 'Purchase' THEN SupplierId ELSE SourceLocationId END;
AND @Target = CASE WHEN @PlanMethod = 'Purchase' THEN SupplierId ELSE SourceLocationId END AND LotNo = @Lot;
IF @Qty = 0
BEGIN
@ -54,7 +56,7 @@ BEGIN
SET @Qty = @Remaining - @Other;
IF @PlanMethod IN ('Transfer', 'Stock')
BEGIN
SELECT @Free = FreeQuantity FROM Prc_V_MaterialRequestPlanSource WHERE BaseId = @ItemId AND LocationId = @Target;
SELECT @Free = AvailableQuantity FROM Prc_V_MaterialRequestPlanSource WHERE BaseId = @ItemId AND LocationId = @Target AND ISNULL(LotNo, '') = @Lot;
IF @Free < @Qty SET @Qty = @Free;
END
IF ISNULL(@Qty, 0) <= 0
@ -71,12 +73,12 @@ BEGIN
IF @PlanMethod IN ('Transfer', 'Stock')
BEGIN
SELECT @Free = FreeQuantity FROM Prc_V_MaterialRequestPlanSource WHERE BaseId = @ItemId AND LocationId = @Target;
SELECT @Free = AvailableQuantity FROM Prc_V_MaterialRequestPlanSource WHERE BaseId = @ItemId AND LocationId = @Target AND ISNULL(LotNo, '') = @Lot;
IF @Free IS NULL
THROW 50197, N'Kaynak konum ürünün stoğu olan bir iç konum olmalıdır.', 1;
THROW 50197, N'Kaynak konum (lot/seri takipli üründe lot) ürünün stoğu olan bir iç konum olmalıdır.', 1;
IF @Qty > @Free
BEGIN
SET @Msg = CONCAT(N'Kaynak konumda yeterli serbest stok yok (serbest: ', FORMAT(CASE WHEN @Free > 0 THEN @Free ELSE 0 END, '0.####'), N' ', @UomId, N').');
SET @Msg = CONCAT(N'Kaynak konumda (lotta) yeterli serbest stok yok (kullanılabilir: ', FORMAT(CASE WHEN @Free > 0 THEN @Free ELSE 0 END, '0.####'), N' ', @UomId, N').');
THROW 50198, @Msg, 1;
END
END
@ -93,10 +95,10 @@ BEGIN
SET Quantity = @Qty, LastModificationTime = GETUTCDATE(), LastModifierId = @LastModifierId
WHERE Id = @Line;
ELSE
INSERT INTO Prc_T_MaterialRequestPlanLine (Id, TenantId, MaterialRequestItemId, PlanMethod, SupplierId, SourceLocationId, Quantity,
INSERT INTO Prc_T_MaterialRequestPlanLine (Id, TenantId, MaterialRequestItemId, PlanMethod, SupplierId, SourceLocationId, LotNo, Quantity,
CreationTime, CreatorId, IsDeleted)
VALUES (NEWID(), @TenantId, @ItemId, @PlanMethod, CASE WHEN @PlanMethod = 'Purchase' THEN @Target END,
CASE WHEN @PlanMethod <> 'Purchase' THEN @Target END, @Qty, GETUTCDATE(), @LastModifierId, 0);
CASE WHEN @PlanMethod <> 'Purchase' THEN @Target END, @Lot, @Qty, GETUTCDATE(), @LastModifierId, 0);
COMMIT TRANSACTION;
END

View file

@ -1,6 +1,7 @@
-- Planla diyaloğunun Öner'i (App.Prc.MaterialRequestPlanLine › InsertCommand):
-- kalemin taslak planını sıfırlayıp planlanacak kalanı dağıtır. Önce stok: teslim konumu (stoktan karşılama), sonra serbest stoğu en çok
-- olan konum (Prc_V_MaterialRequestPlanSource); kalan kısım satınalma: Prc_V_MaterialRequestPlanVendor'ın SuggestRank'ı ilk olan,
-- kalemin taslak planını sıfırlayıp planlanacak kalanı dağıtır. Önce stok, Prc_V_MaterialRequestPlanSource'un RemovalRank sırasıyla: teslim
-- konumu (stoktan karşılama), sonra ürün kategorisinin çıkış stratejisi (FIFO/LIFO); lot/seri takipli üründe lotlar da bu sırayla seçilir.
-- Her satır alabileceği en fazla miktarı alır (eksi miktar, kullanılabilir stok kuralı kayıt yordamındadır). Kalan kısım satınalma: Prc_V_MaterialRequestPlanVendor'ın SuggestRank'ı ilk olan,
-- fiyat listesinde ya da alım geçmişinde bulunan tedarikçi (hiç bilinmeyen kontak seçilmez, kalan planlanmadan kalır). Satırlar
-- Prc_P_MaterialRequestPlanLineSave ile yazılır; kalem, stok ve kalan kuralları oradadır.
CREATE OR ALTER PROCEDURE [dbo].[Prc_P_MaterialRequestPlanSuggest]
@ -11,7 +12,7 @@ AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @Left decimal(18, 4), @Qty decimal(18, 4), @Free decimal(18, 4), @Key nvarchar(80);
DECLARE @Left decimal(18, 4), @Key nvarchar(160);
BEGIN TRANSACTION;
@ -19,19 +20,21 @@ BEGIN
WHERE MaterialRequestItemId = @Id AND (TenantId = @TenantId OR (TenantId IS NULL AND @TenantId IS NULL));
SELECT @Left = ISNULL(RemainingQuantity, 0) FROM Prc_V_MaterialRequestItemPlan WHERE Id = @Id;
DECLARE sources CURSOR LOCAL FAST_FORWARD FOR
SELECT Id, FreeQuantity
DECLARE sources CURSOR LOCAL STATIC FOR
SELECT Id
FROM Prc_V_MaterialRequestPlanSource
WHERE BaseId = @Id AND FreeQuantity > 0
ORDER BY IsDestination DESC, FreeQuantity DESC;
ORDER BY RemovalRank;
OPEN sources;
FETCH NEXT FROM sources INTO @Key, @Free;
FETCH NEXT FROM sources INTO @Key;
WHILE @@FETCH_STATUS = 0 AND @Left > 0
BEGIN
SET @Qty = CASE WHEN @Free < @Left THEN @Free ELSE @Left END;
EXEC Prc_P_MaterialRequestPlanLineSave @Key, 'Transfer', @Qty, @TenantId, @LastModifierId;
SET @Left = @Left - @Qty;
FETCH NEXT FROM sources INTO @Key, @Free;
EXEC Prc_P_MaterialRequestPlanLineSave @Key, 'Transfer', -1, @TenantId, @LastModifierId;
SELECT @Left = ISNULL(ip.RemainingQuantity, 0) - ISNULL((SELECT SUM(x.Quantity) FROM Prc_T_MaterialRequestPlanLine x
WHERE x.MaterialRequestItemId = @Id AND x.IsDeleted = 0), 0)
FROM Prc_V_MaterialRequestItemPlan ip
WHERE ip.Id = @Id;
FETCH NEXT FROM sources INTO @Key;
END
CLOSE sources;
DEALLOCATE sources;

View file

@ -1,29 +0,0 @@
-- Plan Takibi'nin Geri Al'ı (App.Prc.MaterialRequestPlanTrack › UpdateCommand): stoktan karşılamayı geri alır. Stoktan karşılama belge
-- açmadığı için geri dönüşü kalemin kendisidir: stoktan karşılanan miktar teslim edilenden düşülür ve sıfırlanır, kalanı yeniden açılan
-- kapalı kalem Bekliyor'a döner ve Planlama'da yeniden planlanır (Prc_P_MaterialRequestItemSync ile aynı kural).
CREATE OR ALTER PROCEDURE [dbo].[Prc_P_MaterialRequestStockUndo]
@Id uniqueidentifier,
@TenantId uniqueidentifier,
@LastModifierId uniqueidentifier
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
BEGIN TRANSACTION;
UPDATE Prc_T_MaterialRequestItem
SET DeliveredQuantity = CASE WHEN DeliveredQuantity > FromStockQuantity THEN DeliveredQuantity - FromStockQuantity ELSE 0 END,
FromStockQuantity = 0, LastModificationTime = GETUTCDATE(), LastModifierId = @LastModifierId
WHERE Id = @Id AND IsDeleted = 0 AND FromStockQuantity > 0 AND LineStatus IN ('Waiting', 'Done')
AND (TenantId = @TenantId OR (TenantId IS NULL AND @TenantId IS NULL));
IF @@ROWCOUNT = 0
THROW 50202, N'Geri alınacak stoktan karşılama yok ya da kalem kapatılmış.', 1;
UPDATE i SET LineStatus = 'Waiting'
FROM Prc_T_MaterialRequestItem i
INNER JOIN Prc_V_MaterialRequestItemPlan p ON p.Id = i.Id
WHERE i.Id = @Id AND i.LineStatus = 'Done' AND p.RemainingQuantity > 0 AND i.DeliveredQuantity < i.Quantity;
COMMIT TRANSACTION;
END

View file

@ -1,8 +1,9 @@
-- Onaylanan talebin durumu satınalmada ilerledikçe iş akışının durum alanında devam eder: kalemlerinden biri
-- Onaylanan talebin durumu satınalmada ilerledikçe iş akışının durum alanında devam eder: iptal olmayan bütün kalemleri
-- teslim edildiyse (teslim edilen ≥ istenen: iç transfer, Stoktan ya da alım Doğrula'sıyla) Tamamlandı; değilse kalemlerinden biri
-- iptal olmayan bir siparişteyse Satınalma Siparişi, gönderilmiş teklif talebindeyse Teklif Talebi Gönderildi,
-- taslak teklif talebindeyse Teklif Talebi; hiçbirinde değilse Onaylandı'ya döner. Akış "Onaylandı"da bittiği
-- için bu değerler hiçbir onay düğümüyle eşleşmez ve akış butonları kapalı kalır. @DocId verilirse yalnız o
-- belgenin (teklifte bütün ihalenin) kalemlerine bağlı talepler; boşsa onaylanmış bütün talepler yeniden hesaplanır.
-- taslak teklif talebindeyse Teklif Talebi; hiçbirinde değilse Onaylandı'ya döner (iade teslimi geri alırsa Tamamlandı da geri döner).
-- Akış "Onaylandı"da bittiği için bu değerler hiçbir onay düğümüyle eşleşmez ve akış butonları kapalı kalır. @DocId verilirse yalnız o
-- belgenin (teklifte bütün ihalenin; transferde satırlarının) kalemlerine bağlı talepler; boşsa onaylanmış bütün talepler yeniden hesaplanır.
CREATE OR ALTER PROCEDURE [dbo].[Prc_P_MaterialRequestSyncStatus]
@DocId uniqueidentifier = NULL
AS
@ -18,6 +19,11 @@ BEGIN
UPDATE m SET ApprovalStatus = s.Stage
FROM Prc_T_MaterialRequest m
CROSS APPLY (SELECT CASE
WHEN NOT EXISTS (SELECT 1 FROM Prc_T_MaterialRequestItem i
WHERE i.MaterialRequestId = m.Id AND i.IsDeleted = 0 AND i.LineStatus <> 'Cancelled'
AND i.DeliveredQuantity < i.Quantity)
AND EXISTS (SELECT 1 FROM Prc_T_MaterialRequestItem i
WHERE i.MaterialRequestId = m.Id AND i.IsDeleted = 0 AND i.LineStatus <> 'Cancelled') THEN N'Tamamlandı'
WHEN EXISTS (SELECT 1 FROM Prc_T_MaterialRequestItem i
INNER JOIN Prc_T_PurchaseOrderLine ol ON ol.MaterialRequestItemId = i.Id AND ol.IsDeleted = 0
INNER JOIN Prc_T_PurchaseOrder o ON o.Id = ol.PurchaseOrderId AND o.IsDeleted = 0 AND o.Status <> 'Cancelled'
@ -32,7 +38,7 @@ BEGIN
WHERE i.MaterialRequestId = m.Id AND i.IsDeleted = 0) THEN N'Teklif Talebi'
ELSE N'Onaylandı' END AS Stage) s
WHERE m.IsDeleted = 0
AND m.ApprovalStatus IN (N'Onaylandı', N'Teklif Talebi', N'Teklif Talebi Gönderildi', N'Satınalma Siparişi')
AND m.ApprovalStatus IN (N'Onaylandı', N'Teklif Talebi', N'Teklif Talebi Gönderildi', N'Satınalma Siparişi', N'Tamamlandı')
AND m.ApprovalStatus <> s.Stage
-- Silinen satır da kapsamda kalır: kalemi belgeden çıkarılan talep geri dönmelidir.
AND (@DocId IS NULL OR EXISTS (
@ -42,5 +48,7 @@ BEGIN
INNER JOIN Prc_T_PurchaseRfq q ON q.Id = rl.PurchaseRfqId
WHERE rl.MaterialRequestItemId = i.Id AND ISNULL(q.TenderGroupId, q.Id) = @Group)
OR EXISTS (SELECT 1 FROM Prc_T_PurchaseOrderLine ol
WHERE ol.MaterialRequestItemId = i.Id AND ol.PurchaseOrderId = @DocId))));
WHERE ol.MaterialRequestItemId = i.Id AND ol.PurchaseOrderId = @DocId)
OR EXISTS (SELECT 1 FROM Inv_T_TransferLine tl
WHERE tl.MaterialRequestItemId = i.Id AND tl.TransferId = @DocId))));
END

View file

@ -7,7 +7,10 @@ CREATE OR ALTER PROCEDURE [dbo].[Prc_P_PurchaseRfqAward]
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @Group uniqueidentifier, @Tenant uniqueidentifier, @Rfq uniqueidentifier, @Po uniqueidentifier, @No nvarchar(128);
BEGIN TRANSACTION;
DECLARE @Win TABLE (LineId uniqueidentifier PRIMARY KEY, RfqId uniqueidentifier NOT NULL);
SELECT @Group = TenderGroupId, @Tenant = TenantId FROM Prc_T_PurchaseRfq WHERE Id = @Id;
@ -65,4 +68,6 @@ BEGIN
UPDATE r SET Status = CASE WHEN EXISTS (SELECT 1 FROM @Win w WHERE w.RfqId = r.Id) THEN 'Purchase' ELSE 'Cancelled' END
FROM Prc_T_PurchaseRfq r
WHERE r.TenderGroupId = @Group AND r.IsDeleted = 0 AND r.Status <> 'Cancelled';
COMMIT TRANSACTION;
END

View file

@ -11,7 +11,6 @@ BEGIN
[DueDate] date NOT NULL,
[RequestReason] nvarchar(256) NOT NULL,
[DeliveredQuantity] decimal(18, 4) NOT NULL DEFAULT 0,
[FromStockQuantity] decimal(18, 4) NOT NULL DEFAULT 0,
[LineStatus] nvarchar(16) NOT NULL DEFAULT 'Waiting',
[CreationTime] datetime2 NOT NULL DEFAULT GETUTCDATE(),
[CreatorId] uniqueidentifier NULL,

View file

@ -1,5 +1,5 @@
-- Planla diyaloğunun taslak karşılama planı: talep kaleminin onaylanmamış dağıtımı (iç transfer: kaynak konum, satınalma: tedarikçi) ve
-- miktarı. Onay (Prc_P_MaterialRequestPlanConfirm) satırları teklif talebine ya da iç transfere çevirir ve siler.
-- miktarı. İç transferde lot/seri takipli ürünün satırı lotu da taşır (LotNo; takipsiz üründe boş). Onay (Prc_P_MaterialRequestPlanConfirm) satırları teklif talebine ya da iç transfere çevirir ve siler.
IF OBJECT_ID(N'[dbo].[Prc_T_MaterialRequestPlanLine]', 'U') IS NULL
BEGIN
CREATE TABLE [dbo].[Prc_T_MaterialRequestPlanLine]
@ -10,6 +10,7 @@ BEGIN
[PlanMethod] nvarchar(16) NOT NULL,
[SupplierId] uniqueidentifier NULL,
[SourceLocationId] uniqueidentifier NULL,
[LotNo] nvarchar(64) NOT NULL DEFAULT '',
[Quantity] decimal(18, 4) NOT NULL DEFAULT 0,
[CreationTime] datetime2 NOT NULL DEFAULT GETUTCDATE(),
[CreatorId] uniqueidentifier NULL,

View file

@ -1,13 +1,11 @@
-- Talep kaleminin planlanmış payları ve planlanacak kalanı (Planlama, Plan Takibi, kalem durumu). Miktarlar kalemin birimine çevrilir.
-- Satınalma payı: teklif aşamasındaki teklif talebinde ya da iptal olmayan siparişe geçmiş teklif kaleminde duran miktar; ihale aynı kalemi
-- bütün tedarikçilere kopyaladığı için ihale × ihale kalemi başına bir kez (en büyüğü) sayılır.
-- Transfer payı: iptal olmayan iç transfer satırı — tamamlanmış belgede yapılan, açık belgede istenen miktar (eksik tamamlanan belgenin kalanı
-- backorder belgesinde istenir); iade belgesi sayılmaz.
-- Stok payı: stok talebin teslim konumundayken onaylanan, belgesiz karşılanan miktar (FromStockQuantity).
-- Transfer payı (Stoktan kararı dahil — kaynak ve hedefi teslim konumu olan transfer): iptal olmayan iç transfer satırı — tamamlanmış belgede yapılan, açık belgede istenen miktar (eksik tamamlanan belgenin kalanı
-- backorder belgesinde istenir); tamamlanmış iade belgesinin yapılan miktarı paydan düşer (iade edilen kalem yeniden planlanır).
CREATE OR ALTER VIEW [dbo].[Prc_V_MaterialRequestItemPlan] AS
SELECT i.Id, i.TenantId, ISNULL(pq.Quantity, 0) AS PurchaseQuantity, ISNULL(tq.Quantity, 0) AS TransferQuantity,
i.Quantity - ISNULL(pq.Quantity, 0) - ISNULL(tq.Quantity, 0) - i.FromStockQuantity AS RemainingQuantity,
i.FromStockQuantity
i.Quantity - ISNULL(pq.Quantity, 0) - ISNULL(tq.Quantity, 0) AS RemainingQuantity
FROM Prc_T_MaterialRequestItem i
OUTER APPLY (SELECT SUM(g.Quantity) AS Quantity
FROM (SELECT MAX(c.Quantity) AS Quantity
@ -24,9 +22,10 @@ SELECT i.Id, i.TenantId, ISNULL(pq.Quantity, 0) AS PurchaseQuantity, ISNULL(tq.Q
AND o.IsDeleted = 0 AND o.Status <> 'Cancelled')))) c
GROUP BY c.TenderGroupId, c.TenderLineId) g) pq
OUTER APPLY (SELECT SUM(c.Quantity) AS Quantity
FROM (SELECT dbo.Inv_F_UomConvert(CASE WHEN t.Status = 'Done' THEN tl.Quantity ELSE tl.DemandQuantity END, tl.UomId, i.UomId) AS Quantity
FROM (SELECT dbo.Inv_F_UomConvert(CASE WHEN t.ReturnOfId IS NOT NULL THEN CASE WHEN t.Status = 'Done' THEN -tl.Quantity ELSE 0 END
WHEN t.Status = 'Done' THEN tl.Quantity ELSE tl.DemandQuantity END, tl.UomId, i.UomId) AS Quantity
FROM Inv_T_TransferLine tl
INNER JOIN Inv_T_Transfer t ON t.Id = tl.TransferId
WHERE tl.MaterialRequestItemId = i.Id AND tl.IsDeleted = 0 AND t.IsDeleted = 0
AND t.OperationKind = 'InternalTransfer' AND t.Status <> 'Cancelled' AND t.ReturnOfId IS NULL) c) tq
AND t.OperationKind = 'InternalTransfer' AND t.Status <> 'Cancelled') c) tq
WHERE i.IsDeleted = 0

View file

@ -1,8 +1,8 @@
-- Planla diyaloğunun Karşılama Planı ızgarası (App.Prc.MaterialRequestPlanLine): talep kaleminin onay bekleyen taslak planı. Miktar kalemin
-- biriminde; satınalmada birim fiyat teklif kalemine yazılacak fiyattır (tedarikçinin en düşük minimum miktarlı satırı). BaseId kalemdir.
-- biriminde; iç transferde lot/seri takipli ürünün lotu (LotNo); satınalmada birim fiyat teklif kalemine yazılacak fiyattır (tedarikçinin en düşük minimum miktarlı satırı). BaseId kalemdir.
CREATE OR ALTER VIEW [dbo].[Prc_V_MaterialRequestPlanLine] AS
SELECT pl.Id, pl.TenantId, pl.MaterialRequestItemId AS BaseId, pl.PlanMethod, pl.SupplierId, pl.SourceLocationId, pl.Quantity, i.UomId,
ps.Price, ps.CurrencyId, pl.CreationTime, pl.CreatorId, pl.IsDeleted
ps.Price, ps.CurrencyId, pl.CreationTime, pl.CreatorId, pl.IsDeleted, NULLIF(pl.LotNo, '') AS LotNo
FROM Prc_T_MaterialRequestPlanLine pl
INNER JOIN Prc_T_MaterialRequestItem i ON i.Id = pl.MaterialRequestItemId
OUTER APPLY (SELECT TOP 1 x.Price, x.CurrencyId

View file

@ -1,38 +1,80 @@
-- Planla diyaloğunun İç Transfer ızgarası (App.Prc.MaterialRequestPlanSource) ve iç transfer / stoktan karşılama kararlarının stok kuralı:
-- talep kaleminin ürününün stoğu olan iç konumlar. Talebin teslim konumu da listelenir (IsDestination): oraya yazılan plan transfer açmaz,
-- stoktan karşılanır (PlanMethod = Stock). Miktarlar kalemin biriminde; ayrılan = açık (Taslak/Bekleyen/Hazır) transferlerde o
-- konumdan istenen, serbest = eldeki − ayrılan. Plan Miktarı kalemin bu konum için taslak planıdır. BaseId diyaloğun süzdüğü kalem, Id
-- kalem + ':' + konumdur (Prc_P_MaterialRequestPlanLineSave ayırır); taslak kaydı ve onay serbest stoğu buradan okur.
-- MaxQuantity satıra yazılabilecek en fazla plan miktarıdır: serbest stok ile planlanacak kalandan kalemin diğer taslak satırları
-- düşüldükten sonra kalanın küçüğü (ızgaranın doğrulaması; kayıt yordamı aynı kuralı yeniden denetler).
-- talep kaleminin ürününün stoğu olan iç konumlar. Ürün lot/seri ile takip ediliyorsa satır konum × lottur (seride her seri ayrı satır), yoksa
-- konum başına tek satırdır (LotNo boş). Talebin teslim konumu da listelenir (IsDestination): oraya yazılan plan Stoktan kararıdır (PlanMethod =
-- Stock; kaynağı ve hedefi teslim konumu olan iç transfer açar). Miktarlar kalemin biriminde; ayrılan = açık (Taslak/Bekleyen/Hazır) transferlerde o konumdan istenen
-- (lot satırında o lota atanmış), serbest = eldeki − ayrılan, lot satırında konumun serbest stoğuyla sınırlı (lotu henüz atanmamış istek de
-- konumdan düşer). Plan Miktarı kalemin bu satır için taslak planıdır. BaseId diyaloğun süzdüğü kalem, Id kalem + ':' + konum + ':' + lottur
-- (Prc_P_MaterialRequestPlanLineSave ayırır); taslak kaydı ve onay serbest stoğu buradan okur.
-- AvailableQuantity satırın taslak planda kullanabileceği stoktur (aynı konumun diğer lotlarına yazılmış taslak konumdan düşer);
-- MaxQuantity bununla planlanacak kalandan kalemin diğer taslak satırları düşüldükten sonra kalanın küçüğüdür (ızgaranın doğrulaması; kayıt
-- yordamı aynı kuralı yeniden denetler). RemovalRank Öner'in ve Seçilenleri Planla'nın sırasıdır: teslim konumu önce, sonra ürün
-- kategorisinin çıkış stratejisi (FIFO: en eski giriş, LIFO: en yeni giriş; aynı anda girenlerde lot/seri no — LIFO'da büyükten; kategorisiz ürün FIFO).
CREATE OR ALTER VIEW [dbo].[Prc_V_MaterialRequestPlanSource] AS
SELECT CONCAT(CAST(i.Id AS nvarchar(36)), ':', CAST(st.LocationId AS nvarchar(36))) AS Id, i.TenantId, i.Id AS BaseId,
l.BranchId, l.WarehouseId, st.LocationId, st.OnHand, ISNULL(rs.Quantity, 0) AS ReservedQuantity,
st.OnHand - ISNULL(rs.Quantity, 0) AS FreeQuantity, i.UomId, pl.Quantity AS PlanQuantity, i.IsDeleted,
CAST(CASE WHEN st.LocationId = r.LocationId THEN 1 ELSE 0 END AS bit) AS IsDestination, mx.Quantity AS MaxQuantity
FROM Prc_T_MaterialRequestItem i
INNER JOIN Prc_T_MaterialRequest r ON r.Id = i.MaterialRequestId
CROSS APPLY (SELECT c.LocationId, SUM(c.Quantity) AS OnHand
FROM (SELECT s.LocationId, s.Quantity AS Raw, dbo.Inv_F_UomConvert(s.Quantity, s.UomId, i.UomId) AS Quantity
FROM Inv_T_Stock s
WHERE s.ProductId = i.ProductId AND s.IsDeleted = 0) c
GROUP BY c.LocationId
HAVING SUM(c.Raw) > 0) st
INNER JOIN Inv_T_Location l ON l.Id = st.LocationId AND l.LocationType = 'Internal' AND l.IsDeleted = 0
OUTER APPLY (SELECT SUM(c.Quantity) AS Quantity
FROM (SELECT dbo.Inv_F_UomConvert(tl.DemandQuantity, tl.UomId, i.UomId) AS Quantity
FROM Inv_T_TransferLine tl
INNER JOIN Inv_T_Transfer t ON t.Id = tl.TransferId
WHERE t.SourceLocationId = st.LocationId AND tl.ProductId = i.ProductId AND tl.IsDeleted = 0 AND t.IsDeleted = 0
AND t.Status IN ('Draft', 'Waiting', 'Ready')) c) rs
WITH it AS (
SELECT i.Id, i.TenantId, i.ProductId, i.UomId, i.IsDeleted, r.LocationId AS DestinationId,
CASE WHEN p.TrackInventory = 1 AND p.TrackingMethod IN ('Lot', 'Serial') THEN 1 ELSE 0 END AS IsTracked,
ISNULL(pc.RemovalStrategy, 'FIFO') AS RemovalStrategy
FROM Prc_T_MaterialRequestItem i
INNER JOIN Prc_T_MaterialRequest r ON r.Id = i.MaterialRequestId
INNER JOIN Inv_T_Product p ON p.Id = i.ProductId
LEFT JOIN Inv_T_ProductCategory pc ON pc.Id = p.CategoryId
WHERE i.IsDeleted = 0),
st AS (
SELECT it.Id AS ItemId, s.LocationId, CASE WHEN it.IsTracked = 1 THEN s.LotNo ELSE '' END AS LotNo,
SUM(dbo.Inv_F_UomConvert(s.Quantity, s.UomId, it.UomId)) AS OnHand, MIN(s.InDate) AS FirstIn, MAX(s.InDate) AS LastIn
FROM it
INNER JOIN Inv_T_Stock s ON s.ProductId = it.ProductId AND s.IsDeleted = 0
GROUP BY it.Id, s.LocationId, CASE WHEN it.IsTracked = 1 THEN s.LotNo ELSE '' END
HAVING SUM(s.Quantity) > 0),
rs AS (
SELECT it.Id AS ItemId, t.SourceLocationId AS LocationId, SUM(dbo.Inv_F_UomConvert(tl.DemandQuantity, tl.UomId, it.UomId)) AS Quantity
FROM it
INNER JOIN Inv_T_TransferLine tl ON tl.ProductId = it.ProductId AND tl.IsDeleted = 0
INNER JOIN Inv_T_Transfer t ON t.Id = tl.TransferId AND t.IsDeleted = 0 AND t.Status IN ('Draft', 'Waiting', 'Ready')
GROUP BY it.Id, t.SourceLocationId),
lr AS (
SELECT it.Id AS ItemId, t.SourceLocationId AS LocationId, tll.LotNo, SUM(dbo.Inv_F_UomConvert(tll.Quantity, tl.UomId, it.UomId)) AS Quantity
FROM it
INNER JOIN Inv_T_TransferLine tl ON tl.ProductId = it.ProductId AND tl.IsDeleted = 0
INNER JOIN Inv_T_Transfer t ON t.Id = tl.TransferId AND t.IsDeleted = 0 AND t.Status IN ('Draft', 'Waiting', 'Ready')
INNER JOIN Inv_T_TransferLineLot tll ON tll.TransferLineId = tl.Id AND tll.IsDeleted = 0
WHERE it.IsTracked = 1
GROUP BY it.Id, t.SourceLocationId, tll.LotNo),
b AS (
SELECT st.ItemId, st.LocationId, st.LotNo, st.OnHand, st.FirstIn, st.LastIn,
CASE WHEN it.IsTracked = 1 THEN ISNULL(lr.Quantity, 0) ELSE ISNULL(rs.Quantity, 0) END AS Reserved,
SUM(st.OnHand) OVER (PARTITION BY st.ItemId, st.LocationId) - ISNULL(rs.Quantity, 0) AS LocationFree
FROM st
INNER JOIN it ON it.Id = st.ItemId
LEFT JOIN rs ON rs.ItemId = st.ItemId AND rs.LocationId = st.LocationId
LEFT JOIN lr ON lr.ItemId = st.ItemId AND lr.LocationId = st.LocationId AND lr.LotNo = st.LotNo)
SELECT CONCAT(CAST(it.Id AS nvarchar(36)), ':', CAST(b.LocationId AS nvarchar(36)), ':', b.LotNo) AS Id, it.TenantId, it.Id AS BaseId,
l.BranchId, l.WarehouseId, b.LocationId, NULLIF(b.LotNo, '') AS LotNo, b.OnHand, b.Reserved AS ReservedQuantity,
fr.Quantity AS FreeQuantity, it.UomId, pl.Quantity AS PlanQuantity, it.IsDeleted,
CAST(CASE WHEN b.LocationId = it.DestinationId THEN 1 ELSE 0 END AS bit) AS IsDestination, mx.Quantity AS MaxQuantity,
av.Quantity AS AvailableQuantity,
ROW_NUMBER() OVER (PARTITION BY it.Id
ORDER BY CASE WHEN b.LocationId = it.DestinationId THEN 0 ELSE 1 END,
CASE WHEN it.RemovalStrategy = 'LIFO' THEN NULL ELSE ISNULL(b.FirstIn, '9999-12-31') END,
CASE WHEN it.RemovalStrategy = 'LIFO' THEN ISNULL(b.LastIn, '1900-01-01') END DESC,
fr.Quantity DESC,
CASE WHEN it.RemovalStrategy = 'LIFO' THEN NULL ELSE b.LotNo END,
CASE WHEN it.RemovalStrategy = 'LIFO' THEN b.LotNo END DESC) AS RemovalRank
FROM b
INNER JOIN it ON it.Id = b.ItemId
INNER JOIN Inv_T_Location l ON l.Id = b.LocationId AND l.LocationType = 'Internal' AND l.IsDeleted = 0
INNER JOIN Prc_V_MaterialRequestItemPlan ip ON ip.Id = it.Id
LEFT JOIN Prc_T_MaterialRequestPlanLine pl
ON pl.MaterialRequestItemId = i.Id AND pl.PlanMethod IN ('Transfer', 'Stock') AND pl.SourceLocationId = st.LocationId AND pl.IsDeleted = 0
INNER JOIN Prc_V_MaterialRequestItemPlan ip ON ip.Id = i.Id
OUTER APPLY (SELECT SUM(x.Quantity) AS Quantity
FROM Prc_T_MaterialRequestPlanLine x
WHERE x.MaterialRequestItemId = i.Id AND x.IsDeleted = 0 AND (x.SourceLocationId IS NULL OR x.SourceLocationId <> st.LocationId)) od
ON pl.MaterialRequestItemId = it.Id AND pl.PlanMethod IN ('Transfer', 'Stock') AND pl.SourceLocationId = b.LocationId
AND pl.LotNo = b.LotNo AND pl.IsDeleted = 0
OUTER APPLY (SELECT SUM(y.Quantity) AS Total, SUM(y.SameLocation) AS SameLocation
FROM (SELECT x.Quantity, CASE WHEN x.SourceLocationId = b.LocationId THEN x.Quantity ELSE 0 END AS SameLocation
FROM Prc_T_MaterialRequestPlanLine x
WHERE x.MaterialRequestItemId = it.Id AND x.IsDeleted = 0 AND (pl.Id IS NULL OR x.Id <> pl.Id)) y) od
CROSS APPLY (SELECT CASE WHEN b.OnHand - b.Reserved < b.LocationFree THEN b.OnHand - b.Reserved ELSE b.LocationFree END AS Quantity) fr
CROSS APPLY (SELECT CASE WHEN fr.Quantity < b.LocationFree - ISNULL(od.SameLocation, 0) THEN fr.Quantity
ELSE b.LocationFree - ISNULL(od.SameLocation, 0) END AS Quantity) av
CROSS APPLY (SELECT CASE WHEN v.Quantity < 0 THEN 0 ELSE v.Quantity END AS Quantity
FROM (SELECT CASE WHEN st.OnHand - ISNULL(rs.Quantity, 0) < ip.RemainingQuantity - ISNULL(od.Quantity, 0)
THEN st.OnHand - ISNULL(rs.Quantity, 0) ELSE ip.RemainingQuantity - ISNULL(od.Quantity, 0) END AS Quantity) v) mx
WHERE i.IsDeleted = 0;
FROM (SELECT CASE WHEN av.Quantity < ip.RemainingQuantity - ISNULL(od.Total, 0) THEN av.Quantity
ELSE ip.RemainingQuantity - ISNULL(od.Total, 0) END AS Quantity) v) mx;
GO

View file

@ -1,7 +1,7 @@
-- Plan Takibi (App.Prc.MaterialRequestPlanTrack): talep kalemleri için verilen her karar — satınalmada ihalenin kök teklif talebindeki kalem
-- (alternatif tedarikçilere kopyalanan satırlar tekrar listelenmez; siparişe dönüştüyse ihale kaleminin siparişi ve tedarikçisi), iç
-- transferde transfer satırı, stoktan karşılamada kalemin kendisi (belgesiz; konum talebin teslim konumu). Gerçekleşen: siparişte alınan,
-- transferde tamamlanmış belgede yapılan, stokta karşılanan miktar.
-- transferde transfer satırı; kaynak ve hedefi aynı (teslim konumu) olan transfer Stoktan kararıdır. Gerçekleşen: siparişte alınan,
-- transferde tamamlanmış belgede yapılan miktar.
CREATE OR ALTER VIEW [dbo].[Prc_V_MaterialRequestPlanTrack] AS
SELECT rl.Id, rl.TenantId, i.Id AS MaterialRequestItemId, i.MaterialRequestId, r.RequestNo, r.BranchId, r.DepartmentId, r.WarehouseId,
r.LocationId, i.ProductId, i.DueDate, CAST('Purchase' AS nvarchar(16)) AS PlanMethod, q.Id AS DocumentId, q.RfqNo AS DocumentNo,
@ -21,7 +21,7 @@ SELECT rl.Id, rl.TenantId, i.Id AS MaterialRequestItemId, i.MaterialRequestId, r
WHERE rl.IsDeleted = 0
UNION ALL
SELECT tl.Id, tl.TenantId, i.Id, i.MaterialRequestId, r.RequestNo, r.BranchId, r.DepartmentId, r.WarehouseId,
r.LocationId, i.ProductId, i.DueDate, CAST('Transfer' AS nvarchar(16)), t.Id, t.TransferNo,
r.LocationId, i.ProductId, i.DueDate, CAST(CASE WHEN t.SourceLocationId = t.DestinationLocationId THEN 'Stock' ELSE 'Transfer' END AS nvarchar(16)), t.Id, t.TransferNo,
t.Status, NULL, t.SourceLocationId,
NULL, NULL, NULL, tl.DemandQuantity, tl.UomId,
CASE WHEN t.Status = 'Done' THEN tl.Quantity ELSE 0 END, tl.CreationTime, tl.CreatorId, tl.IsDeleted
@ -30,12 +30,3 @@ SELECT tl.Id, tl.TenantId, i.Id, i.MaterialRequestId, r.RequestNo, r.BranchId, r
INNER JOIN Prc_T_MaterialRequestItem i ON i.Id = tl.MaterialRequestItemId
INNER JOIN Prc_T_MaterialRequest r ON r.Id = i.MaterialRequestId
WHERE tl.IsDeleted = 0
UNION ALL
SELECT i.Id, i.TenantId, i.Id, i.MaterialRequestId, r.RequestNo, r.BranchId, r.DepartmentId, r.WarehouseId,
r.LocationId, i.ProductId, i.DueDate, CAST('Stock' AS nvarchar(16)), NULL, NULL,
NULL, NULL, r.LocationId,
NULL, NULL, NULL, i.FromStockQuantity, i.UomId,
i.FromStockQuantity, i.LastModificationTime, i.LastModifierId, i.IsDeleted
FROM Prc_T_MaterialRequestItem i
INNER JOIN Prc_T_MaterialRequest r ON r.Id = i.MaterialRequestId
WHERE i.FromStockQuantity > 0

View file

@ -4,6 +4,7 @@ BEGIN
(
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
[TenantId] uniqueidentifier NULL,
[BranchId] uniqueidentifier NOT NULL,
[ProjectId] uniqueidentifier NOT NULL,
[WorkPackageId] uniqueidentifier NULL,
[UserId] uniqueidentifier NOT NULL,

View file

@ -4,6 +4,7 @@ BEGIN
(
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
[TenantId] uniqueidentifier NULL,
[BranchId] uniqueidentifier NOT NULL,
[ProjectNo] nvarchar(32) NOT NULL,
[Name] nvarchar(512) NOT NULL,
[ProjectType] nvarchar(32) NULL,

View file

@ -4,6 +4,7 @@ BEGIN
(
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
[TenantId] uniqueidentifier NULL,
[BranchId] uniqueidentifier NOT NULL,
[ProjectId] uniqueidentifier NOT NULL,
[ParentId] uniqueidentifier NULL,
[Code] nvarchar(16) NOT NULL,

View file

@ -1,7 +1,7 @@
CREATE OR ALTER VIEW [dbo].[Prj_V_BudgetMonthly]
AS
WITH base AS (
SELECT x.[TenantId], w.[ProjectId], x.[ResourceType], x.[Kind], ISNULL(x.[Cost], 0) AS [Cost],
SELECT x.[TenantId], p.[BranchId], w.[ProjectId], x.[ResourceType], x.[Kind], ISNULL(x.[Cost], 0) AS [Cost],
DATEFROMPARTS(YEAR(COALESCE(x.[DocumentDate], w.[StartDate])), MONTH(COALESCE(x.[DocumentDate], w.[StartDate])), 1) AS [PeriodDate]
FROM [dbo].[Prj_T_WorkPackageResource] x
INNER JOIN [dbo].[Prj_T_WorkPackage] w ON w.[Id] = x.[WorkPackageId] AND w.[IsDeleted] = 0
@ -9,11 +9,11 @@ WITH base AS (
WHERE x.[IsDeleted] = 0
),
monthly AS (
SELECT [TenantId], [ProjectId], [ResourceType], [PeriodDate],
SELECT [TenantId], [BranchId], [ProjectId], [ResourceType], [PeriodDate],
SUM(CASE WHEN [Kind] = 'Planned' THEN [Cost] ELSE 0 END) AS [Planned],
SUM(CASE WHEN [Kind] = 'Actual' THEN [Cost] ELSE 0 END) AS [Actual]
FROM base
GROUP BY [TenantId], [ProjectId], [ResourceType], [PeriodDate]
GROUP BY [TenantId], [BranchId], [ProjectId], [ResourceType], [PeriodDate]
)
SELECT
CAST(CONCAT(CAST(m.[ProjectId] AS nvarchar(36)), '|', m.[ResourceType]) AS nvarchar(120)) AS [Id],
@ -26,9 +26,10 @@ SELECT
CAST(SUM(m.[Planned]) AS decimal(18, 4)) AS [Planned],
CAST(SUM(m.[Actual]) AS decimal(18, 4)) AS [Actual],
CAST(CASE WHEN SUM(m.[Planned]) > 0 THEN SUM(m.[Actual]) * 100.0 / SUM(m.[Planned]) ELSE 0 END AS decimal(18, 4)) AS [Ratio],
CAST(CASE WHEN SUM(m.[Planned]) > 0 THEN CASE WHEN SUM(m.[Actual]) * 100.0 / SUM(m.[Planned]) > 100 THEN 100 ELSE SUM(m.[Actual]) * 100.0 / SUM(m.[Planned]) END ELSE 0 END AS decimal(18, 4)) AS [Progress]
CAST(CASE WHEN SUM(m.[Planned]) > 0 THEN CASE WHEN SUM(m.[Actual]) * 100.0 / SUM(m.[Planned]) > 100 THEN 100 ELSE SUM(m.[Actual]) * 100.0 / SUM(m.[Planned]) END ELSE 0 END AS decimal(18, 4)) AS [Progress],
m.[BranchId]
FROM monthly m
GROUP BY m.[TenantId], m.[ProjectId], m.[ResourceType]
GROUP BY m.[TenantId], m.[BranchId], m.[ProjectId], m.[ResourceType]
UNION ALL
SELECT
CAST(CONCAT(CAST(m.[ProjectId] AS nvarchar(36)), '|', m.[ResourceType], '|', FORMAT(m.[PeriodDate], 'yyyy-MM')) AS nvarchar(120)),
@ -40,6 +41,7 @@ SELECT
YEAR(m.[PeriodDate]), MONTH(m.[PeriodDate]),
CAST(m.[Planned] AS decimal(18, 4)), CAST(m.[Actual] AS decimal(18, 4)),
CAST(CASE WHEN m.[Planned] > 0 THEN m.[Actual] * 100.0 / m.[Planned] ELSE 0 END AS decimal(18, 4)),
CAST(CASE WHEN m.[Planned] > 0 THEN CASE WHEN m.[Actual] * 100.0 / m.[Planned] > 100 THEN 100 ELSE m.[Actual] * 100.0 / m.[Planned] END ELSE 0 END AS decimal(18, 4))
CAST(CASE WHEN m.[Planned] > 0 THEN CASE WHEN m.[Actual] * 100.0 / m.[Planned] > 100 THEN 100 ELSE m.[Actual] * 100.0 / m.[Planned] END ELSE 0 END AS decimal(18, 4)),
m.[BranchId]
FROM monthly m
GO

View file

@ -1,7 +1,7 @@
CREATE OR ALTER VIEW [dbo].[Prj_V_ManMonthGantt]
AS
WITH base AS (
SELECT r.[TenantId], w.[ProjectId], r.[UserId], w.[Id] AS [WorkPackageId],
SELECT r.[TenantId], p.[BranchId], w.[ProjectId], r.[UserId], w.[Id] AS [WorkPackageId],
w.[Code], w.[Name], r.[Rate], DATEFROMPARTS(r.[Year], r.[Month], 1) AS [PeriodDate]
FROM [dbo].[Prj_T_WorkPackageMonthRate] r
INNER JOIN [dbo].[Prj_T_WorkPackage] w ON w.[Id] = r.[WorkPackageId] AND w.[IsDeleted] = 0
@ -19,10 +19,11 @@ SELECT
CAST(AVG(b.[Rate]) AS decimal(18, 4)) AS [Progress],
CAST(AVG(b.[Rate]) AS decimal(18, 4)) AS [AvgRate],
CAST(SUM(b.[Rate]) AS decimal(18, 4)) AS [TotalRate],
COUNT(DISTINCT b.[PeriodDate]) AS [MonthCount]
COUNT(DISTINCT b.[PeriodDate]) AS [MonthCount],
b.[BranchId]
FROM base b
LEFT JOIN [dbo].[AbpUsers] u ON u.[Id] = b.[UserId]
GROUP BY b.[TenantId], b.[ProjectId], b.[UserId]
GROUP BY b.[TenantId], b.[BranchId], b.[ProjectId], b.[UserId]
UNION ALL
SELECT
CAST(CONCAT(CAST(b.[ProjectId] AS nvarchar(36)), '|', CAST(b.[UserId] AS nvarchar(36)), '|', CAST(b.[WorkPackageId] AS nvarchar(36))) AS nvarchar(120)),
@ -35,7 +36,8 @@ SELECT
CAST(AVG(b.[Rate]) AS decimal(18, 4)),
CAST(AVG(b.[Rate]) AS decimal(18, 4)),
CAST(SUM(b.[Rate]) AS decimal(18, 4)),
COUNT(DISTINCT b.[PeriodDate])
COUNT(DISTINCT b.[PeriodDate]),
b.[BranchId]
FROM base b
GROUP BY b.[TenantId], b.[ProjectId], b.[UserId], b.[WorkPackageId]
GROUP BY b.[TenantId], b.[BranchId], b.[ProjectId], b.[UserId], b.[WorkPackageId]
GO

View file

@ -10,7 +10,8 @@ SELECT
CAST(ISNULL(u.[Rate], 100) AS decimal(18, 4)) AS [MonthlyRate],
CAST(r.[Rate] * ISNULL(u.[Rate], 100) / 100.0 AS decimal(18, 4)) AS [EffectiveRate],
CAST(ISNULL(pm.[AvgMonthlyCost], 0) AS decimal(18, 4)) AS [UnitCost],
CAST(ISNULL(pm.[AvgMonthlyCost], 0) * r.[Rate] * ISNULL(u.[Rate], 100) / 10000.0 AS decimal(18, 4)) AS [TotalCost]
CAST(ISNULL(pm.[AvgMonthlyCost], 0) * r.[Rate] * ISNULL(u.[Rate], 100) / 10000.0 AS decimal(18, 4)) AS [TotalCost],
p.[BranchId]
FROM [dbo].[Prj_T_WorkPackageMonthRate] r
INNER JOIN [dbo].[Prj_T_WorkPackage] w ON w.[Id] = r.[WorkPackageId] AND w.[IsDeleted] = 0
INNER JOIN [dbo].[Prj_T_Project] p ON p.[Id] = w.[ProjectId] AND p.[IsDeleted] = 0

View file

@ -7,7 +7,8 @@ SELECT
x.[Kind], x.[ResourceType], x.[UserId], x.[ResourceName],
x.[Quantity], x.[Unit], x.[Price], x.[VatRate], x.[Cost],
x.[DocumentDate], x.[DocumentNo], x.[OrganizationType], x.[OrganizationName],
x.[WorkDone], x.[WorkDescription]
x.[WorkDone], x.[WorkDescription],
p.[BranchId]
FROM [dbo].[Prj_T_WorkPackageResource] x
INNER JOIN [dbo].[Prj_T_WorkPackage] w ON w.[Id] = x.[WorkPackageId] AND w.[IsDeleted] = 0
INNER JOIN [dbo].[Prj_T_Project] p ON p.[Id] = w.[ProjectId] AND p.[IsDeleted] = 0

View file

@ -370,6 +370,7 @@
"AllowAllDeleting": false,
"AllowAdding": true,
"AllowDuplicate": false,
"OpenDetailAfterInsert": false,
"UseIcons": false,
"ConfirmDelete": true,
"NewRowPosition": "viewportTop",
@ -450,6 +451,7 @@
"ApprovalDescriptionFieldName": null,
"ApprovalIsFilterUserName": false,
"ApprovalIsResetWorkflow": false,
"ApprovalIsManualStart": false,
"Criteria": []
},
"UserId": null,
@ -918,7 +920,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT d.Id AS [Key], CONCAT(b.Name, ' - ', d.Name) AS [Name] FROM Hr_T_Department d INNER JOIN Sas_T_Branch b ON b.Id = d.BranchId AND b.IsActive = 1 AND b.IsDeleted = 'false' WHERE d.IsDeleted = 'false' ORDER BY b.Name, d.Name"
"LookupQuery": "SELECT d.Id AS [Key], CONCAT(b.Name, ' - ', d.Name) AS [Name] FROM Hr_T_Department d INNER JOIN Sas_T_Branch b ON b.Id = d.BranchId AND b.IsActive = 1 AND b.IsDeleted = 'false' WHERE d.TenantId = '@TENANTID' AND d.IsDeleted = 'false' ORDER BY b.Name, d.Name"
},
"ValidationRuleDto": [
{
@ -927,6 +929,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1065,6 +1069,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1194,7 +1200,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT UserName AS [Key], CONCAT(Name, ' ', Surname) AS [Name] FROM AbpUsers WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name, Surname"
"LookupQuery": "SELECT UserName AS [Key], CONCAT(Name, ' ', Surname) AS [Name] FROM AbpUsers WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name, Surname"
},
"ValidationRuleDto": [
{
@ -1203,6 +1209,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1341,6 +1349,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,

View file

@ -3168,7 +3168,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": "",
"CascadeEmptyFields": "",
"LookupQuery": "SELECT Name AS [Key], Name AS [Name], Color AS [Color] FROM Adm_T_ContactTag WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Name AS [Key], Name AS [Name], Color AS [Color] FROM Adm_T_ContactTag WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -331,6 +331,7 @@
"AllowAllDeleting": false,
"AllowAdding": true,
"AllowDuplicate": false,
"OpenDetailAfterInsert": false,
"UseIcons": false,
"ConfirmDelete": true,
"NewRowPosition": "viewportTop",
@ -411,6 +412,7 @@
"ApprovalDescriptionFieldName": null,
"ApprovalIsFilterUserName": false,
"ApprovalIsResetWorkflow": false,
"ApprovalIsManualStart": false,
"Criteria": []
},
"UserId": null,
@ -879,7 +881,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Contact WHERE IsDeleted = 'false' ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Contact WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1140,6 +1142,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,

View file

@ -343,6 +343,7 @@
"AllowAllDeleting": false,
"AllowAdding": true,
"AllowDuplicate": false,
"OpenDetailAfterInsert": false,
"UseIcons": false,
"ConfirmDelete": true,
"NewRowPosition": "viewportTop",
@ -423,6 +424,7 @@
"ApprovalDescriptionFieldName": null,
"ApprovalIsFilterUserName": false,
"ApprovalIsResetWorkflow": false,
"ApprovalIsManualStart": false,
"Criteria": []
},
"UserId": null,
@ -891,7 +893,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Contact WHERE IsDeleted = 'false' ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Contact WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1152,6 +1154,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1416,6 +1420,8 @@
"IgnoreEmptyValue": true,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1554,6 +1560,8 @@
"IgnoreEmptyValue": true,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "^[0-9]{10}$",
"Max": null,
"Min": null,
@ -1692,6 +1700,8 @@
"IgnoreEmptyValue": true,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "^[0-9]{10}$",
"Max": null,
"Min": null,

View file

@ -349,6 +349,7 @@
"AllowAllDeleting": false,
"AllowAdding": false,
"AllowDuplicate": false,
"OpenDetailAfterInsert": false,
"UseIcons": false,
"ConfirmDelete": true,
"NewRowPosition": "viewportTop",
@ -429,6 +430,7 @@
"ApprovalDescriptionFieldName": null,
"ApprovalIsFilterUserName": false,
"ApprovalIsResetWorkflow": false,
"ApprovalIsManualStart": false,
"Criteria": []
},
"UserId": null,
@ -906,6 +908,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1035,7 +1039,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], CONCAT(Name, ' ', Surname) AS [Name] FROM AbpUsers WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], CONCAT(Name, ' ', Surname) AS [Name] FROM AbpUsers WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1161,7 +1165,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Prc_T_PaymentTerm WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY DueDays, Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Prc_T_PaymentTerm WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY DueDays, Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1287,7 +1291,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Prc_T_PaymentMethod WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Prc_T_PaymentMethod WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1791,7 +1795,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], CONCAT('[', Code, '] ', Name) AS [Name] FROM Prc_T_Incoterm WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Code"
"LookupQuery": "SELECT Id AS [Key], CONCAT('[', Code, '] ', Name) AS [Name] FROM Prc_T_Incoterm WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Code"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -337,6 +337,7 @@
"AllowAllDeleting": false,
"AllowAdding": false,
"AllowDuplicate": false,
"OpenDetailAfterInsert": false,
"UseIcons": false,
"ConfirmDelete": true,
"NewRowPosition": "viewportTop",
@ -417,6 +418,7 @@
"ApprovalDescriptionFieldName": null,
"ApprovalIsFilterUserName": false,
"ApprovalIsResetWorkflow": false,
"ApprovalIsManualStart": false,
"Criteria": []
},
"UserId": null,
@ -885,7 +887,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], CONCAT(Name, ' ', Surname) AS [Name] FROM AbpUsers WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], CONCAT(Name, ' ', Surname) AS [Name] FROM AbpUsers WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1137,7 +1139,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Prc_T_PaymentTerm WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY DueDays, Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Prc_T_PaymentTerm WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY DueDays, Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1263,7 +1265,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Prc_T_PaymentMethod WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Prc_T_PaymentMethod WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1389,7 +1391,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Prc_T_DeliveryMethod WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Prc_T_DeliveryMethod WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1515,7 +1517,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], CONCAT('[', Code, '] ', Name) AS [Name] FROM Prc_T_Incoterm WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Code"
"LookupQuery": "SELECT Id AS [Key], CONCAT('[', Code, '] ', Name) AS [Name] FROM Prc_T_Incoterm WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Code"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -379,6 +379,7 @@
"AllowAllDeleting": false,
"AllowAdding": false,
"AllowDuplicate": false,
"OpenDetailAfterInsert": false,
"UseIcons": false,
"ConfirmDelete": true,
"NewRowPosition": "viewportTop",
@ -551,6 +552,7 @@
"ApprovalDescriptionFieldName": null,
"ApprovalIsFilterUserName": false,
"ApprovalIsResetWorkflow": false,
"ApprovalIsManualStart": false,
"Criteria": []
},
"UserId": null,
@ -2027,7 +2029,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT \"Id\" AS \"Key\", \"Name\" AS \"Name\" FROM \"Hr_T_Department\" WHERE \"IsDeleted\" = 'false' ORDER BY \"Name\""
"LookupQuery": "SELECT \"Id\" AS \"Key\", \"Name\" AS \"Name\" FROM \"Hr_T_Department\" WHERE \"TenantId\" = '@TENANTID' AND \"IsDeleted\" = 'false' ORDER BY \"Name\""
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -2153,7 +2155,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT \"Id\" AS \"Key\", \"Name\" AS \"Name\" FROM \"Hr_T_JobPosition\" WHERE \"IsDeleted\" = 'false' ORDER BY \"Name\""
"LookupQuery": "SELECT \"Id\" AS \"Key\", \"Name\" AS \"Name\" FROM \"Hr_T_JobPosition\" WHERE \"TenantId\" = '@TENANTID' AND \"IsDeleted\" = 'false' ORDER BY \"Name\""
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -900,7 +900,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Attribute WHERE IsDeleted = 'false' ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Attribute WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -178,7 +178,7 @@
{
"FieldName": "Quantity",
"FieldDbType": 7,
"Value": "0",
"Value": "1",
"CustomValueType": 1,
"SqlQuery": ""
}
@ -374,6 +374,7 @@
"AllowAllDeleting": false,
"AllowAdding": true,
"AllowDuplicate": false,
"OpenDetailAfterInsert": false,
"UseIcons": false,
"ConfirmDelete": true,
"NewRowPosition": "viewportTop",
@ -507,6 +508,7 @@
"ApprovalDescriptionFieldName": null,
"ApprovalIsFilterUserName": false,
"ApprovalIsResetWorkflow": false,
"ApprovalIsManualStart": false,
"Criteria": []
},
"UserId": null,
@ -975,7 +977,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": "VariantKey",
"LookupQuery": "SELECT Id AS [Key], CASE WHEN InternalReference IS NULL OR InternalReference = '' THEN Name ELSE '[' + InternalReference + '] ' + Name END AS [Name] FROM Inv_T_Product WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], CASE WHEN InternalReference IS NULL OR InternalReference = '' THEN Name ELSE '[' + InternalReference + '] ' + Name END AS [Name] FROM Inv_T_Product WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -984,6 +986,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1239,7 +1243,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": "ProductId",
"CascadeEmptyFields": null,
"LookupQuery": "SELECT CONCAT_WS('|', l1.VId, l2.VId, l3.VId, l4.VId, l5.VId) AS [Key], CONCAT_WS(', ', l1.VName, l2.VName, l3.VName, l4.VName, l5.VName) AS [Name] FROM Inv_T_Product p INNER JOIN (SELECT x.ProductId, x.Rk, CAST(s.value AS nvarchar(36)) AS VId, av.Name AS VName 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 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 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 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 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 WHERE p.IsDeleted = 'false' AND (p.Id = @param0 OR @param0 IS NULL)"
"LookupQuery": "SELECT CONCAT_WS('|', l1.VId, l2.VId, l3.VId, l4.VId, l5.VId) AS [Key], CONCAT_WS(', ', l1.VName, l2.VName, l3.VName, l4.VName, l5.VName) AS [Name] FROM Inv_T_Product p INNER JOIN (SELECT x.ProductId, x.Rk, CAST(s.value AS nvarchar(36)) AS VId, av.Name AS VName 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 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 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 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 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 WHERE p.IsDeleted = 'false' AND p.TenantId = '@TENANTID' AND (p.Id = @param0 OR @param0 IS NULL)"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1374,6 +1378,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1503,7 +1509,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1512,6 +1518,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1650,6 +1658,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,

View file

@ -160,7 +160,15 @@
"UpdateBeforeCommand": null,
"UpdateAfterCommand": null,
"UpdateFieldsDefaultValueDto": [],
"FormFieldsDefaultValueDto": [],
"FormFieldsDefaultValueDto": [
{
"FieldName": "Quantity",
"FieldDbType": 7,
"Value": "1",
"CustomValueType": 1,
"SqlQuery": ""
}
],
"WidgetsDto": [],
"ExtraFilterEditDto": [],
"ListFormCode": "App.Inventory.BomComponent",
@ -337,6 +345,7 @@
"AllowAllDeleting": false,
"AllowAdding": true,
"AllowDuplicate": false,
"OpenDetailAfterInsert": false,
"UseIcons": false,
"ConfirmDelete": true,
"NewRowPosition": "viewportTop",
@ -417,6 +426,7 @@
"ApprovalDescriptionFieldName": null,
"ApprovalIsFilterUserName": false,
"ApprovalIsResetWorkflow": false,
"ApprovalIsManualStart": false,
"Criteria": []
},
"UserId": null,
@ -1011,7 +1021,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": "VariantKey",
"LookupQuery": "SELECT Id AS [Key], CASE WHEN InternalReference IS NULL OR InternalReference = '' THEN Name ELSE '[' + InternalReference + '] ' + Name END AS [Name], UomId FROM Inv_T_Product WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], CASE WHEN InternalReference IS NULL OR InternalReference = '' THEN Name ELSE '[' + InternalReference + '] ' + Name END AS [Name], UomId FROM Inv_T_Product WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1020,6 +1030,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1149,7 +1161,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": "ProductId",
"CascadeEmptyFields": null,
"LookupQuery": "SELECT CONCAT_WS('|', l1.VId, l2.VId, l3.VId, l4.VId, l5.VId) AS [Key], CONCAT_WS(', ', l1.VName, l2.VName, l3.VName, l4.VName, l5.VName) AS [Name] FROM Inv_T_Product p INNER JOIN (SELECT x.ProductId, x.Rk, CAST(s.value AS nvarchar(36)) AS VId, av.Name AS VName 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 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 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 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 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 WHERE p.IsDeleted = 'false' AND (p.Id = @param0 OR @param0 IS NULL)"
"LookupQuery": "SELECT CONCAT_WS('|', l1.VId, l2.VId, l3.VId, l4.VId, l5.VId) AS [Key], CONCAT_WS(', ', l1.VName, l2.VName, l3.VName, l4.VName, l5.VName) AS [Name] FROM Inv_T_Product p INNER JOIN (SELECT x.ProductId, x.Rk, CAST(s.value AS nvarchar(36)) AS VId, av.Name AS VName 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 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 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 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 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 WHERE p.IsDeleted = 'false' AND p.TenantId = '@TENANTID' AND (p.Id = @param0 OR @param0 IS NULL)"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1284,6 +1296,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1413,7 +1427,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1422,6 +1436,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1551,7 +1567,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": "BomId",
"CascadeEmptyFields": null,
"LookupQuery": "SELECT o.Id AS [Key], op.Name + ' - ' + w.Name AS [Name] FROM Inv_T_BomOperation o INNER JOIN Prd_T_Operation op ON op.Id = o.OperationId INNER JOIN Prd_T_WorkCenter w ON w.Id = o.WorkCenterId WHERE o.IsDeleted = 'false' AND (o.BomId = @param0 OR @param0 IS NULL) ORDER BY o.SortOrder, op.Name"
"LookupQuery": "SELECT o.Id AS [Key], op.Name + ' - ' + w.Name AS [Name] FROM Inv_T_BomOperation o INNER JOIN Prd_T_Operation op ON op.Id = o.OperationId INNER JOIN Prd_T_WorkCenter w ON w.Id = o.WorkCenterId WHERE o.IsDeleted = 'false' AND o.TenantId = '@TENANTID' AND (o.BomId = @param0 OR @param0 IS NULL) ORDER BY o.SortOrder, op.Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -148,7 +148,15 @@
"UpdateBeforeCommand": null,
"UpdateAfterCommand": null,
"UpdateFieldsDefaultValueDto": [],
"FormFieldsDefaultValueDto": [],
"FormFieldsDefaultValueDto": [
{
"FieldName": "DurationMin",
"FieldDbType": 7,
"Value": "60",
"CustomValueType": 1,
"SqlQuery": ""
}
],
"WidgetsDto": [],
"ExtraFilterEditDto": [],
"ListFormCode": "App.Inventory.BomOperation",
@ -325,6 +333,7 @@
"AllowAllDeleting": false,
"AllowAdding": true,
"AllowDuplicate": false,
"OpenDetailAfterInsert": false,
"UseIcons": false,
"ConfirmDelete": true,
"NewRowPosition": "viewportTop",
@ -405,6 +414,7 @@
"ApprovalDescriptionFieldName": null,
"ApprovalIsFilterUserName": false,
"ApprovalIsResetWorkflow": false,
"ApprovalIsManualStart": false,
"Criteria": []
},
"UserId": null,
@ -999,7 +1009,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name], WorkCenterId, DefaultDurationMin FROM Prd_T_Operation WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name], WorkCenterId, DefaultDurationMin FROM Prd_T_Operation WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1008,6 +1018,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1137,7 +1149,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Prd_T_WorkCenter WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Prd_T_WorkCenter WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1146,6 +1158,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1284,6 +1298,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,

View file

@ -195,6 +195,12 @@
"CaptionName": "App.Listform.ListformField.LineSummary",
"En": "LineSummary",
"Tr": "LineSummary"
},
{
"FieldName": "ReturnOfId",
"CaptionName": "App.Listform.ListformField.ReturnOfId",
"En": "Return Of",
"Tr": "İade Edilen Belge"
}
]
}
@ -609,7 +615,7 @@
"DialogParameters": null,
"OnClick": "(async () => { const r = e.row.data; if (!window.confirm(translate('::App.Inventory.Transfer.ConfirmAction'))) return; await dynamicFetch('list-form-data/update', 'POST', null, { listFormCode, keys: [r.Id], data: { PendingAction: 'Return' } }); e.component.refresh(); })().catch(() => {})",
"IsVisible": true,
"VisibleExpression": "(e) => !!e.row && !e.row.isEditing && ['Done'].includes(e.row.data.Status)"
"VisibleExpression": "(e) => !!e.row && !e.row.isEditing && ['Done'].includes(e.row.data.Status) && !e.row.data.ReturnOfId"
},
{
"ButtonPosition": 0,
@ -638,7 +644,7 @@
"InsertServiceAddress": "list-form-data/insert",
"DeleteServiceAddress": "list-form-data/delete",
"IsTenant": true,
"IsBranch": false,
"IsBranch": true,
"IsOrganizationUnit": false,
"ListFormType": "List",
"IsSubForm": false,
@ -1329,7 +1335,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 2,
"EditOrderNo": 9,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
@ -1469,7 +1475,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 3,
"EditOrderNo": 2,
"EditGroupOrderNo": 1,
"EditorType2": "dxDateBox",
"ColSpan": 1,
@ -1598,7 +1604,7 @@
"EditOrderNo": 4,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 2,
"ColSpan": 3,
"EditorOptions": "{\"showClearButton\":true,\"searchEnabled\":true}",
"GridBoxOptions": null,
"TagBoxOptions": null,
@ -1691,7 +1697,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": "WarehouseId,OperationTypeId,SourceLocationId,DestinationLocationId",
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -2407,7 +2413,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 9,
"EditOrderNo": 3,
"EditGroupOrderNo": 1,
"EditorType2": "dxDateBox",
"ColSpan": 1,
@ -3065,6 +3071,132 @@
"CreationTime": "0001-01-01T00:00:00",
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
},
{
"EditType": null,
"ListFormCode": "App.Inventory.Delivery",
"RoleId": null,
"UserId": null,
"ColumnJoinTableDto": {
"JoinType": null,
"TableName": null,
"JoinFieldName": null,
"BaseTableJoinFieldName": null,
"SelectFieldName": null,
"FieldNameAlias": null,
"JoinCondition2": "AND",
"JoinFieldName2": null,
"BaseTableJoinFieldName2_OrValue": null
},
"FieldName": "ReturnOfId",
"CaptionName": "App.Listform.ListformField.ReturnOfId",
"PlaceHolder": null,
"ReadOnly": false,
"Visible": false,
"IsActive": true,
"Width": 0,
"ListOrderNo": 17,
"SourceDbType": 9,
"CultureName": "en",
"DataType": "string",
"SortIndex": 0,
"SortDirection": null,
"AllowSearch": true,
"AllowEditing": true,
"AllowAdding": true,
"ColumnCssClass": null,
"ColumnCssValue": null,
"BandName": null,
"ColumnFilterDto": {
"AllowFiltering": true,
"FilterOperations": null,
"SelectedFilterOperation": null,
"FilterValue": null
},
"ColumnHeaderDto": {
"AllowHeaderFiltering": true,
"AllowSearch": false,
"DataSource": null,
"DataSourceString": ""
},
"ColumnGroupingDto": {
"AllowGrouping": true,
"GroupIndex": null,
"AutoExpandGroup": false
},
"ColumnCustomizationDto": {
"Fixed": false,
"FixedPosition": "left",
"AllowReordering": true
},
"ColumnTotalSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"ColumnGroupSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"LookupDto": {
"DataSourceType": 0,
"ValueExpr": "Key",
"DisplayExpr": "Name",
"CascadeRelationField": null,
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": null
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
"PermissionDto": {
"Deny": false,
"C": "App.Inventory.Delivery.Create",
"R": "App.Inventory.Delivery",
"U": "App.Inventory.Delivery.Update",
"E": true,
"I": true
},
"CanRead": false,
"CanCreate": false,
"CanUpdate": false,
"CanExport": false,
"DefaultValue": null,
"DefaultValueType": 0,
"PivotSettingsDto": {
"IsPivot": true,
"Expanded": false,
"SortOrder": "asc",
"Area": "filter",
"Format": null,
"SummaryType": null,
"GroupInterval": "",
"WordWrapEnabled": false
},
"Alignment": "left",
"Format": null,
"EditOrderNo": null,
"EditGroupOrderNo": null,
"EditorType2": "dxTextBox",
"ColSpan": 1,
"EditorOptions": null,
"GridBoxOptions": null,
"TagBoxOptions": null,
"ImageUploadOptions": null,
"EditorScript": null,
"LastModificationTime": null,
"LastModifierId": null,
"CreationTime": "0001-01-01T00:00:00",
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
}
],
"IsDeletedField": true,

View file

@ -32,8 +32,8 @@
"MenuTr": "İç Transferler",
"TitleEn": "Internal Transfers",
"TitleTr": "İç Transferler",
"DescEn": "Internal Transfers — moves between internal locations (within a warehouse or between warehouses).\nWhere: Inventory › Operations › Internal Transfers; extra tab Approval & Delivery.\nFields: contact, branch › warehouse › operation type (internal transfer types only), source and destination location (internal locations only, different from each other), scheduled date, source document.\nOrder: enter the lines › Start Workflow › the warehouse responsible of the source location gives Source Warehouse Approval › the document is made ready automatically (Ready/Waiting) › select lots › Validate. A location without a responsible has no approval step (No Approval Needed) and Mark as To Do is pressed by hand. Approval comes before the stock move; Validate writes the receiving user and date.\nMaterial request lines come to a transfer through the Internal Transfer decision in Purchasing › Requests › Planning: the line is added to the draft transfer for the same source → destination location that has not entered approval, otherwise a new draft is opened with the source warehouse's internal transfer type. Validate writes the delivered quantity to the request line; cancelling the transfer or deleting its line returns the quantity to Planning.\nStatuses: Draft › Waiting / Ready › Done; Cancelled. Row buttons appear according to the document status. Mark as To Do checks stock and fills the done quantity; Validate posts stock by branch › warehouse › location › product › lot; the remainder of lines done below demand moves to a new document (backorder). Return opens a reverse draft document from a done one; Print prints the transfer slip.\nTabs: Operations (product lines; Details for lots/serials, Generate Lot/Serial and Auto Assign), Additional Info (shipping, responsible, project), Note.\nProducts with inventory tracking off create no stock move; products tracked by lot or serial need a lot distribution before Validate. The number comes from the operation type's sequence. Related screens: Inventory › Stock, Moves and Product Moves.",
"DescTr": "İç Transferler — iç konumlar arasında taşıma (aynı depo ya da depolar arası).\nNerede: Envanter › Operasyonlar › İç Transferler; ek sekme Onay ve Teslim.\nAlanlar: kontak, şube › depo › operasyon türü (yalnız iç transfer türleri), kaynak ve hedef konum (yalnız iç konumlar, birbirinden farklı), planlanan tarih, kaynak belge.\nSıra: satırlar girilir › Onayla › kaynak konumun depo sorumlusu Kaynak Depo Onayı verir › belge kendiliğinden hazırlanır (Hazır/Bekleyen) › lotlar seçilir › Doğrula. Sorumlusu olmayan konumda onay adımı yoktur (Onay Gerekmez) ve Yapılacak olarak işaretle elle basılır. Onay stok hareketinden önce gelir; Doğrula teslim alanı ve teslim alma tarihini yazar.\nMalzeme talebi kalemleri transfere Satınalma › Talepler › Planlama'daki İç Transfer kararıyla gelir: aynı kaynak → hedef konum için onaya girmemiş taslak transfer varsa satır ona eklenir, yoksa kaynak deponun iç transfer türüyle yeni taslak açılır. Doğrula teslim edilen miktarı talep kalemine yazar; transfer iptal edilir ya da satırı silinirse miktar Planlama'ya döner.\nDurumlar: Taslak › Bekleyen / Hazır › Tamamlandı; İptal. Satırdaki butonlar belgenin durumuna göre görünür. Yapılacak olarak işaretle stoğu kontrol eder ve yapılacak miktarı doldurur; Doğrula stoğu şube › depo › konum › ürün › lot bazında günceller, talepten az yapılan satırların kalanı aynı türde yeni belgeye (backorder) geçer. İade Et, tamamlanmış belgeden ters yönlü taslak belge açar; Yazdır transfer fişini basar.\nSekmeler: Operasyonlar (ürün satırları; Detaylar ile lot/seri, Lot/Seri Oluştur ve Otomatik Ata), Ek Bilgi (nakliye, sorumlu, proje), Not.\nÜrünün Envanter Takibi kapalıysa stok hareketi oluşmaz; Takip Yöntemi Lot ya da Seri ise Doğrula'dan önce lot dağılımı girilmelidir. Numara operasyon türünün numaratöründen verilir. İlişkili ekranlar: Envanter › Stok, Hareketler ve Ürün Hareketleri.",
"DescEn": "Internal Transfers — moves between internal locations (within a warehouse or between warehouses).\nWhere: Inventory › Operations › Internal Transfers.\nFields: contact, branch › warehouse › operation type (internal transfer types only), source and destination location (internal locations only), scheduled date, source document.\nOrder: enter the lines › Mark as To Do (stock check, Ready/Waiting) › select lots › Validate. There is no approval step; like receipts and deliveries the document moves on with the status buttons on its row. Validate writes the receiving user and date (Additional Info tab).\nMaterial request lines come to a transfer through the Internal Transfer or From Stock decision in Purchasing › Requests › Planning: the line is added to the draft transfer for the same source → destination location, otherwise a new draft is opened with the source warehouse's Internal Transfers type; with From Stock the source and destination are the request's delivery location and Validate records the delivery without moving stock. Validate writes the delivered quantity to the request line; cancelling the transfer or deleting its line returns the quantity to Planning.\nStatuses: Draft › Waiting / Ready › Done; Cancelled. Mark as To Do checks stock and fills the done quantity; Validate posts stock by branch › warehouse › location › product › lot; the remainder of lines done below demand moves to a new document (backorder). Return opens a reverse draft document from a done one; Print prints the transfer slip.\nTabs: Operations (product lines; Details for lots/serials, Generate Lot/Serial and Auto Assign), Additional Info (shipping, responsible, project, received by), Note.\nProducts with inventory tracking off create no stock move; products tracked by lot or serial need a lot distribution before Validate. The number comes from the operation type's sequence. Related screens: Inventory › Stock, Moves and Product Moves.",
"DescTr": "İç Transferler — iç konumlar arasında taşıma (aynı depo ya da depolar arası).\nNerede: Envanter › Operasyonlar › İç Transferler.\nAlanlar: kontak, şube › depo › operasyon türü (yalnız iç transfer türleri), kaynak ve hedef konum (yalnız iç konumlar), planlanan tarih, kaynak belge.\nSıra: satırlar girilir › Yapılacak olarak işaretle (stok kontrolü, Hazır/Bekleyen) › lotlar seçilir › Doğrula. Onay adımı yoktur; alım ve teslimat gibi satırdaki durum butonlarıyla ilerler. Doğrula teslim alanı ve teslim alma tarihini yazar (Ek Bilgi sekmesi).\nMalzeme talebi kalemleri transfere Satınalma › Talepler › Planlama'daki İç Transfer ya da Stoktan kararıyla gelir: aynı kaynak → hedef konum için taslak transfer varsa satır ona eklenir, yoksa kaynak deponun İç Transferler türüyle yeni taslak açılır; Stoktan kararında kaynak ve hedef talebin teslim konumudur, Doğrula stoğa dokunmadan teslimi kaydeder. Doğrula teslim edilen miktarı talep kalemine yazar; transfer iptal edilir ya da satırı silinirse miktar Planlama'ya döner.\nDurumlar: Taslak › Bekleyen / Hazır › Tamamlandı; İptal. Yapılacak olarak işaretle stoğu kontrol eder ve yapılacak miktarı doldurur; Doğrula stoğu şube › depo › konum › ürün › lot bazında günceller, talepten az yapılan satırların kalanı aynı türde yeni belgeye (backorder) geçer. İade Et, tamamlanmış belgeden ters yönlü taslak belge açar; Yazdır transfer fişini basar.\nSekmeler: Operasyonlar (ürün satırları; Detaylar ile lot/seri, Lot/Seri Oluştur ve Otomatik Ata), Ek Bilgi (nakliye, sorumlu, proje, teslim alan), Not.\nÜrünün Envanter Takibi kapalıysa stok hareketi oluşmaz; Takip Yöntemi Lot ya da Seri ise Doğrula'dan önce lot dağılımı girilmelidir. Numara operasyon türünün numaratöründen verilir. İlişkili ekranlar: Envanter › Stok, Hareketler ve Ürün Hareketleri.",
"Texts": [
{
"Key": "App.Inventory.Transfer.Action.Confirm",
@ -94,11 +94,6 @@
"Key": "App.Inventory.Widget.Late",
"En": "Late",
"Tr": "Geciken"
},
{
"Key": "App.Inventory.Transfer.Tab.Approval",
"En": "Approval & Delivery",
"Tr": "Onay ve Teslim"
}
]
},
@ -196,34 +191,10 @@
"Tr": "LineSummary"
},
{
"FieldName": "ApprovalStatus",
"CaptionName": "App.Inventory.TransferApproval.ApprovalStatus",
"En": "Source Warehouse Approval",
"Tr": "Kaynak Depo Onayı"
},
{
"FieldName": "ApprovalUserName",
"CaptionName": "App.Listform.ListformField.ApprovalUserName",
"En": "Approval User",
"Tr": "Onaylayan"
},
{
"FieldName": "ApprovalDate",
"CaptionName": "App.Listform.ListformField.ApprovalDate",
"En": "Approval Date",
"Tr": "Onay Tarihi"
},
{
"FieldName": "ApprovalDescription",
"CaptionName": "App.Listform.ListformField.ApprovalDescription",
"En": "Approval Description",
"Tr": "Onay Açıklaması"
},
{
"FieldName": "SourceApproverUserNames",
"CaptionName": "App.Listform.ListformField.SourceApproverUserNames",
"En": "SourceApproverUserNames",
"Tr": "SourceApproverUserNames"
"FieldName": "ReturnOfId",
"CaptionName": "App.Listform.ListformField.ReturnOfId",
"En": "Return Of",
"Tr": "İade Edilen Belge"
}
]
}
@ -589,7 +560,7 @@
"DialogParameters": null,
"OnClick": "(async () => { const r = e.row.data; if (!window.confirm(translate('::App.Inventory.Transfer.ConfirmAction'))) return; await dynamicFetch('list-form-data/update', 'POST', null, { listFormCode, keys: [r.Id], data: { PendingAction: r.Status === 'Draft' ? 'Confirm' : 'Check' } }); e.component.refresh(); })().catch(() => {})",
"IsVisible": true,
"VisibleExpression": "(e) => !!e.row && !e.row.isEditing && (e.row.data.Status === 'Waiting' || (e.row.data.Status === 'Draft' && ['Onaylandı', 'Onay Gerekmez'].includes(e.row.data.ApprovalStatus)))"
"VisibleExpression": "(e) => !!e.row && !e.row.isEditing && ['Draft', 'Waiting'].includes(e.row.data.Status)"
},
{
"ButtonPosition": 0,
@ -631,7 +602,7 @@
"DialogParameters": null,
"OnClick": "(async () => { const r = e.row.data; if (!window.confirm(translate('::App.Inventory.Transfer.ConfirmAction'))) return; await dynamicFetch('list-form-data/update', 'POST', null, { listFormCode, keys: [r.Id], data: { PendingAction: 'Return' } }); e.component.refresh(); })().catch(() => {})",
"IsVisible": true,
"VisibleExpression": "(e) => !!e.row && !e.row.isEditing && ['Done'].includes(e.row.data.Status)"
"VisibleExpression": "(e) => !!e.row && !e.row.isEditing && ['Done'].includes(e.row.data.Status) && !e.row.data.ReturnOfId"
},
{
"ButtonPosition": 0,
@ -660,7 +631,7 @@
"InsertServiceAddress": "list-form-data/insert",
"DeleteServiceAddress": "list-form-data/delete",
"IsTenant": true,
"IsBranch": false,
"IsBranch": true,
"IsOrganizationUnit": false,
"ListFormType": "List",
"IsSubForm": false,
@ -705,19 +676,6 @@
"ChildFieldName": "Id"
}
]
},
{
"TabType": "Form",
"TabTitle": "App.Inventory.Transfer.Tab.Approval",
"Code": "App.Inventory.TransferApproval",
"IsRefresh": false,
"Relation": [
{
"ParentFieldName": "Id",
"DbType": 9,
"ChildFieldName": "Id"
}
]
}
],
"ExtraFilterDto": [],
@ -733,87 +691,14 @@
"DefaultLayout": "grid"
},
"WorkflowDto": {
"ApprovalUserFieldName": "ApprovalUserName",
"ApprovalDateFieldName": "ApprovalDate",
"ApprovalStatusFieldName": "ApprovalStatus",
"ApprovalDescriptionFieldName": "ApprovalDescription",
"ApprovalUserFieldName": null,
"ApprovalDateFieldName": null,
"ApprovalStatusFieldName": null,
"ApprovalDescriptionFieldName": null,
"ApprovalIsFilterUserName": false,
"ApprovalIsResetWorkflow": true,
"ApprovalIsManualStart": true,
"Criteria": [
{
"ListFormCode": "App.Inventory.InternalTransfer",
"Kind": "Start",
"Title": "Onaya Gönderildi",
"CompareColumn": "",
"CompareOperator": "",
"CompareValue": 0,
"Approver": "",
"NextOnStart": "App.Inventory.InternalTransfer-N2",
"NextOnTrue": "",
"NextOnFalse": "",
"NextOnApprove": "",
"NextOnReject": "",
"PositionX": 40,
"PositionY": 40,
"CompareOutcomes": [],
"Id": "App.Inventory.InternalTransfer-N1"
},
{
"ListFormCode": "App.Inventory.InternalTransfer",
"Kind": "Approval",
"Title": "Kaynak Depo Onayı",
"CompareColumn": "",
"CompareOperator": "",
"CompareValue": 0,
"Approver": "@SourceApproverUserNames",
"NextOnStart": "",
"NextOnTrue": "",
"NextOnFalse": "",
"NextOnApprove": "App.Inventory.InternalTransfer-N3",
"NextOnReject": "App.Inventory.InternalTransfer-N4",
"PositionX": 40,
"PositionY": 160,
"CompareOutcomes": [],
"Id": "App.Inventory.InternalTransfer-N2"
},
{
"ListFormCode": "App.Inventory.InternalTransfer",
"Kind": "End",
"Title": "Onaylandı",
"CompareColumn": "",
"CompareOperator": "",
"CompareValue": 0,
"Approver": "",
"NextOnStart": "",
"NextOnTrue": "",
"NextOnFalse": "",
"NextOnApprove": "",
"NextOnReject": "",
"PositionX": 40,
"PositionY": 280,
"CompareOutcomes": [],
"Id": "App.Inventory.InternalTransfer-N3"
},
{
"ListFormCode": "App.Inventory.InternalTransfer",
"Kind": "End",
"Title": "Reddedildi",
"CompareColumn": "",
"CompareOperator": "",
"CompareValue": 0,
"Approver": "",
"NextOnStart": "",
"NextOnTrue": "",
"NextOnFalse": "",
"NextOnApprove": "",
"NextOnReject": "",
"PositionX": 320,
"PositionY": 280,
"CompareOutcomes": [],
"Id": "App.Inventory.InternalTransfer-N4"
}
]
"ApprovalIsResetWorkflow": false,
"ApprovalIsManualStart": false,
"Criteria": []
},
"UserId": null,
"RoleId": null,
@ -1451,7 +1336,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 4,
"EditOrderNo": 2,
"EditGroupOrderNo": 1,
"EditorType2": "dxDateBox",
"ColSpan": 1,
@ -1577,10 +1462,10 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 2,
"EditOrderNo": 4,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 2,
"ColSpan": 3,
"EditorOptions": "{\"showClearButton\":true,\"searchEnabled\":true}",
"GridBoxOptions": null,
"TagBoxOptions": null,
@ -1703,7 +1588,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 3,
"EditOrderNo": 10,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
@ -1799,7 +1684,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": "WarehouseId,OperationTypeId,SourceLocationId,DestinationLocationId",
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1843,7 +1728,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 6,
"EditOrderNo": 5,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
@ -1983,7 +1868,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 7,
"EditOrderNo": 6,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
@ -2123,7 +2008,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 8,
"EditOrderNo": 7,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
@ -2249,7 +2134,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 5,
"EditOrderNo": 3,
"EditGroupOrderNo": 1,
"EditorType2": "dxDateBox",
"ColSpan": 1,
@ -2389,7 +2274,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 9,
"EditOrderNo": 8,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
@ -2500,19 +2385,6 @@
"Max": null,
"Min": null,
"Trim": true
},
{
"Type": "compare",
"Message": "App.Inventory.Transfer.SameLocation",
"IgnoreEmptyValue": true,
"Reevaluate": true,
"ComparisonType": "!=",
"ComparisonTarget": "SourceLocationId",
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
"Trim": true
}
],
"ColumnStylingDto": [],
@ -2542,7 +2414,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 10,
"EditOrderNo": 9,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
@ -3077,519 +2949,15 @@
"JoinFieldName2": null,
"BaseTableJoinFieldName2_OrValue": null
},
"FieldName": "ApprovalStatus",
"CaptionName": "App.Inventory.TransferApproval.ApprovalStatus",
"PlaceHolder": null,
"ReadOnly": false,
"Visible": true,
"IsActive": true,
"Width": 0,
"ListOrderNo": 16,
"SourceDbType": 16,
"CultureName": "en",
"DataType": "string",
"SortIndex": 0,
"SortDirection": null,
"AllowSearch": true,
"AllowEditing": true,
"AllowAdding": true,
"ColumnCssClass": null,
"ColumnCssValue": null,
"BandName": null,
"ColumnFilterDto": {
"AllowFiltering": true,
"FilterOperations": null,
"SelectedFilterOperation": null,
"FilterValue": null
},
"ColumnHeaderDto": {
"AllowHeaderFiltering": true,
"AllowSearch": false,
"DataSource": null,
"DataSourceString": ""
},
"ColumnGroupingDto": {
"AllowGrouping": true,
"GroupIndex": null,
"AutoExpandGroup": false
},
"ColumnCustomizationDto": {
"Fixed": false,
"FixedPosition": "left",
"AllowReordering": true
},
"ColumnTotalSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"ColumnGroupSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"LookupDto": {
"DataSourceType": 0,
"ValueExpr": "Key",
"DisplayExpr": "Name",
"CascadeRelationField": null,
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": null
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
"PermissionDto": {
"Deny": false,
"C": "App.Inventory.InternalTransfer.Create",
"R": "App.Inventory.InternalTransfer",
"U": "App.Inventory.InternalTransfer.Update",
"E": true,
"I": true
},
"CanRead": false,
"CanCreate": false,
"CanUpdate": false,
"CanExport": false,
"DefaultValue": null,
"DefaultValueType": 0,
"PivotSettingsDto": {
"IsPivot": true,
"Expanded": false,
"SortOrder": "asc",
"Area": "filter",
"Format": null,
"SummaryType": null,
"GroupInterval": "",
"WordWrapEnabled": false
},
"Alignment": "left",
"Format": null,
"EditOrderNo": null,
"EditGroupOrderNo": null,
"EditorType2": "dxTextBox",
"ColSpan": 1,
"EditorOptions": "{\"readOnly\":true}",
"GridBoxOptions": null,
"TagBoxOptions": null,
"ImageUploadOptions": null,
"EditorScript": null,
"LastModificationTime": null,
"LastModifierId": null,
"CreationTime": "0001-01-01T00:00:00",
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
},
{
"EditType": null,
"ListFormCode": "App.Inventory.InternalTransfer",
"RoleId": null,
"UserId": null,
"ColumnJoinTableDto": {
"JoinType": null,
"TableName": null,
"JoinFieldName": null,
"BaseTableJoinFieldName": null,
"SelectFieldName": null,
"FieldNameAlias": null,
"JoinCondition2": "AND",
"JoinFieldName2": null,
"BaseTableJoinFieldName2_OrValue": null
},
"FieldName": "ApprovalUserName",
"CaptionName": "App.Listform.ListformField.ApprovalUserName",
"PlaceHolder": null,
"ReadOnly": false,
"Visible": true,
"IsActive": true,
"Width": 0,
"ListOrderNo": 17,
"SourceDbType": 16,
"CultureName": "en",
"DataType": "string",
"SortIndex": 0,
"SortDirection": null,
"AllowSearch": true,
"AllowEditing": true,
"AllowAdding": true,
"ColumnCssClass": null,
"ColumnCssValue": null,
"BandName": null,
"ColumnFilterDto": {
"AllowFiltering": true,
"FilterOperations": null,
"SelectedFilterOperation": null,
"FilterValue": null
},
"ColumnHeaderDto": {
"AllowHeaderFiltering": true,
"AllowSearch": false,
"DataSource": null,
"DataSourceString": ""
},
"ColumnGroupingDto": {
"AllowGrouping": true,
"GroupIndex": null,
"AutoExpandGroup": false
},
"ColumnCustomizationDto": {
"Fixed": false,
"FixedPosition": "left",
"AllowReordering": true
},
"ColumnTotalSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"ColumnGroupSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"LookupDto": {
"DataSourceType": 0,
"ValueExpr": "Key",
"DisplayExpr": "Name",
"CascadeRelationField": null,
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": null
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
"PermissionDto": {
"Deny": false,
"C": "App.Inventory.InternalTransfer.Create",
"R": "App.Inventory.InternalTransfer",
"U": "App.Inventory.InternalTransfer.Update",
"E": true,
"I": true
},
"CanRead": false,
"CanCreate": false,
"CanUpdate": false,
"CanExport": false,
"DefaultValue": null,
"DefaultValueType": 0,
"PivotSettingsDto": {
"IsPivot": true,
"Expanded": false,
"SortOrder": "asc",
"Area": "filter",
"Format": null,
"SummaryType": null,
"GroupInterval": "",
"WordWrapEnabled": false
},
"Alignment": "left",
"Format": null,
"EditOrderNo": null,
"EditGroupOrderNo": null,
"EditorType2": "dxTextBox",
"ColSpan": 1,
"EditorOptions": "{\"readOnly\":true}",
"GridBoxOptions": null,
"TagBoxOptions": null,
"ImageUploadOptions": null,
"EditorScript": null,
"LastModificationTime": null,
"LastModifierId": null,
"CreationTime": "0001-01-01T00:00:00",
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
},
{
"EditType": null,
"ListFormCode": "App.Inventory.InternalTransfer",
"RoleId": null,
"UserId": null,
"ColumnJoinTableDto": {
"JoinType": null,
"TableName": null,
"JoinFieldName": null,
"BaseTableJoinFieldName": null,
"SelectFieldName": null,
"FieldNameAlias": null,
"JoinCondition2": "AND",
"JoinFieldName2": null,
"BaseTableJoinFieldName2_OrValue": null
},
"FieldName": "ApprovalDate",
"CaptionName": "App.Listform.ListformField.ApprovalDate",
"PlaceHolder": null,
"ReadOnly": false,
"Visible": true,
"IsActive": true,
"Width": 0,
"ListOrderNo": 18,
"SourceDbType": 6,
"CultureName": "en",
"DataType": "datetime",
"SortIndex": 0,
"SortDirection": null,
"AllowSearch": true,
"AllowEditing": true,
"AllowAdding": true,
"ColumnCssClass": null,
"ColumnCssValue": null,
"BandName": null,
"ColumnFilterDto": {
"AllowFiltering": true,
"FilterOperations": null,
"SelectedFilterOperation": null,
"FilterValue": null
},
"ColumnHeaderDto": {
"AllowHeaderFiltering": true,
"AllowSearch": false,
"DataSource": null,
"DataSourceString": ""
},
"ColumnGroupingDto": {
"AllowGrouping": true,
"GroupIndex": null,
"AutoExpandGroup": false
},
"ColumnCustomizationDto": {
"Fixed": false,
"FixedPosition": "left",
"AllowReordering": true
},
"ColumnTotalSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"ColumnGroupSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"LookupDto": {
"DataSourceType": 0,
"ValueExpr": "Key",
"DisplayExpr": "Name",
"CascadeRelationField": null,
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": null
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
"PermissionDto": {
"Deny": false,
"C": "App.Inventory.InternalTransfer.Create",
"R": "App.Inventory.InternalTransfer",
"U": "App.Inventory.InternalTransfer.Update",
"E": true,
"I": true
},
"CanRead": false,
"CanCreate": false,
"CanUpdate": false,
"CanExport": false,
"DefaultValue": null,
"DefaultValueType": 0,
"PivotSettingsDto": {
"IsPivot": true,
"Expanded": false,
"SortOrder": "asc",
"Area": "filter",
"Format": null,
"SummaryType": null,
"GroupInterval": "",
"WordWrapEnabled": false
},
"Alignment": "left",
"Format": null,
"EditOrderNo": null,
"EditGroupOrderNo": null,
"EditorType2": "dxDateBox",
"ColSpan": 1,
"EditorOptions": "{\"type\":\"datetime\",\"displayFormat\":\"dd.MM.yyyy HH:mm\",\"readOnly\":true}",
"GridBoxOptions": null,
"TagBoxOptions": null,
"ImageUploadOptions": null,
"EditorScript": null,
"LastModificationTime": null,
"LastModifierId": null,
"CreationTime": "0001-01-01T00:00:00",
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
},
{
"EditType": null,
"ListFormCode": "App.Inventory.InternalTransfer",
"RoleId": null,
"UserId": null,
"ColumnJoinTableDto": {
"JoinType": null,
"TableName": null,
"JoinFieldName": null,
"BaseTableJoinFieldName": null,
"SelectFieldName": null,
"FieldNameAlias": null,
"JoinCondition2": "AND",
"JoinFieldName2": null,
"BaseTableJoinFieldName2_OrValue": null
},
"FieldName": "ApprovalDescription",
"CaptionName": "App.Listform.ListformField.ApprovalDescription",
"PlaceHolder": null,
"ReadOnly": false,
"Visible": true,
"IsActive": true,
"Width": 0,
"ListOrderNo": 19,
"SourceDbType": 16,
"CultureName": "en",
"DataType": "string",
"SortIndex": 0,
"SortDirection": null,
"AllowSearch": true,
"AllowEditing": true,
"AllowAdding": true,
"ColumnCssClass": null,
"ColumnCssValue": null,
"BandName": null,
"ColumnFilterDto": {
"AllowFiltering": true,
"FilterOperations": null,
"SelectedFilterOperation": null,
"FilterValue": null
},
"ColumnHeaderDto": {
"AllowHeaderFiltering": true,
"AllowSearch": false,
"DataSource": null,
"DataSourceString": ""
},
"ColumnGroupingDto": {
"AllowGrouping": true,
"GroupIndex": null,
"AutoExpandGroup": false
},
"ColumnCustomizationDto": {
"Fixed": false,
"FixedPosition": "left",
"AllowReordering": true
},
"ColumnTotalSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"ColumnGroupSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"LookupDto": {
"DataSourceType": 0,
"ValueExpr": "Key",
"DisplayExpr": "Name",
"CascadeRelationField": null,
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": null
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
"PermissionDto": {
"Deny": false,
"C": "App.Inventory.InternalTransfer.Create",
"R": "App.Inventory.InternalTransfer",
"U": "App.Inventory.InternalTransfer.Update",
"E": true,
"I": true
},
"CanRead": false,
"CanCreate": false,
"CanUpdate": false,
"CanExport": false,
"DefaultValue": null,
"DefaultValueType": 0,
"PivotSettingsDto": {
"IsPivot": true,
"Expanded": false,
"SortOrder": "asc",
"Area": "filter",
"Format": null,
"SummaryType": null,
"GroupInterval": "",
"WordWrapEnabled": false
},
"Alignment": "left",
"Format": null,
"EditOrderNo": null,
"EditGroupOrderNo": null,
"EditorType2": "dxTextBox",
"ColSpan": 1,
"EditorOptions": "{\"readOnly\":true}",
"GridBoxOptions": null,
"TagBoxOptions": null,
"ImageUploadOptions": null,
"EditorScript": null,
"LastModificationTime": null,
"LastModifierId": null,
"CreationTime": "0001-01-01T00:00:00",
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
},
{
"EditType": null,
"ListFormCode": "App.Inventory.InternalTransfer",
"RoleId": null,
"UserId": null,
"ColumnJoinTableDto": {
"JoinType": null,
"TableName": null,
"JoinFieldName": null,
"BaseTableJoinFieldName": null,
"SelectFieldName": null,
"FieldNameAlias": null,
"JoinCondition2": "AND",
"JoinFieldName2": null,
"BaseTableJoinFieldName2_OrValue": null
},
"FieldName": "SourceApproverUserNames",
"CaptionName": "App.Listform.ListformField.SourceApproverUserNames",
"FieldName": "ReturnOfId",
"CaptionName": "App.Listform.ListformField.ReturnOfId",
"PlaceHolder": null,
"ReadOnly": false,
"Visible": false,
"IsActive": true,
"Width": 0,
"ListOrderNo": 20,
"SourceDbType": 16,
"ListOrderNo": 16,
"SourceDbType": 9,
"CultureName": "en",
"DataType": "string",
"SortIndex": 0,
@ -3710,8 +3078,7 @@
"App.Inventory.Transfer.Tab.Note",
"App.Inventory.Widget.Ready",
"App.Inventory.Widget.Waiting",
"App.Inventory.Widget.Late",
"App.Inventory.Transfer.Tab.Approval"
"App.Inventory.Widget.Late"
],
"PermissionGroupNames": [],
"PermissionNames": [

View file

@ -38,12 +38,12 @@
{
"Key": "App.StaticLookup.Internal",
"En": "Internal",
"Tr": "İç"
"Tr": "Dahili"
},
{
"Key": "App.StaticLookup.External",
"En": "External",
"Tr": "Dış"
"Tr": "Harici"
}
]
},
@ -124,9 +124,9 @@
"SelectCommandType": 1,
"SelectFieldsDefaultValueDto": [],
"SeedFilePath": "data/App.Inventory.Location.json",
"SeedSyncInsert": true,
"SeedSyncUpdate": true,
"SeedSyncDelete": true,
"SeedSyncInsert": false,
"SeedSyncUpdate": false,
"SeedSyncDelete": false,
"DeleteCommand": "UPDATE \"Inv_T_Location\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\" IN @Id",
"DeleteBeforeCommand": null,
"DeleteAfterCommand": null,
@ -940,7 +940,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": "WarehouseId,ParentId,DepartmentId",
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1080,7 +1080,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": "BranchId",
"CascadeEmptyFields": "ParentId",
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Warehouse WHERE (BranchId = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Warehouse WHERE TenantId = '@TENANTID' AND (BranchId = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1486,7 +1486,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": "BranchId",
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Hr_T_Department WHERE (BranchId = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Hr_T_Department WHERE TenantId = '@TENANTID' AND (BranchId = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1612,7 +1612,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT UserName AS [Key], CONCAT(Name, ' ', Surname) AS [Name] FROM AbpUsers WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT UserName AS [Key], CONCAT(Name, ' ', Surname) AS [Name] FROM AbpUsers WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1878,7 +1878,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": "WarehouseId",
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Location WHERE (WarehouseId = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Location WHERE TenantId = '@TENANTID' AND (WarehouseId = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -955,7 +955,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": "WarehouseId,SourceLocationId,DestinationLocationId",
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1095,7 +1095,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": "BranchId",
"CascadeEmptyFields": "SourceLocationId,DestinationLocationId",
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Warehouse WHERE (BranchId = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Warehouse WHERE TenantId = '@TENANTID' AND (BranchId = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1781,7 +1781,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": "WarehouseId",
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Location WHERE (WarehouseId = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Location WHERE TenantId = '@TENANTID' AND (WarehouseId = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1907,7 +1907,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": "WarehouseId",
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Location WHERE (WarehouseId = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Location WHERE TenantId = '@TENANTID' AND (WarehouseId = @param0 OR @param0 IS NULL) AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -266,13 +266,6 @@
"CustomValueType": 1,
"SqlQuery": ""
},
{
"FieldName": "IsFavorite",
"FieldDbType": 3,
"Value": "false",
"CustomValueType": 1,
"SqlQuery": ""
},
{
"FieldName": "UomId",
"FieldDbType": 16,
@ -514,6 +507,7 @@
"AllowAllDeleting": false,
"AllowAdding": true,
"AllowDuplicate": false,
"OpenDetailAfterInsert": false,
"UseIcons": false,
"ConfirmDelete": true,
"NewRowPosition": "viewportTop",
@ -673,6 +667,7 @@
"ApprovalDescriptionFieldName": null,
"ApprovalIsFilterUserName": false,
"ApprovalIsResetWorkflow": false,
"ApprovalIsManualStart": false,
"Criteria": []
},
"UserId": null,
@ -1150,6 +1145,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1792,6 +1789,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1921,7 +1920,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_ProductCategory WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_ProductCategory WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -2677,7 +2676,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -2686,6 +2685,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -2815,7 +2816,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -2950,6 +2951,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,

View file

@ -987,7 +987,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": "ValueIds",
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Attribute WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Attribute WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1125,7 +1125,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": "AttributeId",
"CascadeEmptyFields": "",
"LookupQuery": "SELECT CAST(Id AS nvarchar(36)) AS [Key], Name AS [Name], ColorCode AS [Color] FROM Inv_T_AttributeValue WHERE IsDeleted = 'false' AND IsActive = 1 AND (AttributeId = @param0 OR @param0 IS NULL) ORDER BY SortOrder, Name"
"LookupQuery": "SELECT CAST(Id AS nvarchar(36)) AS [Key], Name AS [Name], ColorCode AS [Color] FROM Inv_T_AttributeValue WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 AND (AttributeId = @param0 OR @param0 IS NULL) ORDER BY SortOrder, Name"
},
"ValidationRuleDto": [
{

View file

@ -32,8 +32,8 @@
"MenuTr": "Ürün Kategorileri",
"TitleEn": "Product Categories",
"TitleTr": "Ürün Kategorileri",
"DescEn": "Product Categories — groups products for reporting, filtering and default accounting (e.g. Electrical & Electronic Materials, Finished Wares).\nWhere: Inventory › Definitions › Product Categories.\nFields: name, parent category (optional, builds a hierarchy), active.\nUsed by: Products › Category field. Passive categories are hidden in lookups; existing products keep their category.",
"DescTr": "Ürün Kategorileri — ürünleri raporlama, filtreleme ve varsayılan muhasebe için gruplar (ör. Elektrik ve Elektronik Malzemeler, Mamuller).\nNerede: Envanter › Tanımlamalar › Ürün Kategorileri.\nAlanlar: ad, üst kategori (isteğe bağlı, hiyerarşi kurar), aktif.\nKullanıldığı yer: Ürünler › Kategori alanı. Pasif kategoriler lookup'ta görünmez; mevcut ürünler kategorisini korur."
"DescEn": "Product Categories — groups products for reporting, filtering and default accounting (e.g. Electrical & Electronic Materials, Finished Wares).\nWhere: Inventory › Definitions › Product Categories.\nFields: name, parent category (optional, builds a hierarchy), removal strategy, active.\nThe removal strategy decides which lot/location leaves stock first (each category carries its own value, it is not inherited from the parent): FIFO — first in, first out (oldest receipt date), LIFO — last in, first out (newest receipt date). The order in the Internal Transfer tab of Purchasing › Planning, Suggest and Plan Selected, and Auto Assign in Internal Transfers follow it; a product without a category uses FIFO.\nUsed by: Products › Category field. Passive categories are hidden in lookups; existing products keep their category.",
"DescTr": "Ürün Kategorileri — ürünleri raporlama, filtreleme ve varsayılan muhasebe için gruplar (ör. Elektrik ve Elektronik Malzemeler, Mamuller).\nNerede: Envanter › Tanımlamalar › Ürün Kategorileri.\nAlanlar: ad, üst kategori (isteğe bağlı, hiyerarşi kurar), çıkış stratejisi, aktif.\nÇıkış stratejisi stoktan hangi lotun/konumun önce çıkacağını belirler (her kategori kendi değerini taşır, üst kategoriden devralınmaz): FIFO — ilk giren ilk çıkar (en eski giriş tarihi), LIFO — son giren ilk çıkar (en yeni giriş tarihi). Satınalma › Planlama'nın İç Transfer sekmesindeki sıra, Öner ve Seçilenleri Planla ile İç Transferler'deki Otomatik Ata bu stratejiyi izler; kategorisi olmayan ürün FIFO çalışır.\nKullanıldığı yer: Ürünler › Kategori alanı. Pasif kategoriler lookup'ta görünmez; mevcut ürünler kategorisini korur."
},
"Groups": [
{
@ -56,6 +56,12 @@
"En": "Parent Category",
"Tr": "Üst Kategori"
},
{
"FieldName": "RemovalStrategy",
"CaptionName": "App.Listform.ListformField.RemovalStrategy",
"En": "Removal Strategy",
"Tr": "Çıkış Stratejisi"
},
{
"FieldName": "IsActive",
"CaptionName": "App.Listform.ListformField.IsActive",
@ -135,7 +141,22 @@
"UpdateBeforeCommand": null,
"UpdateAfterCommand": null,
"UpdateFieldsDefaultValueDto": [],
"FormFieldsDefaultValueDto": [],
"FormFieldsDefaultValueDto": [
{
"FieldName": "RemovalStrategy",
"FieldDbType": 16,
"Value": "FIFO",
"CustomValueType": 1,
"SqlQuery": ""
},
{
"FieldName": "IsActive",
"FieldDbType": 3,
"Value": "true",
"CustomValueType": 1,
"SqlQuery": ""
}
],
"WidgetsDto": [
{
"ColGap": 3,
@ -327,6 +348,7 @@
"AllowAllDeleting": false,
"AllowAdding": true,
"AllowDuplicate": false,
"OpenDetailAfterInsert": false,
"UseIcons": false,
"ConfirmDelete": true,
"NewRowPosition": "viewportTop",
@ -407,6 +429,7 @@
"ApprovalDescriptionFieldName": null,
"ApprovalIsFilterUserName": false,
"ApprovalIsResetWorkflow": false,
"ApprovalIsManualStart": false,
"Criteria": []
},
"UserId": null,
@ -884,6 +907,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1013,7 +1038,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_ProductCategory WHERE IsDeleted = 'false' ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_ProductCategory WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1058,6 +1083,146 @@
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
},
{
"EditType": null,
"ListFormCode": "App.Inventory.ProductCategory",
"RoleId": null,
"UserId": null,
"ColumnJoinTableDto": {
"JoinType": null,
"TableName": null,
"JoinFieldName": null,
"BaseTableJoinFieldName": null,
"SelectFieldName": null,
"FieldNameAlias": null,
"JoinCondition2": "AND",
"JoinFieldName2": null,
"BaseTableJoinFieldName2_OrValue": null
},
"FieldName": "RemovalStrategy",
"CaptionName": "App.Listform.ListformField.RemovalStrategy",
"PlaceHolder": null,
"ReadOnly": false,
"Visible": true,
"IsActive": true,
"Width": 0,
"ListOrderNo": 4,
"SourceDbType": 16,
"CultureName": "en",
"DataType": "string",
"SortIndex": 0,
"SortDirection": null,
"AllowSearch": true,
"AllowEditing": true,
"AllowAdding": true,
"ColumnCssClass": null,
"ColumnCssValue": null,
"BandName": null,
"ColumnFilterDto": {
"AllowFiltering": true,
"FilterOperations": null,
"SelectedFilterOperation": null,
"FilterValue": null
},
"ColumnHeaderDto": {
"AllowHeaderFiltering": true,
"AllowSearch": false,
"DataSource": null,
"DataSourceString": ""
},
"ColumnGroupingDto": {
"AllowGrouping": true,
"GroupIndex": null,
"AutoExpandGroup": false
},
"ColumnCustomizationDto": {
"Fixed": false,
"FixedPosition": "left",
"AllowReordering": true
},
"ColumnTotalSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"ColumnGroupSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"LookupDto": {
"DataSourceType": 1,
"ValueExpr": "key",
"DisplayExpr": "name",
"CascadeRelationField": "",
"CascadeFilterOperator": "=",
"CascadeParentFields": "",
"CascadeEmptyFields": "",
"LookupQuery": "[{\"key\":\"FIFO\",\"name\":\"App.StaticLookup.Fifo\"},{\"key\":\"LIFO\",\"name\":\"App.StaticLookup.Lifo\"}]"
},
"ValidationRuleDto": [
{
"Type": "required",
"Message": null,
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
"Trim": true
}
],
"ColumnStylingDto": [],
"PermissionDto": {
"Deny": false,
"C": "App.Inventory.ProductCategory.Create",
"R": "App.Inventory.ProductCategory",
"U": "App.Inventory.ProductCategory.Update",
"E": true,
"I": true
},
"CanRead": false,
"CanCreate": false,
"CanUpdate": false,
"CanExport": false,
"DefaultValue": null,
"DefaultValueType": 0,
"PivotSettingsDto": {
"IsPivot": true,
"Expanded": false,
"SortOrder": "asc",
"Area": "filter",
"Format": null,
"SummaryType": null,
"GroupInterval": "",
"WordWrapEnabled": false
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 3,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
"EditorOptions": null,
"GridBoxOptions": null,
"TagBoxOptions": null,
"ImageUploadOptions": null,
"EditorScript": null,
"LastModificationTime": null,
"LastModifierId": null,
"CreationTime": "0001-01-01T00:00:00",
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
},
{
"EditType": null,
"ListFormCode": "App.Inventory.ProductCategory",
@ -1081,7 +1246,7 @@
"Visible": true,
"IsActive": true,
"Width": 0,
"ListOrderNo": 4,
"ListOrderNo": 5,
"SourceDbType": 3,
"CultureName": "en",
"DataType": "boolean",
@ -1148,6 +1313,8 @@
"IgnoreEmptyValue": false,
"Reevaluate": true,
"ComparisonType": "",
"ComparisonTarget": null,
"ValidationCallback": null,
"Pattern": "",
"Max": null,
"Min": null,
@ -1181,7 +1348,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 3,
"EditOrderNo": 4,
"EditGroupOrderNo": 1,
"EditorType2": "dxCheckBox",
"ColSpan": 1,
@ -1206,7 +1373,10 @@
"App.Inventory.ProductCategory.Desc",
"App.Inventory",
"App.Inventory.Definitions",
"App.Listform.ListformField.ParentCategory"
"App.Listform.ListformField.ParentCategory",
"App.Listform.ListformField.RemovalStrategy",
"App.StaticLookup.Fifo",
"App.StaticLookup.Lifo"
],
"PermissionGroupNames": [
"App.Inventory"

View file

@ -903,7 +903,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], CONCAT(Name, ' ', Surname) AS [Name] FROM AbpUsers WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], CONCAT(Name, ' ', Surname) AS [Name] FROM AbpUsers WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -1054,7 +1054,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Contact WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Contact WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1194,7 +1194,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": "ProductId",
"CascadeEmptyFields": null,
"LookupQuery": "SELECT CONCAT_WS('|', l1.VId, l2.VId, l3.VId, l4.VId, l5.VId) AS [Key], CONCAT_WS(', ', l1.VName, l2.VName, l3.VName, l4.VName, l5.VName) AS [Name] FROM Inv_T_Product p INNER JOIN (SELECT x.ProductId, x.Rk, CAST(s.value AS nvarchar(36)) AS VId, av.Name AS VName 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 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 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 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 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 WHERE p.IsDeleted = 'false' AND (p.Id = @param0 OR @param0 IS NULL)"
"LookupQuery": "SELECT CONCAT_WS('|', l1.VId, l2.VId, l3.VId, l4.VId, l5.VId) AS [Key], CONCAT_WS(', ', l1.VName, l2.VName, l3.VName, l4.VName, l5.VName) AS [Name] FROM Inv_T_Product p INNER JOIN (SELECT x.ProductId, x.Rk, CAST(s.value AS nvarchar(36)) AS VId, av.Name AS VName 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 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 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 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 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 WHERE p.IsDeleted = 'false' AND p.TenantId = '@TENANTID' AND (p.Id = @param0 OR @param0 IS NULL)"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1460,7 +1460,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -885,7 +885,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Product WHERE IsDeleted = 'false' ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_Product WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1641,7 +1641,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE IsDeleted = 'false' ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1767,7 +1767,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_ProductCategory WHERE IsDeleted = 'false' ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Inv_T_ProductCategory WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -106,18 +106,18 @@
"En": "Id",
"Tr": "Kimlik"
},
{
"FieldName": "PartnerId",
"CaptionName": "App.Inventory.Receipt.PartnerId",
"En": "Supplier Name",
"Tr": "Tedarikçi Adı"
},
{
"FieldName": "TransferNo",
"CaptionName": "App.Listform.ListformField.TransferNo",
"En": "Slip No",
"Tr": "Fiş No"
},
{
"FieldName": "PartnerId",
"CaptionName": "App.Inventory.Receipt.PartnerId",
"En": "Supplier Name",
"Tr": "Tedarikçi Adı"
},
{
"FieldName": "Status",
"CaptionName": "App.Listform.ListformField.Status",
@ -189,6 +189,12 @@
"CaptionName": "App.Listform.ListformField.SourceDocument",
"En": "Source Document",
"Tr": "Kaynak Belge"
},
{
"FieldName": "ReturnOfId",
"CaptionName": "App.Listform.ListformField.ReturnOfId",
"En": "Return Of",
"Tr": "İade Edilen Belge"
}
]
}
@ -596,7 +602,7 @@
"DialogParameters": null,
"OnClick": "(async () => { const r = e.row.data; if (!window.confirm(translate('::App.Inventory.Transfer.ConfirmAction'))) return; await dynamicFetch('list-form-data/update', 'POST', null, { listFormCode, keys: [r.Id], data: { PendingAction: 'Return' } }); e.component.refresh(); })().catch(() => {})",
"IsVisible": true,
"VisibleExpression": "(e) => !!e.row && !e.row.isEditing && ['Done'].includes(e.row.data.Status)"
"VisibleExpression": "(e) => !!e.row && !e.row.isEditing && ['Done'].includes(e.row.data.Status) && !e.row.data.ReturnOfId"
},
{
"ButtonPosition": 0,
@ -625,7 +631,7 @@
"InsertServiceAddress": "list-form-data/insert",
"DeleteServiceAddress": "list-form-data/delete",
"IsTenant": true,
"IsBranch": false,
"IsBranch": true,
"IsOrganizationUnit": false,
"ListFormType": "List",
"IsSubForm": false,
@ -1079,132 +1085,6 @@
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
},
{
"EditType": null,
"ListFormCode": "App.Inventory.Receipt",
"RoleId": null,
"UserId": null,
"ColumnJoinTableDto": {
"JoinType": null,
"TableName": null,
"JoinFieldName": null,
"BaseTableJoinFieldName": null,
"SelectFieldName": null,
"FieldNameAlias": null,
"JoinCondition2": "AND",
"JoinFieldName2": null,
"BaseTableJoinFieldName2_OrValue": null
},
"FieldName": "PartnerId",
"CaptionName": "App.Inventory.Receipt.PartnerId",
"PlaceHolder": null,
"ReadOnly": false,
"Visible": true,
"IsActive": true,
"Width": 0,
"ListOrderNo": 2,
"SourceDbType": 9,
"CultureName": "en",
"DataType": "string",
"SortIndex": 0,
"SortDirection": null,
"AllowSearch": true,
"AllowEditing": true,
"AllowAdding": true,
"ColumnCssClass": null,
"ColumnCssValue": null,
"BandName": null,
"ColumnFilterDto": {
"AllowFiltering": true,
"FilterOperations": null,
"SelectedFilterOperation": null,
"FilterValue": null
},
"ColumnHeaderDto": {
"AllowHeaderFiltering": true,
"AllowSearch": false,
"DataSource": null,
"DataSourceString": ""
},
"ColumnGroupingDto": {
"AllowGrouping": true,
"GroupIndex": null,
"AutoExpandGroup": false
},
"ColumnCustomizationDto": {
"Fixed": false,
"FixedPosition": "left",
"AllowReordering": true
},
"ColumnTotalSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"ColumnGroupSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"LookupDto": {
"DataSourceType": 2,
"ValueExpr": "Key",
"DisplayExpr": "Name",
"CascadeRelationField": null,
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Contact WHERE IsDeleted = 'false' AND IsActive = 1 AND TenantId = '@TENANTID' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
"PermissionDto": {
"Deny": false,
"C": "App.Inventory.Receipt.Create",
"R": "App.Inventory.Receipt",
"U": "App.Inventory.Receipt.Update",
"E": true,
"I": true
},
"CanRead": false,
"CanCreate": false,
"CanUpdate": false,
"CanExport": false,
"DefaultValue": null,
"DefaultValueType": 0,
"PivotSettingsDto": {
"IsPivot": true,
"Expanded": false,
"SortOrder": "asc",
"Area": "filter",
"Format": null,
"SummaryType": null,
"GroupInterval": "",
"WordWrapEnabled": false
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 1,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 2,
"EditorOptions": "{\"showClearButton\":true,\"searchEnabled\":true}",
"GridBoxOptions": null,
"TagBoxOptions": null,
"ImageUploadOptions": null,
"EditorScript": null,
"LastModificationTime": null,
"LastModifierId": null,
"CreationTime": "0001-01-01T00:00:00",
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
},
{
"EditType": null,
"ListFormCode": "App.Inventory.Receipt",
@ -1228,7 +1108,7 @@
"Visible": true,
"IsActive": true,
"Width": 0,
"ListOrderNo": 3,
"ListOrderNo": 2,
"SourceDbType": 16,
"CultureName": "en",
"DataType": "string",
@ -1316,7 +1196,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 2,
"EditOrderNo": 1,
"EditGroupOrderNo": 1,
"EditorType2": "dxTextBox",
"ColSpan": 1,
@ -1331,6 +1211,132 @@
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
},
{
"EditType": null,
"ListFormCode": "App.Inventory.Receipt",
"RoleId": null,
"UserId": null,
"ColumnJoinTableDto": {
"JoinType": null,
"TableName": null,
"JoinFieldName": null,
"BaseTableJoinFieldName": null,
"SelectFieldName": null,
"FieldNameAlias": null,
"JoinCondition2": "AND",
"JoinFieldName2": null,
"BaseTableJoinFieldName2_OrValue": null
},
"FieldName": "PartnerId",
"CaptionName": "App.Inventory.Receipt.PartnerId",
"PlaceHolder": null,
"ReadOnly": false,
"Visible": true,
"IsActive": true,
"Width": 0,
"ListOrderNo": 3,
"SourceDbType": 9,
"CultureName": "en",
"DataType": "string",
"SortIndex": 0,
"SortDirection": null,
"AllowSearch": true,
"AllowEditing": true,
"AllowAdding": true,
"ColumnCssClass": null,
"ColumnCssValue": null,
"BandName": null,
"ColumnFilterDto": {
"AllowFiltering": true,
"FilterOperations": null,
"SelectedFilterOperation": null,
"FilterValue": null
},
"ColumnHeaderDto": {
"AllowHeaderFiltering": true,
"AllowSearch": false,
"DataSource": null,
"DataSourceString": ""
},
"ColumnGroupingDto": {
"AllowGrouping": true,
"GroupIndex": null,
"AutoExpandGroup": false
},
"ColumnCustomizationDto": {
"Fixed": false,
"FixedPosition": "left",
"AllowReordering": true
},
"ColumnTotalSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"ColumnGroupSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"LookupDto": {
"DataSourceType": 2,
"ValueExpr": "Key",
"DisplayExpr": "Name",
"CascadeRelationField": null,
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Contact WHERE IsDeleted = 'false' AND IsActive = 1 AND TenantId = '@TENANTID' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
"PermissionDto": {
"Deny": false,
"C": "App.Inventory.Receipt.Create",
"R": "App.Inventory.Receipt",
"U": "App.Inventory.Receipt.Update",
"E": true,
"I": true
},
"CanRead": false,
"CanCreate": false,
"CanUpdate": false,
"CanExport": false,
"DefaultValue": null,
"DefaultValueType": 0,
"PivotSettingsDto": {
"IsPivot": true,
"Expanded": false,
"SortOrder": "asc",
"Area": "filter",
"Format": null,
"SummaryType": null,
"GroupInterval": "",
"WordWrapEnabled": false
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 4,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 3,
"EditorOptions": "{\"showClearButton\":true,\"searchEnabled\":true}",
"GridBoxOptions": null,
"TagBoxOptions": null,
"ImageUploadOptions": null,
"EditorScript": null,
"LastModificationTime": null,
"LastModifierId": null,
"CreationTime": "0001-01-01T00:00:00",
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
},
{
"EditType": null,
"ListFormCode": "App.Inventory.Receipt",
@ -1442,7 +1448,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 5,
"EditOrderNo": 9,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
@ -1582,7 +1588,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 3,
"EditOrderNo": 2,
"EditGroupOrderNo": 1,
"EditorType2": "dxDateBox",
"ColSpan": 1,
@ -1708,7 +1714,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 4,
"EditOrderNo": 3,
"EditGroupOrderNo": 1,
"EditorType2": "dxDateBox",
"ColSpan": 1,
@ -1804,7 +1810,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": "WarehouseId,OperationTypeId,SourceLocationId,DestinationLocationId",
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [
{
@ -1848,7 +1854,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 6,
"EditOrderNo": 5,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
@ -1988,7 +1994,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 7,
"EditOrderNo": 6,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
@ -2128,7 +2134,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 8,
"EditOrderNo": 7,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
@ -2268,7 +2274,7 @@
},
"Alignment": "left",
"Format": null,
"EditOrderNo": 9,
"EditOrderNo": 8,
"EditGroupOrderNo": 1,
"EditorType2": "dxSelectBox",
"ColSpan": 1,
@ -2912,6 +2918,132 @@
"CreationTime": "0001-01-01T00:00:00",
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
},
{
"EditType": null,
"ListFormCode": "App.Inventory.Receipt",
"RoleId": null,
"UserId": null,
"ColumnJoinTableDto": {
"JoinType": null,
"TableName": null,
"JoinFieldName": null,
"BaseTableJoinFieldName": null,
"SelectFieldName": null,
"FieldNameAlias": null,
"JoinCondition2": "AND",
"JoinFieldName2": null,
"BaseTableJoinFieldName2_OrValue": null
},
"FieldName": "ReturnOfId",
"CaptionName": "App.Listform.ListformField.ReturnOfId",
"PlaceHolder": null,
"ReadOnly": false,
"Visible": false,
"IsActive": true,
"Width": 0,
"ListOrderNo": 16,
"SourceDbType": 9,
"CultureName": "en",
"DataType": "string",
"SortIndex": 0,
"SortDirection": null,
"AllowSearch": true,
"AllowEditing": true,
"AllowAdding": true,
"ColumnCssClass": null,
"ColumnCssValue": null,
"BandName": null,
"ColumnFilterDto": {
"AllowFiltering": true,
"FilterOperations": null,
"SelectedFilterOperation": null,
"FilterValue": null
},
"ColumnHeaderDto": {
"AllowHeaderFiltering": true,
"AllowSearch": false,
"DataSource": null,
"DataSourceString": ""
},
"ColumnGroupingDto": {
"AllowGrouping": true,
"GroupIndex": null,
"AutoExpandGroup": false
},
"ColumnCustomizationDto": {
"Fixed": false,
"FixedPosition": "left",
"AllowReordering": true
},
"ColumnTotalSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"ColumnGroupSummaryDto": {
"SummaryType": null,
"ValueFormat": null,
"ShowInGroupFooter": false,
"AlignByColumn": false,
"DisplayFormat": null,
"ShowInColumn": null
},
"LookupDto": {
"DataSourceType": 0,
"ValueExpr": "Key",
"DisplayExpr": "Name",
"CascadeRelationField": null,
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": null
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
"PermissionDto": {
"Deny": false,
"C": "App.Inventory.Receipt.Create",
"R": "App.Inventory.Receipt",
"U": "App.Inventory.Receipt.Update",
"E": true,
"I": true
},
"CanRead": false,
"CanCreate": false,
"CanUpdate": false,
"CanExport": false,
"DefaultValue": null,
"DefaultValueType": 0,
"PivotSettingsDto": {
"IsPivot": true,
"Expanded": false,
"SortOrder": "asc",
"Area": "filter",
"Format": null,
"SummaryType": null,
"GroupInterval": "",
"WordWrapEnabled": false
},
"Alignment": "left",
"Format": null,
"EditOrderNo": null,
"EditGroupOrderNo": null,
"EditorType2": "dxTextBox",
"ColSpan": 1,
"EditorOptions": null,
"GridBoxOptions": null,
"TagBoxOptions": null,
"ImageUploadOptions": null,
"EditorScript": null,
"LastModificationTime": null,
"LastModifierId": null,
"CreationTime": "0001-01-01T00:00:00",
"CreatorId": null,
"Id": "00000000-0000-0000-0000-000000000000"
}
],
"IsDeletedField": true,

View file

@ -442,7 +442,7 @@
"InsertServiceAddress": "list-form-data/insert",
"DeleteServiceAddress": "list-form-data/delete",
"IsTenant": true,
"IsBranch": false,
"IsBranch": true,
"IsOrganizationUnit": false,
"ListFormType": "List",
"IsSubForm": false,
@ -937,7 +937,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -1693,7 +1693,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE IsDeleted = 'false' ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -543,7 +543,7 @@
"InsertServiceAddress": "list-form-data/insert",
"DeleteServiceAddress": "list-form-data/delete",
"IsTenant": true,
"IsBranch": false,
"IsBranch": true,
"IsOrganizationUnit": false,
"ListFormType": "List",
"IsSubForm": false,
@ -2424,7 +2424,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE IsDeleted = 'false' ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Adm_T_Uom WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],
@ -2550,7 +2550,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

View file

@ -508,7 +508,7 @@
"InsertServiceAddress": "list-form-data/insert",
"DeleteServiceAddress": "list-form-data/delete",
"IsTenant": true,
"IsBranch": false,
"IsBranch": true,
"IsOrganizationUnit": false,
"ListFormType": "List",
"IsSubForm": false,
@ -1521,7 +1521,7 @@
"CascadeFilterOperator": "=",
"CascadeParentFields": null,
"CascadeEmptyFields": null,
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
"LookupQuery": "SELECT Id AS [Key], Name AS [Name] FROM Sas_T_Branch WHERE TenantId = '@TENANTID' AND IsDeleted = 'false' AND IsActive = 1 ORDER BY Name"
},
"ValidationRuleDto": [],
"ColumnStylingDto": [],

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more