Satınalma Talepleri

This commit is contained in:
Sedat ÖZTÜRK 2026-10-09 20:02:27 +03:00
parent 1e3c66913d
commit 94ae8ed7ac
37 changed files with 23689 additions and 66 deletions

View file

@ -525,7 +525,7 @@ alanlar wizard dosyasının `Fields` bölümünden) ve yalnızca `create_table`
| `delete_wizard` | Wizard'ı ve yalnızca onun ürettiği kayıtları siler; `dropTables: true` ekranın tablosunu da düşürür | Bağımlı wizard varsa reddeder. Tablo kullanıcı açıkça onaylamadan düşürülmez; `App.SqlQueryManager` ister (§4.5) | | `delete_wizard` | Wizard'ı ve yalnızca onun ürettiği kayıtları siler; `dropTables: true` ekranın tablosunu da düşürür | Bağımlı wizard varsa reddeder. Tablo kullanıcı açıkça onaylamadan düşürülmez; `App.SqlQueryManager` ister (§4.5) |
| `start_dev_request` | `App.DevRequests` talebini üstlenir: `Ready to Start` durumundaysa `In Progress` durumuna alır, değilse reddeder | Ek olarak `App.DevRequests.Update` ister. Açıklamadaki görseller ayrı resim içeriği olarak gelir (§0.11) | | `start_dev_request` | `App.DevRequests` talebini üstlenir: `Ready to Start` durumundaysa `In Progress` durumuna alır, değilse reddeder | Ek olarak `App.DevRequests.Update` ister. Açıklamadaki görseller ayrı resim içeriği olarak gelir (§0.11) |
| `get_dev_request` | Talebi durumuna dokunmadan okur (aynı metin + analiz + resim içerikleri) | Analizden önce ya da yarım kalan talebe dönmek için; `App.DevRequests` ister | | `get_dev_request` | Talebi durumuna dokunmadan okur (aynı metin + analiz + resim içerikleri) | Analizden önce ya da yarım kalan talebe dönmek için; `App.DevRequests` ister |
| `save_dev_request_analysis` | `Backlog`/`Analysis` durumundaki talebin analizini `Analysis` kolonuna yazar (var olanı değiştirir); `productionReady: true` (Üretime hazır: Evet) talebi `Ready to Start`'a, `false` (şartlı/Hayır) `Analysis` durumuna alır; diğer durumları reddeder. Modül dokümanına yazmaz; doküman üretimde açılır (§0.13) | Ek olarak `App.DevRequests.Update` ister. Standart §0.12; `Description`'a dokunmaz | | `save_dev_request_analysis` | `Backlog`/`Analysis`/`Ready to Start` durumundaki talebin analizini `Analysis` kolonuna yazar (var olanı değiştirir); `productionReady: true` (Üretime hazır: Evet) talebi `Ready to Start`'a, `false` (şartlı/Hayır) `Analysis` durumuna alır; diğer durumları reddeder. Modül dokümanına yazmaz; doküman üretimde açılır (§0.13) | Ek olarak `App.DevRequests.Update` ister. Standart §0.12; `Description`'a dokunmaz |
| `append_dev_request_note` | Talebin `Analysis` kolonunun sonuna HTML ekler | Üretim sonuç notu için; `Description` ve `Analysis` `update_row` ile yazılmaz (§0.11) | | `append_dev_request_note` | Talebin `Analysis` kolonunun sonuna HTML ekler | Üretim sonuç notu için; `Description` ve `Analysis` `update_row` ile yazılmaz (§0.11) |
| `add_dev_request_subtasks` | `SubTasks` listesine tamamlanmış satırlar ekler | Atanan = bağlanan kullanıcı, bitiş = bugün (sunucu yazar); `SubTasks`'ı `update_row` ile yazma (§0.11) | | `add_dev_request_subtasks` | `SubTasks` listesine tamamlanmış satırlar ekler | Atanan = bağlanan kullanıcı, bitiş = bugün (sunucu yazar); `SubTasks`'ı `update_row` ile yazma (§0.11) |
| `verify_wizard` | DB Migrate ile kurulmuş ekranı veri yazmadan doğrular (migrate bekleyen dosyada `install` kontrolü başarısız döner, diğerleri yapılmaz): menü, yetki tanımı, ekran sorgusu (List) ya da bileşen (Custom), seed kapanışı | İsteğe bağlı: kullanıcı migrate sonrası isterse. Talep döngüsünün (§0.11) adımı değildir. `passed` yalnızca engelleyici bir kontrol kalırsa `false` | | `verify_wizard` | DB Migrate ile kurulmuş ekranı veri yazmadan doğrular (migrate bekleyen dosyada `install` kontrolü başarısız döner, diğerleri yapılmaz): menü, yetki tanımı, ekran sorgusu (List) ya da bileşen (Custom), seed kapanışı | İsteğe bağlı: kullanıcı migrate sonrası isterse. Talep döngüsünün (§0.11) adımı değildir. `passed` yalnızca engelleyici bir kontrol kalırsa `false` |
@ -1013,7 +1013,8 @@ Query'de üretilmez (kaynak tablo adı değildir), gerekiyorsa elle yazılır.
**`LookupDataSourceType`** — `1` StaticData · `2` Query · `3` WebService **`LookupDataSourceType`** — `1` StaticData · `2` Query · `3` WebService
**`CustomValueType`** (`FieldCustomValueTypeEnum`) — `1` Value · `2` CustomKey · `3` DbQuery · **`CustomValueType`** (`FieldCustomValueTypeEnum`) — `1` Value · `2` CustomKey · `3` DbQuery ·
`4` QueryParams · `5` Sequence (§4.3.5) `4` QueryParams · `5` Sequence (§4.3.5). `DbQuery`'nin `SqlQuery` metnindeki yer tutucular (`'@USERID'`,
`'@TENANTID'`, `@USERNAME` …) liste sorgularındaki gibi `DefaultValueHelper` ile çözülür.
**`SortMode`** (`UiGridSortModeEnum`) — `1` Single · `2` Multiple · `3` None **`SortMode`** (`UiGridSortModeEnum`) — `1` Single · `2` Multiple · `3` None
@ -1122,6 +1123,10 @@ menü, izin grubu, paylaşılan dil anahtarı) dokunulmaz — metni kendi ekran
Kurulum **DB Migrate**'tedir (Wizard Manager'daki buton, `POST /api/setup/migrate`). Sıra: Kurulum **DB Migrate**'tedir (Wizard Manager'daki buton, `POST /api/setup/migrate`). Sıra:
`WizardDataSeeder` ekrana özgü kayıtları kurar (veri kaynağı, ListForm, alanlar, iş akışı), ardından `WizardDataSeeder` ekrana özgü kayıtları kurar (veri kaynağı, ListForm, alanlar, iş akışı), ardından
`ListFormSeedDataApplier` menü/yetki/dil satırlarını ekler (eksik olanı ekler, var olana dokunmaz). `ListFormSeedDataApplier` menü/yetki/dil satırlarını ekler (eksik olanı ekler, var olana dokunmaz).
Her wizard dosyası kendi unit of work'ünde kurulur: hata veren dosya geri alınır (önceki ekran yerinde
kalır, `Pending` silinmez), sonraki dosyalar etkilenmez. İş akışı kurulumdan önce
`ListFormWizardDto.NormalizeWorkflow`'dan geçer (adım kimliği `{ListFormCode}-N…`, boş onaycı/kolon
`''`); MCP'nin `ListForm` katmanıyla gelen `WorkflowDto` deploy'da da aynı metottan geçer.
**Yetkiler hiçbir role otomatik atanmaz** — admin dahil; ekranı hangi rolün göreceği rol ekranından **Yetkiler hiçbir role otomatik atanmaz** — admin dahil; ekranı hangi rolün göreceği rol ekranından
seçilir. Tek istisna yeni kiracının yöneticisidir: ilk seed'de, o anda tanımlı olan kiracı tarafı seçilir. Tek istisna yeni kiracının yöneticisidir: ilk seed'de, o anda tanımlı olan kiracı tarafı
yetkilerin hepsini alır (`PlatformIdentityDataSeeder`). yetkilerin hepsini alır (`PlatformIdentityDataSeeder`).
@ -1953,6 +1958,7 @@ ile ekler (§4.0). Sıra değerleri veritabanı ile dosyadaki satırların birle
| `DefaultFilter` | `IsDeletedField: true` ise `"IsDeleted" = 'false'` | | `DefaultFilter` | `IsDeletedField: true` ise `"IsDeleted" = 'false'` |
| `InsertFieldsDefaultValueJson` | `IsCreatedField: true` ise `CreationTime=@NOW`, `CreatorId=@USERID`, `IsDeleted=false`, `Id=@NEWID`; değilse yalnızca `Id=@NEWID` | | `InsertFieldsDefaultValueJson` | `IsCreatedField: true` ise `CreationTime=@NOW`, `CreatorId=@USERID`, `IsDeleted=false`, `Id=@NEWID`; değilse yalnızca `Id=@NEWID` |
| `DeleteFieldsDefaultValueJson` | `IsDeletedField: true` ise `DeleterId=@USERID`, `Id=@ID`; değilse yalnızca `Id=@ID` | | `DeleteFieldsDefaultValueJson` | `IsDeletedField: true` ise `DeleterId=@USERID`, `Id=@ID`; değilse yalnızca `Id=@ID` |
| `UpdateFieldsDefaultValueJson` | Tabloda `LastModifierId` varsa `LastModificationTime=@NOW`, `LastModifierId=@USERID`; yoksa boş. `*AfterCommand`/`*BeforeCommand` içindeki `@LastModifierId` bu satırdan gelir |
| `ValidationRuleJson` | `IsRequired: true` olan alanlara required kuralı | | `ValidationRuleJson` | `IsRequired: true` olan alanlara required kuralı |
| `LookupJson` | `LookupQuery` doluysa `LookupDataSourceType` + `DisplayExpr` + `ValueExpr` ile | | `LookupJson` | `LookupQuery` doluysa `LookupDataSourceType` + `DisplayExpr` + `ValueExpr` ile |
| `ShowNote` | Alt form veya iş akışı varsa açılır | | `ShowNote` | Alt form veya iş akışı varsa açılır |

View file

@ -1570,7 +1570,7 @@ liste süzgeci ve çağrı kapısı aynı kuralı kullanır.
| `verify_wizard` | Deploy edilmiş ekranı veri yazmadan doğrular: menü kaydı ve URL'si, menünün istediği yetki tanımı (`AbpPermissions`), List yolunda ekran sorgusu (`GetSelectAsync`, tek satır, çağıranın yetkisiyle), Custom yolunda bileşen (etkin, rota = menü URL'si) ve seed kapanışı (`ExportAnalysis` uyarıları; engellemez). İsteğe bağlıdır, migrate sonrasında kullanılır; `App.DevRequests` döngüsünün adımı değildir — döngü `Testing`'de biter, kullanıcı elle test edip `Staging`'e alır (`lowcode.instructions.md` §0.11). | | `verify_wizard` | Deploy edilmiş ekranı veri yazmadan doğrular: menü kaydı ve URL'si, menünün istediği yetki tanımı (`AbpPermissions`), List yolunda ekran sorgusu (`GetSelectAsync`, tek satır, çağıranın yetkisiyle), Custom yolunda bileşen (etkin, rota = menü URL'si) ve seed kapanışı (`ExportAnalysis` uyarıları; engellemez). İsteğe bağlıdır, migrate sonrasında kullanılır; `App.DevRequests` döngüsünün adımı değildir — döngü `Testing`'de biter, kullanıcı elle test edip `Staging`'e alır (`lowcode.instructions.md` §0.11). |
| `start_dev_request` | Geliştirme talebini Id ya da tam başlıkla üstlenir: yalnızca `Ready to Start` durumundakini `In Progress` durumuna alır, diğerlerini reddeder; talebin metnini döndürür. Açıklamaya yapıştırılmış base64 görseller (`data:image/png|jpeg|gif|webp`) metinden ayıklanır (`McpDevRequestImages`), yerlerinde `[image-N]` kalır ve her biri ayrı MCP resim içeriği (`ImageContentBlock`) olarak döner — model görseli resim olarak görür, görsel hiçbir yere yüklenmez. Sonuç istemcinin 1 MB sınırına sığdırılır: büyük görseller küçültülüp JPEG'e çevrilir (`IMcpImageShrinker`), sığmayan gönderilmez ve metinde bildirilir. `.Write` + `App.DevRequests.Update` ister. | | `start_dev_request` | Geliştirme talebini Id ya da tam başlıkla üstlenir: yalnızca `Ready to Start` durumundakini `In Progress` durumuna alır, diğerlerini reddeder; talebin metnini döndürür. Açıklamaya yapıştırılmış base64 görseller (`data:image/png|jpeg|gif|webp`) metinden ayıklanır (`McpDevRequestImages`), yerlerinde `[image-N]` kalır ve her biri ayrı MCP resim içeriği (`ImageContentBlock`) olarak döner — model görseli resim olarak görür, görsel hiçbir yere yüklenmez. Sonuç istemcinin 1 MB sınırına sığdırılır: büyük görseller küçültülüp JPEG'e çevrilir (`IMcpImageShrinker`), sığmayan gönderilmez ve metinde bildirilir. `.Write` + `App.DevRequests.Update` ister. |
| `get_dev_request` | Talebi durumuna dokunmadan, `start_dev_request` ile aynı biçimde (metin + analiz + resim içerikleri) okur; analizden önce ya da yarım kalan talebe dönmek için. `App.DevRequests` ister. | | `get_dev_request` | Talebi durumuna dokunmadan, `start_dev_request` ile aynı biçimde (metin + analiz + resim içerikleri) okur; analizden önce ya da yarım kalan talebe dönmek için. `App.DevRequests` ister. |
| `save_dev_request_analysis` | `Backlog` ya da `Analysis` durumundaki talebin analizini (HTML) `Analysis` kolonuna yazar — var olanı değiştirir; `productionReady: true` (Üretime hazır: Evet) talebi `Ready to Start`'a, `false` (şartlı ya da Hayır) `Analysis` durumuna alır; diğer durumları reddeder. `Description`'a dokunmaz. Modül dokümanına yazmaz; doküman üretimde açılır. Analizin standardı `lowcode.instructions.md` §0.12. `.Write` + `App.DevRequests.Update` ister. | | `save_dev_request_analysis` | `Backlog`, `Analysis` ya da `Ready to Start` durumundaki talebin analizini (HTML) `Analysis` kolonuna yazar — var olanı değiştirir; `productionReady: true` (Üretime hazır: Evet) talebi `Ready to Start`'a, `false` (şartlı ya da Hayır) `Analysis` durumuna alır; diğer durumları reddeder. `Description`'a dokunmaz. Modül dokümanına yazmaz; doküman üretimde açılır. Analizin standardı `lowcode.instructions.md` §0.12. `.Write` + `App.DevRequests.Update` ister. |
| `add_dev_request_subtasks` | Talebin `SubTasks` listesine tamamlanmış satırlar ekler: model yalnızca başlığı verir, atanan kişi bağlanan kullanıcının adı (`userName`), bitiş tarihi bugün (`yyyy-MM-dd`) olarak sunucuda yazılır; var olan satırlar korunur. `.Write` + `App.DevRequests.Update` ister. | | `add_dev_request_subtasks` | Talebin `SubTasks` listesine tamamlanmış satırlar ekler: model yalnızca başlığı verir, atanan kişi bağlanan kullanıcının adı (`userName`), bitiş tarihi bugün (`yyyy-MM-dd`) olarak sunucuda yazılır; var olan satırlar korunur. `.Write` + `App.DevRequests.Update` ister. |
| `append_dev_request_note` | Talebin `Analysis` kolonunun sonuna HTML ekler (üretim sonuç notu); `Description` talebin yazıldığı hâliyle kalır. İkisi de `update_row` ile yazılmaz — açıklama base64 görsel taşır. `.Write` + `App.DevRequests.Update` ister. | | `append_dev_request_note` | Talebin `Analysis` kolonunun sonuna HTML ekler (üretim sonuç notu); `Description` talebin yazıldığı hâliyle kalır. İkisi de `update_row` ile yazılmaz — açıklama base64 görsel taşır. `.Write` + `App.DevRequests.Update` ister. |
| `list_components` / `get_component` / `save_component` / `delete_component` | Custom component'ler `ICustomComponentAppService` üzerinden; seed senkronu ve `DataSources` çözümü aynen çalışır. `save_component` ada göre ekler/günceller, tasarımcı belgesi (`Props.visualDesigner`, `sourceMode ≠ code`) taşıyan bileşene kod yazmayı reddeder — kod belgeden üretildiği için tasarımcıdaki ilk kayıtta ezilirdi. | | `list_components` / `get_component` / `save_component` / `delete_component` | Custom component'ler `ICustomComponentAppService` üzerinden; seed senkronu ve `DataSources` çözümü aynen çalışır. `save_component` ada göre ekler/günceller, tasarımcı belgesi (`Props.visualDesigner`, `sourceMode ≠ code`) taşıyan bileşene kod yazmayı reddeder — kod belgeden üretildiği için tasarımcıdaki ilk kayıtta ezilirdi. |
@ -1675,9 +1675,10 @@ servisinin sınıf düzeyindeki `[Authorize]` attribute'undadır; `/mcp` ucu yal
ister (ucun kendisinde aranırsa kullanıcı nedeni yazmayan bir 403 alır). Araç listesi aynı ister (ucun kendisinde aranırsa kullanıcı nedeni yazmayan bir 403 alır). Araç listesi aynı
kurallarla süzülür (`GetAvailableToolsAsync`), çağrı anında kontrol tekrarlanır. kurallarla süzülür (`GetAvailableToolsAsync`), çağrı anında kontrol tekrarlanır.
**Yetkisi olmayan çağrı ne görür.** SDK araç hatasının mesajını yalnızca `McpException` ise **Yetkisi olmayan çağrı ne görür.** SDK çevrilmemiş istisnayı "An error occurred invoking '…'"
iletir; diğer her istisna "An error occurred invoking '…'" olarak gider. `McpToolErrorTranslator` olarak iletir. `McpToolErrorTranslator` (çağrı ve araç listesi filtresi, `McpHttpApiModule`) iki tür
(çağrı ve araç listesi filtresi, `McpHttpApiModule`) iki tür hatayı çevirir: hatayı mesaja çevirir; çağrı filtresi mesajı istisna atmadan hata sonucu (`CallToolResult.IsError`)
olarak döner — beklenen ret sunucu logunda yığın izli `ERR` üretmez, model nedeni okuyup devam eder:
- **Yetki reddi** → `App.Mcp.Error.PermissionDenied`: "'deploy_wizard' için gereken yetkiniz yok: - **Yetki reddi** → `App.Mcp.Error.PermissionDenied`: "'deploy_wizard' için gereken yetkiniz yok:
Wizard (App.Listforms.Wizard). Yöneticinizden bu yetkiyi isteyin." Eksik yetkiler aracın bilinen Wizard (App.Listforms.Wizard). Yöneticinizden bu yetkiyi isteyin." Eksik yetkiler aracın bilinen

View file

