ListFormun birden fazla SubFormların FormReport raporu hatası giderildi.

This commit is contained in:
Sedat ÖZTÜRK 2026-10-02 12:29:22 +03:00
parent d331fb62d4
commit 5e6e3970c5
8 changed files with 29 additions and 10 deletions

View file

@ -378,7 +378,7 @@ Wizard varsayılan olarak `DefaultFieldPermissionJson(permissionName)` üretir.
| `TabType` | Sekmenin görünümü — `ListFormTabTypeEnum`: `List` \| `Card` \| `Tree` \| `Gantt` \| `Scheduler` \| `Todo` \| `Form` \| `Chart` \| `Pivot`. `Form` ana kayda bağlı **tek** kaydı gösterir: kayıt yokken "Yeni" düğmesi (hedef ekranda `AllowAdding` açıksa), kayıt varken yalnızca düzenleme; ikinci kayıt açılmaz | | `TabType` | Sekmenin görünümü — `ListFormTabTypeEnum`: `List` \| `Card` \| `Tree` \| `Gantt` \| `Scheduler` \| `Todo` \| `Form` \| `Chart` \| `Pivot`. `Form` ana kayda bağlı **tek** kaydı gösterir: kayıt yokken "Yeni" düğmesi (hedef ekranda `AllowAdding` açıksa), kayıt varken yalnızca düzenleme; ikinci kayıt açılmaz |
| `TabTitle` | Dil anahtarı | | `TabTitle` | Dil anahtarı |
| `Code` | Hedef `ListFormCode` | | `Code` | Hedef `ListFormCode` |
| `IsRefresh` | Ana kayıt değişince yenilensin | | `IsRefresh` | Ana kayıt değişince yenilensin. MCP `deploy_wizard` yeni alt form bağlantısını `false` yazar; var olan bağlantıda önceki değer korunur |
| `Relation[]` | `ParentFieldName` → `ChildFieldName` + `DbType` (`System.Data.DbType`, **sayı**; bileşik anahtarda birden çok satır) | | `Relation[]` | `ParentFieldName` → `ChildFieldName` + `DbType` (`System.Data.DbType`, **sayı**; bileşik anahtarda birden çok satır) |
Alt formun kendisi de bir ListForm'dur: `IsSubForm = true` olmalı ve genellikle `CreateMenu: Alt formun kendisi de bir ListForm'dur: `IsSubForm = true` olmalı ve genellikle `CreateMenu:

View file

@ -1849,7 +1849,7 @@ Wizard Manager'daki talep silmesini kullanır.
"TabType": "List", // List|Card|Tree|Gantt|Scheduler|Todo|Form|Chart|Pivot "TabType": "List", // List|Card|Tree|Gantt|Scheduler|Todo|Form|Chart|Pivot
"TabTitle": "App.Mrp.OrderItems", // dil anahtarı "TabTitle": "App.Mrp.OrderItems", // dil anahtarı
"Code": "App.Mrp.OrderItems", // hedef ListFormCode "Code": "App.Mrp.OrderItems", // hedef ListFormCode
"IsRefresh": true, // ana kayıt değişince yenilensin "IsRefresh": false, // ana kayıt değişince yenilensin; MCP yeni bağlantıda false yazar
"Relation": [ "Relation": [
{ "ParentFieldName": "Id", "ChildFieldName": "OrderId", "DbType": 11 } { "ParentFieldName": "Id", "ChildFieldName": "OrderId", "DbType": 11 }
] ]

View file

@ -211,9 +211,18 @@ public class McpDevelopAppService(
// Menu sirasi modelin karari degildir: yeni ekran kardeslerinin sonuna eklenir (deploy // Menu sirasi modelin karari degildir: yeni ekran kardeslerinin sonuna eklenir (deploy
// bagimlilik sirasiyla yapildigi icin lookup kaynagi tuketen ekranin ustunde kalir), // bagimlilik sirasiyla yapildigi icin lookup kaynagi tuketen ekranin ustunde kalir),
// guncelleme ekranin mevcut yerini korur. // guncelleme ekranin mevcut yerini korur.
wizard.MenuOrder = wizard.EditFileName is null var previous = wizard.EditFileName is null ? null : (await wizardAppService.GetFile(wizard.EditFileName)).Wizard;
? 0 wizard.MenuOrder = previous?.MenuOrder ?? 0;
: (await wizardAppService.GetFile(wizard.EditFileName)).Wizard?.MenuOrder ?? 0;
// Alt form sekmesi ana kayit her degistiginde yeniden sorgulanmaz; MCP yeni baglanti
// acarken yenilemeyi kapali yazar. Var olan baglantida kullanicinin ekrandan verdigi
// deger korunur.
var previousRefresh = (previous?.SubForms ?? [])
.Where(subForm => !string.IsNullOrWhiteSpace(subForm.Code))
.GroupBy(subForm => subForm.Code, StringComparer.OrdinalIgnoreCase)
.ToDictionary(group => group.Key, group => group.First().IsRefresh, StringComparer.OrdinalIgnoreCase);
foreach (var subForm in wizard.SubForms ?? [])
subForm.IsRefresh = subForm.Code is not null && previousRefresh.GetValueOrDefault(subForm.Code);
// Tek gruplu duzenleme formunda grup basligi popup basligini tekrarlar; baslik yalnizca // Tek gruplu duzenleme formunda grup basligi popup basligini tekrarlar; baslik yalnizca
// birden fazla grubu birbirinden ayirmak icin yazilir. // birden fazla grubu birbirinden ayirmak icin yazilir.

View file

@ -27,6 +27,11 @@ public class MsDynamicDataRepository : IDynamicDataRepository, IScopedDependency
private readonly HashSet<string> _registeredConnections; private readonly HashSet<string> _registeredConnections;
private readonly object _lock = new object(); private readonly object _lock = new object();
// Bağlantı ve transaction bu örneğe aittir ve kapsamı kapanınca dispose edilir; aynı UoW içinde
// ikinci bir DI kapsamı (ör. form raporunun alt form raporları) aynı anahtarla AddTransactionApi
// çağırıp UoW'yi reddettirmesin diye anahtar örneğe özgüdür.
private readonly string _instanceId = Guid.NewGuid().ToString("N");
public bool IsDisposed { get; private set; } public bool IsDisposed { get; private set; }
public MsDynamicDataRepository( public MsDynamicDataRepository(
@ -45,7 +50,7 @@ public class MsDynamicDataRepository : IDynamicDataRepository, IScopedDependency
private string BuildKey(string cs) private string BuildKey(string cs)
{ {
var uowId = _unitOfWorkManager.Current?.GetHashCode() ?? 0; var uowId = _unitOfWorkManager.Current?.GetHashCode() ?? 0;
return $"Dapper_{uowId}_{cs}"; return $"Dapper_{uowId}_{_instanceId}_{cs}";
} }
private async Task<SqlConnection> GetOrCreateConnectionAsync(string cs) private async Task<SqlConnection> GetOrCreateConnectionAsync(string cs)

View file

@ -27,6 +27,11 @@ public class PgDynamicDataRepository : IDynamicDataRepository, IScopedDependency
private readonly HashSet<string> _registeredConnections; private readonly HashSet<string> _registeredConnections;
private readonly object _lock = new object(); private readonly object _lock = new object();
// Bağlantı ve transaction bu örneğe aittir ve kapsamı kapanınca dispose edilir; aynı UoW içinde
// ikinci bir DI kapsamı (ör. form raporunun alt form raporları) aynı anahtarla AddTransactionApi
// çağırıp UoW'yi reddettirmesin diye anahtar örneğe özgüdür.
private readonly string _instanceId = Guid.NewGuid().ToString("N");
public bool IsDisposed { get; private set; } public bool IsDisposed { get; private set; }
public PgDynamicDataRepository( public PgDynamicDataRepository(
@ -44,7 +49,7 @@ public class PgDynamicDataRepository : IDynamicDataRepository, IScopedDependency
private string BuildKey(string cs) private string BuildKey(string cs)
{ {
var uowId = _unitOfWorkManager.Current?.GetHashCode() ?? 0; var uowId = _unitOfWorkManager.Current?.GetHashCode() ?? 0;
return $"Dapper_{uowId}_{cs}"; return $"Dapper_{uowId}_{_instanceId}_{cs}";
} }
private async Task<NpgsqlConnection> GetOrCreateConnectionAsync(string cs) private async Task<NpgsqlConnection> GetOrCreateConnectionAsync(string cs)

View file

@ -701,7 +701,7 @@ public class DynamicFormReport : XtraReport
var lookup = DynamicReportImageHelper.GetLookup(field); var lookup = DynamicReportImageHelper.GetLookup(field);
var isMultiValue = IsMultiValueLookupEditor(editorType); var isMultiValue = IsMultiValueLookupEditor(editorType);
if (lookup == null || selectField?.JoinOptions != null) if (lookup == null || selectField?.IsJoined == true)
{ {
return new FormReportField(field, bindingName, editorType, columnSpan, null, null, isMultiValue, DynamicReportImageHelper.IsImageEditor(editorType)); return new FormReportField(field, bindingName, editorType, columnSpan, null, null, isMultiValue, DynamicReportImageHelper.IsImageEditor(editorType));
} }

View file

@ -44,7 +44,7 @@ internal static class DynamicReportColumnFactory
var isImage = DynamicReportImageHelper.IsImageEditor(editorType); var isImage = DynamicReportImageHelper.IsImageEditor(editorType);
var isHtml = editorType == PlatformConsts.EditorTypes.dxHtmlEditor; var isHtml = editorType == PlatformConsts.EditorTypes.dxHtmlEditor;
if (lookup == null || selectField?.JoinOptions != null) if (lookup == null || selectField?.IsJoined == true)
{ {
return new DynamicReportColumn(field, bindingName, null, null, isMultiValue, isImage, isHtml, editorType); return new DynamicReportColumn(field, bindingName, null, null, isMultiValue, isImage, isHtml, editorType);
} }

View file

@ -95,7 +95,7 @@ internal static class DynamicReportImageHelper
public static string GetReportFieldName(SelectField selectField) public static string GetReportFieldName(SelectField selectField)
{ {
if (selectField?.JoinOptions != null && !string.IsNullOrWhiteSpace(selectField.JoinOptions.FieldNameAlias)) if (selectField?.IsJoined == true && !string.IsNullOrWhiteSpace(selectField.JoinOptions.FieldNameAlias))
{ {
return selectField.JoinOptions.FieldNameAlias; return selectField.JoinOptions.FieldNameAlias;
} }