Merge branch 'FruitBank_v0.0.8.2' of https://git.aycode.com/Adam/Mango.Nop.Plugins into FruitBank_v0.0.8.2
This commit is contained in:
@@ -6,7 +6,7 @@ This file is injected by the host. **Before answering anything, read `.github/LL
|
||||
|
||||
Every response begins with the `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files (+K this turn: <short names>)]` prefix — `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files, no new loads]` when nothing new. The timestamp is the present time, obtained in this turn; `no clock` only where the clock cannot be read. Semantics in `BASE:CONTEXT_LEDGER`.
|
||||
|
||||
After any context compaction or session summary, `[LOADED_DOCS]` is `NONE` — the count survives compaction, the file contents do not. Run Session Setup again before answering: a continuation instruction resumes the task, never the context.
|
||||
`[LOADED_DOCS]` counts only what a tool call in the visible conversation loaded. A summary or a compaction is not a tool call: after one the ledger is `NONE`, whatever the previous prefix claimed. The first response of a context runs Session Setup and names the loaded files in `+K`; a context's first prefix never says `no new loads`. A continuation instruction resumes the task, never the context.
|
||||
|
||||
## Sequential execution
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ CRITICAL: Your FIRST action in every session is the bootstrap chain below. Compl
|
||||
|
||||
Every response begins with the `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files (+K this turn: <short names>)]` prefix — `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files, no new loads]` when nothing new. The timestamp is the present time, obtained in this turn; `no clock` only where the clock cannot be read. Semantics in `BASE:CONTEXT_LEDGER`.
|
||||
|
||||
After any context compaction or session summary, `[LOADED_DOCS]` is `NONE` — the count survives compaction, the file contents do not. Run Session Setup again before answering: a continuation instruction resumes the task, never the context.
|
||||
`[LOADED_DOCS]` counts only what a tool call in the visible conversation loaded. A summary or a compaction is not a tool call: after one the ledger is `NONE`, whatever the previous prefix claimed. The first response of a context runs Session Setup and names the loaded files in `+K`; a context's first prefix never says `no new loads`. A continuation instruction resumes the task, never the context.
|
||||
|
||||
## Sequential execution
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ CRITICAL: Your FIRST action in every session is the bootstrap chain below. Compl
|
||||
|
||||
Every response begins with the `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files (+K this turn: <short names>)]` prefix — `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files, no new loads]` when nothing new. The timestamp is the present time, obtained in this turn; `no clock` only where the clock cannot be read. Semantics in `BASE:CONTEXT_LEDGER`.
|
||||
|
||||
After any context compaction or session summary, `[LOADED_DOCS]` is `NONE` — the count survives compaction, the file contents do not. Run Session Setup again before answering: a continuation instruction resumes the task, never the context.
|
||||
`[LOADED_DOCS]` counts only what a tool call in the visible conversation loaded. A summary or a compaction is not a tool call: after one the ledger is `NONE`, whatever the previous prefix claimed. The first response of a context runs Session Setup and names the loaded files in `+K`; a context's first prefix never says `no new loads`. A continuation instruction resumes the task, never the context.
|
||||
|
||||
## Sequential execution
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ This file is injected by the host. **Before answering anything, read `.github/LL
|
||||
|
||||
Every response begins with the `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files (+K this turn: <short names>)]` prefix — `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files, no new loads]` when nothing new. The timestamp is the present time, obtained in this turn; `no clock` only where the clock cannot be read. Semantics in `BASE:CONTEXT_LEDGER`.
|
||||
|
||||
After any context compaction or session summary, `[LOADED_DOCS]` is `NONE` — the count survives compaction, the file contents do not. Run Session Setup again before answering: a continuation instruction resumes the task, never the context.
|
||||
`[LOADED_DOCS]` counts only what a tool call in the visible conversation loaded. A summary or a compaction is not a tool call: after one the ledger is `NONE`, whatever the previous prefix claimed. The first response of a context runs Session Setup and names the loaded files in `+K`; a context's first prefix never says `no new loads`. A continuation instruction resumes the task, never the context.
|
||||
|
||||
## Sequential execution
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ CRITICAL: Your FIRST action in every session is the bootstrap chain below. Compl
|
||||
|
||||
Every response begins with the `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files (+K this turn: <short names>)]` prefix — `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files, no new loads]` when nothing new. The timestamp is the present time, obtained in this turn; `no clock` only where the clock cannot be read. Semantics in `BASE:CONTEXT_LEDGER`.
|
||||
|
||||
After any context compaction or session summary, `[LOADED_DOCS]` is `NONE` — the count survives compaction, the file contents do not. Run Session Setup again before answering: a continuation instruction resumes the task, never the context.
|
||||
`[LOADED_DOCS]` counts only what a tool call in the visible conversation loaded. A summary or a compaction is not a tool call: after one the ledger is `NONE`, whatever the previous prefix claimed. The first response of a context runs Session Setup and names the loaded files in `+K`; a context's first prefix never says `no new loads`. A continuation instruction resumes the task, never the context.
|
||||
|
||||
## Sequential execution
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ CRITICAL: Your FIRST action in every session is the bootstrap chain below. Compl
|
||||
|
||||
Every response begins with the `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files (+K this turn: <short names>)]` prefix — `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files, no new loads]` when nothing new. The timestamp is the present time, obtained in this turn; `no clock` only where the clock cannot be read. Semantics in `BASE:CONTEXT_LEDGER`.
|
||||
|
||||
After any context compaction or session summary, `[LOADED_DOCS]` is `NONE` — the count survives compaction, the file contents do not. Run Session Setup again before answering: a continuation instruction resumes the task, never the context.
|
||||
`[LOADED_DOCS]` counts only what a tool call in the visible conversation loaded. A summary or a compaction is not a tool call: after one the ledger is `NONE`, whatever the previous prefix claimed. The first response of a context runs Session Setup and names the loaded files in `+K`; a context's first prefix never says `no new loads`. A continuation instruction resumes the task, never the context.
|
||||
|
||||
## Sequential execution
|
||||
|
||||
|
||||
@@ -542,12 +542,10 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers
|
||||
|
||||
// Partner/dokumentum nélküli allocation CSENDBEN kihagyva — nincs feladó, nem kész; a mentes partner
|
||||
// (IsEkaer=false) is. A maradék (Shipping=allocation.ShippingId, Partner, PartnerDepot) csoportban.
|
||||
// A csoportok ShippingDate szerint növekvő sorrendben kerülnek beszúrásra, hogy a keletkező Id-sorrend
|
||||
// kronologikus legyen (a grid irányonként szűrve így dátum szerint rendezetten mutatja őket).
|
||||
// A sorrend itt közömbös: mindkét ág csak GYŰJT, a beszúrás egyetlen közös ciklusban rendez (lásd lentebb).
|
||||
foreach (var group in candidates
|
||||
.Where(a => a.ShippingItem?.ShippingDocument?.Partner != null && a.ShippingItem.ShippingDocument.Partner!.IsEkaer != false)
|
||||
.GroupBy(a => (a.ShippingId, a.ShippingItem!.ShippingDocument!.PartnerId, a.ShippingItem.ShippingDocument.PartnerDepotId))
|
||||
.OrderBy(g => g.Min(a => a.ShippingItem!.ShippingDocument!.ShippingDate)))
|
||||
.GroupBy(a => (a.ShippingId, a.ShippingItem!.ShippingDocument!.PartnerId, a.ShippingItem.ShippingDocument.PartnerDepotId)))
|
||||
{
|
||||
var allocs = group.ToList();
|
||||
var doc0 = allocs[0].ShippingItem!.ShippingDocument!;
|
||||
@@ -616,8 +614,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers
|
||||
.ToListAsync())
|
||||
.ToDictionary(ga => ga.EntityId, ga => CommonHelper.To<bool>(ga.Value));
|
||||
|
||||
// DateOfReceipt szerint növekvő — ugyanaz a kronologikus Id-sorrend, mint a bejövő ágon.
|
||||
foreach (var order in missingOrders.OrderBy(o => o.DateOfReceipt))
|
||||
foreach (var order in missingOrders)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -639,8 +636,13 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers
|
||||
}
|
||||
|
||||
// ── Beszúrás ──
|
||||
// A KÉT IRÁNY EGYÜTT rendeződik dátum szerint, mert a beszúrási sorrend adja az Id-ket, és a grid
|
||||
// alapértelmezett nézete Id szerint áll. Ágakon belül rendezve a lista irány-, majd dátum-rendezett
|
||||
// lenne — ezért a rendezés itt van, a közös találkozási ponton, nem a két gyűjtő ágban.
|
||||
// A ShippingDate nullable, de egyik ág sem tud null-t adni: bejövőn a forrás-oszlop nem nullable,
|
||||
// kimenőn a jelölt-szűrő megköveteli az értelmezhető DateOfReceipt attribútumot.
|
||||
var createdCount = 0;
|
||||
foreach (var (history, foreignKeys) in toCreate)
|
||||
foreach (var (history, foreignKeys) in toCreate.OrderBy(x => x.History.ShippingDate))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1463,14 +1465,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers
|
||||
return await ctx.ProductDtos.GetAll(false).ToListAsync();
|
||||
}
|
||||
|
||||
//[SignalR(SignalRTags.GetAllMeasuringProductDtos)]
|
||||
//public async Task<List<MeasuringProductDto>> GetAllMeasuringProductDtos()
|
||||
//{
|
||||
// _logger.Detail($"GetAllMeasuringProductDtos invoked");
|
||||
// return await ctx.GetAllMeasuringProductDtos(false).ToListAsync();
|
||||
//}
|
||||
|
||||
[SignalR(SignalRTags.GetMeasuringProductDtoById)]
|
||||
[SignalR(SignalRTags.GetProductDtoById)]
|
||||
public async Task<ProductDto?> GetProductDtoById(int productId)
|
||||
{
|
||||
_logger.Detail($"GetProductDtoById invoked; productId: {productId}");
|
||||
|
||||
@@ -26,12 +26,20 @@ public class EkaerHistoryDbTable : MgDbTableBase<EkaerHistory>
|
||||
// miatt már nem IOrderedQueryable) → explicit a LinqToDB-é, ugyanúgy mint a CountByFilterAsync-nél.
|
||||
public Task<EkaerHistory> GetByIdAsync(int id, bool loadRelations) => LinqToDB.AsyncExtensions.FirstOrDefaultAsync(GetAll(loadRelations), p => p.Id == id);
|
||||
|
||||
// A NAV-nál lévő partíciók fix StatusId-k; minden más (a jövőbeni új státuszok is) „beküldésre váró".
|
||||
private static readonly int[] ToSubmitStatusIds = [.. Enum.GetValues<EkaerStatus>().Select(s => (int)s).Except([(int)EkaerStatus.Sent, (int)EkaerStatus.SentWithMissingData])];
|
||||
// A partíciók a státusz-kategóriákból SZÁRMAZNAK, nem felsorolásból: egy új EkaerStatus így automatikusan oda
|
||||
// kerül, ahová a helpere sorolja. Felsorolva a kimaradása néma lenne — egy NAV-nál lévő új állapot a
|
||||
// „beküldésre váró" fülre esne, hiba nélkül. A kiértékelés memóriában, típus-inicializáláskor fut egyszer.
|
||||
private static readonly int[] ToSubmitStatusIds = StatusIdsWhere(s => !s.IsSent());
|
||||
private static readonly int[] ClosedStatusIds = StatusIdsWhere(s => s.IsClosed());
|
||||
private static readonly int[] OpenAtNavStatusIds = StatusIdsWhere(s => s.IsOpenAtNav());
|
||||
|
||||
private static int[] StatusIdsWhere(Func<EkaerStatus, bool> predicate)
|
||||
=> [.. Enum.GetValues<EkaerStatus>().Where(predicate).Select(s => (int)s)];
|
||||
|
||||
/// <summary>Flag-alapú szűrés a tabokhoz/count-hoz. <see cref="EkaerHistoryFilter.All"/> (= 0) → minden;
|
||||
/// egyébként a beállított flag-ek diszjunkt StatusId-partícióinak UNIÓJA (IN). A státusz-helperek (IsSent stb.)
|
||||
/// nem fordulnak SQL-re, ezért közvetlen StatusId-halmazzal szűrünk.</summary>
|
||||
/// egyébként a beállított flag-ek diszjunkt StatusId-partícióinak UNIÓJA (IN). A státusz-helperek nem
|
||||
/// fordulnak SQL-re, ezért a szűrés kész StatusId-halmazzal megy — a halmazokat viszont ugyanazok a
|
||||
/// helperek állítják elő (fent), így a partíciók egyetlen forrásból következnek.</summary>
|
||||
public IQueryable<EkaerHistory> GetByFilter(EkaerHistoryFilter filter, bool loadRelations)
|
||||
{
|
||||
// HasFlag(All) mindig true (0 bit), ezért előbb az All-ágat zárjuk rövidre.
|
||||
@@ -39,8 +47,8 @@ public class EkaerHistoryDbTable : MgDbTableBase<EkaerHistory>
|
||||
|
||||
var statusIds = new List<int>();
|
||||
if (filter.HasFlag(EkaerHistoryFilter.ToSubmit)) statusIds.AddRange(ToSubmitStatusIds);
|
||||
if (filter.HasFlag(EkaerHistoryFilter.Sent)) statusIds.Add((int)EkaerStatus.Sent);
|
||||
if (filter.HasFlag(EkaerHistoryFilter.NeedsCompletion)) statusIds.Add((int)EkaerStatus.SentWithMissingData);
|
||||
if (filter.HasFlag(EkaerHistoryFilter.Closed)) statusIds.AddRange(ClosedStatusIds);
|
||||
if (filter.HasFlag(EkaerHistoryFilter.OpenAtNav)) statusIds.AddRange(OpenAtNavStatusIds);
|
||||
|
||||
return GetAll(loadRelations).Where(eh => statusIds.Contains(eh.StatusId));
|
||||
}
|
||||
|
||||
@@ -208,12 +208,6 @@ public class FruitBankDbContext : MgDbContextBase,
|
||||
//public IQueryable<ProductDto> GetAllProductDtos(bool includeDeleted)
|
||||
// => GetAllProducts(includeDeleted).Select(product => new ProductDto(product));
|
||||
|
||||
//public IAsyncEnumerable<MeasuringProductDto> GetAllMeasuringProductDtos(bool includeDeleted)
|
||||
// => GetAllProducts(includeDeleted).AsEnumerable().SelectAwait(async product => new MeasuringProductDto(product, await GetMeasuringAttributeValuesByProductIdAsync(product.Id)));
|
||||
|
||||
//public async Task<MeasuringProductDto?> GetMeasuringProductDtoByIdAsync(int productId)
|
||||
// => await Products.Table.Where(product => product.Id == productId).AsEnumerable().SelectAwait(async product => new MeasuringProductDto(product, await GetMeasuringAttributeValuesByProductIdAsync(product.Id))).FirstOrDefaultAsync();
|
||||
|
||||
//public async Task<MeasuringAttributeValues?> GetMeasuringAttributeValuesByProductIdAsync(int productId)
|
||||
// => await _fruitBankAttributeService.GetMeasuringAttributeValuesAsync<Product>(productId);
|
||||
|
||||
|
||||
@@ -214,7 +214,8 @@ public class PluginNopStartup : INopStartup
|
||||
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { SslProtocols = SslProtocols.Tls12 }); // a NAV TLS 1.2-t vár
|
||||
|
||||
// Ellenőrző végpont: a generáláskor fut, bejelentést NEM hoz létre (validateTradeCardRequest).
|
||||
services.AddHttpClient<EkaerValidateService>()
|
||||
// Interfészen át, mint a beküldő párja — így a NAV-határ mindkét fele kicserélhető (teszt-dublúra).
|
||||
services.AddHttpClient<IEkaerValidateService, EkaerValidateService>()
|
||||
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { SslProtocols = SslProtocols.Tls12 });
|
||||
|
||||
// A NAV-fiók hitelesítő adatai + a saját telephely/raktár — konfigurációból (appsettings "Ekaer" szekció).
|
||||
@@ -264,6 +265,7 @@ public class PluginNopStartup : INopStartup
|
||||
// A NAV a street+streetNumber PÁRT követeli (vagy lotNumber-t) — csak utcanévvel
|
||||
// TC_LOCATION_NOT_COMPLETE-et ad.
|
||||
Street = site["Street"],
|
||||
StreetType = site["StreetType"],
|
||||
StreetNumber = site["StreetNumber"],
|
||||
Phone = co["Phone"],
|
||||
Email = co["Email"],
|
||||
|
||||
@@ -51,6 +51,7 @@ Validációs hiba → **hibalista** (`EkaerSubmitResult.Invalid`), nem megy ki k
|
||||
| `vehicle` / `vehicle2` | `Shipping.CargoTruck` / `CargoTrailer` (`LicencePlate` + `CountrySign` — a felségjel, NEM ISO-2 országkód; normalizálva) |
|
||||
| `loadLocation` (felrakodás) | **bejövő:** a `ShippingDocument.PartnerDepot` **címe** (kötelező — **T-D8R4** kész; a `VatNumber` a Partneré, a depot `TaxId`-ja passthrough); **kimenő:** `company.Site` (configból) |
|
||||
| `unloadLocation` (lerakodás) | **bejövő:** `company.Site`; **kimenő:** az `order.Site` snapshot (fallback: a vevő fő címe) |
|
||||
| a cím **mezői** (`street` / `streetType` / `streetNumber`, vagy helyette `lotNumber`) | `company.Site`: külön config-kulcsok (`Ekaer:Company:Site`), tehát a `streetType` is töltve. Partner/depot és vevő: **egyetlen** szabad szöveges utca-mező, amit a `NavAddress.SplitStreet` bont utcára és házszámra — a `streetType` ott üresen marad. |
|
||||
| tétel `productVtsz` | `ShippingItem.ProductDto.Gtin` (átmenetileg — lásd `EKAER_ISSUES.md`) |
|
||||
| tétel `productName` | `ShippingItem.ProductName` (a VTSZ-szerinti csoportosítás + a csoport-név `Category`-ből: TODO **T-V9G3**) |
|
||||
| tétel `weight` | `ShippingItem.GrossWeightOnDocument` — a **szállítólevélen szereplő** bruttó (a bejelentés a kísérő dokumentum adatairól megy, mint a value; NEM a későbbi mérlegelésről) |
|
||||
|
||||
@@ -101,7 +101,7 @@ a felület azelőtt, hogy a tárolás átállna.
|
||||
|
||||
## Decision
|
||||
|
||||
> **An ADR records reasoning, not the state. What is true now is in the docs.**
|
||||
> **An ADR records reasoning, not the state, and binds nothing — `BASE:ARTIFACT_ROLES`.**
|
||||
|
||||
**Az öt érték elsőrendű, tipizált oszloppá válik egy új, plugin-tulajdonú `ProductMasterData` táblában (1:1 a
|
||||
`Product`-tal), nem pedig a nopCommerce `Product` táblájának bővítésével; a `GenericAttribute`-os tárolás
|
||||
|
||||
@@ -56,7 +56,7 @@ ratifikálásig `Proposed`. Az implementáció állapotát a horgony-bejegyzés
|
||||
|
||||
## Decision
|
||||
|
||||
> **An ADR records reasoning, not the state. What is true now is in the docs.**
|
||||
> **An ADR records reasoning, not the state, and binds nothing — `BASE:ARTIFACT_ROLES`.**
|
||||
|
||||
**A nyereség-kimutatás alapegysége a `ShippingDocument`, a költség-réteg kulcsa a `ShippingItem`; a rendelés-tételek
|
||||
FIFO-val fogyasztják a rétegeket; a fogyasztott mennyiségen kívül semmilyen pénzügyi érték nem tárolódik —
|
||||
|
||||
@@ -6,7 +6,7 @@ This file is injected by the host. **Before answering anything, read `.github/LL
|
||||
|
||||
Every response begins with the `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files (+K this turn: <short names>)]` prefix — `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files, no new loads]` when nothing new. The timestamp is the present time, obtained in this turn; `no clock` only where the clock cannot be read. Semantics in `BASE:CONTEXT_LEDGER`.
|
||||
|
||||
After any context compaction or session summary, `[LOADED_DOCS]` is `NONE` — the count survives compaction, the file contents do not. Run Session Setup again before answering: a continuation instruction resumes the task, never the context.
|
||||
`[LOADED_DOCS]` counts only what a tool call in the visible conversation loaded. A summary or a compaction is not a tool call: after one the ledger is `NONE`, whatever the previous prefix claimed. The first response of a context runs Session Setup and names the loaded files in `+K`; a context's first prefix never says `no new loads`. A continuation instruction resumes the task, never the context.
|
||||
|
||||
## Sequential execution
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ CRITICAL: Your FIRST action in every session is the bootstrap chain below. Compl
|
||||
|
||||
Every response begins with the `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files (+K this turn: <short names>)]` prefix — `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files, no new loads]` when nothing new. The timestamp is the present time, obtained in this turn; `no clock` only where the clock cannot be read. Semantics in `BASE:CONTEXT_LEDGER`.
|
||||
|
||||
After any context compaction or session summary, `[LOADED_DOCS]` is `NONE` — the count survives compaction, the file contents do not. Run Session Setup again before answering: a continuation instruction resumes the task, never the context.
|
||||
`[LOADED_DOCS]` counts only what a tool call in the visible conversation loaded. A summary or a compaction is not a tool call: after one the ledger is `NONE`, whatever the previous prefix claimed. The first response of a context runs Session Setup and names the loaded files in `+K`; a context's first prefix never says `no new loads`. A continuation instruction resumes the task, never the context.
|
||||
|
||||
## Sequential execution
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ CRITICAL: Your FIRST action in every session is the bootstrap chain below. Compl
|
||||
|
||||
Every response begins with the `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files (+K this turn: <short names>)]` prefix — `[LOADED_DOCS: YYYY-MM-DD HH:mm · N files, no new loads]` when nothing new. The timestamp is the present time, obtained in this turn; `no clock` only where the clock cannot be read. Semantics in `BASE:CONTEXT_LEDGER`.
|
||||
|
||||
After any context compaction or session summary, `[LOADED_DOCS]` is `NONE` — the count survives compaction, the file contents do not. Run Session Setup again before answering: a continuation instruction resumes the task, never the context.
|
||||
`[LOADED_DOCS]` counts only what a tool call in the visible conversation loaded. A summary or a compaction is not a tool call: after one the ledger is `NONE`, whatever the previous prefix claimed. The first response of a context runs Session Setup and names the loaded files in `+K`; a context's first prefix never says `no new loads`. A continuation instruction resumes the task, never the context.
|
||||
|
||||
## Sequential execution
|
||||
|
||||
|
||||
Reference in New Issue
Block a user