@ -580,8 +580,8 @@ public class McpDevelopAppService(
} }
/// <summary> /// <summary>
/// Durum kurali modelin dikkatine birakilmaz: yalnizca Backlog ya da Analysis durumundaki talep /// Durum kurali modelin dikkatine birakilmaz: uretimi baslamamis (Backlog, Analysis, Ready to Start)
/// analiz edilir. "Uretime hazir: Evet" analiz uretimin karar vermeden uygulayabilecegi analizdir, /// talep analiz edilir; Ready to Start talebin analizi uretim oncesi yeniden yazilabilir. "Uretime hazir: Evet" analiz uretimin karar vermeden uygulayabilecegi analizdir,
/// talep dogrudan Ready to Start'a gecer; sartli ya da Hayir olan analiz kullanicinin kararini /// talep dogrudan Ready to Start'a gecer; sartli ya da Hayir olan analiz kullanicinin kararini
/// bekledigi icin Analysis'te kalir. /// bekledigi icin Analysis'te kalir.
/// </summary> /// </summary>
@ -597,7 +597,7 @@ public class McpDevelopAppService(
var devRequest = await FindDevRequestAsync(request); var devRequest = await FindDevRequestAsync(request);
if (devRequest.Status is not (McpConsts.DevRequestStatuses.Backlog or McpConsts.DevRequestStatuses.Analysis)) if (devRequest.Status is not (McpConsts.DevRequestStatuses.Backlog or McpConsts.DevRequestStatuses.Analysis or McpConsts.DevRequestStatuses.ReadyToStart))
{ {
throw new UserFriendlyException(L[McpErrorCodes.DevRequestNotAnalyzable, devRequest.Title ?? devRequest.Id.ToString(), devRequest.Status ?? string.Empty]); throw new UserFriendlyException(L[McpErrorCodes.DevRequestNotAnalyzable, devRequest.Title ?? devRequest.Id.ToString(), devRequest.Status ?? string.Empty]);
} }

View file

@ -1,7 +1,9 @@
using System; using System;
using System.Linq; using System.Linq;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using ModelContextProtocol;
using ModelContextProtocol.AspNetCore; using ModelContextProtocol.AspNetCore;
using ModelContextProtocol.Protocol;
using Sozsoft.Mcp.Tools; using Sozsoft.Mcp.Tools;
using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
@ -72,14 +74,15 @@ public class McpHttpApiModule : AbpModule
} }
catch (System.Exception ex) when (McpToolErrorTranslator.CanTranslate(ex)) catch (System.Exception ex) when (McpToolErrorTranslator.CanTranslate(ex))
{ {
throw await requestContext.Services!.GetRequiredService<McpToolErrorTranslator>().TranslateAsync(ex, null); throw new McpException(await requestContext.Services!.GetRequiredService<McpToolErrorTranslator>().TranslateAsync(ex, null), ex);
} }
return result; return result;
}); });
// SDK arac hatasinin mesajini yalnizca McpException ise iletir; yetki reddi ve is // Yetki reddi ve is kurali hatasi aracin beklenen sonucudur: firlatilirsa SDK onu
// kurali hatalari burada cevrilir ki istemci nedenini (eksik yetkiyi) gorsun. // yigin izli ERR olarak loglar. Hata sonucu (IsError) olarak donulur; model nedeni
// (eksik yetkiyi) okuyup devam eder.
filters.AddCallToolFilter(next => async (requestContext, cancellationToken) => filters.AddCallToolFilter(next => async (requestContext, cancellationToken) =>
{ {
try try
@ -88,7 +91,8 @@ public class McpHttpApiModule : AbpModule
} }
catch (System.Exception ex) when (McpToolErrorTranslator.CanTranslate(ex)) catch (System.Exception ex) when (McpToolErrorTranslator.CanTranslate(ex))
{ {
throw await requestContext.Services!.GetRequiredService<McpToolErrorTranslator>().TranslateAsync(ex, requestContext.Params?.Name); var message = await requestContext.Services!.GetRequiredService<McpToolErrorTranslator>().TranslateAsync(ex, requestContext.Params?.Name);
return new CallToolResult { IsError = true, Content = [new TextContentBlock { Text = message }] };
} }
}); });
}); });

View file

