From 41275dc0033c3ebf1b12ee80b7bf2ac92dc1f045 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 7 Nov 2025 09:57:23 +0100 Subject: [PATCH 1/2] download page --- .../Controllers/AppDownloadController.cs | 145 +++++++++++++++ .../Admin/Models/App/AppDownloadModel.cs | 14 ++ .../Areas/Admin/Models/App/AppVersionModel.cs | 12 ++ .../Admin/Views/AppDownload/Index.cshtml | 167 ++++++++++++++++++ .../Infrastructure/RouteProvider.cs | 10 ++ .../Nop.Plugin.Misc.FruitBankPlugin.csproj | 3 + 6 files changed, 351 insertions(+) create mode 100644 Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/AppDownloadController.cs create mode 100644 Nop.Plugin.Misc.AIPlugin/Areas/Admin/Models/App/AppDownloadModel.cs create mode 100644 Nop.Plugin.Misc.AIPlugin/Areas/Admin/Models/App/AppVersionModel.cs create mode 100644 Nop.Plugin.Misc.AIPlugin/Areas/Admin/Views/AppDownload/Index.cshtml diff --git a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/AppDownloadController.cs b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/AppDownloadController.cs new file mode 100644 index 0000000..ffebb93 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/AppDownloadController.cs @@ -0,0 +1,145 @@ +using Microsoft.AspNetCore.Mvc; +using Nop.Core; +using Nop.Plugin.Misc.FruitBankPlugin.Models.App; +using Nop.Services.Security; +using Nop.Web.Framework; +using Nop.Web.Framework.Controllers; +using Nop.Web.Framework.Mvc.Filters; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers +{ + [Area(AreaNames.ADMIN)] + [AuthorizeAdmin] + [AutoValidateAntiforgeryToken] + public class AppDownloadController : BasePluginController + { + private readonly IPermissionService _permissionService; + private readonly IWebHelper _webHelper; + private readonly IWorkContext _workContext; + + public AppDownloadController( + IPermissionService permissionService, + IWebHelper webHelper, + IWorkContext workContext) + { + _permissionService = permissionService; + _webHelper = webHelper; + _workContext = workContext; + } + + [HttpGet] + public virtual async Task Index() + { + if (!await _permissionService.AuthorizeAsync(StandardPermission.Orders.ORDERS_CREATE_EDIT_DELETE)) + return AccessDeniedView(); + + var model = new AppDownloadModel + { + PreviousVersions = new List() + }; + + var appPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "app", "versions"); + + if (Directory.Exists(appPath)) + { + var versionFolders = Directory.GetDirectories(appPath) + .Select(d => new DirectoryInfo(d)) + .OrderByDescending(d => d.Name) + .ToList(); + + foreach (var folder in versionFolders) + { + var apkFile = Directory.GetFiles(folder.FullName, "*.apk").FirstOrDefault(); + if (apkFile != null) + { + var fileInfo = new FileInfo(apkFile); + var fileName = Path.GetFileName(apkFile); + var versionModel = new AppVersionModel + { + Version = folder.Name, + DownloadUrl = $"/app/versions/{folder.Name}/{fileName}", + FileName = fileName, // Add this + FileSizeFormatted = FormatFileSize(fileInfo.Length), + ReleaseDate = fileInfo.CreationTime + }; + + // Set the latest version + if (model.CurrentVersion == null) + { + model.CurrentVersion = folder.Name; + model.DownloadUrl = versionModel.DownloadUrl; + model.FileName = fileName; // Add this + model.FileSizeBytes = fileInfo.Length; + model.FileSizeFormatted = versionModel.FileSizeFormatted; + model.ReleaseDate = versionModel.ReleaseDate; + + // Read changelog if exists + var changelogFile = Path.Combine(folder.FullName, "changelog.txt"); + if (System.IO.File.Exists(changelogFile)) + { + model.Changelog = await System.IO.File.ReadAllTextAsync(changelogFile); + } + } + else + { + model.PreviousVersions.Add(versionModel); + } + } + } + } + + return View("~/Plugins/Misc.FruitBankPlugin/Areas/Admin/Views/AppDownload/Index.cshtml", model); + } + + [HttpGet] + public virtual IActionResult Download(string version, string fileName) + { + // Validate inputs + if (string.IsNullOrEmpty(version) || string.IsNullOrEmpty(fileName)) + return BadRequest(); + + // Prevent directory traversal + if (version.Contains("..") || fileName.Contains("..")) + return BadRequest(); + + if (!fileName.EndsWith(".apk", StringComparison.OrdinalIgnoreCase)) + return BadRequest(); + + var filePath = Path.Combine( + Directory.GetCurrentDirectory(), + "wwwroot", + "app", + "versions", + version, + fileName); + + if (!System.IO.File.Exists(filePath)) + return NotFound(); + + var fileBytes = System.IO.File.ReadAllBytes(filePath); + + // Set proper headers for APK download + Response.Headers.Add("Content-Disposition", $"attachment; filename=\"{fileName}\""); + + return File(fileBytes, "application/vnd.android.package-archive", fileName); + } + + private string FormatFileSize(long bytes) + { + string[] sizes = { "B", "KB", "MB", "GB", "TB" }; + double len = bytes; + int order = 0; + while (len >= 1024 && order < sizes.Length - 1) + { + order++; + len = len / 1024; + } + return $"{len:0.##} {sizes[order]}"; + } + } +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Models/App/AppDownloadModel.cs b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Models/App/AppDownloadModel.cs new file mode 100644 index 0000000..f20306b --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Models/App/AppDownloadModel.cs @@ -0,0 +1,14 @@ +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.App +{ + public class AppDownloadModel + { + public string CurrentVersion { get; set; } + public string DownloadUrl { get; set; } + public string FileName { get; set; } // Add this + public long FileSizeBytes { get; set; } + public string FileSizeFormatted { get; set; } + public DateTime ReleaseDate { get; set; } + public string Changelog { get; set; } + public List PreviousVersions { get; set; } + } +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Models/App/AppVersionModel.cs b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Models/App/AppVersionModel.cs new file mode 100644 index 0000000..ca46a81 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Models/App/AppVersionModel.cs @@ -0,0 +1,12 @@ +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.App +{ + + public class AppVersionModel + { + public string Version { get; set; } + public string DownloadUrl { get; set; } + public string FileName { get; set; } // Add this + public string FileSizeFormatted { get; set; } + public DateTime ReleaseDate { get; set; } + } +} diff --git a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Views/AppDownload/Index.cshtml b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Views/AppDownload/Index.cshtml new file mode 100644 index 0000000..6f1ba3e --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Views/AppDownload/Index.cshtml @@ -0,0 +1,167 @@ +@using System.IO +@model Nop.Plugin.Misc.FruitBankPlugin.Models.App.AppDownloadModel + +@{ + Layout = "_AdminLayout"; + NopHtml.SetActiveMenuItemSystemName("FruitBank.AppDownload"); +} + +
+

+ Android App letöltés +

+
+ +
+
+ @if (!string.IsNullOrEmpty(Model.CurrentVersion)) + { + +
+
+

+ + Legújabb verzió: @Model.CurrentVersion +

+
+
+
+
+
+ + Telepítési útmutató: +
    +
  1. Engedélyezd az "Ismeretlen forrásokból" való telepítést a táblagépen (Beállítások → Biztonság)
  2. +
  3. Kattints a "Letöltés" gombra
  4. +
  5. Nyisd meg a letöltött APK fájlt
  6. +
  7. Kövesd a telepítési utasításokat
  8. +
+
+ +
+ Verzió: @Model.CurrentVersion
+ Méret: @Model.FileSizeFormatted
+ Kiadás dátuma: @Model.ReleaseDate.ToString("yyyy-MM-dd HH:mm") +
+ + @if (!string.IsNullOrEmpty(Model.Changelog)) + { +
+ Változások: +
@Model.Changelog
+
+ } + + + + Letöltés (@Model.FileSizeFormatted) + +
+ +
+
+ +
+

Szkenneld be a QR kódot a táblagéppel a közvetlen letöltéshez

+
+
+
+
+
+ + @if (Model.PreviousVersions != null && Model.PreviousVersions.Any()) + { + +
+
+

+ + Korábbi verziók +

+
+ +
+
+ +
+ } + } + else + { +
+
+
+ + Nincs elérhető app verzió. Kérlek, helyezd el az APK fájlt a wwwroot/app/versions/ mappában. +
+
+
+ } +
+
+ + + + + + + + \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Infrastructure/RouteProvider.cs b/Nop.Plugin.Misc.AIPlugin/Infrastructure/RouteProvider.cs index 88132a5..5c0f27b 100644 --- a/Nop.Plugin.Misc.AIPlugin/Infrastructure/RouteProvider.cs +++ b/Nop.Plugin.Misc.AIPlugin/Infrastructure/RouteProvider.cs @@ -156,6 +156,16 @@ public class RouteProvider : IRouteProvider name: "Plugin.FruitBank.Admin.ManagementPage.ProcessShippingDocument", pattern: "Admin/ManagamentPage/ProcessShippingDocument/{id}", defaults: new { controller = "ManagementPage", action = "ProcessShippingdocument", area = AreaNames.ADMIN }); + + endpointRouteBuilder.MapControllerRoute( + name: "Plugin.FruitBank.AppDownload", + pattern: "Admin/AppDownload", + defaults: new { controller = "AppDownload", action = "Index", area = AreaNames.ADMIN }); + + endpointRouteBuilder.MapControllerRoute( + name: "Plugin.FruitBank.AppDownload.Download", + pattern: "Admin/AppDownload/Download/{version}/{fileName}", + defaults: new { controller = "AppDownload", action = "Download", area = AreaNames.ADMIN }); } /// diff --git a/Nop.Plugin.Misc.AIPlugin/Nop.Plugin.Misc.FruitBankPlugin.csproj b/Nop.Plugin.Misc.AIPlugin/Nop.Plugin.Misc.FruitBankPlugin.csproj index 1bb38be..2e10b5d 100644 --- a/Nop.Plugin.Misc.AIPlugin/Nop.Plugin.Misc.FruitBankPlugin.csproj +++ b/Nop.Plugin.Misc.AIPlugin/Nop.Plugin.Misc.FruitBankPlugin.csproj @@ -167,6 +167,9 @@ + + Always + Always From a476932b40b6b0ac12e7ed985d5b0ee0b96dc9c0 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 7 Nov 2025 12:09:47 +0100 Subject: [PATCH 2/2] =?UTF-8?q?=C3=9Ajraenged=C3=A9lyez=C3=A9s,=20UI=20?= =?UTF-8?q?=C3=A1talalk=C3=ADt=C3=A1sok,=20=C3=BCzenetk=C3=BCld=C3=A9s=20p?= =?UTF-8?q?opup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/CustomOrderController.cs | 40 +- .../OrderAttributesViewComponent.cs | 2 +- .../Infrastructure/RouteProvider.cs | 5 + .../Models/Orders/OrderAttributesModel.cs | 5 +- .../Models/Orders/OrderRevisionModel.cs | 15 + .../Views/OrderAttributes.cshtml | 346 +++++++++++------- 6 files changed, 280 insertions(+), 133 deletions(-) create mode 100644 Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderRevisionModel.cs diff --git a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/CustomOrderController.cs b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/CustomOrderController.cs index 8a44025..c5b8a4a 100644 --- a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/CustomOrderController.cs +++ b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/CustomOrderController.cs @@ -1,4 +1,6 @@ -using AyCode.Core.Loggers; +using AyCode.Core.Extensions; +using AyCode.Core.Loggers; +using AyCode.Services.Server.SignalRs; using AyCode.Services.SignalRs; using FruitBank.Common.Dtos; using FruitBank.Common.Entities; @@ -8,6 +10,7 @@ using FruitBank.Common.Server.Services.SignalRs; using FruitBank.Common.SignalRs; using Mango.Nop.Core.Extensions; using Mango.Nop.Core.Loggers; +using MessagePack.Resolvers; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; @@ -23,6 +26,7 @@ using Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Models.Order; using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; using Nop.Plugin.Misc.FruitBankPlugin.Factories; using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; +using Nop.Plugin.Misc.FruitBankPlugin.Services; using Nop.Services.Catalog; using Nop.Services.Common; using Nop.Services.Customers; @@ -35,6 +39,7 @@ using Nop.Services.Orders; using Nop.Services.Payments; using Nop.Services.Plugins; using Nop.Services.Security; +using Nop.Services.Tax; using Nop.Web.Areas.Admin.Controllers; using Nop.Web.Areas.Admin.Factories; using Nop.Web.Areas.Admin.Models.Orders; @@ -45,10 +50,6 @@ using System.Text; using System.Text.Json.Serialization; using System.Xml; using System.Xml.Serialization; -using AyCode.Services.Server.SignalRs; -using AyCode.Core.Extensions; -using MessagePack.Resolvers; -using Nop.Services.Tax; namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers { @@ -78,6 +79,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers protected readonly IImportManager _importManager; protected readonly IDateTimeHelper _dateTimeHelper; protected readonly ITaxService _taxService; + protected readonly MeasurementService _measurementService; private static readonly char[] _separator = [',']; // ... other dependencies @@ -124,7 +126,8 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers IGiftCardService giftCardService, IImportManager importManager, IDateTimeHelper dateTimeHelper, - ITaxService taxService) + ITaxService taxService, + MeasurementService measurementService) { _logger = new Logger(logWriters.ToArray()); @@ -151,6 +154,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers _importManager = importManager; _dateTimeHelper = dateTimeHelper; _taxService = taxService; + _measurementService = measurementService; // ... initialize other deps } @@ -408,6 +412,30 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers return RedirectToAction("Edit", "Order", new { id = model.OrderId }); } + [HttpPost] + [ValidateAntiForgeryToken] + public async Task AllowRevision(OrderRevisionModel model) + { + if (!ModelState.IsValid) + { + // reload order page with errors + return RedirectToAction("Edit", "Order", new { id = model.OrderId }); + } + + var order = await _orderService.GetOrderByIdAsync(model.OrderId); + if (order == null) + return RedirectToAction("List", "Order"); + + + //MeasurementService.OrderItemMeasuringReset + //Todo: ezt orderitiemnként kéne kirakni?? - Á. + var valami = await _measurementService.OrderItemMeasuringReset(model.OrderItemId); + + return RedirectToAction("Edit", "Order", new { id = model.OrderId }); + } + + + [HttpPost] //[CheckPermission(StandardPermission.Orders.ORDERS_CREATE)] public virtual async Task Create(int customerId, string orderProductsJson) diff --git a/Nop.Plugin.Misc.AIPlugin/Components/OrderAttributesViewComponent.cs b/Nop.Plugin.Misc.AIPlugin/Components/OrderAttributesViewComponent.cs index 7133647..a832c88 100644 --- a/Nop.Plugin.Misc.AIPlugin/Components/OrderAttributesViewComponent.cs +++ b/Nop.Plugin.Misc.AIPlugin/Components/OrderAttributesViewComponent.cs @@ -44,7 +44,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Components model.IsMeasurable = orderDto.IsMeasurable; model.DateOfReceipt = orderDto.DateOfReceipt; - + model.OrderDto = orderDto; //var orderPickupAttributeValue = await _fruitBankAttributeService.GetGenericAttributeValueAsync(model.OrderId, nameof(IOrderDto.DateOfReceipt)); //if (orderPickupAttributeValue.HasValue && orderPickupAttributeValue.Value != DateTime.MinValue) diff --git a/Nop.Plugin.Misc.AIPlugin/Infrastructure/RouteProvider.cs b/Nop.Plugin.Misc.AIPlugin/Infrastructure/RouteProvider.cs index 5c0f27b..4b35c8a 100644 --- a/Nop.Plugin.Misc.AIPlugin/Infrastructure/RouteProvider.cs +++ b/Nop.Plugin.Misc.AIPlugin/Infrastructure/RouteProvider.cs @@ -132,6 +132,11 @@ public class RouteProvider : IRouteProvider pattern: "Admin/CustomOrder/SaveOrderAttributes", defaults: new { controller = "CustomOrder", action = "SaveOrderAttributes", area = AreaNames.ADMIN }); + endpointRouteBuilder.MapControllerRoute( + name: "Plugin.FruitBank.Admin.Orders.AllowRevision", + pattern: "Admin/CustomOrder/AllowRevision", + defaults: new { controller = "CustomOrder", action = "AllowRevision", area = AreaNames.ADMIN }); + endpointRouteBuilder.MapControllerRoute( name: "Plugin.FruitBank.Admin.Orders.CustomerSearchAutoComplete", pattern: "Admin/CustomOrder/CustomerSearchAutoComplete", diff --git a/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderAttributesModel.cs b/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderAttributesModel.cs index 0fec549..49cf5cc 100644 --- a/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderAttributesModel.cs +++ b/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderAttributesModel.cs @@ -1,4 +1,5 @@ -using FruitBank.Common.Interfaces; +using FruitBank.Common.Dtos; +using FruitBank.Common.Interfaces; using Nop.Web.Framework.Models; using Nop.Web.Framework.Mvc.ModelBinding; @@ -14,5 +15,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Orders [NopResourceDisplayName("Plugins.YourCompany.ProductAttributes.Fields.DateOfReceipt")] public DateTime? DateOfReceipt { get; set; } + public OrderDto OrderDto { get; set; } + } } \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderRevisionModel.cs b/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderRevisionModel.cs new file mode 100644 index 0000000..84a5111 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderRevisionModel.cs @@ -0,0 +1,15 @@ +using FruitBank.Common.Dtos; +using FruitBank.Common.Interfaces; +using Nop.Web.Framework.Models; +using Nop.Web.Framework.Mvc.ModelBinding; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Orders +{ + public record OrderRevisionModel : BaseNopModel + { + public int OrderId { get; set; } + + public int OrderItemId { get; set; } + + } +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Views/OrderAttributes.cshtml b/Nop.Plugin.Misc.AIPlugin/Views/OrderAttributes.cshtml index e271ef6..652506f 100644 --- a/Nop.Plugin.Misc.AIPlugin/Views/OrderAttributes.cshtml +++ b/Nop.Plugin.Misc.AIPlugin/Views/OrderAttributes.cshtml @@ -9,7 +9,7 @@
-
+
@@ -17,53 +17,34 @@
-
- Mérés információ -
-
- @(Model.IsMeasurable ? "Mérendő" : "Nem mérendő") + +
+ @(Model.IsMeasurable ? "Mérendő termék!" : "Nem mérendő termék")
+
-
+
-
-
-
-
+
+
-
-
-
-
-
-
-

Üzenet küldése

-
-
+
-
- - +
+
-
-
-
- -
-
-
-
-
@@ -71,15 +52,15 @@
-
+
- InnVoice Management + Megrendelés beküldése Innvoice-ba
-
Megrendelés beküldése Innvoice-ba
+ @@ -96,7 +77,7 @@
- - @*
-
Invoice
- - -
*@ - - @*
- - -
*@
+ + + + + \ No newline at end of file +