wip - preparations
This commit is contained in:
parent
8a5b5ecc3a
commit
2f900393e9
13 changed files with 229 additions and 14 deletions
|
@ -21,7 +21,7 @@ namespace Wonky.Client.HttpInterfaces;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interface Customer History CRM Http repository
|
/// Interface Customer History CRM Http repository
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ICustomerHistoryRepository
|
public interface IAdvisorCustomerHistoryRepository
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fetch Invoice LIst
|
/// Fetch Invoice LIst
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright (C) 2022 FCS Frede's Computer Services.
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
using Wonky.Entity.Views;
|
||||||
|
|
||||||
|
namespace Wonky.Client.HttpInterfaces;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface Customer History CRM Http repository
|
||||||
|
/// </summary>
|
||||||
|
public interface ICountryCustomerHistoryRepository
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch Invoice LIst
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="companyId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<InvoiceListView> FetchInvoiceList(string countryCode, string companyId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch given invoice for given customer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="companyId"></param>
|
||||||
|
/// <param name="invoiceId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<InvoiceView> FetchInvoice(string countryCode, string companyId, string invoiceId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch inventory from given customer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="companyId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<List<ProductInventoryView>> FetchInventory(string countryCode, string companyId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch History for given customer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="companyId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<List<ProductHistoryView>> FetchHistory(string countryCode, string companyId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch history for given customer and a given product
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="companyId"></param>
|
||||||
|
/// <param name="sku"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<List<ProductHistoryView>> FetchHistory(string countryCode, string companyId, string sku);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// RPC call to initiate remote server sync for given customer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="companyId"></param>
|
||||||
|
/// <param name="syncDate"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<string> ErpInvoiceToCrmRpc(string countryCode, string companyId, string syncDate);
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ using Wonky.Entity.Views;
|
||||||
|
|
||||||
namespace Wonky.Client.HttpRepository;
|
namespace Wonky.Client.HttpRepository;
|
||||||
|
|
||||||
public class CustomerHistoryRepository : ICustomerHistoryRepository
|
public class AdvisorCustomerHistoryRepository : IAdvisorCustomerHistoryRepository
|
||||||
{
|
{
|
||||||
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
|
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
|
||||||
{
|
{
|
||||||
|
@ -33,12 +33,12 @@ public class CustomerHistoryRepository : ICustomerHistoryRepository
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly NavigationManager _navigation;
|
private readonly NavigationManager _navigation;
|
||||||
private ILogger<CustomerHistoryRepository> _logger;
|
private ILogger<AdvisorCustomerHistoryRepository> _logger;
|
||||||
private readonly HttpClient _client;
|
private readonly HttpClient _client;
|
||||||
private readonly ApiConfig _api;
|
private readonly ApiConfig _api;
|
||||||
|
|
||||||
public CustomerHistoryRepository(
|
public AdvisorCustomerHistoryRepository(
|
||||||
HttpClient client, ILogger<CustomerHistoryRepository> logger,
|
HttpClient client, ILogger<AdvisorCustomerHistoryRepository> logger,
|
||||||
NavigationManager navigation, IOptions<ApiConfig> configuration)
|
NavigationManager navigation, IOptions<ApiConfig> configuration)
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
145
Wonky.Client/HttpRepository/CountryCustomerHistoryRepository.cs
Normal file
145
Wonky.Client/HttpRepository/CountryCustomerHistoryRepository.cs
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
// Copyright (C) 2022 FCS Frede's Computer Services.
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||||
|
//
|
||||||
|
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Text.Json;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Wonky.Client.HttpInterfaces;
|
||||||
|
using Wonky.Client.Pages;
|
||||||
|
using Wonky.Entity.Configuration;
|
||||||
|
using Wonky.Entity.DTO;
|
||||||
|
using Wonky.Entity.Views;
|
||||||
|
|
||||||
|
namespace Wonky.Client.HttpRepository;
|
||||||
|
|
||||||
|
public class CountryCustomerHistoryRepository : ICountryCustomerHistoryRepository
|
||||||
|
{
|
||||||
|
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
PropertyNameCaseInsensitive = true
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly NavigationManager _navigation;
|
||||||
|
private ILogger<CountryCustomerHistoryRepository> _logger;
|
||||||
|
private readonly HttpClient _client;
|
||||||
|
private readonly ApiConfig _api;
|
||||||
|
|
||||||
|
public CountryCustomerHistoryRepository(
|
||||||
|
HttpClient client, ILogger<CountryCustomerHistoryRepository> logger,
|
||||||
|
NavigationManager navigation, IOptions<ApiConfig> configuration)
|
||||||
|
{
|
||||||
|
_client = client;
|
||||||
|
_logger = logger;
|
||||||
|
_navigation = navigation;
|
||||||
|
_api = configuration.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch Invoice LIst
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="countryCode"></param>
|
||||||
|
/// <param name="companyId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<InvoiceListView> FetchInvoiceList(string countryCode, string companyId)
|
||||||
|
{
|
||||||
|
var response = await _client.GetAsync($"{_api.OfficeCustomers}/{countryCode}/{companyId}/invoices");
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode) return new InvoiceListView();
|
||||||
|
|
||||||
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
|
return response.IsSuccessStatusCode
|
||||||
|
? JsonSerializer.Deserialize<InvoiceListView>(content, _options)
|
||||||
|
: new InvoiceListView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch given invoice for given customer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="countryCode"></param>
|
||||||
|
/// <param name="companyId"></param>
|
||||||
|
/// <param name="invoiceId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<InvoiceView> FetchInvoice(string countryCode, string companyId, string invoiceId)
|
||||||
|
{
|
||||||
|
return await _client
|
||||||
|
.GetFromJsonAsync<InvoiceView>($"{_api.OfficeCustomers}/{countryCode}/{companyId}/invoices/{invoiceId}", _options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch inventory from given customer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="companyId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<List<ProductInventoryView>> FetchInventory(string countryCode, string companyId)
|
||||||
|
{
|
||||||
|
var response = await _client.GetAsync($"{_api.OfficeCustomers}/{countryCode}/{companyId}/{_api.CrmInventoryExt}");
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
return new List<ProductInventoryView>();
|
||||||
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
|
return string.IsNullOrWhiteSpace(content)
|
||||||
|
? new List<ProductInventoryView>()
|
||||||
|
: JsonSerializer.Deserialize<List<ProductInventoryView>>(content, _options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch History for given customer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="companyId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<List<ProductHistoryView>> FetchHistory(string countryCode, string companyId)
|
||||||
|
{
|
||||||
|
var response = await _client.GetAsync($"{_api.OfficeCustomers}/{countryCode}/{companyId}/{_api.CrmProductExt}");
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode) return new List<ProductHistoryView>();
|
||||||
|
|
||||||
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
|
return string.IsNullOrWhiteSpace(content)
|
||||||
|
? new List<ProductHistoryView>()
|
||||||
|
: JsonSerializer.Deserialize<List<ProductHistoryView>>(content, _options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch history for given customer and a given product
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="companyId"></param>
|
||||||
|
/// <param name="sku"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<List<ProductHistoryView>> FetchHistory(string countryCode, string companyId, string sku)
|
||||||
|
{
|
||||||
|
var response = await _client.GetAsync($"{_api.OfficeCustomers}/{countryCode}/{companyId}/{_api.CrmProductExt}/{sku}");
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
return new List<ProductHistoryView>();
|
||||||
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
|
return string.IsNullOrWhiteSpace(content)
|
||||||
|
? new List<ProductHistoryView>()
|
||||||
|
: JsonSerializer.Deserialize<List<ProductHistoryView>>(content, _options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// RPC call to initiate remote server sync for given customer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="companyId"></param>
|
||||||
|
/// <param name="syncDate"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<string> ErpInvoiceToCrmRpc(string countryCode, string companyId, string syncDate)
|
||||||
|
{
|
||||||
|
var x = await _client.GetAsync($"{_api.OfficeCustomers}/{countryCode}/{companyId}/{_api.CrmRpcSyncExt}/{syncDate}");
|
||||||
|
if (!x.IsSuccessStatusCode)
|
||||||
|
return string.Empty;
|
||||||
|
var content = await x.Content.ReadAsStringAsync();
|
||||||
|
return content.Replace("\"", "");
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,7 +47,7 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
||||||
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||||
[Inject] public IAdvisorActivityRepository AdvisorActivityRepo { get; set; }
|
[Inject] public IAdvisorActivityRepository AdvisorActivityRepo { get; set; }
|
||||||
[Inject] public IAdvisorReportRepository AdvisorReportRepo { get; set; }
|
[Inject] public IAdvisorReportRepository AdvisorReportRepo { get; set; }
|
||||||
[Inject] public ICustomerHistoryRepository HistoryRepo { get; set; }
|
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||||
// variables
|
// variables
|
||||||
private readonly JsonSerializerOptions _options = new() {PropertyNameCaseInsensitive = true};
|
private readonly JsonSerializerOptions _options = new() {PropertyNameCaseInsensitive = true};
|
||||||
private SalesItemView SelectedItem { get; set; } = new();
|
private SalesItemView SelectedItem { get; set; } = new();
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace Wonky.Client.Pages;
|
||||||
|
|
||||||
public partial class AdvisorCustomerInventoryListPage : IDisposable
|
public partial class AdvisorCustomerInventoryListPage : IDisposable
|
||||||
{
|
{
|
||||||
[Inject] public ICustomerHistoryRepository HistoryRepo { get; set; }
|
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||||
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||||
[Inject] public IToastService Toaster { get; set; }
|
[Inject] public IToastService Toaster { get; set; }
|
||||||
|
|
|
@ -17,7 +17,7 @@ public partial class AdvisorCustomerInvoiceListPage : IDisposable
|
||||||
[Parameter] public string CompanyId { get; set; } = "";
|
[Parameter] public string CompanyId { get; set; } = "";
|
||||||
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||||
[Inject] public ICustomerHistoryRepository HistoryRepo { get; set; }
|
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||||
[Inject] public IToastService Toaster { get; set; }
|
[Inject] public IToastService Toaster { get; set; }
|
||||||
[Inject] public ILocalStorageService Storage { get; set; }
|
[Inject] public ILocalStorageService Storage { get; set; }
|
||||||
[Inject] public ILogger<AdvisorCustomerInvoiceListPage> Logger { get; set; }
|
[Inject] public ILogger<AdvisorCustomerInvoiceListPage> Logger { get; set; }
|
||||||
|
|
|
@ -38,7 +38,7 @@ public partial class AdvisorCustomerViewPage : IDisposable
|
||||||
[Inject] public ILogger<AdvisorCustomerViewPage> Logger { get; set; }
|
[Inject] public ILogger<AdvisorCustomerViewPage> Logger { get; set; }
|
||||||
[Inject] public NavigationManager Navigator { get; set; }
|
[Inject] public NavigationManager Navigator { get; set; }
|
||||||
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||||
[Inject] public ICustomerHistoryRepository HistoryRepo { get; set; }
|
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||||
[Inject] public IAdvisorContactRepository AdvisorContactRepo { get; set; }
|
[Inject] public IAdvisorContactRepository AdvisorContactRepo { get; set; }
|
||||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||||
[Inject] public VatInfoLookupService VatService { get; set; }
|
[Inject] public VatInfoLookupService VatService { get; set; }
|
||||||
|
|
|
@ -57,7 +57,7 @@ builder.Services.Configure<AppInfo>(builder.Configuration.GetSection("AppInfo"))
|
||||||
builder.Services.AddScoped<IAdvisorActivityRepository, AdvisorActivityRepository>();
|
builder.Services.AddScoped<IAdvisorActivityRepository, AdvisorActivityRepository>();
|
||||||
builder.Services.AddScoped<IAdvisorCustomerRepository, AdvisorCustomerRepository>();
|
builder.Services.AddScoped<IAdvisorCustomerRepository, AdvisorCustomerRepository>();
|
||||||
builder.Services.AddScoped<IAdvisorContactRepository, AdvisorContactRepository>();
|
builder.Services.AddScoped<IAdvisorContactRepository, AdvisorContactRepository>();
|
||||||
builder.Services.AddScoped<ICustomerHistoryRepository, CustomerHistoryRepository>();
|
builder.Services.AddScoped<IAdvisorCustomerHistoryRepository, AdvisorCustomerHistoryRepository>();
|
||||||
builder.Services.AddScoped<IAdvisorTaskItemRepository, AdvisorTaskItemRepository>();
|
builder.Services.AddScoped<IAdvisorTaskItemRepository, AdvisorTaskItemRepository>();
|
||||||
builder.Services.AddScoped<IWorkplaceRepository, WorkplaceRepository>();
|
builder.Services.AddScoped<IWorkplaceRepository, WorkplaceRepository>();
|
||||||
builder.Services.AddScoped<IAdvisorCatalogRepository, AdvisorCatalogRepository>();
|
builder.Services.AddScoped<IAdvisorCatalogRepository, AdvisorCatalogRepository>();
|
||||||
|
|
|
@ -29,7 +29,7 @@ public partial class InventoryReorderModal
|
||||||
{
|
{
|
||||||
[Parameter] public string CompanyId { get; set; } = "";
|
[Parameter] public string CompanyId { get; set; } = "";
|
||||||
[Parameter] public SalesItemView SalesItem { get; set; } = new();
|
[Parameter] public SalesItemView SalesItem { get; set; } = new();
|
||||||
[Inject] public ICustomerHistoryRepository HistoryRepo { get; set; }
|
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||||
[Parameter] public EventCallback<DraftItem> OnSelected { get; set; }
|
[Parameter] public EventCallback<DraftItem> OnSelected { get; set; }
|
||||||
private List<ProductHistoryView>? History { get; set; } = new();
|
private List<ProductHistoryView>? History { get; set; } = new();
|
||||||
private DraftItem SelectedItem { get; set; } = new();
|
private DraftItem SelectedItem { get; set; } = new();
|
||||||
|
|
|
@ -30,7 +30,7 @@ public partial class InvoiceViewModal : IDisposable
|
||||||
[Parameter] public string CompanyId { get; set; } = "";
|
[Parameter] public string CompanyId { get; set; } = "";
|
||||||
[Parameter] public string InvoiceId { get; set; } = "";
|
[Parameter] public string InvoiceId { get; set; } = "";
|
||||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||||
[Inject] public ICustomerHistoryRepository HistoryRepo { get; set; }
|
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||||
private string _modalDisplay = "";
|
private string _modalDisplay = "";
|
||||||
private bool _showBackdrop;
|
private bool _showBackdrop;
|
||||||
private InvoiceView Invoice { get; set; } = new();
|
private InvoiceView Invoice { get; set; } = new();
|
||||||
|
|
|
@ -29,7 +29,7 @@ public partial class ProductHistoryModal
|
||||||
// [Parameter] public EventCallback<decimal> OnSelected { get; set; }
|
// [Parameter] public EventCallback<decimal> OnSelected { get; set; }
|
||||||
[Parameter] public string CompanyId { get; set; } = "";
|
[Parameter] public string CompanyId { get; set; } = "";
|
||||||
[Parameter] public string ItemSku { get; set; } = "";
|
[Parameter] public string ItemSku { get; set; } = "";
|
||||||
[Inject] public ICustomerHistoryRepository HistoryRepo { get; set; }
|
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||||
private List<ProductHistoryView>? History { get; set; }
|
private List<ProductHistoryView>? History { get; set; }
|
||||||
private string ProductName { get; set; } = "";
|
private string ProductName { get; set; } = "";
|
||||||
private string _modalDisplay = "";
|
private string _modalDisplay = "";
|
||||||
|
|
|
@ -29,7 +29,7 @@ public partial class ProductPriceHistoryModal
|
||||||
[Parameter] public EventCallback<decimal> OnSelected { get; set; }
|
[Parameter] public EventCallback<decimal> OnSelected { get; set; }
|
||||||
[Parameter] public string CompanyId { get; set; } = "";
|
[Parameter] public string CompanyId { get; set; } = "";
|
||||||
[Parameter] public string Sku { get; set; } = "";
|
[Parameter] public string Sku { get; set; } = "";
|
||||||
[Inject] public ICustomerHistoryRepository HistoryRepo { get; set; }
|
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||||
private List<ProductHistoryView>? History { get; set; }
|
private List<ProductHistoryView>? History { get; set; }
|
||||||
private string ProductName { get; set; } = "";
|
private string ProductName { get; set; } = "";
|
||||||
private string _modalDisplay = "";
|
private string _modalDisplay = "";
|
||||||
|
|
Loading…
Reference in a new issue