@ -1,9 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using ModelContextProtocol;
using Sozsoft.Platform.Localization; using Sozsoft.Platform.Localization;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Authorization; using Volo.Abp.Authorization;
@ -13,9 +12,8 @@ using Volo.Abp.DependencyInjection;
namespace Sozsoft.Mcp; namespace Sozsoft.Mcp;
/// <summary> /// <summary>
/// Arac hatalarini istemcinin gorebilecegi bicime cevirir. SDK yalnizca <see cref="McpException"/> /// Arac hatalarini istemcinin gorebilecegi mesaja cevirir. SDK cevrilmemis istisnayi
/// mesajini iletir; diger her istisna "An error occurred invoking" olarak gider ve model neden /// "An error occurred invoking" olarak iletir ve model neden reddedildigini bilemez. Yetki reddinde eksik yetkiler adiyla, is kurali hatasinda
/// reddedildigini bilemez. Yetki reddinde eksik yetkiler adiyla, is kurali hatasinda
/// (<see cref="UserFriendlyException"/>) zaten yerellestirilmis mesaj iletilir. Diger istisnalar /// (<see cref="UserFriendlyException"/>) zaten yerellestirilmis mesaj iletilir. Diger istisnalar
/// cevrilmez: ic ayrinti (SQL, yigin) istemciye sizmaz. /// cevrilmez: ic ayrinti (SQL, yigin) istemciye sizmaz.
/// </summary> /// </summary>
@ -26,10 +24,10 @@ public class McpToolErrorTranslator(
public static bool CanTranslate(Exception exception) public static bool CanTranslate(Exception exception)
=> exception is AbpAuthorizationException or UserFriendlyException; => exception is AbpAuthorizationException or UserFriendlyException;
public async Task<McpException> TranslateAsync(Exception exception, string? toolName) public async Task<string> TranslateAsync(Exception exception, string? toolName)
=> exception is AbpAuthorizationException authorization => exception is AbpAuthorizationException authorization
? new McpException(await DescribeMissingPermissionsAsync(authorization, toolName), exception) ? await DescribeMissingPermissionsAsync(authorization, toolName)
: new McpException(exception.Message, exception); : exception.Message;
/// <summary> /// <summary>
/// <c>CheckAsync("...")</c> reddi yetki adini tasir; <c>[Authorize]</c> attribute'u tasimaz. Ikinci /// <c>CheckAsync("...")</c> reddi yetki adini tasir; <c>[Authorize]</c> attribute'u tasimaz. Ikinci

View file

@ -138,7 +138,7 @@ public sealed class McpDevelopTools(IMcpDevelopAppService developAppService, IMc
=> ToContent(await developAppService.GetDevRequestAsync(request)); => ToContent(await developAppService.GetDevRequestAsync(request));
[McpServerTool(Name = McpToolNames.SaveDevRequestAnalysis, Destructive = true, Idempotent = true)] [McpServerTool(Name = McpToolNames.SaveDevRequestAnalysis, Destructive = true, Idempotent = true)]
[Description("Backlog ya da Analysis durumundaki bir talebin analizini (HTML) Analysis alanina yazar; var olan analiz degistirilir, Description'a dokunulmaz. productionReady true ise talep Ready to Start'a, false ise Analysis durumuna alinir. Diger durumlarda reddeder. Once get_dev_request ile talebi ve gorsellerini oku; analizin bolumleri ve standardi get_dev_guide lowcode 0.12'dedir.")] [Description("Backlog, Analysis ya da Ready to Start durumundaki bir talebin analizini (HTML) Analysis alanina yazar; var olan analiz degistirilir, Description'a dokunulmaz. productionReady true ise talep Ready to Start'a, false ise Analysis durumuna alinir. Diger durumlarda reddeder. Once get_dev_request ile talebi ve gorsellerini oku; analizin bolumleri ve standardi get_dev_guide lowcode 0.12'dedir.")]
public async Task<IList<ContentBlock>> SaveDevRequestAnalysisAsync( public async Task<IList<ContentBlock>> SaveDevRequestAnalysisAsync(
[Description("Talebin Id'si (GUID) ya da tam basligi.")] [Description("Talebin Id'si (GUID) ya da tam basligi.")]
string request, string request,

View file

@ -247,11 +247,12 @@ public class ListFormWizardDto
} }
/// <summary> /// <summary>
/// Wizard girdisinden ListForm sozlesmesini uretir. <paramref name="isDeletedField"/> ve /// Wizard girdisinden ListForm sozlesmesini uretir. <paramref name="isDeletedField"/>,
/// <paramref name="isCreatedField"/> hedef tablonun soft delete / audit kolonlarini tasiyip /// <paramref name="isCreatedField"/> ve <paramref name="isModifiedField"/> hedef tablonun soft delete /
/// tasimadigini bildirir; silme komutu ve varsayilan alan degerleri buna gore kurulur. /// olusturma / degistirme audit kolonlarini tasiyip tasimadigini bildirir; silme komutu ve
/// varsayilan alan degerleri buna gore kurulur.
/// </summary> /// </summary>
public GridOptionsEditDto BuildListForm(bool isDeletedField, bool isCreatedField) public GridOptionsEditDto BuildListForm(bool isDeletedField, bool isCreatedField, bool isModifiedField)
{ {
var code = ResolveMenuCode(); var code = ResolveMenuCode();
var listFormCode = ResolveListFormCode(); var listFormCode = ResolveListFormCode();
@ -347,6 +348,8 @@ public class ListFormWizardDto
dto.InsertFieldsDefaultValueJson = isCreatedField dto.InsertFieldsDefaultValueJson = isCreatedField
? WizardConsts.DefaultInsertFieldsDefaultValueJson(KeyFieldDbSourceType) ? WizardConsts.DefaultInsertFieldsDefaultValueJson(KeyFieldDbSourceType)
: WizardConsts.DefaultInsertFieldsJsonOnlyId(KeyFieldDbSourceType); : WizardConsts.DefaultInsertFieldsJsonOnlyId(KeyFieldDbSourceType);
// Ekranin *AfterCommand'lari (@LastModifierId) ve audit kolonlari guncellemede de dolar.
dto.UpdateFieldsDefaultValueJson = isModifiedField ? WizardConsts.DefaultUpdateFieldsDefaultValueJson : null;
var formDefaults = BuildFormDefaults(groups); var formDefaults = BuildFormDefaults(groups);
dto.FormFieldsDefaultValueJson = formDefaults.Count > 0 ? JsonSerializer.Serialize(formDefaults) : null; dto.FormFieldsDefaultValueJson = formDefaults.Count > 0 ? JsonSerializer.Serialize(formDefaults) : null;
dto.EditingFormJson = editingFormDtos.Count > 0 ? JsonSerializer.Serialize(editingFormDtos) : null; dto.EditingFormJson = editingFormDtos.Count > 0 ? JsonSerializer.Serialize(editingFormDtos) : null;
@ -620,9 +623,11 @@ public class ListFormWizardDto
/// <summary> /// <summary>
/// Workflow adimlarini kaydedilebilir hale getirir: basliklar tekillestirilir, adim /// Workflow adimlarini kaydedilebilir hale getirir: basliklar tekillestirilir, adim
/// kimlikleri ListForm koduyla on eklenir. Seed dosyasina normalize edilmis hali yazilir. /// kimlikleri ListForm koduyla on eklenir, tablonun NOT NULL metin kolonlari bos metinle
/// doldurulur. Seed dosyasina normalize edilmis hali yazilir; MCP katmani (ListForm bolumu) ve
/// elle duzenlenmis dosya da kurulumdan once ayni yoldan gecer.
/// </summary> /// </summary>
private static WorkflowDto NormalizeWorkflow(WorkflowDto workflow, string listFormCode) public static WorkflowDto NormalizeWorkflow(WorkflowDto workflow, string listFormCode)
{ {
workflow ??= new WorkflowDto(); workflow ??= new WorkflowDto();
workflow.Criteria ??= []; workflow.Criteria ??= [];
@ -692,6 +697,10 @@ public class ListFormWizardDto
{ {
item.Id = NormalizeWorkflowCriteriaId(listFormCode, item.Id); item.Id = NormalizeWorkflowCriteriaId(listFormCode, item.Id);
item.ListFormCode = listFormCode; item.ListFormCode = listFormCode;
item.Kind = item.Kind?.Trim() ?? string.Empty;
item.CompareColumn ??= string.Empty;
item.CompareOperator ??= string.Empty;
item.Approver = item.Approver?.Trim() ?? string.Empty;
item.NextOnStart = NormalizeWorkflowTargetId(listFormCode, item.NextOnStart); item.NextOnStart = NormalizeWorkflowTargetId(listFormCode, item.NextOnStart);
item.NextOnTrue = NormalizeWorkflowTargetId(listFormCode, item.NextOnTrue); item.NextOnTrue = NormalizeWorkflowTargetId(listFormCode, item.NextOnTrue);
item.NextOnFalse = NormalizeWorkflowTargetId(listFormCode, item.NextOnFalse); item.NextOnFalse = NormalizeWorkflowTargetId(listFormCode, item.NextOnFalse);

View file

@ -302,11 +302,16 @@ public class ListFormWizardAppService(
List<ColumnFormatEditDto> fieldDtos = []; List<ColumnFormatEditDto> fieldDtos = [];
var isDeleted = false; var isDeleted = false;
var isCreated = false; var isCreated = false;
var isModified = false;
// Custom yolunda ListForm ekosistemi üretilmez: veri kaynağı, ListForm, alanlar, // Custom yolunda ListForm ekosistemi üretilmez: veri kaynağı, ListForm, alanlar,
// subform/widget/workflow kayıtlarının hiçbirine ihtiyaç yoktur. // subform/widget/workflow kayıtlarının hiçbirine ihtiyaç yoktur.
if (!isCustomComponent) if (!isCustomComponent)
{ {
// Wizard ekrani veri kaynagini varsayilanla acar; bos gelen girdi (MCP) ayni varsayilana duser.
if (string.IsNullOrWhiteSpace(input.DataSourceCode))
input.DataSourceCode = SeedConsts.DataSources.DefaultCode;
// Yeni veri kaynagini migrate, wizard dosyasindaki baglanti cumlesinden kurar. // Yeni veri kaynagini migrate, wizard dosyasindaki baglanti cumlesinden kurar.
if (!await repoDataSource.AnyAsync(a => a.Code == input.DataSourceCode)) if (!await repoDataSource.AnyAsync(a => a.Code == input.DataSourceCode))
{ {
@ -327,6 +332,7 @@ public class ListFormWizardAppService(
? await IsQueryMainTableSoftDeletedAsync(input) ? await IsQueryMainTableSoftDeletedAsync(input)
: tableColumns.ContainsKey("IsDeleted"); : tableColumns.ContainsKey("IsDeleted");
isCreated = tableColumns.ContainsKey("CreatorId"); isCreated = tableColumns.ContainsKey("CreatorId");
isModified = tableColumns.ContainsKey("LastModifierId");
// Yeni kaydin form degeri, cevapta yazilmadiysa kolonun sabit DEFAULT'udur (IsActive DEFAULT 1 → // Yeni kaydin form degeri, cevapta yazilmadiysa kolonun sabit DEFAULT'udur (IsActive DEFAULT 1 →
// true, UomId DEFAULT 'Adet'); deger koda degil tabloyu tanimlayan scripte aittir. // true, UomId DEFAULT 'Adet'); deger koda degil tabloyu tanimlayan scripte aittir.
@ -337,7 +343,7 @@ public class ListFormWizardAppService(
} }
foreach (var item in input.Groups.SelectMany(g => g.Items)) foreach (var item in input.Groups.SelectMany(g => g.Items))
item.CaptionName = await ResolveLanguageKeyCasingAsync(rows, item.CaptionName); item.CaptionName = await ResolveLanguageKeyCasingAsync(rows, item.CaptionName);
listFormDto = input.BuildListForm(isDeleted, isCreated); listFormDto = input.BuildListForm(isDeleted, isCreated, isModified);
fieldDtos = input.BuildFields(); fieldDtos = input.BuildFields();
// Veri aynasinin yeri ekranin tanimidir; tasarimcida klasore cevrilmis bir hedef // Veri aynasinin yeri ekranin tanimidir; tasarimcida klasore cevrilmis bir hedef
@ -346,7 +352,7 @@ public class ListFormWizardAppService(
listFormDto.SeedFilePath = previous.ListForm.SeedFilePath; listFormDto.SeedFilePath = previous.ListForm.SeedFilePath;
if (input.ScreenOverlay != null) if (input.ScreenOverlay != null)
(listFormDto, fieldDtos) = await ApplyScreenOverlayAsync(input, listFormDto, fieldDtos, isDeleted, isCreated, rows); (listFormDto, fieldDtos) = await ApplyScreenOverlayAsync(input, listFormDto, fieldDtos, isDeleted, isCreated, isModified, rows);
ValidateImageColumnLengths(input, tableColumns); ValidateImageColumnLengths(input, tableColumns);
await LocalizeStaticLookupsAsync(input, fieldDtos, rows, owned, inserted); await LocalizeStaticLookupsAsync(input, fieldDtos, rows, owned, inserted);
@ -502,6 +508,7 @@ public class ListFormWizardAppService(
List<ColumnFormatEditDto> fields, List<ColumnFormatEditDto> fields,
bool isDeleted, bool isDeleted,
bool isCreated, bool isCreated,
bool isModified,
WizardSeedRowStore rows) WizardSeedRowStore rows)
{ {
var overlay = input.ScreenOverlay; var overlay = input.ScreenOverlay;
@ -509,7 +516,7 @@ public class ListFormWizardAppService(
try try
{ {
listForm = overlay.Apply(listForm, overlay.Baseline.BuildListForm(isDeleted, isCreated), errors); listForm = overlay.Apply(listForm, overlay.Baseline.BuildListForm(isDeleted, isCreated, isModified), errors);
fields = overlay.Apply(fields, overlay.Baseline.BuildFields(), errors); fields = overlay.Apply(fields, overlay.Baseline.BuildFields(), errors);
} }
catch (JsonException ex) catch (JsonException ex)
@ -520,6 +527,9 @@ public class ListFormWizardAppService(
if (errors.Count > 0) if (errors.Count > 0)
throw new UserFriendlyException($"ListForm/Fields bölümü uygulanamadı: {string.Join(" ", errors)}"); throw new UserFriendlyException($"ListForm/Fields bölümü uygulanamadı: {string.Join(" ", errors)}");
// Katmanin is akisi ham gelir (oneksiz "N1", bos onayci); wizard'in urettigi gibi normalize edilir.
listForm.WorkflowDto = ListFormWizardDto.NormalizeWorkflow(listForm.WorkflowDto, listForm.ListFormCode);
foreach (var field in fields) foreach (var field in fields)
field.CaptionName = await ResolveLanguageKeyCasingAsync(rows, field.CaptionName); field.CaptionName = await ResolveLanguageKeyCasingAsync(rows, field.CaptionName);

View file

@ -14,6 +14,7 @@ using Volo.Abp.Data;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
using Volo.Abp.PermissionManagement; using Volo.Abp.PermissionManagement;
using Volo.Abp.Uow;
namespace Sozsoft.Platform.Data.Seeds; namespace Sozsoft.Platform.Data.Seeds;
@ -46,6 +47,7 @@ public class WizardDataSeeder(
IRepository<ListFormWorkflow, string> repoListFormWorkflow, IRepository<ListFormWorkflow, string> repoListFormWorkflow,
IRepository<PermissionGrant, Guid> repoPermGrant, IRepository<PermissionGrant, Guid> repoPermGrant,
WizardInstallationChecker installationChecker, WizardInstallationChecker installationChecker,
IUnitOfWorkManager unitOfWorkManager,
IConfiguration configuration, IConfiguration configuration,
ILogger<WizardDataSeeder> logger) : IDataSeedContributor, ITransientDependency ILogger<WizardDataSeeder> logger) : IDataSeedContributor, ITransientDependency
{ {
@ -115,6 +117,10 @@ public class WizardDataSeeder(
continue; continue;
} }
// Her dosya kendi unit of work'unde kurulur: hata veren dosyanin kayitlari geri alinir
// (onceki ekran yerinde kalir) ve izlenen varliklari sonraki dosyalarin kaydina tasinmaz.
using (var uow = unitOfWorkManager.Begin(requiresNew: true, isTransactional: true))
{
if (seedFile.Pending != null) if (seedFile.Pending != null)
{ {
logger.LogInformation("[{File}] '{WizardName}' has a pending deploy, previous records are being replaced...", fileName, wizard.WizardName); logger.LogInformation("[{File}] '{WizardName}' has a pending deploy, previous records are being replaced...", fileName, wizard.WizardName);
@ -127,6 +133,8 @@ public class WizardDataSeeder(
} }
await InstallAsync(seedFile); await InstallAsync(seedFile);
await uow.CompleteAsync();
}
if (seedFile.Pending != null && SeedFileScope.CompletesPending(context)) if (seedFile.Pending != null && SeedFileScope.CompletesPending(context))
{ {
@ -173,6 +181,9 @@ public class WizardDataSeeder(
// Ekran, seed dosyasinin tasidigi ListForm sozlesmesinden kurulur; boylece wizard // Ekran, seed dosyasinin tasidigi ListForm sozlesmesinden kurulur; boylece wizard
// sonrasinda tasarimci uzerinde yapilan degisiklikler de geri gelir. // sonrasinda tasarimci uzerinde yapilan degisiklikler de geri gelir.
// Elle ya da eski bir surumle yazilmis dosyanin is akisi de kaydedilebilir hale getirilir.
seedFile.ListForm.WorkflowDto = ListFormWizardDto.NormalizeWorkflow(seedFile.ListForm.WorkflowDto, listFormCode);
var listForm = new ListForm(); var listForm = new ListForm();
seedFile.ListForm.ApplyTo(listForm); seedFile.ListForm.ApplyTo(listForm);
await repoListForm.InsertAsync(listForm, autoSave: true); await repoListForm.InsertAsync(listForm, autoSave: true);
@ -200,7 +211,7 @@ public class WizardDataSeeder(
workflows.Add(new ListFormWorkflow(criteria.Id) workflows.Add(new ListFormWorkflow(criteria.Id)
{ {
ListFormCode = string.IsNullOrWhiteSpace(criteria.ListFormCode) ? listFormCode : criteria.ListFormCode, ListFormCode = criteria.ListFormCode,
Kind = criteria.Kind, Kind = criteria.Kind,
Title = criteria.Title, Title = criteria.Title,
CompareColumn = criteria.CompareColumn, CompareColumn = criteria.CompareColumn,

View file

@ -195,6 +195,12 @@ public static class WizardConsts
}); });
} }
public static readonly string DefaultUpdateFieldsDefaultValueJson = JsonSerializer.Serialize(new[]
{
new { FieldName = "LastModificationTime", FieldDbType = DbType.DateTime, Value = "@NOW", CustomValueType = FieldCustomValueTypeEnum.CustomKey },
new { FieldName = "LastModifierId", FieldDbType = DbType.Guid, Value = "@USERID", CustomValueType = FieldCustomValueTypeEnum.CustomKey },
});
public static string DefaultDeleteFieldsDefaultValueJson(DbType dbType = DbType.Guid) public static string DefaultDeleteFieldsDefaultValueJson(DbType dbType = DbType.Guid)
{ {
return JsonSerializer.Serialize(new[] return JsonSerializer.Serialize(new[]

View file

@ -129,7 +129,9 @@ public class DefaultValueManager : PlatformDomainService, IDefaultValueManager
{ {
var dynamicDataManager = LazyServiceProvider.LazyGetRequiredService<IDynamicDataManager>(); var dynamicDataManager = LazyServiceProvider.LazyGetRequiredService<IDynamicDataManager>();
var (dynamicDataRepository, connectionString, _) = await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode); var (dynamicDataRepository, connectionString, _) = await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode);
value = await dynamicDataRepository.ExecuteScalarAsync<object>(defaultField.SqlQuery, connectionString); // Yer tutucular (@USERID, @TENANTID …) liste/lookup sorgularindaki gibi sunucu degerleriyle cozulur.
var sql = LazyServiceProvider.LazyGetRequiredService<DefaultValueHelper>().GetDefaultValue(defaultField.SqlQuery);
value = await dynamicDataRepository.ExecuteScalarAsync<object>(sql, connectionString);
} }
break; break;
case FieldCustomValueTypeEnum.Sequence: case FieldCustomValueTypeEnum.Sequence:

View file

@ -334,8 +334,9 @@ Bir çelişki varsa sıra: `ai.instructions.md` → `dotnet.instructions.md` →
çağrıyı reddeder — süzme tek başına yetki sınırı değildir, ikisi birlikte yazılır. `Invoke` çağrıyı reddeder — süzme tek başına yetki sınırı değildir, ikisi birlikte yazılır. `Invoke`
uçta değil her MCP servisinin sınıf düzeyindeki `[Authorize]`'dadır; yeni bir MCP AppService'i de uçta değil her MCP servisinin sınıf düzeyindeki `[Authorize]`'dadır; yeni bir MCP AppService'i de
bu attribute'la açılır. bu attribute'la açılır.
**Hata istemciye yalnızca `McpException` olarak ulaşır**; `McpToolErrorTranslator` (çağrı **Hata istemciye hata sonucu (`CallToolResult.IsError`) olarak ulaşır**; `McpToolErrorTranslator`
filtresi) yetki reddini "şu yetkiniz yok" mesajına, `UserFriendlyException`'ı mesajına çevirir. (çağrı filtresi) yetki reddini "şu yetkiniz yok" mesajına, `UserFriendlyException`'ı mesajına
çevirir ve istisna atmadan döner (atılan istisna SDK'da yığın izli `ERR` logudur).
Kullanıcının göreceği her hata bu iki türden biriyle atılır. Yeni aracın arkasındaki servis Kullanıcının göreceği her hata bu iki türden biriyle atılır. Yeni aracın arkasındaki servis
bir yetkiyi `[Authorize]` attribute'uyla istiyorsa (ret mesajı yetki adını taşımaz) o yetki bir yetkiyi `[Authorize]` attribute'uyla istiyorsa (ret mesajı yetki adını taşımaz) o yetki
`McpToolNames.ServicePermissions`'a eklenir; ekran yetkisi gereken araç yetkiyi `McpToolNames.ServicePermissions`'a eklenir; ekran yetkisi gereken araç yetkiyi
@ -385,7 +386,7 @@ Bir çelişki varsa sıra: `ai.instructions.md` → `dotnet.instructions.md` →
- **Talep analizi** → `Description` talebin yazıldığı hâliyle kalır; MCP ona yazmaz. Analiz ve - **Talep analizi** → `Description` talebin yazıldığı hâliyle kalır; MCP ona yazmaz. Analiz ve
üretim notları `Analysis` kolonundadır (Todo panosunda `AnalysisExpr`, Açıklama yanında sekme). üretim notları `Analysis` kolonundadır (Todo panosunda `AnalysisExpr`, Açıklama yanında sekme).
Durum sırası `Backlog → Analysis → Ready to Start → …`: "Analiz et" `save_dev_request_analysis` Durum sırası `Backlog → Analysis → Ready to Start → …`: "Analiz et" `save_dev_request_analysis`
ile yalnızca `Backlog`/`Analysis` talebini analiz eder (ekran/tablo üretmez, ile yalnızca üretimi başlamamış (`Backlog`/`Analysis`/`Ready to Start`) talebi analiz eder (ekran/tablo üretmez,
modül dokümanına yazmaz — dosya ve dal bölümü üretimde, deploy ile açılır; onaylanan analiz bölümün modül dokümanına yazmaz — dosya ve dal bölümü üretimde, deploy ile açılır; onaylanan analiz bölümün
"2. Analiz ve kararlar" alt bölümüne üretimde `save_module_doc` ile yazılır). Durumu sunucu "2. Analiz ve kararlar" alt bölümüne üretimde `save_module_doc` ile yazılır). Durumu sunucu
`productionReady` ile belirler: "Üretime hazır: Evet" → `Ready to Start`, şartlı ya da Hayır → `productionReady` ile belirler: "Üretime hazır: Evet" → `Ready to Start`, şartlı ya da Hayır →

View file

@ -16403,6 +16403,506 @@
"IsEnabled": true, "IsEnabled": true,
"MultiTenancySide": 3, "MultiTenancySide": 3,
"Modules": "Adm" "Modules": "Adm"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.RejectReason",
"ParentName": "App.Prc.Definitions",
"DisplayName": "App.Prc.RejectReason",
"Order": 5,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.RejectReason.Create",
"ParentName": "App.Prc.RejectReason",
"DisplayName": "App.Platform.Create",
"Order": 1,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.RejectReason.Update",
"ParentName": "App.Prc.RejectReason",
"DisplayName": "App.Platform.Update",
"Order": 2,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.RejectReason.Delete",
"ParentName": "App.Prc.RejectReason",
"DisplayName": "App.Platform.Delete",
"Order": 3,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.RejectReason.Export",
"ParentName": "App.Prc.RejectReason",
"DisplayName": "App.Platform.Export",
"Order": 4,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.RejectReason.Import",
"ParentName": "App.Prc.RejectReason",
"DisplayName": "App.Platform.Import",
"Order": 5,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.RejectReason.Note",
"ParentName": "App.Prc.RejectReason",
"DisplayName": "App.Platform.Note",
"Order": 6,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestLine",
"ParentName": "App.Prc.MyMaterialRequest",
"DisplayName": "App.Prc.MaterialRequestLine",
"Order": 7,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestLine.Create",
"ParentName": "App.Prc.MaterialRequestLine",
"DisplayName": "App.Platform.Create",
"Order": 1,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestLine.Update",
"ParentName": "App.Prc.MaterialRequestLine",
"DisplayName": "App.Platform.Update",
"Order": 2,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestLine.Delete",
"ParentName": "App.Prc.MaterialRequestLine",
"DisplayName": "App.Platform.Delete",
"Order": 3,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestLine.Export",
"ParentName": "App.Prc.MaterialRequestLine",
"DisplayName": "App.Platform.Export",
"Order": 4,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestLine.Import",
"ParentName": "App.Prc.MaterialRequestLine",
"DisplayName": "App.Platform.Import",
"Order": 5,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestLine.Note",
"ParentName": "App.Prc.MaterialRequestLine",
"DisplayName": "App.Platform.Note",
"Order": 6,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequests",
"ParentName": null,
"DisplayName": "App.Prc.MaterialRequests",
"Order": 3,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MyMaterialRequest",
"ParentName": "App.Prc.MaterialRequests",
"DisplayName": "App.Prc.MyMaterialRequest",
"Order": 1,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MyMaterialRequest.Create",
"ParentName": "App.Prc.MyMaterialRequest",
"DisplayName": "App.Platform.Create",
"Order": 1,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MyMaterialRequest.Update",
"ParentName": "App.Prc.MyMaterialRequest",
"DisplayName": "App.Platform.Update",
"Order": 2,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MyMaterialRequest.Delete",
"ParentName": "App.Prc.MyMaterialRequest",
"DisplayName": "App.Platform.Delete",
"Order": 3,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MyMaterialRequest.Export",
"ParentName": "App.Prc.MyMaterialRequest",
"DisplayName": "App.Platform.Export",
"Order": 4,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MyMaterialRequest.Import",
"ParentName": "App.Prc.MyMaterialRequest",
"DisplayName": "App.Platform.Import",
"Order": 5,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MyMaterialRequest.Note",
"ParentName": "App.Prc.MyMaterialRequest",
"DisplayName": "App.Platform.Note",
"Order": 6,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestDeptApproval",
"ParentName": "App.Prc.MaterialRequests",
"DisplayName": "App.Prc.MaterialRequestDeptApproval",
"Order": 2,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestDeptApproval.Create",
"ParentName": "App.Prc.MaterialRequestDeptApproval",
"DisplayName": "App.Platform.Create",
"Order": 1,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestDeptApproval.Update",
"ParentName": "App.Prc.MaterialRequestDeptApproval",
"DisplayName": "App.Platform.Update",
"Order": 2,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestDeptApproval.Delete",
"ParentName": "App.Prc.MaterialRequestDeptApproval",
"DisplayName": "App.Platform.Delete",
"Order": 3,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestDeptApproval.Export",
"ParentName": "App.Prc.MaterialRequestDeptApproval",
"DisplayName": "App.Platform.Export",
"Order": 4,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestDeptApproval.Import",
"ParentName": "App.Prc.MaterialRequestDeptApproval",
"DisplayName": "App.Platform.Import",
"Order": 5,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestDeptApproval.Note",
"ParentName": "App.Prc.MaterialRequestDeptApproval",
"DisplayName": "App.Platform.Note",
"Order": 6,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPurchaseApproval",
"ParentName": "App.Prc.MaterialRequests",
"DisplayName": "App.Prc.MaterialRequestPurchaseApproval",
"Order": 3,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPurchaseApproval.Create",
"ParentName": "App.Prc.MaterialRequestPurchaseApproval",
"DisplayName": "App.Platform.Create",
"Order": 1,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPurchaseApproval.Update",
"ParentName": "App.Prc.MaterialRequestPurchaseApproval",
"DisplayName": "App.Platform.Update",
"Order": 2,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPurchaseApproval.Delete",
"ParentName": "App.Prc.MaterialRequestPurchaseApproval",
"DisplayName": "App.Platform.Delete",
"Order": 3,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPurchaseApproval.Export",
"ParentName": "App.Prc.MaterialRequestPurchaseApproval",
"DisplayName": "App.Platform.Export",
"Order": 4,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPurchaseApproval.Import",
"ParentName": "App.Prc.MaterialRequestPurchaseApproval",
"DisplayName": "App.Platform.Import",
"Order": 5,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPurchaseApproval.Note",
"ParentName": "App.Prc.MaterialRequestPurchaseApproval",
"DisplayName": "App.Platform.Note",
"Order": 6,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPlanning",
"ParentName": "App.Prc.MaterialRequests",
"DisplayName": "App.Prc.MaterialRequestPlanning",
"Order": 4,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPlanning.Create",
"ParentName": "App.Prc.MaterialRequestPlanning",
"DisplayName": "App.Platform.Create",
"Order": 1,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPlanning.Update",
"ParentName": "App.Prc.MaterialRequestPlanning",
"DisplayName": "App.Platform.Update",
"Order": 2,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPlanning.Delete",
"ParentName": "App.Prc.MaterialRequestPlanning",
"DisplayName": "App.Platform.Delete",
"Order": 3,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPlanning.Export",
"ParentName": "App.Prc.MaterialRequestPlanning",
"DisplayName": "App.Platform.Export",
"Order": 4,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPlanning.Import",
"ParentName": "App.Prc.MaterialRequestPlanning",
"DisplayName": "App.Platform.Import",
"Order": 5,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequestPlanning.Note",
"ParentName": "App.Prc.MaterialRequestPlanning",
"DisplayName": "App.Platform.Note",
"Order": 6,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequest",
"ParentName": "App.Prc.MaterialRequests",
"DisplayName": "App.Prc.MaterialRequest",
"Order": 5,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequest.Create",
"ParentName": "App.Prc.MaterialRequest",
"DisplayName": "App.Platform.Create",
"Order": 1,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequest.Update",
"ParentName": "App.Prc.MaterialRequest",
"DisplayName": "App.Platform.Update",
"Order": 2,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequest.Delete",
"ParentName": "App.Prc.MaterialRequest",
"DisplayName": "App.Platform.Delete",
"Order": 3,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequest.Export",
"ParentName": "App.Prc.MaterialRequest",
"DisplayName": "App.Platform.Export",
"Order": 4,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequest.Import",
"ParentName": "App.Prc.MaterialRequest",
"DisplayName": "App.Platform.Import",
"Order": 5,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
},
{
"GroupName": "App.Prc",
"Name": "App.Prc.MaterialRequest.Note",
"ParentName": "App.Prc.MaterialRequest",
"DisplayName": "App.Platform.Note",
"Order": 6,
"IsEnabled": true,
"MultiTenancySide": 3,
"Modules": "Prc"
} }
] ]
} }

File diff suppressed because one or more lines are too long

View file

@ -69505,14 +69505,14 @@
"CultureName": "en", "CultureName": "en",
"ResourceName": "Platform", "ResourceName": "Platform",
"Key": "App.Mcp.Error.DevRequestNotAnalyzable", "Key": "App.Mcp.Error.DevRequestNotAnalyzable",
"Value": "Development request \"{0}\" is in \"{1}\"; only requests in \"Backlog\" or \"Analysis\" can be analyzed." "Value": "Development request \"{0}\" is in \"{1}\"; only requests in \"Backlog\", \"Analysis\" or \"Ready to Start\" can be analyzed."
}, },
{ {
"Id": "4f36d621-7053-5d99-b952-37a64b4f63dc", "Id": "4f36d621-7053-5d99-b952-37a64b4f63dc",
"CultureName": "tr", "CultureName": "tr",
"ResourceName": "Platform", "ResourceName": "Platform",
"Key": "App.Mcp.Error.DevRequestNotAnalyzable", "Key": "App.Mcp.Error.DevRequestNotAnalyzable",
"Value": "\"{0}\" geliştirme talebi \"{1}\" durumunda; yalnızca \"Backlog\" ya da \"Analysis\" durumundaki talepler analiz edilebilir." "Value": "\"{0}\" geliştirme talebi \"{1}\" durumunda; yalnızca \"Backlog\", \"Analysis\" ya da \"Ready to Start\" durumundaki talepler analiz edilebilir."
}, },
{ {
"Id": "6cac6a6b-9329-5552-86d9-08e602afcb0f", "Id": "6cac6a6b-9329-5552-86d9-08e602afcb0f",
@ -92969,14 +92969,14 @@
"CultureName": "en", "CultureName": "en",
"ResourceName": "Platform", "ResourceName": "Platform",
"Key": "App.Definitions.Approver.Desc", "Key": "App.Definitions.Approver.Desc",
"Value": "Approvers — the single list of who approves what for each department across the application.\nWhere: Administration › Definitions › Approvers.\nFields: department (shown as Branch - Department), approval area (Purchasing / Warehouse / Human Resources / Finance), approver user, active.\nUsed by: approval workflows read the approvers of the record's department and area (e.g. Purchasing › Material Requests department approval uses area Purchasing). Several approvers may be defined for the same department and area; any one of them can approve. Passive rows are ignored by workflows." "Value": "Approvers — the single list of who approves what for each department across the application.\nWhere: Administration › Definitions › Approvers.\nFields: department (shown as Branch - Department), approval area (Purchasing / Purchasing Desk / Warehouse / Human Resources / Finance), approver user, active.\nUsed by: approval workflows read the approvers of the record's department and area. Purchasing › Material Requests: the department approval uses area Purchasing for the requester's department; the purchasing approval uses area Purchasing Desk (any department). Several approvers may be defined for the same department and area; any one of them can approve. Passive rows are ignored by workflows."
}, },
{ {
"Id": "3663c5aa-4036-5381-810f-8acee720724c", "Id": "3663c5aa-4036-5381-810f-8acee720724c",
"CultureName": "tr", "CultureName": "tr",
"ResourceName": "Platform", "ResourceName": "Platform",
"Key": "App.Definitions.Approver.Desc", "Key": "App.Definitions.Approver.Desc",
"Value": "Onaycılar — uygulamadaki tüm onay adımlarında her departman için kimin onaylayacağını tutan tek liste.\nNerede: Yönetim › Tanımlamalar › Onaycılar.\nAlanlar: departman (Şube - Departman olarak gösterilir), onay yeri (Satınalma / Depo / İnsan Kaynakları / Finans), onaylayacak kişi, aktif.\nKullanıldığı yer: onay akışları kaydın departmanı ve onay yerine göre onaycıları buradan okur (ör. Satınalma › Malzeme Talepleri departman onayı Satınalma yerini kullanır). Aynı departman ve onay yerine birden çok onaycı girilebilir; herhangi birinin onayı yeterlidir. Pasif satırlar akışlarda kullanılmaz." "Value": "Onaycılar — uygulamadaki tüm onay adımlarında her departman için kimin onaylayacağını tutan tek liste.\nNerede: Yönetim › Tanımlamalar › Onaycılar.\nAlanlar: departman (Şube - Departman olarak gösterilir), onay yeri (Satınalma / Satınalma Masası / Depo / İnsan Kaynakları / Finans), onaylayacak kişi, aktif.\nKullanıldığı yer: onay akışları kaydın departmanı ve onay yerine göre onaycıları buradan okur. Satınalma › Malzeme Talepleri: departman onayı talep edenin departmanındaki Satınalma satırlarını, satınalma onayı ise Satınalma Masası satırlarını (departmandan bağımsız) kullanır. Aynı departman ve onay yerine birden çok onaycı girilebilir; herhangi birinin onayı yeterlidir. Pasif satırlar akışlarda kullanılmaz."
}, },
{ {
"Id": "cd7ff644-eefa-516e-8c8c-8b4fa0ec76f8", "Id": "cd7ff644-eefa-516e-8c8c-8b4fa0ec76f8",
@ -93061,6 +93061,888 @@
"ResourceName": "Platform", "ResourceName": "Platform",
"Key": "App.Listform.ListformField.ApproverUser", "Key": "App.Listform.ListformField.ApproverUser",
"Value": "Onaylayacak Kişi" "Value": "Onaylayacak Kişi"
},
{
"Id": "a0bd0fe5-757d-57a9-b689-e1b0e9af639e",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.StaticLookup.PurchaseDesk",
"Value": "Purchasing Desk"
},
{
"Id": "ed5a8261-8b99-5809-b1fc-5012e9064ad4",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.StaticLookup.PurchaseDesk",
"Value": "Satınalma Masası"
},
{
"Id": "05f3d2d1-2824-5ec8-afa8-2631940be01b",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.RejectReason",
"Value": "Rejection Reasons"
},
{
"Id": "32df78e7-7e15-50b5-9924-ac564130ee5b",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.RejectReason",
"Value": "Red Nedenleri"
},
{
"Id": "aba17195-ba0c-5ab9-bba7-c0e1b7319fc4",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.RejectReason.Title",
"Value": "Rejection Reasons"
},
{
"Id": "c6e0b306-c574-540e-9913-7f5ab63bb585",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.RejectReason.Title",
"Value": "Red Nedenleri"
},
{
"Id": "80196edb-82e8-5618-b2bc-96210a3177eb",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.RejectReason.Desc",
"Value": "Rejection Reasons — reasons a purchasing request can be rejected for (no need, quantity not suitable, wrong product, budget not suitable, other).\nWhere: Purchasing › Definitions › Rejection Reasons.\nFields: reason, sort order (order in the selection list), active.\nUsed by: Purchasing › Material Requests — the department approver or purchasing selects a reason when rejecting a request. Only active reasons are offered; deactivate a used reason instead of deleting it."
},
{
"Id": "07b19938-74f3-5212-b45e-ca548c821b5a",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.RejectReason.Desc",
"Value": "Red Nedenleri — satınalma taleplerinin reddedilme sebepleri (ihtiyaç yok, miktar uygun değil, yanlış ürün, bütçe uygun değil, diğer).\nNerede: Satınalma › Tanımlamalar › Red Nedenleri.\nAlanlar: red nedeni, sıra (seçim listesindeki sırası), aktif.\nKullanıldığı yer: Satınalma › Malzeme Talepleri — departman onaycısı ya da satınalma talebi reddederken neden seçer. Yalnız aktif nedenler listelenir; kullanılmış neden silinmez, pasife alınır."
},
{
"Id": "31115331-7e79-54e9-ae55-a2e682571c43",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.RejectReason",
"Value": "Rejection Reason"
},
{
"Id": "8706eb33-870d-576d-91bd-5cf80829efd3",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.RejectReason",
"Value": "Red Nedeni"
},
{
"Id": "76bcc304-a6bb-5060-982d-fa32865fd8b8",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestLine",
"Value": "Request Lines"
},
{
"Id": "0000da27-00b8-5d60-ad89-fb6a5a5896af",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestLine",
"Value": "Talep Satırları"
},
{
"Id": "9f310b90-7983-56ac-959d-7b23c601e932",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestLine.Title",
"Value": "Request Lines"
},
{
"Id": "1b46c95c-18f4-503f-87b8-d3ca7c8f1928",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestLine.Title",
"Value": "Talep Satırları"
},
{
"Id": "0a0666e7-1ea9-5030-bd76-ce78c8bd6bb8",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestLine.Desc",
"Value": "Request Lines — the products requested in a material request.\nWhere: Purchasing › Material Requests › any list › Request Lines tab (no menu of its own).\nFields: product (active, purchasable products), quantity, unit (copied from the product's purchase unit, read-only), fulfilment (Purchasing / Warehouse Transfer), due date, request reason, delivered quantity (read-only), planned quantity (defaults to quantity), purchasing responsible, line status (Waiting / Planned / Done / Cancelled).\nRules: lines can be added or deleted only while the request has not been sent for approval. Changing line statuses recalculates the request status (In Progress / Partially Done / Done)."
},
{
"Id": "cd985741-f49b-5a73-80a5-10f6ea403c1e",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestLine.Desc",
"Value": "Talep Satırları — malzeme talebinde istenen ürünler.\nNerede: Satınalma › Malzeme Talepleri › herhangi bir liste › Talep Satırları sekmesi (kendi menüsü yoktur).\nAlanlar: ürün (aktif ve satın alınabilir ürünler), miktar, birim (ürünün satınalma biriminden gelir, salt okunur), karşılama şekli (Satınalma / Depodan Transfer), termin tarihi, talep nedeni, teslim edilen miktar (salt okunur), planlanacak miktar (boşsa miktar), satınalma sorumlusu, satır durumu (Bekliyor / Planlandı / Tamamlandı / İptal).\nKurallar: satır yalnız talep onaya gönderilmeden eklenip silinebilir. Satır durumları değişince talebin durumu yeniden hesaplanır (İşlemde / Kısmi Tamamlandı / Tamamlandı)."
},
{
"Id": "d6911bd6-3f4a-582d-8328-e01403808802",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.StaticLookup.WarehouseTransfer",
"Value": "Warehouse Transfer"
},
{
"Id": "edbab48a-17e3-57b3-b80d-b2055550c4c8",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.StaticLookup.WarehouseTransfer",
"Value": "Depodan Transfer"
},
{
"Id": "df777320-d7c8-5c5d-8954-65a3d2ac46b4",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.LineStatus.Waiting",
"Value": "Waiting"
},
{
"Id": "8085df17-dc10-5e97-b1f6-7663710144a2",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.LineStatus.Waiting",
"Value": "Bekliyor"
},
{
"Id": "dbb37c7a-6cc4-5357-9c5f-f5d519f216bb",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.LineStatus.Planned",
"Value": "Planned"
},
{
"Id": "d6f9b304-674f-53d7-82d6-b8df5c44e4de",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.LineStatus.Planned",
"Value": "Planlandı"
},
{
"Id": "d09ac050-b969-5106-9199-e1e08c021126",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.LineStatus.Done",
"Value": "Done"
},
{
"Id": "00dee90f-282c-5643-9f5a-e283e6c2702e",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.LineStatus.Done",
"Value": "Tamamlandı"
},
{
"Id": "af2fccb3-47a1-5565-8b36-4d2e59f766b3",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.LineStatus.Cancelled",
"Value": "Cancelled"
},
{
"Id": "711c8685-b79a-59dd-a54d-8f50875b21ee",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.LineStatus.Cancelled",
"Value": "İptal"
},
{
"Id": "7b6ad8c3-f204-5710-b477-840acf068000",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.MaterialRequestId",
"Value": "Material Request"
},
{
"Id": "6cc3cbf1-d9ba-5bd1-bf19-23acf6eeb637",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.MaterialRequestId",
"Value": "Malzeme Talebi"
},
{
"Id": "81ab2aca-ff95-55bf-9c20-aab648a997ff",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.FulfillmentMethod",
"Value": "Fulfilment"
},
{
"Id": "a751bbc2-6d6e-5374-9b2d-e919fcc6d908",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.FulfillmentMethod",
"Value": "Karşılama Şekli"
},
{
"Id": "54f9886c-7e06-59e9-a3cf-45ad39dd70d1",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.RequestReason",
"Value": "Request Reason"
},
{
"Id": "c8a0e858-6e0b-5191-888c-1fd8f7a7f874",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.RequestReason",
"Value": "Talep Nedeni"
},
{
"Id": "ac55e99e-e5ab-54fa-a59b-aa28ce55db35",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.DeliveredQuantity",
"Value": "Delivered"
},
{
"Id": "20d9544e-d614-552a-9ce8-afd6abbe4dab",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.DeliveredQuantity",
"Value": "Teslim"
},
{
"Id": "8f7f947a-46b2-5c0e-ae78-ba3224f77560",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.PurchaseResponsibleUserId",
"Value": "Purchasing Responsible"
},
{
"Id": "e34f6e86-982f-5148-a48b-78bff7a68ae3",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.PurchaseResponsibleUserId",
"Value": "Satınalma Sorumlusu"
},
{
"Id": "31d24887-d9a3-5139-bca1-ed3d1113bb2e",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.LineStatus",
"Value": "Line Status"
},
{
"Id": "01b3a68a-6015-52a3-81c4-95eceb001264",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.LineStatus",
"Value": "Satır Durumu"
},
{
"Id": "26de53c5-0ec4-5917-ab7d-876131c099c7",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MyMaterialRequest",
"Value": "My Requests"
},
{
"Id": "28140c33-2afd-5cda-bb34-cf7ff8133079",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MyMaterialRequest",
"Value": "Taleplerim"
},
{
"Id": "1d69bdad-cb10-505d-b6c3-ce95d05ee56e",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MyMaterialRequest.Title",
"Value": "My Material Requests"
},
{
"Id": "fa742a93-888a-5ea9-9717-9f8b78f6b7e7",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MyMaterialRequest.Title",
"Value": "Taleplerim"
},
{
"Id": "704fff03-2957-5ee2-a9ee-6ac41cb16672",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MyMaterialRequest.Desc",
"Value": "My Requests — the material requests you opened, in every status.\nWhere: Purchasing › Material Requests › My Requests.\nFields: request no (MT-YYYY-00001, automatic), priority, requester (you), department (your department by default), warehouse and location where the goods will be put, request date, status, general description; Request Lines tab: product, quantity, unit, fulfilment, due date, request reason.\nFlow: add lines, then send for approval — the department approver (Approvers › area Purchasing for your department) and then purchasing (area Purchasing Desk) approve or reject. Lines can only be added or removed before sending. Approval / rejection details are shown in the approval group.\nRelated: Awaiting Department Approval, Awaiting Purchasing Approval, Awaiting Planning, All Requests."
},
{
"Id": "cdcb1b32-ecb7-5fd1-af5b-fdfd2614d779",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MyMaterialRequest.Desc",
"Value": "Taleplerim — açtığınız malzeme talepleri, tüm durumlarıyla.\nNerede: Satınalma › Malzeme Talepleri › Taleplerim.\nAlanlar: talep no (MT-YYYY-00001, otomatik), öncelik, talep eden (siz), departman (varsayılan olarak sizin departmanınız), malın konulacağı depo ve konum, talep tarihi, durum, genel açıklama; Talep Satırları sekmesi: ürün, miktar, birim, karşılama şekli, termin tarihi, talep nedeni.\nAkış: satırları girip onaya gönderin — önce departman onaycısı (Onaycılar › departmanınız için Satınalma onay yeri), ardından satınalma (Satınalma Masası onay yeri) onaylar ya da reddeder. Satırlar yalnız onaya göndermeden önce eklenip silinebilir. Onay / red bilgileri onay grubunda görünür.\nİlişkili: Departman Onayı Bekleyenler, Satınalma Onayı Bekleyenler, Planlama Bekleyenler, Tüm Talepler."
},
{
"Id": "ce3d734c-f508-5647-8f8d-2bf6b056c79a",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Group.Request",
"Value": "Material Request"
},
{
"Id": "81c20a7d-9ff4-54de-bcfb-b8d9b15ef3a5",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Group.Request",
"Value": "Malzeme Talebi"
},
{
"Id": "c9f7e34c-6282-548b-bdff-3be6d4478d71",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Group.Approval",
"Value": "Approval / Rejection"
},
{
"Id": "fcec5d8b-d157-5f55-a321-a71e1230ffcd",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Group.Approval",
"Value": "Onay / Red Bilgileri"
},
{
"Id": "048c326c-7709-52a2-919f-928eb4f02fc2",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.Draft",
"Value": "Draft"
},
{
"Id": "e490d63f-4209-516f-9bf7-ded12e62c7e1",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.Draft",
"Value": "Taslak"
},
{
"Id": "3708a984-4c9b-536b-b4f8-3928bad0c787",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.DeptApproval",
"Value": "Department Approval"
},
{
"Id": "f306d454-8502-53cc-bec3-264ebced8ef9",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.DeptApproval",
"Value": "Departman Onayı"
},
{
"Id": "5290089b-4ae3-57b2-9cbe-6aa2b196e9c5",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.PurchaseApproval",
"Value": "Purchasing Approval"
},
{
"Id": "e0d6b371-9103-5793-9a55-ed14c1853486",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.PurchaseApproval",
"Value": "Satınalma Onayı"
},
{
"Id": "ddfa1050-d441-5e8b-af2e-e1fc80c90821",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.Approved",
"Value": "Approved"
},
{
"Id": "a1f5eff0-aaca-5220-897d-3bdfa6a799e4",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.Approved",
"Value": "Onaylandı"
},
{
"Id": "fc01609d-1b30-57e7-a8aa-a2ba025f8793",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.InProgress",
"Value": "In Progress"
},
{
"Id": "72fa09da-1c88-59b0-a11e-7d9ed3599ea4",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.InProgress",
"Value": "İşlemde"
},
{
"Id": "c1b67758-5e95-5dfd-81b7-4d601ee1a492",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.PartiallyDone",
"Value": "Partially Done"
},
{
"Id": "9dae2baf-ae05-5877-9194-e2ebacb20945",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.PartiallyDone",
"Value": "Kısmi Tamamlandı"
},
{
"Id": "0ae3f045-c580-5a1c-8ffb-2f34940230a0",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.Done",
"Value": "Done"
},
{
"Id": "ccda2c9c-6397-52dc-a159-5b3fd83f8820",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.Done",
"Value": "Tamamlandı"
},
{
"Id": "b29fee10-a751-5dec-9eb5-8ac8837d5ef8",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.Rejected",
"Value": "Rejected"
},
{
"Id": "d4e2e10a-3aec-5117-b22f-335a8229402c",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Status.Rejected",
"Value": "Reddedildi"
},
{
"Id": "74718b81-46f9-5106-a6d9-16c7a094bf66",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Widget.Mine",
"Value": "My Requests"
},
{
"Id": "f4646c43-bfc5-53a2-b033-ddbd7f3439cd",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Widget.Mine",
"Value": "Taleplerim"
},
{
"Id": "3b12d816-8b02-5a7d-b0d4-73ff09fc62a1",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Widget.Pending",
"Value": "Awaiting Approval"
},
{
"Id": "72b44c8e-4d18-5169-9e8c-18f9c667a687",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Widget.Pending",
"Value": "Onay Bekleyen"
},
{
"Id": "7ff98615-551b-5cc2-a570-5938e1fe832e",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Widget.Approved",
"Value": "Approved"
},
{
"Id": "e91e02a3-91e5-5956-a533-566da3b5d1ee",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Widget.Approved",
"Value": "Onaylanan"
},
{
"Id": "cf23c629-2c24-5d9e-8c9c-6ac36e770b37",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Widget.Rejected",
"Value": "Rejected"
},
{
"Id": "6294b7ea-665f-5a0a-8225-1f9abbe4b321",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Widget.Rejected",
"Value": "Reddedilen"
},
{
"Id": "c098056f-f2b6-5cac-a112-b507dbdf3cc5",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequests",
"Value": "Material Requests"
},
{
"Id": "fa18f835-7a61-5d24-bac1-aaebbe596fea",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequests",
"Value": "Malzeme Talepleri"
},
{
"Id": "cf76b42b-82ed-5838-9fb2-30b0c8caf3e5",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.RequesterUserId",
"Value": "Requester"
},
{
"Id": "76676b8f-bcf1-5b38-a517-4a4a774f3b5d",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.RequesterUserId",
"Value": "Talep Eden"
},
{
"Id": "dafc6b73-5969-52ae-900c-3f46bafcc34e",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.LocationId",
"Value": "Location"
},
{
"Id": "de1684aa-ebce-5b65-8cc2-f8cee4940787",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.LocationId",
"Value": "Konum"
},
{
"Id": "caada0e9-b75d-52f2-b07e-c25384a2532e",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.RejectReasonId",
"Value": "Rejection Reason"
},
{
"Id": "787d4dd5-867b-52a0-8689-f55801750fe0",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.RejectReasonId",
"Value": "Red Nedeni"
},
{
"Id": "354564b7-be8f-5e32-9add-9fbda8f912f2",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.GeneralDescription",
"Value": "General Description"
},
{
"Id": "f486af31-9f19-5622-aaf0-22d93aa67457",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.GeneralDescription",
"Value": "Genel Açıklama"
},
{
"Id": "34475eec-bb9e-5403-a092-f5d441edc558",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.PurchaseApproverUserNames",
"Value": "Purchasing Approvers"
},
{
"Id": "989e089f-4938-5f20-859f-7bd80b39db7d",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.PurchaseApproverUserNames",
"Value": "Satınalma Onaycıları"
},
{
"Id": "6f297c45-bc1e-5235-a511-f96c07ef970c",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.ApproverId",
"Value": "Approver Id"
},
{
"Id": "5d442093-8ce2-5d44-9ea1-4306060a8fd4",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.ApproverId",
"Value": "Onaylayan Kimlik"
},
{
"Id": "8647efbf-f775-5e53-a00e-f1ce508c609f",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.ApprovalNote",
"Value": "Approval Note"
},
{
"Id": "9d232928-5938-5b1d-b3c3-d752e1cd2077",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.ApprovalNote",
"Value": "Onay Notu"
},
{
"Id": "3cb0bb36-408f-50e8-b260-850cbdd25e7a",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.DeptApproverUserNames",
"Value": "Department Approvers"
},
{
"Id": "49151317-6795-55d2-8387-b528047c441c",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.DeptApproverUserNames",
"Value": "Departman Onaycıları"
},
{
"Id": "8e05f767-5e90-5aed-8e15-f544883da7b4",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.PurchaseApprovedBy",
"Value": "Purchasing Approved By"
},
{
"Id": "5294b27e-2e61-5c0c-8b69-406425b5f592",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.PurchaseApprovedBy",
"Value": "Satınalma Onaylayan"
},
{
"Id": "7697f43d-e5da-5666-b919-ae0eb6b7a6a0",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.DeptApprovedBy",
"Value": "Department Approved By"
},
{
"Id": "f56eb927-0d12-5192-bf36-edb5847aae45",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.DeptApprovedBy",
"Value": "Departman Onaylayan"
},
{
"Id": "b71494eb-3a96-5f3d-bf22-87421cad6f5c",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.PurchaseApprovalDate",
"Value": "Purchasing Approval Date"
},
{
"Id": "d4e99bb0-b797-5dd1-a4f8-18163b533b5b",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.PurchaseApprovalDate",
"Value": "Satınalma Onay Tarihi"
},
{
"Id": "423c12ac-9935-54f0-8973-9e508cc0961a",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.DeptApprovalDate",
"Value": "Department Approval Date"
},
{
"Id": "c86753a5-1b33-5b79-8fe4-55a8dfd87e88",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.DeptApprovalDate",
"Value": "Departman Onay Tarihi"
},
{
"Id": "46d7172f-46ca-5b5c-af1b-01b30e4e78e9",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.PurchaseApprovalNote",
"Value": "Purchasing Approval Note"
},
{
"Id": "1615218a-57a7-5398-b0d3-1f9eef0039db",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.PurchaseApprovalNote",
"Value": "Satınalma Onay Notu"
},
{
"Id": "08ed225a-1c13-5c79-970e-7ec77930277a",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.DeptApprovalNote",
"Value": "Department Approval Note"
},
{
"Id": "238cae24-91e7-5c8e-82a7-ba6807076cdd",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Listform.ListformField.DeptApprovalNote",
"Value": "Departman Onay Notu"
},
{
"Id": "6992315a-5810-5cf8-9061-6c9f8b61d750",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestDeptApproval",
"Value": "Awaiting Department Approval"
},
{
"Id": "34bbd97a-e1e1-55d4-b06b-adec3ce909d1",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestDeptApproval",
"Value": "Departman Onayı Bekleyenler"
},
{
"Id": "25672416-32c5-5de8-b212-dac0ff393459",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestDeptApproval.Title",
"Value": "Awaiting Department Approval"
},
{
"Id": "27f5097d-8d38-58e2-8c04-efa37e096f0d",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestDeptApproval.Title",
"Value": "Departman Onayı Bekleyenler"
},
{
"Id": "657f6bf8-8a4c-5eae-a3cb-c5b723127108",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestDeptApproval.Desc",
"Value": "Awaiting Department Approval — material requests waiting for the department approver's decision.\nWhere: Purchasing › Material Requests › Awaiting Department Approval.\nWho: approvers defined in Administration › Definitions › Approvers with area Purchasing for the requester's department; each approver sees only the requests assigned to them.\nWhat to do: open the request, review the Request Lines tab, then Approve (the request moves to purchasing approval) or Reject with a note and a rejection reason (Purchasing › Definitions › Rejection Reasons). Lines cannot be added or removed here.\nRelated: My Requests, Awaiting Purchasing Approval, All Requests."
},
{
"Id": "3467add9-46c6-59ea-b3ea-19d8524bb6bb",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestDeptApproval.Desc",
"Value": "Departman Onayı Bekleyenler — departman onaycısının kararını bekleyen malzeme talepleri.\nNerede: Satınalma › Malzeme Talepleri › Departman Onayı Bekleyenler.\nKim: Yönetim › Tanımlamalar › Onaycılar'da talep edenin departmanı için Satınalma onay yerinde tanımlı onaycılar; her onaycı yalnız kendisine düşen talepleri görür.\nNe yapılır: talebi açıp Talep Satırları sekmesini inceleyin, ardından Onayla (talep satınalma onayına geçer) ya da not ve red nedeniyle (Satınalma › Tanımlamalar › Red Nedenleri) Reddet. Burada satır eklenip silinemez.\nİlişkili: Taleplerim, Satınalma Onayı Bekleyenler, Tüm Talepler."
},
{
"Id": "1c9a636f-fdfa-50bf-b3a4-874deed5dad1",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPurchaseApproval",
"Value": "Awaiting Purchasing Approval"
},
{
"Id": "c02cb476-5498-5784-b85f-64ff5ba17fe2",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPurchaseApproval",
"Value": "Satınalma Onayı Bekleyenler"
},
{
"Id": "7fd95c2b-4835-5161-a491-8a9a4953484d",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPurchaseApproval.Title",
"Value": "Awaiting Purchasing Approval"
},
{
"Id": "356321c8-b95e-5fbb-bc43-fc1620cdc306",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPurchaseApproval.Title",
"Value": "Satınalma Onayı Bekleyenler"
},
{
"Id": "967954de-1c69-555f-9c42-757484cdde25",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPurchaseApproval.Desc",
"Value": "Awaiting Purchasing Approval — material requests approved by the department and waiting for purchasing.\nWhere: Purchasing › Material Requests › Awaiting Purchasing Approval.\nWho: approvers defined in Administration › Definitions › Approvers with area Purchasing Desk (any department); each approver sees only the requests assigned to them.\nWhat to do: review the request and its lines, then Approve (the request becomes Approved and appears in Awaiting Planning, the requester is notified) or Reject with a note and a rejection reason.\nRelated: Awaiting Department Approval, Awaiting Planning, All Requests."
},
{
"Id": "bbcdb2c8-96fc-5ae3-b948-1d68b8a334c5",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPurchaseApproval.Desc",
"Value": "Satınalma Onayı Bekleyenler — departmanca onaylanmış ve satınalmanın kararını bekleyen malzeme talepleri.\nNerede: Satınalma › Malzeme Talepleri › Satınalma Onayı Bekleyenler.\nKim: Yönetim › Tanımlamalar › Onaycılar'da Satınalma Masası onay yerinde tanımlı onaycılar (departmandan bağımsız); her onaycı yalnız kendisine düşen talepleri görür.\nNe yapılır: talebi ve satırlarını inceleyip Onayla (talep Onaylandı olur, Planlama Bekleyenler'e düşer, talep edene bilgi gider) ya da not ve red nedeniyle Reddet.\nİlişkili: Departman Onayı Bekleyenler, Planlama Bekleyenler, Tüm Talepler."
},
{
"Id": "9e5e455f-ecc8-5066-8fb4-63884166647d",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanning",
"Value": "Awaiting Planning"
},
{
"Id": "14c03915-e459-560b-b860-60547e1601a7",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanning",
"Value": "Planlama Bekleyenler"
},
{
"Id": "95fbb1fd-77cb-58f7-a493-e8b65c7c2d7a",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanning.Title",
"Value": "Awaiting Planning"
},
{
"Id": "46910333-c5f6-59a3-a23f-c1492f1601d4",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanning.Title",
"Value": "Planlama Bekleyenler"
},
{
"Id": "2891afab-5548-5940-9e42-2bbba6f98611",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanning.Desc",
"Value": "Awaiting Planning — approved material requests whose lines are not all completed yet; the purchasing team's work list.\nWhere: Purchasing › Material Requests › Awaiting Planning.\nWhat to do: open the request and, on the Request Lines tab, set the purchasing responsible, the quantity to plan and the line status (Waiting / Planned / Done / Cancelled). The request status follows the lines: any line Planned → In Progress, some lines Done → Partially Done, all lines Done or Cancelled → Done (the request then leaves this list). This list is the starting point of the quotation process.\nRelated: Awaiting Purchasing Approval, All Requests."
},
{
"Id": "93219adb-c4b3-5455-a59b-4d08b8a39e6b",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequestPlanning.Desc",
"Value": "Planlama Bekleyenler — onaylanmış ve satırları henüz tamamlanmamış malzeme talepleri; satınalma ekibinin iş listesi.\nNerede: Satınalma › Malzeme Talepleri › Planlama Bekleyenler.\nNe yapılır: talebi açıp Talep Satırları sekmesinde satınalma sorumlusunu, planlanacak miktarı ve satır durumunu (Bekliyor / Planlandı / Tamamlandı / İptal) girin. Talebin durumu satırları izler: bir satır Planlandı → İşlemde, satırların bir kısmı Tamamlandı → Kısmi Tamamlandı, tüm satırlar Tamamlandı ya da İptal → Tamamlandı (talep bu listeden çıkar). Teklif toplama sürecinin giriş noktasıdır.\nİlişkili: Satınalma Onayı Bekleyenler, Tüm Talepler."
},
{
"Id": "04e8c193-a841-520d-b338-0d4a73ca066b",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest",
"Value": "All Requests"
},
{
"Id": "56791585-d328-586e-b1b4-e51cf0b5648f",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest",
"Value": "Tüm Talepler"
},
{
"Id": "2680879d-1e84-5624-a4cc-88cfe3bd8d7d",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Title",
"Value": "All Material Requests"
},
{
"Id": "7a5da2a3-effa-5701-9a6b-ae602ad32cb6",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Title",
"Value": "Tüm Talepler"
},
{
"Id": "71e1acbb-33a9-5585-928f-2fa5287264de",
"CultureName": "en",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Desc",
"Value": "All Requests — every material request of the company in every status; used by purchasing management.\nWhere: Purchasing › Material Requests › All Requests.\nFields: request no (MT-YYYY-00001, automatic), priority, requester, department, warehouse and location, request date, status (Draft › Department Approval › Purchasing Approval › Approved › In Progress › Partially Done › Done, or Rejected), approval status, rejection reason, general description; approval group: department approvers, department / purchasing approver, date and note; Request Lines tab.\nFlow: Grid Workflow — department approver (Approvers › area Purchasing of the request's department) → purchasing (area Purchasing Desk) → Approved / Rejected; the requester is notified. Status after approval follows the line statuses.\nRelated: My Requests, Awaiting Department Approval, Awaiting Purchasing Approval, Awaiting Planning, Purchasing › Definitions › Rejection Reasons."
},
{
"Id": "b9ef44e8-a325-544f-b552-bda2fb6ca9c1",
"CultureName": "tr",
"ResourceName": "Platform",
"Key": "App.Prc.MaterialRequest.Desc",
"Value": "Tüm Talepler — kurumun bütün malzeme talepleri, tüm durumlarıyla; satınalma yönetiminin listesi.\nNerede: Satınalma › Malzeme Talepleri › Tüm Talepler.\nAlanlar: talep no (MT-YYYY-00001, otomatik), öncelik, talep eden, departman, depo ve konum, talep tarihi, durum (Taslak › Departman Onayı › Satınalma Onayı › Onaylandı › İşlemde › Kısmi Tamamlandı › Tamamlandı ya da Reddedildi), onay durumu, red nedeni, genel açıklama; onay grubu: departman onaycıları, departman / satınalma onaylayanı, tarihi ve notu; Talep Satırları sekmesi.\nAkış: Grid Workflow — departman onaycısı (Onaycılar › talebin departmanı için Satınalma onay yeri) → satınalma (Satınalma Masası onay yeri) → Onaylandı / Reddedildi; talep edene bilgi gider. Onay sonrası durum satır durumlarını izler.\nİlişkili: Taleplerim, Departman Onayı Bekleyenler, Satınalma Onayı Bekleyenler, Planlama Bekleyenler, Satınalma › Tanımlamalar › Red Nedenleri."
} }
] ]
} }

View file

@ -2807,6 +2807,83 @@
"RequiredPermissionName": "App.Definitions.Approver", "RequiredPermissionName": "App.Definitions.Approver",
"IsDisabled": false, "IsDisabled": false,
"ModuleId": "Adm" "ModuleId": "Adm"
},
{
"ParentCode": "App.Prc.Definitions",
"Code": "App.Prc.RejectReason",
"DisplayName": "App.Prc.RejectReason",
"Order": 5,
"Url": "/admin/list/App.Prc.RejectReason",
"Icon": "FcCancel",
"RequiredPermissionName": "App.Prc.RejectReason",
"IsDisabled": false,
"ModuleId": "Prc"
},
{
"ParentCode": "App.Prc",
"Code": "App.Prc.MaterialRequests",
"DisplayName": "App.Prc.MaterialRequests",
"Order": 2,
"Url": null,
"Icon": "FcList",
"RequiredPermissionName": null,
"IsDisabled": false,
"ModuleId": "Prc"
},
{
"ParentCode": "App.Prc.MaterialRequests",
"Code": "App.Prc.MyMaterialRequest",
"DisplayName": "App.Prc.MyMaterialRequest",
"Order": 1,
"Url": "/admin/list/App.Prc.MyMaterialRequest",
"Icon": "FcPortraitMode",
"RequiredPermissionName": "App.Prc.MyMaterialRequest",
"IsDisabled": false,
"ModuleId": "Prc"
},
{
"ParentCode": "App.Prc.MaterialRequests",
"Code": "App.Prc.MaterialRequestDeptApproval",
"DisplayName": "App.Prc.MaterialRequestDeptApproval",
"Order": 2,
"Url": "/admin/list/App.Prc.MaterialRequestDeptApproval",
"Icon": "FcApproval",
"RequiredPermissionName": "App.Prc.MaterialRequestDeptApproval",
"IsDisabled": false,
"ModuleId": "Prc"
},
{
"ParentCode": "App.Prc.MaterialRequests",
"Code": "App.Prc.MaterialRequestPurchaseApproval",
"DisplayName": "App.Prc.MaterialRequestPurchaseApproval",
"Order": 3,
"Url": "/admin/list/App.Prc.MaterialRequestPurchaseApproval",
"Icon": "FcApproval",
"RequiredPermissionName": "App.Prc.MaterialRequestPurchaseApproval",
"IsDisabled": false,
"ModuleId": "Prc"
},
{
"ParentCode": "App.Prc.MaterialRequests",
"Code": "App.Prc.MaterialRequestPlanning",
"DisplayName": "App.Prc.MaterialRequestPlanning",
"Order": 4,
"Url": "/admin/list/App.Prc.MaterialRequestPlanning",
"Icon": "FcPlanner",
"RequiredPermissionName": "App.Prc.MaterialRequestPlanning",
"IsDisabled": false,
"ModuleId": "Prc"
},
{
"ParentCode": "App.Prc.MaterialRequests",
"Code": "App.Prc.MaterialRequest",
"DisplayName": "App.Prc.MaterialRequest",
"Order": 5,
"Url": "/admin/list/App.Prc.MaterialRequest",
"Icon": "FcDocument",
"RequiredPermissionName": "App.Prc.MaterialRequest",
"IsDisabled": false,
"ModuleId": "Prc"
} }
] ]
} }

View file

@ -0,0 +1,38 @@
{
"ListFormCode": "App.Prc.RejectReason",
"KeyFieldName": "Id",
"GeneratedAt": "2026-10-09T14:16:42.3444667Z",
"Order": 0,
"Rows": [
{
"Name": "İhtiyaç yok",
"SortOrder": 1,
"IsActive": true,
"Id": "d6822a96-42f7-24d4-a7c3-3a243332d267"
},
{
"Name": "Miktar uygun değil",
"SortOrder": 2,
"IsActive": true,
"Id": "cc36350b-8217-9db6-8c30-3a243332d267"
},
{
"Name": "Yanlış ürün seçildi",
"SortOrder": 3,
"IsActive": true,
"Id": "7d60f700-18b1-1caf-2a2c-3a243332d267"
},
{
"Name": "Bütçe uygun değil",
"SortOrder": 4,
"IsActive": true,
"Id": "43d3032e-5f1e-fb27-81bd-3a243332d267"
},
{
"Name": "Diğer",
"SortOrder": 5,
"IsActive": true,
"Id": "689d3573-5b86-ad86-1097-3a243332d267"
}
]
}

View file

@ -178,7 +178,7 @@ Dış entegrasyon yok. Ülke/Şehir/İlçe, Para Birimi, Dil, Sektör, Kullanıc
| Menü | `App.Administration.Definitions` › `App.Definitions.Approver` (sıra 6) | | Menü | `App.Administration.Definitions` › `App.Definitions.Approver` (sıra 6) |
| Yetki | `App.Definitions.Approver` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` | | Yetki | `App.Definitions.Approver` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Onaycılar — uygulamadaki tüm onay adımlarında her departman için kimin onaylayacağını tutan tek liste. | | Açıklama | Onaycılar — uygulamadaki tüm onay adımlarında her departman için kimin onaylayacağını tutan tek liste. |
| Geliştirme talebi | Satınalma Onaycıları | | Geliştirme talebi | Satınalma -> Malzeme Talepleri |
| Kaynak | `Adm_T_Approver` · filtre `"IsDeleted" = 'false'` | | Kaynak | `Adm_T_Approver` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) | | Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup | | Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
@ -189,7 +189,7 @@ Dış entegrasyon yok. Ülke/Şehir/İlçe, Para Birimi, Dil, Sektör, Kullanıc
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak | | Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| `DepartmentId` | Departman | dxSelectBox | ✓ | ✓ | sorgu: Hr_T_Department | | `DepartmentId` | Departman | dxSelectBox | ✓ | ✓ | sorgu: Hr_T_Department |
| `ApprovalArea` | Onay Yeri | dxSelectBox | ✓ | ✓ | liste: Purchase, Warehouse, HumanResources, Finance | | `ApprovalArea` | Onay Yeri | dxSelectBox | ✓ | ✓ | liste: Purchase, PurchaseDesk, Warehouse, HumanResources, Finance |
| `ApproverUserId` | Onaylayacak Kişi | dxSelectBox | ✓ | ✓ | sorgu: AbpUsers | | `ApproverUserId` | Onaylayacak Kişi | dxSelectBox | ✓ | ✓ | sorgu: AbpUsers |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | | | `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |

View file

@ -66,6 +66,87 @@ Yok. Tanımlar Yönetim › Tanımlamalar › Kontaklar'ın Satış ve Satınalm
- Demo veri: `data/App.Prc.{PaymentTerm,PaymentMethod,Incoterm,DeliveryMethod}.json`. - Demo veri: `data/App.Prc.{PaymentTerm,PaymentMethod,Incoterm,DeliveryMethod}.json`.
- Geri alma: Kontak sekmeleri bu tanımlara bağlı olduğu için önce kontak tarafındaki seçimler temizlenir; ekranlar `delete_wizard` ile silinir, tablolar yalnızca açık onayla `dropTables: true` ile düşürülür. - Geri alma: Kontak sekmeleri bu tanımlara bağlı olduğu için önce kontak tarafındaki seçimler temizlenir; ekranlar `delete_wizard` ile silinir, tablolar yalnızca açık onayla `dropTables: true` ile düşürülür.
<!-- module-doc:section App.Prc.MaterialRequests -->
## Malzeme Talepleri (`App.Prc.MaterialRequests`)
### 1. Amaç ve kapsam
Departmanların iç ve dış ihtiyaç duydukları malzemeleri satınalmaya iletmesi. Talep eden personel talebi ve satırlarını girer, onaya gönderir; talep önce talep edenin departman onaycısına, sonra satınalmaya (Satınalma Masası) düşer. Onaylanan talep Planlama Bekleyenler listesine geçer ve satınalma ekibi satırları planlar; teklif toplama süreci bu listeden başlar. Teklif, sipariş, transfer ve stok miktarı bu dalın kapsamında değildir.
### 2. Analiz ve kararlar
- Wizard List ekranları + menüsüz satır alt formu + Grid Workflow. Beş liste aynı tabloyu (`Prc_T_MaterialRequest`) filtreyle gösterir.
- 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'a eklenen yeni Onay Yeri **Satınalma Masası** (`PurchaseDesk`) satırları, departmandan bağımsız. 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.
- Görseldeki "Kendi Depomda" ve "Tüm Depolar" stok kolonları üretilmedi: uygulamada stok miktarı/hareket tablosu yok; stok modülü gelince ayrı talep.
- Karşılama Şekli: Satınalma / Depodan Transfer.
- Onay akışının "onaylayan" alanı platformda kullanıcı adı (metin) yazdığı için akışa bağlanmadı (`ApprovalUserFieldName` boş); departman/satınalma onaylayanı kayıt sonrası prosedürde kaydı son güncelleyen kullanıcıdan yazılır. `ApproverId` kolonu kullanılmaz.
- 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 (UomId uniqueidentifier) kullanılmıyor.
- Talep durumu satırlardan türetilir; ayrı İşlemde / Tamamlandı butonu yerine satır durumu (Bekliyor / Planlandı / Tamamlandı / İptal) kullanılır.
### 3. Menü ve ekranlar
Satınalma (`App.Prc`) › Malzeme Talepleri (`App.Prc.MaterialRequests`):
| Ekran | Kod | Filtre / not |
| --- | --- | --- |
| Taleplerim | `App.Prc.MyMaterialRequest` | talep eden = oturumdaki kullanıcı; ekle/sil açık, akış |
| 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 Bekleyenler | `App.Prc.MaterialRequestPlanning` | ApprovalStatus = Onaylandı ve Status ≠ Done; akış yok |
| Tüm Talepler | `App.Prc.MaterialRequest` | filtresiz; ekle/sil açık, akış |
Talep Satırları (`App.Prc.MaterialRequestLine`) menüsüz alt formdur; beş listenin hepsinde sekmedir. Red Nedenleri (`App.Prc.RejectReason`) Satınalma › Tanımlamalar altındadır (bkz. Tanımlamalar).
### 4. Veri modeli
Tüm tablolar kiracı + tam audit + soft delete taşır.
- `Prc_T_MaterialRequest`: RequestNo, Priority (0–3), RequesterUserId, DepartmentId, WarehouseId, LocationId, RequestDate, Description, Status (Draft / DeptApproval / PurchaseApproval / Approved / InProgress / PartiallyDone / Done / Rejected), ApprovalStatus, ApprovalDate, ApprovalNote (akış), DeptApproverUserNames / PurchaseApproverUserNames (`|` ayrılmış kullanıcı adları), DeptApprovedBy/Date/Note, PurchaseApprovedBy/Date/Note, RejectReasonId, ApproverId (kullanılmaz).
- `Prc_T_MaterialRequestItem`: MaterialRequestId (FK, cascade), ProductId, Quantity, UomId (nvarchar, `Adm_T_Uom`), FulfillmentMethod (Purchase / Transfer), DueDate, RequestReason, DeliveredQuantity, PlannedQuantity, PurchaseResponsibleUserId, LineStatus (Waiting / Planned / Done / Cancelled).
- `Prc_T_RejectReason`: Name, SortOrder, IsActive.
- Prosedür `Prc_P_MaterialRequestAfterSave(@Id, @UserId)`.
### 5. İş kuralları ve hesaplar
- `Prc_P_MaterialRequestAfterSave` talep kaydı/güncellemesi ve satır ekleme/güncelleme/silme sonrasında çalışır: boş planlanacak miktarı talep miktarıyla doldurur; onaycı kullanıcı listelerini Onaycılar'dan yeniden yazar; ApprovalStatus departman adımını geçince departman onay bilgilerini, Onaylandı/Reddedildi olunca satınalma onay bilgilerini (onaylayan, tarih, not) kopyalar; Status'u türetir: Departman Onayı → DeptApproval, Satınalma Onayı → PurchaseApproval, Reddedildi → Rejected, Onaylandı → satırlara göre (tümü Tamamlandı/İptal → Done, bir kısmı Tamamlandı → PartiallyDone, Planlandı varsa → InProgress, değilse Approved), boş → Draft.
- Onaya gönderilmiş talebe satır eklenemez ve satır silinemez (alt form Insert/Delete Before komutu). 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.
- Depo değişince konum temizlenir; konum listesi depoya göre süzülür. Talep eden değişince departmanı kullanıcı kartından gelir; yeni kayıtta departman oturumdaki kullanıcının departmanıdır.
- Onaycı listesi boşsa akış o adımda hata verir: Onaycılar'a ilgili departman için Satınalma ve en az bir Satınalma Masası satırı tanımlanmalıdır.
### 6. Yetki ve görünürlük
Yetki ağacı: `App.Prc` › `App.Prc.MaterialRequests` › her liste (+ Create/Update/Delete/Export/Import/Note); alt form `App.Prc.MaterialRequestLine` listenin altında. Talep edenlere Taleplerim (+Create, +Update), onaycılara ilgili onay listesi (+Update), satınalma ekibine Planlama Bekleyenler ve Tüm Talepler verilir; satır alt formunun yetkisi de role verilmelidir. Onay listeleri yalnız kullanıcının onayına düşen kayıtları gösterir. Kiracı kapsamlı, şube filtresi yok.
### 7. Entegrasyonlar
Yönetim › Tanımlamalar › Onaycılar (onay yerleri Satınalma ve Satınalma Masası); Envanter › Tanımlamalar › Ürünler, Depolar, Konumlar; İK departmanları; Yönetim › Tanımlamalar › Diziler (`MaterialRequest`). Akış e-posta bildirimi platformun iş akışı altyapısındadır. Teklif/sipariş modülüyle entegrasyon yok.
### 8. Akış örneği
1. Onaycılar'da BT departmanı için Satınalma yerinde Ayşe, Satınalma Masası yerinde Mehmet tanımlıdır.
2. BT'den Ali Taleplerim'de yeni talep açar (MT-2026-00001), depo/konum 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, talep Planlama Bekleyenler'de görünür.
5. Satınalma satırda sorumluyu atar, satırı Planlandı yapar (talep İşlemde), sonra Tamamlandı yapar (talep Tamamlandı, listeden çıkar).
### 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 aktif Satınalma Masası satırı gerekir.
- **Onaya gönderdikten sonra satır ekleyebilir miyim?** Hayır; talep reddedilirse ya da akış başa dönerse yeniden düzenlenir.
- **Kendi Depomda / Tüm Depolar miktarları nerede?** Stok modülü geldiğinde eklenecek.
- **Red nedeni nereden seçilir?** Onay listelerindeki talep formunda Red Nedeni alanından (Satınalma › Tanımlamalar › Red Nedenleri).
### 10. Dosyalar ve geri alma
- Tablolar: `sql/object/Prc_T_MaterialRequest.sql`, `Prc_T_MaterialRequestItem.sql`, `Prc_T_RejectReason.sql` (+ postgres eşleri); kullanılmayan `Prc_T_MaterialRequestLine.sql`.
- Prosedür: `sql/object/Prc_P_MaterialRequestAfterSave.sql` (+ postgres).
- Wizard'lar: `Prc_MaterialRequestLine.json`, `Prc_MyMaterialRequest.json`, `Prc_MaterialRequestDeptApproval.json`, `Prc_MaterialRequestPurchaseApproval.json`, `Prc_MaterialRequestPlanning.json`, `Prc_MaterialRequest.json`, `Prc_RejectReason.json`; güncellenen `Adm_Approver.json`.
- 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.
<!-- module-doc:auto:begin --> <!-- module-doc:auto:begin -->
## Ek — Ekran envanteri (otomatik) ## Ek — Ekran envanteri (otomatik)
@ -165,4 +246,267 @@ Yok. Tanımlar Yönetim › Tanımlamalar › Kontaklar'ın Satış ve Satınalm
| `Name` | Ad | dxTextBox | ✓ | ✓ | | | `Name` | Ad | dxTextBox | ✓ | ✓ | |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | | | `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
#### Red Nedenleri — `App.Prc.RejectReason`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Prc_RejectReason.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Prc.Definitions` › `App.Prc.RejectReason` (sıra 5) |
| Yetki | `App.Prc.RejectReason` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Red Nedenleri — satınalma taleplerinin reddedilme sebepleri (ihtiyaç yok, miktar uygun değil, yanlış ürün, bütçe uygun değil, diğer). |
| Geliştirme talebi | Satınalma -> Malzeme Talepleri |
| Kaynak | `Prc_T_RejectReason` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Widget'lar | `App.Widget.Total`, `App.Widget.Active`, `App.Widget.Passive` |
| Form varsayılanları | SortOrder=0, IsActive=true |
| Veri aynası | `data/App.Prc.RejectReason.json` |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `Name` | Red Nedeni | dxTextBox | ✓ | ✓ | |
| `SortOrder` | Sıra | dxNumberBox | ✓ | ✓ | |
| `IsActive` | Aktif | dxCheckBox | ✓ | ✓ | |
### Malzeme Talepleri (`App.Prc.MaterialRequests`)
#### Taleplerim — `App.Prc.MyMaterialRequest`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Prc_MyMaterialRequest.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Prc.MaterialRequests` › `App.Prc.MyMaterialRequest` (sıra 1) |
| Yetki | `App.Prc.MyMaterialRequest` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Taleplerim — açtığınız malzeme talepleri, tüm durumlarıyla. |
| Geliştirme talebi | Satınalma -> Malzeme Talepleri |
| Kaynak | `Prc_T_MaterialRequest` · filtre `"IsDeleted" = 'false' AND "RequesterUserId" = '@USERID'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Prc.MaterialRequestLine` (Id → MaterialRequestId) |
| Widget'lar | `App.Prc.MaterialRequest.Widget.Mine`, `App.Prc.MaterialRequest.Widget.Pending`, `App.Prc.MaterialRequest.Widget.Approved`, `App.Prc.MaterialRequest.Widget.Rejected` |
| Komutlar | InsertAfter: `Prc_P_MaterialRequestAfterSave` · UpdateAfter: `Prc_P_MaterialRequestAfterSave` · DeleteBefore: SQL |
| Form varsayılanları | RequestNo=MaterialRequest, RequesterUserId=@USERID, DepartmentId=, RequestDate=@NOW, Priority=0, Status=Draft |
| Onay akışı | Start 'Onaya Gönderildi' → Approval 'Departman Onayı' → Approval 'Satınalma Onayı' → End 'Onaylandı' → End 'Reddedildi' |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `RequestNo` | Talep No | dxTextBox | | ✓ | |
| `Priority` | Öncelik (0-3) | dxNumberBox | ✓ | ✓ | |
| `RequesterUserId` | Talep Eden | dxSelectBox | ✓ | ✓ | sorgu: AbpUsers · script |
| `DepartmentId` | Departman | dxSelectBox | ✓ | ✓ | sorgu: Hr_T_Department |
| `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse · script |
| `LocationId` | Konum | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Location (← WarehouseId) |
| `RequestDate` | Talep Tarihi | dxDateBox | ✓ | ✓ | |
| `Status` | Durum | dxSelectBox | ✓ | ✓ | liste: Draft, DeptApproval, PurchaseApproval, Approved, InProgress, PartiallyDone, Done, Rejected |
| `ApprovalStatus` | Onay Durumu | dxTextBox | | ✓ | |
| `RejectReasonId` | Red Nedeni | dxSelectBox | | ✓ | sorgu: Prc_T_RejectReason |
| `Description` | Genel Açıklama | dxTextArea | | ✓ | |
| `PurchaseApproverUserNames` | Satınalma Onaycıları | dxTextBox | | | |
| `ApproverId` | Onaylayan Kimlik | dxTextBox | | | |
| `ApprovalDate` | Onay Tarihi | dxDateBox | | | |
| `ApprovalNote` | Onay Notu | dxTextArea | | | |
| `DeptApproverUserNames` | Departman Onaycıları | dxTextBox | | ✓ | |
| `PurchaseApprovedBy` | Satınalma Onaylayan | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `DeptApprovedBy` | Departman Onaylayan | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `PurchaseApprovalDate` | Satınalma Onay Tarihi | dxDateBox | | ✓ | |
| `DeptApprovalDate` | Departman Onay Tarihi | dxDateBox | | ✓ | |
| `PurchaseApprovalNote` | Satınalma Onay Notu | dxTextArea | | ✓ | |
| `DeptApprovalNote` | Departman Onay Notu | dxTextArea | | ✓ | |
#### Departman Onayı Bekleyenler — `App.Prc.MaterialRequestDeptApproval`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Prc_MaterialRequestDeptApproval.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Prc.MaterialRequests` › `App.Prc.MaterialRequestDeptApproval` (sıra 2) |
| Yetki | `App.Prc.MaterialRequestDeptApproval` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Departman Onayı Bekleyenler — departman onaycısının kararını bekleyen malzeme talepleri. |
| Geliştirme talebi | Satınalma -> Malzeme Talepleri |
| Kaynak | `Prc_T_MaterialRequest` · filtre `"IsDeleted" = 'false' AND "ApprovalStatus" = N'Departman Onayı'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Prc.MaterialRequestLine` (Id → MaterialRequestId) |
| Widget'lar | `App.Prc.MaterialRequest.Status.DeptApproval`, `App.Prc.MaterialRequest.Status.PurchaseApproval`, `App.Prc.MaterialRequest.Status.Rejected` |
| Komutlar | UpdateAfter: `Prc_P_MaterialRequestAfterSave` |
| Form varsayılanları | Priority=0, Status=Draft |
| Onay akışı | Start 'Onaya Gönderildi' → Approval 'Departman Onayı' → Approval 'Satınalma Onayı' → End 'Onaylandı' → End 'Reddedildi' |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `RequestNo` | Talep No | dxTextBox | | ✓ | |
| `Priority` | Öncelik (0-3) | dxNumberBox | ✓ | ✓ | |
| `RequesterUserId` | Talep Eden | dxSelectBox | ✓ | ✓ | sorgu: AbpUsers |
| `DepartmentId` | Departman | dxSelectBox | ✓ | ✓ | sorgu: Hr_T_Department |
| `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse |
| `LocationId` | Konum | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Location |
| `RequestDate` | Talep Tarihi | dxDateBox | ✓ | ✓ | |
| `Status` | Durum | dxSelectBox | ✓ | ✓ | liste: Draft, DeptApproval, PurchaseApproval, Approved, InProgress, PartiallyDone, Done, Rejected |
| `ApprovalStatus` | Onay Durumu | dxTextBox | | ✓ | |
| `RejectReasonId` | Red Nedeni | dxSelectBox | | ✓ | sorgu: Prc_T_RejectReason |
| `Description` | Genel Açıklama | dxTextArea | | ✓ | |
| `DeptApproverUserNames` | Departman Onaycıları | dxTextBox | | | |
| `PurchaseApproverUserNames` | Satınalma Onaycıları | dxTextBox | | | |
| `ApprovalDate` | Onay Tarihi | dxDateBox | | | |
| `ApprovalNote` | Onay Notu | dxTextArea | | | |
#### Satınalma Onayı Bekleyenler — `App.Prc.MaterialRequestPurchaseApproval`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Prc_MaterialRequestPurchaseApproval.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Prc.MaterialRequests` › `App.Prc.MaterialRequestPurchaseApproval` (sıra 3) |
| Yetki | `App.Prc.MaterialRequestPurchaseApproval` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Satınalma Onayı Bekleyenler — departmanca onaylanmış ve satınalmanın kararını bekleyen malzeme talepleri. |
| Geliştirme talebi | Satınalma -> Malzeme Talepleri |
| Kaynak | `Prc_T_MaterialRequest` · filtre `"IsDeleted" = 'false' AND "ApprovalStatus" = N'Satınalma Onayı'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Prc.MaterialRequestLine` (Id → MaterialRequestId) |
| Widget'lar | `App.Prc.MaterialRequest.Status.PurchaseApproval`, `App.Prc.MaterialRequest.Status.Approved`, `App.Prc.MaterialRequest.Status.Rejected` |
| Komutlar | UpdateAfter: `Prc_P_MaterialRequestAfterSave` |
| Form varsayılanları | Priority=0, Status=Draft |
| Onay akışı | Start 'Onaya Gönderildi' → Approval 'Departman Onayı' → Approval 'Satınalma Onayı' → End 'Onaylandı' → End 'Reddedildi' |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `RequestNo` | Talep No | dxTextBox | | ✓ | |
| `Priority` | Öncelik (0-3) | dxNumberBox | ✓ | ✓ | |
| `RequesterUserId` | Talep Eden | dxSelectBox | ✓ | ✓ | sorgu: AbpUsers |
| `DepartmentId` | Departman | dxSelectBox | ✓ | ✓ | sorgu: Hr_T_Department |
| `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse |
| `LocationId` | Konum | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Location |
| `RequestDate` | Talep Tarihi | dxDateBox | ✓ | ✓ | |
| `Status` | Durum | dxSelectBox | ✓ | ✓ | liste: Draft, DeptApproval, PurchaseApproval, Approved, InProgress, PartiallyDone, Done, Rejected |
| `ApprovalStatus` | Onay Durumu | dxTextBox | | ✓ | |
| `RejectReasonId` | Red Nedeni | dxSelectBox | | ✓ | sorgu: Prc_T_RejectReason |
| `Description` | Genel Açıklama | dxTextArea | | ✓ | |
| `DeptApproverUserNames` | Departman Onaycıları | dxTextBox | | | |
| `PurchaseApproverUserNames` | Satınalma Onaycıları | dxTextBox | | | |
| `ApprovalDate` | Onay Tarihi | dxDateBox | | | |
| `ApprovalNote` | Onay Notu | dxTextArea | | | |
| `DeptApprovedBy` | Departman Onaylayan | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `DeptApprovalDate` | Departman Onay Tarihi | dxDateBox | | ✓ | |
| `DeptApprovalNote` | Departman Onay Notu | dxTextArea | | ✓ | |
#### Planlama Bekleyenler — `App.Prc.MaterialRequestPlanning`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Prc_MaterialRequestPlanning.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Prc.MaterialRequests` › `App.Prc.MaterialRequestPlanning` (sıra 4) |
| Yetki | `App.Prc.MaterialRequestPlanning` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Planlama Bekleyenler — onaylanmış ve satırları henüz tamamlanmamış malzeme talepleri; satınalma ekibinin iş listesi. |
| Geliştirme talebi | Satınalma -> Malzeme Talepleri |
| Kaynak | `Prc_T_MaterialRequest` · filtre `"IsDeleted" = 'false' AND "ApprovalStatus" = N'Onaylandı' AND "Status" <> 'Done'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✗ · düzenle ✓ · sil ✗ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Prc.MaterialRequestLine` (Id → MaterialRequestId) |
| Widget'lar | `App.Prc.MaterialRequest.Status.Approved`, `App.Prc.MaterialRequest.Status.InProgress`, `App.Prc.MaterialRequest.Status.PartiallyDone` |
| Komutlar | UpdateAfter: `Prc_P_MaterialRequestAfterSave` |
| Form varsayılanları | Priority=0, Status=Draft |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `RequestNo` | Talep No | dxTextBox | | ✓ | |
| `Priority` | Öncelik (0-3) | dxNumberBox | ✓ | ✓ | |
| `RequesterUserId` | Talep Eden | dxSelectBox | ✓ | ✓ | sorgu: AbpUsers |
| `DepartmentId` | Departman | dxSelectBox | ✓ | ✓ | sorgu: Hr_T_Department |
| `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse |
| `LocationId` | Konum | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Location |
| `RequestDate` | Talep Tarihi | dxDateBox | ✓ | ✓ | |
| `Status` | Durum | dxSelectBox | ✓ | ✓ | liste: Draft, DeptApproval, PurchaseApproval, Approved, InProgress, PartiallyDone, Done, Rejected |
| `Description` | Genel Açıklama | dxTextArea | | ✓ | |
| `DeptApprovedBy` | Departman Onaylayan | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `PurchaseApprovedBy` | Satınalma Onaylayan | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `DeptApprovalDate` | Departman Onay Tarihi | dxDateBox | | ✓ | |
| `PurchaseApprovalDate` | Satınalma Onay Tarihi | dxDateBox | | ✓ | |
| `DeptApprovalNote` | Departman Onay Notu | dxTextArea | | ✓ | |
| `PurchaseApprovalNote` | Satınalma Onay Notu | dxTextArea | | ✓ | |
#### Tüm Talepler — `App.Prc.MaterialRequest`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Prc_MaterialRequest.json` |
| Yol | Liste (Wizard) |
| Menü | `App.Prc.MaterialRequests` › `App.Prc.MaterialRequest` (sıra 5) |
| Yetki | `App.Prc.MaterialRequest` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Tüm Talepler — kurumun bütün malzeme talepleri, tüm durumlarıyla; satınalma yönetiminin listesi. |
| Geliştirme talebi | Satınalma -> Malzeme Talepleri |
| Kaynak | `Prc_T_MaterialRequest` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Alt formlar | `App.Prc.MaterialRequestLine` (Id → MaterialRequestId) |
| Widget'lar | `App.Prc.MaterialRequest.Status.DeptApproval`, `App.Prc.MaterialRequest.Status.PurchaseApproval`, `App.Prc.MaterialRequest.Status.Approved`, `App.Prc.MaterialRequest.Status.Rejected` |
| Komutlar | InsertAfter: `Prc_P_MaterialRequestAfterSave` · UpdateAfter: `Prc_P_MaterialRequestAfterSave` · DeleteBefore: SQL |
| Form varsayılanları | RequestNo=MaterialRequest, RequesterUserId=@USERID, DepartmentId=, RequestDate=@NOW, Priority=0, Status=Draft |
| Onay akışı | Start 'Onaya Gönderildi' → Approval 'Departman Onayı' → Approval 'Satınalma Onayı' → End 'Onaylandı' → End 'Reddedildi' |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `RequestNo` | Talep No | dxTextBox | | ✓ | |
| `Priority` | Öncelik (0-3) | dxNumberBox | ✓ | ✓ | |
| `RequesterUserId` | Talep Eden | dxSelectBox | ✓ | ✓ | sorgu: AbpUsers · script |
| `DepartmentId` | Departman | dxSelectBox | ✓ | ✓ | sorgu: Hr_T_Department |
| `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse · script |
| `LocationId` | Konum | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Location (← WarehouseId) |
| `RequestDate` | Talep Tarihi | dxDateBox | ✓ | ✓ | |
| `Status` | Durum | dxSelectBox | ✓ | ✓ | liste: Draft, DeptApproval, PurchaseApproval, Approved, InProgress, PartiallyDone, Done, Rejected |
| `ApprovalStatus` | Onay Durumu | dxTextBox | | ✓ | |
| `RejectReasonId` | Red Nedeni | dxSelectBox | | ✓ | sorgu: Prc_T_RejectReason |
| `Description` | Genel Açıklama | dxTextArea | | ✓ | |
| `PurchaseApproverUserNames` | Satınalma Onaycıları | dxTextBox | | | |
| `ApproverId` | Onaylayan Kimlik | dxTextBox | | | |
| `ApprovalDate` | Onay Tarihi | dxDateBox | | | |
| `ApprovalNote` | Onay Notu | dxTextArea | | | |
| `DeptApproverUserNames` | Departman Onaycıları | dxTextBox | | ✓ | |
| `PurchaseApprovedBy` | Satınalma Onaylayan | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `DeptApprovedBy` | Departman Onaylayan | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `PurchaseApprovalDate` | Satınalma Onay Tarihi | dxDateBox | | ✓ | |
| `DeptApprovalDate` | Departman Onay Tarihi | dxDateBox | | ✓ | |
| `PurchaseApprovalNote` | Satınalma Onay Notu | dxTextArea | | ✓ | |
| `DeptApprovalNote` | Departman Onay Notu | dxTextArea | | ✓ | |
#### Talep Satırları — `App.Prc.MaterialRequestLine`
| Özellik | Değer |
| --- | --- |
| Wizard | `wizard/Prc_MaterialRequestLine.json` |
| Yol | Liste (Wizard) |
| Menü | Menüsüz (alt form) |
| Yetki | `App.Prc.MaterialRequestLine` + `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note` |
| Açıklama | Talep Satırları — malzeme talebinde istenen ürünler. |
| Geliştirme talebi | Satınalma -> Malzeme Talepleri |
| Kaynak | `Prc_T_MaterialRequestItem` · filtre `"IsDeleted" = 'false'` |
| Görünümler | Grid, Card, Pivot, Chart (açılış grid) |
| Düzenleme | ekle ✓ · düzenle ✓ · sil ✓ · popup |
| Kapsam | Kiracı |
| Komutlar | InsertBefore: SQL · InsertAfter: `Prc_P_MaterialRequestAfterSave` · UpdateAfter: `Prc_P_MaterialRequestAfterSave` · DeleteBefore: SQL · DeleteAfter: `Prc_P_MaterialRequestAfterSave` |
| Form varsayılanları | FulfillmentMethod=Purchase, DeliveredQuantity=0, LineStatus=Waiting |
| Alan | Başlık | Editör | Zorunlu | Formda | Kaynak |
| --- | --- | --- | --- | --- | --- |
| `MaterialRequestId` | Malzeme Talebi | dxTextBox | | | |
| `ProductId` | Ürün | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Product · script |
| `Quantity` | Miktar | dxNumberBox | ✓ | ✓ | |
| `UomId` | Birim | dxSelectBox | ✓ | ✓ | sorgu: Adm_T_Uom |
| `FulfillmentMethod` | Karşılama Şekli | dxSelectBox | ✓ | ✓ | liste: Purchase, Transfer |
| `DueDate` | Termin Tarihi | dxDateBox | ✓ | ✓ | |
| `RequestReason` | Talep Nedeni | dxTextBox | ✓ | ✓ | |
| `DeliveredQuantity` | Teslim | dxNumberBox | | ✓ | |
| `PlannedQuantity` | Planlanacak Miktar | dxNumberBox | | ✓ | |
| `PurchaseResponsibleUserId` | Satınalma Sorumlusu | dxSelectBox | | ✓ | sorgu: AbpUsers |
| `LineStatus` | Satır Durumu | dxSelectBox | ✓ | ✓ | liste: Waiting, Planned, Done, Cancelled |
<!-- module-doc:auto:end --> <!-- module-doc:auto:end -->

View file

@ -0,0 +1,66 @@
CREATE OR REPLACE PROCEDURE public."Prc_P_MaterialRequestAfterSave"(
"p_Id" uuid,
"p_UserId" uuid DEFAULT NULL
)
LANGUAGE plpgsql
AS $$
BEGIN
IF "p_Id" IS NULL THEN RETURN; END IF;
UPDATE "Prc_T_MaterialRequestItem" l SET "PlannedQuantity" = l."Quantity"
WHERE l."MaterialRequestId" = "p_Id" AND l."IsDeleted" = false AND l."PlannedQuantity" IS NULL;
UPDATE "Prc_T_MaterialRequest" r SET
"DeptApproverUserNames" = (
SELECT string_agg(u."UserName", '|')
FROM "Adm_T_Approver" a
INNER JOIN "AbpUsers" u ON u."Id" = a."ApproverUserId" AND u."IsDeleted" = false
WHERE a."IsDeleted" = false AND a."IsActive" = true AND a."ApprovalArea" = 'Purchase'
AND a."DepartmentId" = r."DepartmentId"
AND a."TenantId" IS NOT DISTINCT FROM r."TenantId"),
"PurchaseApproverUserNames" = (
SELECT string_agg(u."UserName", '|')
FROM "Adm_T_Approver" a
INNER JOIN "AbpUsers" u ON u."Id" = a."ApproverUserId" AND u."IsDeleted" = false
WHERE a."IsDeleted" = false AND a."IsActive" = true AND a."ApprovalArea" = 'PurchaseDesk'
AND a."TenantId" IS NOT DISTINCT FROM r."TenantId")
WHERE r."Id" = "p_Id";
UPDATE "Prc_T_MaterialRequest" r SET
"PurchaseApprovedBy" = COALESCE("p_UserId", r."LastModifierId"),
"PurchaseApprovalDate" = COALESCE(r."ApprovalDate", now()),
"PurchaseApprovalNote" = r."ApprovalNote"
WHERE r."Id" = "p_Id" AND r."PurchaseApprovedBy" IS NULL AND r."DeptApprovedBy" IS NOT NULL
AND r."ApprovalStatus" IN ('Onaylandı', 'Reddedildi');
UPDATE "Prc_T_MaterialRequest" r SET
"DeptApprovedBy" = COALESCE("p_UserId", r."LastModifierId"),
"DeptApprovalDate" = COALESCE(r."ApprovalDate", now()),
"DeptApprovalNote" = r."ApprovalNote"
WHERE r."Id" = "p_Id" AND r."DeptApprovedBy" IS NULL
AND r."ApprovalStatus" IN ('Satınalma Onayı', 'Onaylandı', 'Reddedildi');
UPDATE "Prc_T_MaterialRequest" r SET "Status" =
CASE
WHEN r."ApprovalStatus" = 'Departman Onayı' THEN 'DeptApproval'
WHEN r."ApprovalStatus" = 'Satınalma Onayı' THEN 'PurchaseApproval'
WHEN r."ApprovalStatus" = 'Reddedildi' THEN 'Rejected'
WHEN r."ApprovalStatus" = 'Onaylandı' THEN
CASE
WHEN s."Total" > 0 AND s."Closed" = s."Total" THEN 'Done'
WHEN s."Closed" > 0 THEN 'PartiallyDone'
WHEN s."Planned" > 0 THEN 'InProgress'
ELSE 'Approved'
END
ELSE 'Draft'
END
FROM (
SELECT COUNT(*) AS "Total",
COALESCE(SUM(CASE WHEN l."LineStatus" IN ('Done', 'Cancelled') THEN 1 ELSE 0 END), 0) AS "Closed",
COALESCE(SUM(CASE WHEN l."LineStatus" IN ('Planned', 'Done') THEN 1 ELSE 0 END), 0) AS "Planned"
FROM "Prc_T_MaterialRequestItem" l
WHERE l."MaterialRequestId" = "p_Id" AND l."IsDeleted" = false
) s
WHERE r."Id" = "p_Id";
END;
$$;

View file

@ -0,0 +1,39 @@
CREATE TABLE IF NOT EXISTS public."Prc_T_MaterialRequest"
(
"Id" uuid NOT NULL DEFAULT gen_random_uuid(),
"TenantId" uuid NULL,
"RequestNo" varchar(32) NULL,
"Priority" integer NOT NULL DEFAULT 0,
"RequesterUserId" uuid NOT NULL,
"DepartmentId" uuid NOT NULL,
"WarehouseId" uuid NOT NULL,
"LocationId" uuid NOT NULL,
"RequestDate" timestamp NOT NULL DEFAULT LOCALTIMESTAMP,
"Description" text NULL,
"Status" varchar(32) NOT NULL DEFAULT 'Draft',
"ApprovalStatus" varchar(32) NULL,
"ApproverId" uuid NULL,
"ApprovalDate" timestamp NULL,
"ApprovalNote" text NULL,
"DeptApproverUserNames" text NULL,
"PurchaseApproverUserNames" text NULL,
"DeptApprovedBy" uuid NULL,
"DeptApprovalDate" timestamp NULL,
"DeptApprovalNote" text NULL,
"PurchaseApprovedBy" uuid NULL,
"PurchaseApprovalDate" timestamp NULL,
"PurchaseApprovalNote" text NULL,
"RejectReasonId" uuid NULL,
"CreationTime" timestamp NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'),
"CreatorId" uuid NULL,
"LastModificationTime" timestamp NULL,
"LastModifierId" uuid NULL,
"IsDeleted" boolean NOT NULL DEFAULT FALSE,
"DeletionTime" timestamp NULL,
"DeleterId" uuid NULL,
CONSTRAINT "PK_Prc_T_MaterialRequest" PRIMARY KEY ("Id")
);
CREATE INDEX IF NOT EXISTS "IX_Prc_T_MaterialRequest_TenantId_Status" ON public."Prc_T_MaterialRequest" ("TenantId", "Status");
CREATE INDEX IF NOT EXISTS "IX_Prc_T_MaterialRequest_TenantId_RequesterUserId" ON public."Prc_T_MaterialRequest" ("TenantId", "RequesterUserId");

View file

@ -0,0 +1,34 @@
CREATE TABLE IF NOT EXISTS public."Prc_T_MaterialRequestItem"
(
"Id" uuid NOT NULL DEFAULT gen_random_uuid(),
"TenantId" uuid NULL,
"MaterialRequestId" uuid NOT NULL,
"ProductId" uuid NOT NULL,
"Quantity" numeric(18, 4) NOT NULL,
"UomId" varchar(64) NOT NULL,
"FulfillmentMethod" varchar(16) NOT NULL DEFAULT 'Purchase',
"DueDate" date NOT NULL,
"RequestReason" varchar(256) NOT NULL,
"DeliveredQuantity" numeric(18, 4) NOT NULL DEFAULT 0,
"PlannedQuantity" numeric(18, 4) NULL,
"PurchaseResponsibleUserId" uuid NULL,
"LineStatus" varchar(16) NOT NULL DEFAULT 'Waiting',
"CreationTime" timestamp NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'),
"CreatorId" uuid NULL,
"LastModificationTime" timestamp NULL,
"LastModifierId" uuid NULL,
"IsDeleted" boolean NOT NULL DEFAULT FALSE,
"DeletionTime" timestamp NULL,
"DeleterId" uuid NULL,
CONSTRAINT "PK_Prc_T_MaterialRequestItem" PRIMARY KEY ("Id")
);
CREATE INDEX IF NOT EXISTS "IX_Prc_T_MaterialRequestItem_MaterialRequestId" ON public."Prc_T_MaterialRequestItem" ("MaterialRequestId");
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'FK_Prc_T_MaterialRequestItem_MaterialRequestId') THEN
ALTER TABLE public."Prc_T_MaterialRequestItem" ADD CONSTRAINT "FK_Prc_T_MaterialRequestItem_MaterialRequestId" FOREIGN KEY ("MaterialRequestId") REFERENCES public."Prc_T_MaterialRequest" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;
END IF;
END
$$;

View file

@ -0,0 +1,34 @@
CREATE TABLE IF NOT EXISTS public."Prc_T_MaterialRequestLine"
(
"Id" uuid NOT NULL DEFAULT gen_random_uuid(),
"TenantId" uuid NULL,
"MaterialRequestId" uuid NOT NULL,
"ProductId" uuid NOT NULL,
"Quantity" numeric(18, 4) NOT NULL,
"UomId" uuid NOT NULL,
"FulfillmentMethod" varchar(16) NOT NULL DEFAULT 'Purchase',
"DueDate" date NOT NULL,
"RequestReason" varchar(256) NOT NULL,
"DeliveredQuantity" numeric(18, 4) NOT NULL DEFAULT 0,
"PlannedQuantity" numeric(18, 4) NULL,
"PurchaseResponsibleUserId" uuid NULL,
"LineStatus" varchar(16) NOT NULL DEFAULT 'Waiting',
"CreationTime" timestamp NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'),
"CreatorId" uuid NULL,
"LastModificationTime" timestamp NULL,
"LastModifierId" uuid NULL,
"IsDeleted" boolean NOT NULL DEFAULT FALSE,
"DeletionTime" timestamp NULL,
"DeleterId" uuid NULL,
CONSTRAINT "PK_Prc_T_MaterialRequestLine" PRIMARY KEY ("Id")
);
CREATE INDEX IF NOT EXISTS "IX_Prc_T_MaterialRequestLine_MaterialRequestId" ON public."Prc_T_MaterialRequestLine" ("MaterialRequestId");
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'FK_Prc_T_MaterialRequestLine_MaterialRequestId') THEN
ALTER TABLE public."Prc_T_MaterialRequestLine" ADD CONSTRAINT "FK_Prc_T_MaterialRequestLine_MaterialRequestId" FOREIGN KEY ("MaterialRequestId") REFERENCES public."Prc_T_MaterialRequest" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;
END IF;
END
$$;

View file

@ -0,0 +1,18 @@
CREATE TABLE IF NOT EXISTS public."Prc_T_RejectReason"
(
"Id" uuid NOT NULL DEFAULT gen_random_uuid(),
"TenantId" uuid NULL,
"Name" varchar(128) NOT NULL,
"SortOrder" integer NOT NULL DEFAULT 0,
"IsActive" boolean NOT NULL DEFAULT TRUE,
"CreationTime" timestamp NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'),
"CreatorId" uuid NULL,
"LastModificationTime" timestamp NULL,
"LastModifierId" uuid NULL,
"IsDeleted" boolean NOT NULL DEFAULT FALSE,
"DeletionTime" timestamp NULL,
"DeleterId" uuid NULL,
CONSTRAINT "PK_Prc_T_RejectReason" PRIMARY KEY ("Id")
);
CREATE INDEX IF NOT EXISTS "IX_Prc_T_RejectReason_TenantId_Name" ON public."Prc_T_RejectReason" ("TenantId", "Name");

View file

@ -0,0 +1,75 @@
CREATE OR ALTER PROCEDURE [dbo].[Prc_P_MaterialRequestAfterSave]
@Id uniqueidentifier,
@UserId uniqueidentifier = NULL
AS
BEGIN
SET NOCOUNT ON;
IF @Id IS NULL RETURN;
-- Satır planlanan miktarı boşsa talep miktarıyla doldur
UPDATE l SET PlannedQuantity = l.Quantity
FROM Prc_T_MaterialRequestItem l
WHERE l.MaterialRequestId = @Id AND l.IsDeleted = 0 AND l.PlannedQuantity IS NULL;
-- Onaycılar (Adm_T_Approver): departman onayı = Purchase + talebin departmanı, satınalma onayı = PurchaseDesk
UPDATE r SET
DeptApproverUserNames = (
SELECT STRING_AGG(u.UserName, '|')
FROM Adm_T_Approver a
INNER JOIN AbpUsers u ON u.Id = a.ApproverUserId AND u.IsDeleted = 0
WHERE a.IsDeleted = 0 AND a.IsActive = 1 AND a.ApprovalArea = 'Purchase'
AND a.DepartmentId = r.DepartmentId
AND ((a.TenantId IS NULL AND r.TenantId IS NULL) OR a.TenantId = r.TenantId)),
PurchaseApproverUserNames = (
SELECT STRING_AGG(u.UserName, '|')
FROM Adm_T_Approver a
INNER JOIN AbpUsers u ON u.Id = a.ApproverUserId AND u.IsDeleted = 0
WHERE a.IsDeleted = 0 AND a.IsActive = 1 AND a.ApprovalArea = 'PurchaseDesk'
AND ((a.TenantId IS NULL AND r.TenantId IS NULL) OR a.TenantId = r.TenantId))
FROM Prc_T_MaterialRequest r
WHERE r.Id = @Id;
-- Satınalma kararı: departman adımı daha önce kaydedilmişse
UPDATE r SET
PurchaseApprovedBy = COALESCE(@UserId, r.LastModifierId),
PurchaseApprovalDate = COALESCE(r.ApprovalDate, GETDATE()),
PurchaseApprovalNote = r.ApprovalNote
FROM Prc_T_MaterialRequest r
WHERE r.Id = @Id AND r.PurchaseApprovedBy IS NULL AND r.DeptApprovedBy IS NOT NULL
AND r.ApprovalStatus IN (N'Onaylandı', N'Reddedildi');
-- Departman kararı (onaylanıp satınalmaya geçti ya da departmanda reddedildi)
UPDATE r SET
DeptApprovedBy = COALESCE(@UserId, r.LastModifierId),
DeptApprovalDate = COALESCE(r.ApprovalDate, GETDATE()),
DeptApprovalNote = r.ApprovalNote
FROM Prc_T_MaterialRequest r
WHERE r.Id = @Id AND r.DeptApprovedBy IS NULL
AND r.ApprovalStatus IN (N'Satınalma Onayı', N'Onaylandı', N'Reddedildi');
-- Durum: onay akışından ve satır durumlarından türetilir
UPDATE r SET Status =
CASE
WHEN r.ApprovalStatus = N'Departman Onayı' THEN 'DeptApproval'
WHEN r.ApprovalStatus = N'Satınalma Onayı' THEN 'PurchaseApproval'
WHEN r.ApprovalStatus = N'Reddedildi' THEN 'Rejected'
WHEN r.ApprovalStatus = N'Onaylandı' THEN
CASE
WHEN s.Total > 0 AND s.Closed = s.Total THEN 'Done'
WHEN s.Closed > 0 THEN 'PartiallyDone'
WHEN s.Planned > 0 THEN 'InProgress'
ELSE 'Approved'
END
ELSE 'Draft'
END
FROM Prc_T_MaterialRequest r
CROSS APPLY (
SELECT COUNT(*) AS Total,
ISNULL(SUM(CASE WHEN l.LineStatus IN ('Done', 'Cancelled') THEN 1 ELSE 0 END), 0) AS Closed,
ISNULL(SUM(CASE WHEN l.LineStatus IN ('Planned', 'Done') THEN 1 ELSE 0 END), 0) AS Planned
FROM Prc_T_MaterialRequestItem l
WHERE l.MaterialRequestId = r.Id AND l.IsDeleted = 0
) s
WHERE r.Id = @Id;
END
GO

View file

@ -0,0 +1,54 @@
IF OBJECT_ID(N'[dbo].[Prc_T_MaterialRequest]', 'U') IS NULL
BEGIN
CREATE TABLE [dbo].[Prc_T_MaterialRequest]
(
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
[TenantId] uniqueidentifier NULL,
[RequestNo] nvarchar(32) NULL,
[Priority] int NOT NULL DEFAULT 0,
[RequesterUserId] uniqueidentifier NOT NULL,
[DepartmentId] uniqueidentifier NOT NULL,
[WarehouseId] uniqueidentifier NOT NULL,
[LocationId] uniqueidentifier NOT NULL,
[RequestDate] datetime NOT NULL DEFAULT GETDATE(),
[Description] nvarchar(MAX) NULL,
[Status] nvarchar(32) NOT NULL DEFAULT 'Draft',
[ApprovalStatus] nvarchar(32) NULL,
[ApproverId] uniqueidentifier NULL,
[ApprovalDate] datetime NULL,
[ApprovalNote] nvarchar(MAX) NULL,
[DeptApproverUserNames] nvarchar(MAX) NULL,
[PurchaseApproverUserNames] nvarchar(MAX) NULL,
[DeptApprovedBy] uniqueidentifier NULL,
[DeptApprovalDate] datetime NULL,
[DeptApprovalNote] nvarchar(MAX) NULL,
[PurchaseApprovedBy] uniqueidentifier NULL,
[PurchaseApprovalDate] datetime NULL,
[PurchaseApprovalNote] nvarchar(MAX) NULL,
[RejectReasonId] uniqueidentifier NULL,
[CreationTime] datetime2 NOT NULL DEFAULT GETUTCDATE(),
[CreatorId] uniqueidentifier NULL,
[LastModificationTime] datetime2 NULL,
[LastModifierId] uniqueidentifier NULL,
[IsDeleted] bit NOT NULL DEFAULT 0,
[DeletionTime] datetime2 NULL,
[DeleterId] uniqueidentifier NULL,
CONSTRAINT [PK_Prc_T_MaterialRequest] PRIMARY KEY NONCLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
END
GO
IF INDEXPROPERTY(OBJECT_ID(N'[dbo].[Prc_T_MaterialRequest]'), 'IX_Prc_T_MaterialRequest_TenantId_Status', 'IndexID') IS NULL
BEGIN
CREATE INDEX [IX_Prc_T_MaterialRequest_TenantId_Status] ON [dbo].[Prc_T_MaterialRequest] ([TenantId] ASC, [Status] ASC);
END
GO
IF INDEXPROPERTY(OBJECT_ID(N'[dbo].[Prc_T_MaterialRequest]'), 'IX_Prc_T_MaterialRequest_TenantId_RequesterUserId', 'IndexID') IS NULL
BEGIN
CREATE INDEX [IX_Prc_T_MaterialRequest_TenantId_RequesterUserId] ON [dbo].[Prc_T_MaterialRequest] ([TenantId] ASC, [RequesterUserId] ASC);
END
GO

View file

@ -0,0 +1,43 @@
IF OBJECT_ID(N'[dbo].[Prc_T_MaterialRequestItem]', 'U') IS NULL
BEGIN
CREATE TABLE [dbo].[Prc_T_MaterialRequestItem]
(
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
[TenantId] uniqueidentifier NULL,
[MaterialRequestId] uniqueidentifier NOT NULL,
[ProductId] uniqueidentifier NOT NULL,
[Quantity] decimal(18, 4) NOT NULL,
[UomId] nvarchar(64) NOT NULL,
[FulfillmentMethod] nvarchar(16) NOT NULL DEFAULT 'Purchase',
[DueDate] date NOT NULL,
[RequestReason] nvarchar(256) NOT NULL,
[DeliveredQuantity] decimal(18, 4) NOT NULL DEFAULT 0,
[PlannedQuantity] decimal(18, 4) NULL,
[PurchaseResponsibleUserId] uniqueidentifier NULL,
[LineStatus] nvarchar(16) NOT NULL DEFAULT 'Waiting',
[CreationTime] datetime2 NOT NULL DEFAULT GETUTCDATE(),
[CreatorId] uniqueidentifier NULL,
[LastModificationTime] datetime2 NULL,
[LastModifierId] uniqueidentifier NULL,
[IsDeleted] bit NOT NULL DEFAULT 0,
[DeletionTime] datetime2 NULL,
[DeleterId] uniqueidentifier NULL,
CONSTRAINT [PK_Prc_T_MaterialRequestItem] PRIMARY KEY NONCLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
END
GO
IF INDEXPROPERTY(OBJECT_ID(N'[dbo].[Prc_T_MaterialRequestItem]'), 'IX_Prc_T_MaterialRequestItem_MaterialRequestId', 'IndexID') IS NULL
BEGIN
CREATE INDEX [IX_Prc_T_MaterialRequestItem_MaterialRequestId] ON [dbo].[Prc_T_MaterialRequestItem] ([MaterialRequestId] ASC);
END
GO
IF OBJECT_ID(N'[dbo].[FK_Prc_T_MaterialRequestItem_MaterialRequestId]', 'F') IS NULL
BEGIN
ALTER TABLE [dbo].[Prc_T_MaterialRequestItem] ADD CONSTRAINT [FK_Prc_T_MaterialRequestItem_MaterialRequestId] FOREIGN KEY ([MaterialRequestId]) REFERENCES [dbo].[Prc_T_MaterialRequest] ([Id]) ON DELETE CASCADE ON UPDATE NO ACTION;
END
GO

View file

@ -0,0 +1,43 @@
IF OBJECT_ID(N'[dbo].[Prc_T_MaterialRequestLine]', 'U') IS NULL
BEGIN
CREATE TABLE [dbo].[Prc_T_MaterialRequestLine]
(
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
[TenantId] uniqueidentifier NULL,
[MaterialRequestId] uniqueidentifier NOT NULL,
[ProductId] uniqueidentifier NOT NULL,
[Quantity] decimal(18, 4) NOT NULL,
[UomId] uniqueidentifier NOT NULL,
[FulfillmentMethod] nvarchar(16) NOT NULL DEFAULT 'Purchase',
[DueDate] date NOT NULL,
[RequestReason] nvarchar(256) NOT NULL,
[DeliveredQuantity] decimal(18, 4) NOT NULL DEFAULT 0,
[PlannedQuantity] decimal(18, 4) NULL,
[PurchaseResponsibleUserId] uniqueidentifier NULL,
[LineStatus] nvarchar(16) NOT NULL DEFAULT 'Waiting',
[CreationTime] datetime2 NOT NULL DEFAULT GETUTCDATE(),
[CreatorId] uniqueidentifier NULL,
[LastModificationTime] datetime2 NULL,
[LastModifierId] uniqueidentifier NULL,
[IsDeleted] bit NOT NULL DEFAULT 0,
[DeletionTime] datetime2 NULL,
[DeleterId] uniqueidentifier NULL,
CONSTRAINT [PK_Prc_T_MaterialRequestLine] PRIMARY KEY NONCLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
END
GO
IF INDEXPROPERTY(OBJECT_ID(N'[dbo].[Prc_T_MaterialRequestLine]'), 'IX_Prc_T_MaterialRequestLine_MaterialRequestId', 'IndexID') IS NULL
BEGIN
CREATE INDEX [IX_Prc_T_MaterialRequestLine_MaterialRequestId] ON [dbo].[Prc_T_MaterialRequestLine] ([MaterialRequestId] ASC);
END
GO
IF OBJECT_ID(N'[dbo].[FK_Prc_T_MaterialRequestLine_MaterialRequestId]', 'F') IS NULL
BEGIN
ALTER TABLE [dbo].[Prc_T_MaterialRequestLine] ADD CONSTRAINT [FK_Prc_T_MaterialRequestLine_MaterialRequestId] FOREIGN KEY ([MaterialRequestId]) REFERENCES [dbo].[Prc_T_MaterialRequest] ([Id]) ON DELETE CASCADE ON UPDATE NO ACTION;
END
GO

View file

@ -0,0 +1,29 @@
IF OBJECT_ID(N'[dbo].[Prc_T_RejectReason]', 'U') IS NULL
BEGIN
CREATE TABLE [dbo].[Prc_T_RejectReason]
(
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
[TenantId] uniqueidentifier NULL,
[Name] nvarchar(128) NOT NULL,
[SortOrder] int NOT NULL DEFAULT 0,
[IsActive] bit NOT NULL DEFAULT 1,
[CreationTime] datetime2 NOT NULL DEFAULT GETUTCDATE(),
[CreatorId] uniqueidentifier NULL,
[LastModificationTime] datetime2 NULL,
[LastModifierId] uniqueidentifier NULL,
[IsDeleted] bit NOT NULL DEFAULT 0,
[DeletionTime] datetime2 NULL,
[DeleterId] uniqueidentifier NULL,
CONSTRAINT [PK_Prc_T_RejectReason] PRIMARY KEY NONCLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
END
GO
IF INDEXPROPERTY(OBJECT_ID(N'[dbo].[Prc_T_RejectReason]'), 'IX_Prc_T_RejectReason_TenantId_Name', 'IndexID') IS NULL
BEGIN
CREATE INDEX [IX_Prc_T_RejectReason_TenantId_Name] ON [dbo].[Prc_T_RejectReason] ([TenantId] ASC, [Name] ASC);
END
GO

View file

@ -32,14 +32,19 @@
"MenuTr": "Onaycılar", "MenuTr": "Onaycılar",
"TitleEn": "Approvers", "TitleEn": "Approvers",
"TitleTr": "Onaycılar", "TitleTr": "Onaycılar",
"DescEn": "Approvers — the single list of who approves what for each department across the application.\nWhere: Administration › Definitions › Approvers.\nFields: department (shown as Branch - Department), approval area (Purchasing / Warehouse / Human Resources / Finance), approver user, active.\nUsed by: approval workflows read the approvers of the record's department and area (e.g. Purchasing › Material Requests department approval uses area Purchasing). Several approvers may be defined for the same department and area; any one of them can approve. Passive rows are ignored by workflows.", "DescEn": "Approvers — the single list of who approves what for each department across the application.\nWhere: Administration › Definitions › Approvers.\nFields: department (shown as Branch - Department), approval area (Purchasing / Purchasing Desk / Warehouse / Human Resources / Finance), approver user, active.\nUsed by: approval workflows read the approvers of the record's department and area. Purchasing › Material Requests: the department approval uses area Purchasing for the requester's department; the purchasing approval uses area Purchasing Desk (any department). Several approvers may be defined for the same department and area; any one of them can approve. Passive rows are ignored by workflows.",
"DescTr": "Onaycılar — uygulamadaki tüm onay adımlarında her departman için kimin onaylayacağını tutan tek liste.\nNerede: Yönetim › Tanımlamalar › Onaycılar.\nAlanlar: departman (Şube - Departman olarak gösterilir), onay yeri (Satınalma / Depo / İnsan Kaynakları / Finans), onaylayacak kişi, aktif.\nKullanıldığı yer: onay akışları kaydın departmanı ve onay yerine göre onaycıları buradan okur (ör. Satınalma › Malzeme Talepleri departman onayı Satınalma yerini kullanır). Aynı departman ve onay yerine birden çok onaycı girilebilir; herhangi birinin onayı yeterlidir. Pasif satırlar akışlarda kullanılmaz.", "DescTr": "Onaycılar — uygulamadaki tüm onay adımlarında her departman için kimin onaylayacağını tutan tek liste.\nNerede: Yönetim › Tanımlamalar › Onaycılar.\nAlanlar: departman (Şube - Departman olarak gösterilir), onay yeri (Satınalma / Satınalma Masası / Depo / İnsan Kaynakları / Finans), onaylayacak kişi, aktif.\nKullanıldığı yer: onay akışları kaydın departmanı ve onay yerine göre onaycıları buradan okur. Satınalma › Malzeme Talepleri: departman onayı talep edenin departmanındaki Satınalma satırlarını, satınalma onayı ise Satınalma Masası satırlarını (departmandan bağımsız) kullanır. Aynı departman ve onay yerine birden çok onaycı girilebilir; herhangi birinin onayı yeterlidir. Pasif satırlar akışlarda kullanılmaz.",
"Texts": [ "Texts": [
{ {
"Key": "App.StaticLookup.Purchase", "Key": "App.StaticLookup.Purchase",
"En": "Purchasing", "En": "Purchasing",
"Tr": "Satınalma" "Tr": "Satınalma"
}, },
{
"Key": "App.StaticLookup.PurchaseDesk",
"En": "Purchasing Desk",
"Tr": "Satınalma Masası"
},
{ {
"Key": "App.StaticLookup.Warehouse", "Key": "App.StaticLookup.Warehouse",
"En": "Warehouse", "En": "Warehouse",
@ -820,7 +825,7 @@
"GroupInterval": "", "GroupInterval": "",
"WordWrapEnabled": false "WordWrapEnabled": false
}, },
"Alignment": "left", "Alignment": null,
"Format": null, "Format": null,
"EditOrderNo": null, "EditOrderNo": null,
"EditGroupOrderNo": null, "EditGroupOrderNo": null,
@ -958,7 +963,7 @@
"GroupInterval": "", "GroupInterval": "",
"WordWrapEnabled": false "WordWrapEnabled": false
}, },
"Alignment": "left", "Alignment": null,
"Format": null, "Format": null,
"EditOrderNo": 1, "EditOrderNo": 1,
"EditGroupOrderNo": 1, "EditGroupOrderNo": 1,
@ -1056,7 +1061,7 @@
"CascadeFilterOperator": "=", "CascadeFilterOperator": "=",
"CascadeParentFields": null, "CascadeParentFields": null,
"CascadeEmptyFields": null, "CascadeEmptyFields": null,
"LookupQuery": "[{\"key\":\"Purchase\",\"name\":\"App.StaticLookup.Purchase\"},{\"key\":\"Warehouse\",\"name\":\"App.StaticLookup.Warehouse\"},{\"key\":\"HumanResources\",\"name\":\"App.StaticLookup.HumanResources\"},{\"key\":\"Finance\",\"name\":\"App.StaticLookup.Finance\"}]" "LookupQuery": "[{\"key\":\"Purchase\",\"name\":\"App.StaticLookup.Purchase\"},{\"key\":\"PurchaseDesk\",\"name\":\"App.StaticLookup.PurchaseDesk\"},{\"key\":\"Warehouse\",\"name\":\"App.StaticLookup.Warehouse\"},{\"key\":\"HumanResources\",\"name\":\"App.StaticLookup.HumanResources\"},{\"key\":\"Finance\",\"name\":\"App.StaticLookup.Finance\"}]"
}, },
"ValidationRuleDto": [ "ValidationRuleDto": [
{ {
@ -1096,7 +1101,7 @@
"GroupInterval": "", "GroupInterval": "",
"WordWrapEnabled": false "WordWrapEnabled": false
}, },
"Alignment": "left", "Alignment": null,
"Format": null, "Format": null,
"EditOrderNo": 2, "EditOrderNo": 2,
"EditGroupOrderNo": 1, "EditGroupOrderNo": 1,
@ -1234,7 +1239,7 @@
"GroupInterval": "", "GroupInterval": "",
"WordWrapEnabled": false "WordWrapEnabled": false
}, },
"Alignment": "left", "Alignment": null,
"Format": null, "Format": null,
"EditOrderNo": 3, "EditOrderNo": 3,
"EditGroupOrderNo": 1, "EditGroupOrderNo": 1,
@ -1372,7 +1377,7 @@
"GroupInterval": "", "GroupInterval": "",
"WordWrapEnabled": false "WordWrapEnabled": false
}, },
"Alignment": "left", "Alignment": null,
"Format": null, "Format": null,
"EditOrderNo": 4, "EditOrderNo": 4,
"EditGroupOrderNo": 1, "EditGroupOrderNo": 1,
@ -1398,6 +1403,7 @@
"App.Definitions.Approver.Title", "App.Definitions.Approver.Title",
"App.Definitions.Approver.Desc", "App.Definitions.Approver.Desc",
"App.StaticLookup.Purchase", "App.StaticLookup.Purchase",
"App.StaticLookup.PurchaseDesk",
"App.StaticLookup.Warehouse", "App.StaticLookup.Warehouse",
"App.StaticLookup.HumanResources", "App.StaticLookup.HumanResources",
"App.StaticLookup.Finance", "App.StaticLookup.Finance",
@ -1421,7 +1427,7 @@
"ModuleIds": [] "ModuleIds": []
}, },
"DevRequest": { "DevRequest": {
"Id": "fc6d0fbb-6b04-4d15-9d27-fec98e5c30fb", "Id": "53294e77-a4fb-45e4-a80e-acf07b5d75be",
"Title": "Satınalma Onaycıları" "Title": "Satınalma -> Malzeme Talepleri"
} }
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff