xml download
This commit is contained in:
parent
0638c89989
commit
169f7fc133
|
|
@ -21,9 +21,22 @@ public sealed class PreOrder : MgEntityBase
|
|||
[ToonDescription(Purpose = "Requested delivery date. Drives the conversion window (only preorders within PreOrderConversionWindowDays — 4 days — of this date are eligible for allocation) and the expiry sweep — once this date is past, any still-Pending items are Dropped.")]
|
||||
public DateTime DateOfReceipt { get; set; }
|
||||
|
||||
// Persisted as an int column ("Status"). A raw enum property is NOT mapped/written by the
|
||||
// nopCommerce LinqToDB stack (nop stores enums as int + a [NotMapped] wrapper — cf. Order.OrderStatusId),
|
||||
// so writing the enum directly left the column stuck at 0. StatusId is the real mapped column;
|
||||
// the Status wrapper below is the typed API.
|
||||
[Column("Status")]
|
||||
[ToonDescription(Purpose = "Header lifecycle status, stored as int. See the Status wrapper for the enum semantics.")]
|
||||
public int StatusId { get; set; }
|
||||
|
||||
[NotColumn, System.ComponentModel.DataAnnotations.Schema.NotMapped]
|
||||
[ToonDescription(Purpose = "Header lifecycle: Pending / Confirmed (all items Fulfilled) / PartiallyFulfilled (some Dropped or partial, none left Pending) / Cancelled.",
|
||||
BusinessRule = "set by RefreshPreOrderStatusAsync from item states: items.All(Fulfilled) => Confirmed; (any Dropped or PartiallyFulfilled) && none Pending => PartiallyFulfilled; else Pending. Cancelled is set explicitly.")]
|
||||
public PreOrderStatus Status { get; set; }
|
||||
BusinessRule = "set by RefreshPreOrderStatusAsync from item states: items.All(Fulfilled) => Confirmed; (any Dropped or PartiallyFulfilled) && none Pending => PartiallyFulfilled; else Pending. Cancelled is set explicitly. Persisted via StatusId.")]
|
||||
public PreOrderStatus Status
|
||||
{
|
||||
get => (PreOrderStatus)StatusId;
|
||||
set => StatusId = (int)value;
|
||||
}
|
||||
|
||||
[ToonDescription(Purpose = "Optional free-text note entered by the customer when placing the preorder.")]
|
||||
public string? CustomerNote { get; set; }
|
||||
|
|
|
|||
|
|
@ -29,7 +29,19 @@ public sealed class PreOrderItem : MgEntityBase
|
|||
Constraints = "non-negative")]
|
||||
public decimal UnitPriceInclTax { get; set; }
|
||||
|
||||
// Persisted as an int column ("Status"). A raw enum property is NOT mapped/written by the
|
||||
// nopCommerce LinqToDB stack, so writing the enum directly left the column stuck at 0.
|
||||
// StatusId is the real mapped column; the Status wrapper below is the typed API.
|
||||
[Column("Status")]
|
||||
[ToonDescription(Purpose = "Item lifecycle status, stored as int. See the Status wrapper for the enum semantics.")]
|
||||
public int StatusId { get; set; }
|
||||
|
||||
[NotColumn, System.ComponentModel.DataAnnotations.Schema.NotMapped]
|
||||
[ToonDescription(Purpose = "Item lifecycle: Pending / Fulfilled (fully allocated) / PartiallyFulfilled (partly allocated) / Dropped (expired or no incoming stock).",
|
||||
BusinessRule = "set during conversion: FulfilledQuantity >= RequestedQuantity ? Fulfilled : FulfilledQuantity > 0 ? PartiallyFulfilled : Dropped; stays Pending until first allocation")]
|
||||
public PreOrderItemStatus Status { get; set; }
|
||||
BusinessRule = "set during conversion: FulfilledQuantity >= RequestedQuantity ? Fulfilled : FulfilledQuantity > 0 ? PartiallyFulfilled : Dropped; stays Pending until first allocation. Persisted via StatusId.")]
|
||||
public PreOrderItemStatus Status
|
||||
{
|
||||
get => (PreOrderItemStatus)StatusId;
|
||||
set => StatusId = (int)value;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,12 +83,12 @@
|
|||
Enabled="@(CanGenerate(row))"
|
||||
Attributes="@(new Dictionary<string, object> { ["title"] = row.ErrorText ?? "EKÁER XML generálása és validálása" })"
|
||||
Click="async () => await OnGenerateClick(row)" />
|
||||
<DxButton Text="Copy"
|
||||
<DxButton Text="Letöltés"
|
||||
SizeMode="SizeMode.Small"
|
||||
RenderStyle="ButtonRenderStyle.Secondary"
|
||||
Enabled="@(CanCopy(row))"
|
||||
Attributes="@(new Dictionary<string, object> { ["title"] = CanCopy(row) ? "A generált XML vágólapra másolása (kézi NAV-beadáshoz)" : "Hibás bejelentés nem másolható — javítsd az adatokat és generáld újra." })"
|
||||
Click="async () => await OnCopyClick(row)" />
|
||||
Enabled="@(CanDownload(row))"
|
||||
Attributes="@(new Dictionary<string, object> { ["title"] = CanDownload(row) ? "A generált XML letöltése fájlként (kézi NAV-beadáshoz)" : "Hibás bejelentés nem tölthető le — javítsd az adatokat és generáld újra." })"
|
||||
Click="async () => await OnDownloadClick(row)" />
|
||||
}
|
||||
</CellDisplayTemplate>
|
||||
</DxGridDataColumn>
|
||||
|
|
@ -215,8 +215,8 @@
|
|||
private bool CanGenerate(EkaerHistory ekaerHistory)
|
||||
=> !ekaerHistory.Status.IsSent() && !_generatingIds.Contains(ekaerHistory.Id);
|
||||
|
||||
// Csak BLOKKOLÓ hiba (ValidationError) esetén NEM másolható; a warning (pl. hiányzó rendszám) küldhető → másolható.
|
||||
private static bool CanCopy(EkaerHistory ekaerHistory)
|
||||
// Csak BLOKKOLÓ hiba (ValidationError) esetén NEM tölthető le; a warning (pl. hiányzó rendszám) küldhető → letölthető.
|
||||
private static bool CanDownload(EkaerHistory ekaerHistory)
|
||||
=> ekaerHistory.Status.IsSubmittable() && !string.IsNullOrWhiteSpace(ekaerHistory.XmlDoc);
|
||||
|
||||
// A szülő-oldal (fül-számlálók) értesítése egy státuszt érintő művelet után. Üres delegáltnál no-op.
|
||||
|
|
@ -297,17 +297,25 @@
|
|||
await DialogService.ShowMessageBoxAsync("EKÁER — kihagyott tételek", string.Join(Environment.NewLine, skipped), MessageBoxRenderStyle.Warning);
|
||||
}
|
||||
|
||||
private async Task OnCopyClick(EkaerHistory ekaerHistory)
|
||||
private async Task OnDownloadClick(EkaerHistory ekaerHistory)
|
||||
{
|
||||
if (!CanCopy(ekaerHistory)) return;
|
||||
if (!CanDownload(ekaerHistory)) return;
|
||||
|
||||
// Fájlnév: "yyyy.MM.dd-Partner.xml" — a partnernévből az érvénytelen fájlnév-karaktereket kicseréljük.
|
||||
var datePart = ekaerHistory.ShippingDate?.ToString("yyyy.MM.dd") ?? "nincs-datum";
|
||||
var partner = string.IsNullOrWhiteSpace(ekaerHistory.Partner) ? "partner" : ekaerHistory.Partner;
|
||||
var invalid = System.IO.Path.GetInvalidFileNameChars();
|
||||
var safePartner = new string(partner.Select(c => invalid.Contains(c) ? '_' : c).ToArray()).Trim();
|
||||
if (string.IsNullOrWhiteSpace(safePartner)) safePartner = "partner";
|
||||
var fileName = $"{datePart}-{safePartner}.xml";
|
||||
|
||||
try
|
||||
{
|
||||
await JS.InvokeVoidAsync("navigator.clipboard.writeText", ekaerHistory.XmlDoc);
|
||||
await JS.InvokeVoidAsync("downloadFileFromText", fileName, ekaerHistory.XmlDoc, "application/xml");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"XmlDoc vágólapra másolása sikertelen; EkaerHistory.Id: {ekaerHistory.Id}", ex);
|
||||
_logger.Error($"XmlDoc letöltése sikertelen; EkaerHistory.Id: {ekaerHistory.Id}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
// Triggers a client-side file download from in-memory text (no server round-trip).
|
||||
// Used e.g. by the EKÁER grid to save the generated trade-card XML as a file.
|
||||
window.downloadFileFromText = function (filename, content, mime) {
|
||||
try {
|
||||
const blob = new Blob([content], { type: mime || 'application/octet-stream' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = filename || 'download';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
setTimeout(function () {
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
}, 0);
|
||||
} catch (e) {
|
||||
console.error('downloadFileFromText failed', e);
|
||||
}
|
||||
};
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';
|
||||
</script>
|
||||
<script src="_content/FruitBankHybrid.Shared/js/pdfViewer.js"></script>
|
||||
<script src="_content/FruitBankHybrid.Shared/js/fileDownload.js"></script>
|
||||
<script src="@Assets["/_framework/blazor.web.js"]"></script>
|
||||
</body>
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';
|
||||
</script>
|
||||
<script src="_content/FruitBankHybrid.Shared/js/pdfViewer.js"></script>
|
||||
<script src="_content/FruitBankHybrid.Shared/js/fileDownload.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue