edit and update ismeasurable, netweight, incomingQuantity
This commit is contained in:
parent
244181bebd
commit
7e7a6e0982
|
|
@ -234,13 +234,13 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
|
|||
// - IF WE DON'T HAVE PARTNERID ALREADY: read partner information
|
||||
// (check if all 3 refers to the same partner)
|
||||
// save partner information to partners table { Id, Name, TaxId, CertificationNumber, PostalCode, Country, State, County, City, Street }
|
||||
if (partnerId == null)
|
||||
if (partnerId != null)
|
||||
{
|
||||
string partnerAnalysisPrompt = "Extract the partner information from this document, and return them as JSON: name, taxId, certificationNumber, postalCode, country, state, county, city, street. " +
|
||||
string partnerAnalysisPrompt = "Extract the sender information from this document, and return them as JSON: name, taxId, certificationNumber, postalCode, country, state, county, city, street. " +
|
||||
"If you can't find information of any of these, return null value for that field.";
|
||||
|
||||
//here I can start preparing the file entity
|
||||
var partnerAnalyzis = await _aiCalculationService.GetOpenAIPDFAnalysisFromText(pdfText.ToString(), analysisPrompt);
|
||||
var partnerAnalyzis = await _aiCalculationService.GetOpenAIPDFAnalysisFromText(pdfText.ToString(), partnerAnalysisPrompt);
|
||||
var extractedPartnerData = ParsePartnerDataAIResponse(partnerAnalyzis);
|
||||
|
||||
if (extractedPartnerData.Name != null)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
using Nop.Web.Areas.Admin.Models.Catalog;
|
||||
using Nop.Web.Framework.Models;
|
||||
using Nop.Web.Framework.Mvc.ModelBinding;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Models.Catalog
|
||||
{
|
||||
public partial record ProductModel : BaseNopEntityModel
|
||||
{
|
||||
// ... existing properties ...
|
||||
|
||||
[NopResourceDisplayName("Admin.Catalog.Products.Fields.IsMeasurable")]
|
||||
public bool IsMeasurable { get; set; }
|
||||
|
||||
// ... rest of your model ...
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
// File: Plugins/YourCompany.ProductAttributes/Components/ProductAttributesViewComponent.cs
|
||||
|
||||
using FruitBank.Common.Interfaces;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Nop.Core;
|
||||
using Nop.Core.Domain.Catalog;
|
||||
using Nop.Plugin.Misc.FruitBankPlugin.Models;
|
||||
using Nop.Services.Common;
|
||||
using Nop.Web.Areas.Admin.Models.Catalog;
|
||||
using Nop.Web.Framework.Components;
|
||||
|
||||
namespace Nop.Plugin.Misc.FruitBankPlugin.Components
|
||||
{
|
||||
[ViewComponent(Name = "ProductAttributes")]
|
||||
public class ProductAttributesViewComponent : NopViewComponent
|
||||
{
|
||||
private const string NET_WEIGHT_KEY = nameof(IMeasuringAttributeValues.NetWeight);
|
||||
private const string GROSS_WEIGHT_KEY = nameof(IMeasuringAttributeValues.GrossWeight);
|
||||
private const string IS_MEASURABLE_KEY = nameof(IMeasuringAttributeValues.IsMeasurable);
|
||||
|
||||
private readonly IGenericAttributeService _genericAttributeService;
|
||||
private readonly IWorkContext _workContext;
|
||||
private readonly IStoreContext _storeContext;
|
||||
|
||||
public ProductAttributesViewComponent(
|
||||
IGenericAttributeService genericAttributeService,
|
||||
IWorkContext workContext,
|
||||
IStoreContext storeContext)
|
||||
{
|
||||
_genericAttributeService = genericAttributeService;
|
||||
_workContext = workContext;
|
||||
_storeContext = storeContext;
|
||||
}
|
||||
|
||||
public async Task<IViewComponentResult> InvokeAsync(string widgetZone, object additionalData)
|
||||
{
|
||||
|
||||
|
||||
if (additionalData is not ProductModel product)
|
||||
return Content("");
|
||||
|
||||
var model = new ProductAttributesModel
|
||||
{
|
||||
ProductId = product.Id
|
||||
};
|
||||
|
||||
//get store scope
|
||||
var storeScope = await _storeContext.GetCurrentStoreAsync();
|
||||
|
||||
|
||||
if (product.Id > 0)
|
||||
{
|
||||
// Load existing values
|
||||
var dbProduct = new Core.Domain.Catalog.Product { Id = product.Id };
|
||||
|
||||
//var dbMesaurable = await _genericAttributeService.GetAttributeAsync<bool>(dbProduct, IS_MEASURABLE_KEY, storeScope.Id);
|
||||
//var dbNetWeight = await _genericAttributeService.GetAttributeAsync<decimal?>(dbProduct, NET_WEIGHT_KEY, storeScope.Id);
|
||||
//var dbIncomingQuantity = await _genericAttributeService.GetAttributeAsync<decimal?>(dbProduct, "IncomingQuantity", storeScope.Id);
|
||||
|
||||
model.IsMeasurable = await _genericAttributeService
|
||||
.GetAttributeAsync<bool>(dbProduct, IS_MEASURABLE_KEY, storeScope.Id);
|
||||
|
||||
model.NetWeight = await _genericAttributeService
|
||||
.GetAttributeAsync<decimal?>(dbProduct, NET_WEIGHT_KEY, storeScope.Id);
|
||||
|
||||
model.IncomingQuantity = await _genericAttributeService
|
||||
.GetAttributeAsync<int?>(dbProduct, "IncomingQuantity", storeScope.Id);
|
||||
}
|
||||
|
||||
return View("~/Plugins/Misc.FruitBankPlugin/Views/ProductAttributes.cshtml", model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
using AyCode.Core.Loggers;
|
||||
using AyCode.Interfaces.Entities;
|
||||
using DevExpress.XtraPrinting.Native;
|
||||
using FruitBank.Common.Entities;
|
||||
using FruitBank.Common.Interfaces;
|
||||
using FruitBank.Common.Loggers;
|
||||
|
|
@ -18,12 +19,15 @@ using Nop.Services.Events;
|
|||
|
||||
namespace Nop.Plugin.Misc.FruitBankPlugin.Domains.EventConsumers;
|
||||
|
||||
public class FruitBankEventConsumer(IHttpContextAccessor httpContextAccessor, FruitBankDbContext ctx, FruitBankAttributeService fruitBankAttributeService, IStoreContext storeContext, IEnumerable<IAcLogWriterBase> logWriters) :
|
||||
public class FruitBankEventConsumer(IHttpContextAccessor httpContextAccessor, FruitBankDbContext ctx, FruitBankAttributeService fruitBankAttributeService, IStoreContext storeContext, IEnumerable<IAcLogWriterBase> logWriters, IGenericAttributeService genericAttributeService) :
|
||||
MgEventConsumer(httpContextAccessor, logWriters), IConsumer<EntityUpdatedEvent<ShippingItem>>, IConsumer<EntityUpdatedEvent<ShippingDocument>>
|
||||
{
|
||||
public override async Task HandleEventAsync(EntityUpdatedEvent<Product> eventMessage)
|
||||
{
|
||||
var product = eventMessage.Entity;
|
||||
|
||||
await SaveCustomAttributesAsync(eventMessage.Entity);
|
||||
|
||||
var isMeasurableProduct = await fruitBankAttributeService.IsMeasurableEntityAsync<Product>(product.Id);
|
||||
|
||||
var shippingItems = await ctx.ShippingItems.Table
|
||||
|
|
@ -37,6 +41,55 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAccessor, Fr
|
|||
await base.HandleEventAsync(eventMessage);
|
||||
}
|
||||
|
||||
|
||||
public async Task HandleEventAsync(EntityInsertedEvent<Product> eventMessage)
|
||||
{
|
||||
await SaveCustomAttributesAsync(eventMessage.Entity);
|
||||
}
|
||||
|
||||
private async Task SaveCustomAttributesAsync(Product product)
|
||||
{
|
||||
if (product == null)
|
||||
return;
|
||||
|
||||
var form = httpContextAccessor.HttpContext?.Request?.Form;
|
||||
if (form == null || !form.Any())
|
||||
return;
|
||||
|
||||
var isMeasurable = form["IsMeasurable"].ToString().Contains("true");
|
||||
|
||||
// Save IsMeasurable
|
||||
if (form.ContainsKey("IsMeasurable"))
|
||||
{
|
||||
await genericAttributeService.SaveAttributeAsync(product, "IsMeasurable", isMeasurable);
|
||||
//Akkor ez kell? - Á.
|
||||
//await fruitBankAttributeService.InsertOrUpdateMeasuringAttributeValuesAsync<Product>(product.Id, 0, 0, isMeasurable, false);
|
||||
}
|
||||
|
||||
// Save NetWeight
|
||||
if (form.ContainsKey("NetWeight"))
|
||||
{
|
||||
var netWeightStr = form["NetWeight"].ToString();
|
||||
if (!string.IsNullOrWhiteSpace(netWeightStr) && decimal.TryParse(netWeightStr, out var netWeight))
|
||||
{
|
||||
await genericAttributeService.SaveAttributeAsync(product, "NetWeight", netWeight);
|
||||
|
||||
//await fruitBankAttributeService.InsertOrUpdateMeasuringAttributeValuesAsync<Product>(product.Id, 0, 0, , false);
|
||||
}
|
||||
}
|
||||
|
||||
// Save IncomingQuantity
|
||||
if (form.ContainsKey("IncomingQuantity"))
|
||||
{
|
||||
var incomingQtyStr = form["IncomingQuantity"].ToString();
|
||||
if (!string.IsNullOrWhiteSpace(incomingQtyStr) && int.TryParse(incomingQtyStr, out var incomingQuantity))
|
||||
{
|
||||
await genericAttributeService.SaveAttributeAsync(product, "IncomingQuantity", incomingQuantity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task HandleEventAsync(EntityInsertedEvent<ShippingItem> eventMessage)
|
||||
{
|
||||
Logger.Info($"HandleEventAsync EntityInsertedEvent<ShippingItem>; id: {eventMessage.Entity.Id}");
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin
|
|||
|
||||
public Task<IList<string>> GetWidgetZonesAsync()
|
||||
{
|
||||
return Task.FromResult<IList<string>>(new List<string> { PublicWidgetZones.ProductBoxAddinfoBefore, PublicWidgetZones.ProductDetailsBottom });
|
||||
return Task.FromResult<IList<string>>(new List<string> { PublicWidgetZones.ProductBoxAddinfoBefore, PublicWidgetZones.ProductDetailsBottom, AdminWidgetZones.ProductDetailsBlock });
|
||||
}
|
||||
|
||||
//public string GetWidgetViewComponentName(string widgetZone)
|
||||
|
|
@ -128,7 +128,20 @@ namespace Nop.Plugin.Misc.FruitBankPlugin
|
|||
|
||||
var zones = GetWidgetZonesAsync().Result;
|
||||
|
||||
return zones.Any(widgetZone.Equals) ? typeof(ProductAIWidgetViewComponent) : null;
|
||||
if (zones.Any(widgetZone.Equals))
|
||||
{
|
||||
if (widgetZone == PublicWidgetZones.ProductBoxAddinfoBefore || widgetZone == PublicWidgetZones.ProductDetailsBottom)
|
||||
{
|
||||
return zones.Any(widgetZone.Equals) ? typeof(ProductAIWidgetViewComponent) : null;
|
||||
}
|
||||
else if (widgetZone == AdminWidgetZones.ProductDetailsBlock)
|
||||
{
|
||||
return zones.Any(widgetZone.Equals) ? typeof(ProductAttributesViewComponent) : null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
using Nop.Web.Framework.Models;
|
||||
using Nop.Web.Framework.Mvc.ModelBinding;
|
||||
|
||||
namespace Nop.Plugin.Misc.FruitBankPlugin.Models
|
||||
{
|
||||
public record ProductAttributesModel : BaseNopModel
|
||||
{
|
||||
public int ProductId { get; set; }
|
||||
|
||||
[NopResourceDisplayName("Plugins.YourCompany.ProductAttributes.Fields.IsMeasurable")]
|
||||
public bool IsMeasurable { get; set; }
|
||||
|
||||
[NopResourceDisplayName("Plugins.YourCompany.ProductAttributes.Fields.NetWeight")]
|
||||
public decimal? NetWeight { get; set; }
|
||||
|
||||
[NopResourceDisplayName("Plugins.YourCompany.ProductAttributes.Fields.IncomingQuantity")]
|
||||
public int? IncomingQuantity { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -605,6 +605,12 @@
|
|||
<None Update="Views\ProductAIListWidget.cshtml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Views\ProductAttributes.cshtml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Views\ProductList.cshtml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Views\ProductAIWidget.cshtml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
@* File: Plugins/Nop.Plugin.YourCompany.ProductAttributes/Views/ProductCustomAttributes.cshtml *@
|
||||
|
||||
@model Nop.Plugin.Misc.FruitBankPlugin.Models.ProductAttributesModel
|
||||
|
||||
<div class="card card-default">
|
||||
<div class="card-header">
|
||||
<i class="fas fa-tags"></i>
|
||||
Custom Product Attributes
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="IsMeasurable" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="IsMeasurable" />
|
||||
<span asp-validation-for="IsMeasurable"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="NetWeight" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="NetWeight" />
|
||||
<span asp-validation-for="NetWeight"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="IncomingQuantity" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="IncomingQuantity" />
|
||||
<span asp-validation-for="IncomingQuantity"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
@* File: Plugins/YourCompany.ProductAttributes/Views/ProductList.cshtml *@
|
||||
@* This view component will inject into the product list page *@
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
// Wait for the DataTable to be initialized
|
||||
console.log('custom product list JS triggered');
|
||||
var checkDataTable = setInterval(function() {
|
||||
if (typeof $('#products-grid').DataTable !== 'undefined') {
|
||||
clearInterval(checkDataTable);
|
||||
customizeProductGrid();
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
|
||||
function customizeProductGrid() {
|
||||
var table = $('#products-grid').DataTable();
|
||||
|
||||
// Add custom columns after initialization
|
||||
if (table.column('ismeasurable:name').length === 0) {
|
||||
table.column.add([
|
||||
{
|
||||
data: 'CustomProperties.IsMeasurable',
|
||||
title: 'Measurable',
|
||||
width: '80px',
|
||||
render: function (data, type, row) {
|
||||
return data ? '<i class="fas fa-check true-icon"></i>' : '<i class="fas fa-times false-icon"></i>';
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'CustomProperties.NetWeight',
|
||||
title: 'Net Weight (kg)',
|
||||
width: '100px'
|
||||
},
|
||||
{
|
||||
data: 'CustomProperties.IncomingQuantity',
|
||||
title: 'Incoming Qty',
|
||||
width: '100px'
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.true-icon {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.false-icon {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
Reference in New Issue