440 lines
16 KiB
C#
440 lines
16 KiB
C#
using Netina.Domain.Entities.Seo;
|
|
|
|
namespace Netina.AdminPanel.PWA.Dialogs;
|
|
|
|
public class ProductActionDialogBoxViewModel : BaseViewModel<ProductLDto>
|
|
{
|
|
private readonly ISnackbar _snackbar;
|
|
private readonly IRestWrapper _restWrapper;
|
|
private readonly IUserUtility _userUtility;
|
|
private readonly IDialogService _dialogService;
|
|
private readonly MudDialogInstance _mudDialog;
|
|
|
|
public ProductActionDialogBoxViewModel(ISnackbar snackbar,
|
|
IRestWrapper restWrapper,
|
|
IUserUtility userUtility,
|
|
IDialogService dialogService,
|
|
MudDialogInstance mudDialog) : base(userUtility)
|
|
{
|
|
_snackbar = snackbar;
|
|
_restWrapper = restWrapper;
|
|
_userUtility = userUtility;
|
|
_dialogService = dialogService;
|
|
_mudDialog = mudDialog;
|
|
}
|
|
public ProductActionDialogBoxViewModel(ISnackbar snackbar,
|
|
IRestWrapper restWrapper,
|
|
IUserUtility userUtility,
|
|
IDialogService dialogService,
|
|
MudDialogInstance mudDialog,
|
|
ProductSDto product) : base(userUtility)
|
|
{
|
|
_snackbar = snackbar;
|
|
_restWrapper = restWrapper;
|
|
_userUtility = userUtility;
|
|
_dialogService = dialogService;
|
|
_mudDialog = mudDialog;
|
|
Product = product;
|
|
}
|
|
|
|
private ProductSDto? _product = null;
|
|
public ProductSDto? Product
|
|
{
|
|
get => _product;
|
|
set
|
|
{
|
|
_product = value;
|
|
if (_product != null)
|
|
{
|
|
IsEditing = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Cancel() => _mudDialog.Cancel();
|
|
|
|
public bool IsEditing = false;
|
|
private bool _isSpecialOffer;
|
|
|
|
public bool IsSpecialOffer
|
|
{
|
|
get => _isSpecialOffer;
|
|
set
|
|
{
|
|
_isSpecialOffer = value;
|
|
PageDto.IsSpecialOffer = value;
|
|
if (!value)
|
|
{
|
|
IsAmountType = value;
|
|
IsPercentType = value;
|
|
}
|
|
else if(!IsAmountType)
|
|
IsPercentType = true;
|
|
}
|
|
}
|
|
|
|
public string SpecificationTitle = string.Empty;
|
|
public string SpecificationValue = string.Empty;
|
|
public readonly ObservableCollection<SpecificationSDto> Specifications = new ObservableCollection<SpecificationSDto>();
|
|
public readonly ObservableCollection<StorageFileSDto> Files = new ObservableCollection<StorageFileSDto>();
|
|
|
|
|
|
public override async Task InitializeAsync()
|
|
{
|
|
if (IsEditing && _product != null)
|
|
{
|
|
try
|
|
{
|
|
IsProcessing = true;
|
|
var response = await _restWrapper.ProductRestApi.ReadOne(_product.Id);
|
|
var productLDto = response.Product;
|
|
PageDto = productLDto;
|
|
productLDto.Specifications.ForEach(s => Specifications.Add(s));
|
|
productLDto.Files.ForEach(f => Files.Add(f));
|
|
productLDto.MetaTags.ForEach(m => MetaTags.Add(m));
|
|
SelectedCategory = new ProductCategorySDto { Id = productLDto.CategoryId, Name = productLDto.CategoryName };
|
|
SelectedBrand = new BrandSDto { Id = productLDto.BrandId, PersianName = productLDto.BrandName };
|
|
PageDto.IsSpecialOffer = productLDto.IsSpecialOffer;
|
|
IsSpecialOffer = PageDto.IsSpecialOffer;
|
|
|
|
if (!PageDto.Slug.IsNullOrEmpty())
|
|
{
|
|
var faq = await _restWrapper.FaqApiRest.ReadOne(PageDto.GetWebSiteUrl());
|
|
if (faq.Faqs != null)
|
|
{
|
|
foreach (var pair in faq.Faqs)
|
|
Faqs.Add(pair.Key, pair.Value);
|
|
}
|
|
}
|
|
|
|
if (productLDto.SpecialOffer != null)
|
|
{
|
|
Discount = productLDto.SpecialOffer;
|
|
switch (Discount.AmountType)
|
|
{
|
|
case DiscountAmountType.Amount:
|
|
IsAmountType = true;
|
|
IsPercentType = false;
|
|
break;
|
|
case DiscountAmountType.Percent:
|
|
IsAmountType = false;
|
|
IsPercentType = true;
|
|
break;
|
|
}
|
|
|
|
ExpireDate = Discount.ExpireDate;
|
|
StartDate = Discount.StartDate;
|
|
IsSpecialOffer = true;
|
|
}
|
|
}
|
|
catch (ApiException ex)
|
|
{
|
|
var exe = await ex.GetContentAsAsync<ApiResult>();
|
|
if (exe != null)
|
|
_snackbar.Add(exe.Message, Severity.Error);
|
|
_snackbar.Add(ex.Content, Severity.Error);
|
|
_mudDialog.Cancel();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_snackbar.Add(e.Message, Severity.Error);
|
|
_mudDialog.Cancel();
|
|
}
|
|
finally
|
|
{
|
|
|
|
IsProcessing = false;
|
|
}
|
|
};
|
|
}
|
|
|
|
public async Task SubmitEditAsync()
|
|
{
|
|
try
|
|
{
|
|
IsProcessing = true;
|
|
if (Product == null || Product.Id == default)
|
|
throw new Exception("محصول اشتباه است");
|
|
if (SelectedCategory == null)
|
|
throw new Exception("لطفا یک دسته بندی انتخاب کنید");
|
|
if (SelectedBrand == null)
|
|
throw new Exception("لطفا یک برند انتخاب کنید");
|
|
var token = await _userUtility.GetBearerTokenAsync();
|
|
if (token == null)
|
|
throw new Exception("Token is null");
|
|
PageDto.Specifications = Specifications.ToList();
|
|
PageDto.Files = Files.ToList();
|
|
PageDto.Id = Product.Id;
|
|
PageDto.CategoryId = SelectedCategory?.Id ?? default;
|
|
PageDto.BrandId = SelectedBrand?.Id ?? default;
|
|
if (PageDto.IsSpecialOffer)
|
|
{
|
|
if (ExpireDate != null)
|
|
Discount.ExpireDate = ExpireDate.Value;
|
|
if (StartDate != null)
|
|
Discount.StartDate = StartDate.Value;
|
|
PageDto.SpecialOffer = Discount;
|
|
}
|
|
|
|
var request = new UpdateProductCommand(PageDto.Id,
|
|
PageDto.PersianName,
|
|
PageDto.EnglishName,
|
|
PageDto.Summery,
|
|
PageDto.ExpertCheck,
|
|
PageDto.Tags,
|
|
PageDto.Warranty,
|
|
PageDto.BeDisplayed,
|
|
PageDto.Cost,
|
|
PageDto.PackingCost,
|
|
PageDto.Stock,
|
|
PageDto.HasExpressDelivery,
|
|
PageDto.MaxOrderCount,
|
|
PageDto.IsSpecialOffer,
|
|
PageDto.BrandId,
|
|
PageDto.CategoryId,
|
|
PageDto.SpecialOffer ?? new DiscountSDto(),
|
|
PageDto.Specifications,
|
|
PageDto.Files,
|
|
Faqs,
|
|
MetaTags.ToDictionary(x => x.Type, x => x.Value));
|
|
|
|
await _restWrapper.CrudApiRest<Product, Guid>(Address.ProductController).Update<UpdateProductCommand>(request, token);
|
|
_snackbar.Add($"ویرایش محصول {PageDto.PersianName} با موفقیت انجام شد", Severity.Success);
|
|
_mudDialog.Close();
|
|
}
|
|
catch (ApiException ex)
|
|
{
|
|
var exe = await ex.GetContentAsAsync<ApiResult>();
|
|
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_snackbar.Add(e.Message, Severity.Error);
|
|
}
|
|
finally
|
|
{
|
|
|
|
IsProcessing = false;
|
|
}
|
|
}
|
|
public async Task SubmitCreateAsync()
|
|
{
|
|
try
|
|
{
|
|
IsProcessing = true;
|
|
if (SelectedCategory == null)
|
|
throw new Exception("لطفا یک دسته بندی انتخاب کنید");
|
|
if (SelectedBrand == null)
|
|
throw new Exception("لطفا یک برند انتخاب کنید");
|
|
var token = await _userUtility.GetBearerTokenAsync();
|
|
if (token == null)
|
|
throw new Exception("Token is null");
|
|
PageDto.Specifications = Specifications.ToList();
|
|
PageDto.Files = Files.ToList();
|
|
PageDto.CategoryId = SelectedCategory?.Id ?? default;
|
|
PageDto.BrandId = SelectedBrand?.Id ?? default;
|
|
if (PageDto.IsSpecialOffer)
|
|
{
|
|
if (ExpireDate != null)
|
|
Discount.ExpireDate = ExpireDate.Value;
|
|
if (StartDate != null)
|
|
Discount.StartDate = StartDate.Value;
|
|
PageDto.SpecialOffer = Discount;
|
|
}
|
|
var request = new CreateProductCommand(
|
|
PageDto.PersianName,
|
|
PageDto.EnglishName,
|
|
PageDto.Summery,
|
|
PageDto.ExpertCheck,
|
|
PageDto.Tags,
|
|
PageDto.Warranty,
|
|
PageDto.BeDisplayed,
|
|
PageDto.Cost,
|
|
PageDto.PackingCost,
|
|
PageDto.Stock,
|
|
PageDto.HasExpressDelivery,
|
|
PageDto.MaxOrderCount,
|
|
PageDto.IsSpecialOffer,
|
|
PageDto.BrandId,
|
|
PageDto.CategoryId,
|
|
PageDto.SpecialOffer ?? new DiscountSDto(),
|
|
PageDto.Specifications,
|
|
PageDto.Files,
|
|
Faqs,
|
|
MetaTags.ToDictionary(x => x.Type, x => x.Value));
|
|
await _restWrapper.CrudDtoApiRest<Product, ProductLDto, Guid>(Address.ProductController).Create<CreateProductCommand>(request, token);
|
|
|
|
_snackbar.Add($"ساخت محصول {PageDto.PersianName} با موفقیت انجام شد", Severity.Success);
|
|
_mudDialog.Close(DialogResult.Ok(true));
|
|
}
|
|
catch (ApiException ex)
|
|
{
|
|
var exe = await ex.GetContentAsAsync<ApiResult>();
|
|
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_snackbar.Add(e.Message, Severity.Error);
|
|
}
|
|
finally
|
|
{
|
|
|
|
IsProcessing = false;
|
|
}
|
|
}
|
|
|
|
public bool IsPercentType { get; set; } = true;
|
|
public bool IsAmountType { get; set; }
|
|
public DateTime? ExpireDate { get; set; }
|
|
public DateTime? StartDate { get; set; }
|
|
public DiscountSDto Discount { get; set; } = new DiscountSDto();
|
|
public void AmountTypeChanged(DiscountAmountType type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case DiscountAmountType.Amount:
|
|
IsAmountType = true;
|
|
IsPercentType = false;
|
|
Discount.AmountType = DiscountAmountType.Amount;
|
|
break;
|
|
case DiscountAmountType.Percent:
|
|
IsAmountType = false;
|
|
IsPercentType = true;
|
|
Discount.AmountType = DiscountAmountType.Percent;
|
|
break;
|
|
}
|
|
}
|
|
|
|
private List<ProductCategorySDto> _productCategories = new List<ProductCategorySDto>();
|
|
public ProductCategorySDto? SelectedCategory;
|
|
public async Task<IEnumerable<ProductCategorySDto>> SearchProductCategory(string category)
|
|
{
|
|
try
|
|
{
|
|
if (category.IsNullOrEmpty())
|
|
_productCategories = await _restWrapper.ProductCategoryRestApi.ReadAll(0);
|
|
else
|
|
_productCategories = await _restWrapper.ProductCategoryRestApi.ReadAll(category);
|
|
return _productCategories;
|
|
}
|
|
catch (ApiException ex)
|
|
{
|
|
var exe = await ex.GetContentAsAsync<ApiResult>();
|
|
if (exe != null)
|
|
_snackbar.Add(exe.Message, Severity.Error);
|
|
_snackbar.Add(ex.Content, Severity.Error);
|
|
return _productCategories;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_snackbar.Add(e.Message, Severity.Error);
|
|
return _productCategories;
|
|
}
|
|
}
|
|
|
|
private List<BrandSDto> _brands = new List<BrandSDto>();
|
|
public BrandSDto? SelectedBrand;
|
|
public async Task<IEnumerable<BrandSDto>> SearchBrand(string brand)
|
|
{
|
|
try
|
|
{
|
|
if (brand.IsNullOrEmpty())
|
|
_brands = await _restWrapper.BrandRestApi.ReadAll(0);
|
|
else
|
|
_brands = await _restWrapper.BrandRestApi.ReadAll(brand);
|
|
return _brands;
|
|
}
|
|
catch (ApiException ex)
|
|
{
|
|
var exe = await ex.GetContentAsAsync<ApiResult>();
|
|
_snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
|
|
return _brands;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_snackbar.Add(e.Message, Severity.Error);
|
|
return _brands;
|
|
}
|
|
}
|
|
|
|
|
|
public string FaqQuestion { get; set; } = string.Empty;
|
|
public string FaqAnswer { get; set; } = string.Empty;
|
|
public Dictionary<string, string> Faqs = new();
|
|
public void AddFaq()
|
|
{
|
|
try
|
|
{
|
|
if (FaqAnswer.IsNullOrEmpty())
|
|
throw new Exception("لطفا پاسخ را وارد کنید");
|
|
|
|
if (FaqQuestion.IsNullOrEmpty())
|
|
throw new Exception("لطفا سوال را وارد کنید");
|
|
|
|
Faqs.Add(FaqQuestion, FaqAnswer);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_snackbar.Add(e.Message, Severity.Error);
|
|
}
|
|
}
|
|
|
|
public readonly ObservableCollection<MetaTagSDto> MetaTags = new();
|
|
public string MetaTagType { get; set; } = string.Empty;
|
|
public string MetaTagValue { get; set; } = string.Empty;
|
|
public void AddMetaTag()
|
|
{
|
|
try
|
|
{
|
|
if (MetaTagType.IsNullOrEmpty())
|
|
throw new Exception("لطفا نوع متا مورد نظر را وارد کنید");
|
|
if (MetaTagValue.IsNullOrEmpty())
|
|
throw new Exception("لطفا مقدار متا مورد نظر را وارد کنید");
|
|
|
|
MetaTags.Add(new MetaTagSDto() { Type = MetaTagType, Value = MetaTagValue });
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_snackbar.Add(e.Message, Severity.Error);
|
|
}
|
|
}
|
|
|
|
public void AddSpecification()
|
|
{
|
|
try
|
|
{
|
|
if (SpecificationTitle.IsNullOrEmpty())
|
|
throw new AppException("عنوان ویژگی مورد نظر را وارد کنید");
|
|
if (SpecificationValue.IsNullOrEmpty())
|
|
throw new AppException("مقدار ویژگی مورد نظر را وارد کنید");
|
|
Specifications.Add(new SpecificationSDto { Title = SpecificationTitle.ToString(), Value = SpecificationValue.ToString() });
|
|
|
|
SpecificationTitle = string.Empty;
|
|
SpecificationValue = string.Empty;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_snackbar.Add(e.Message, Severity.Error);
|
|
}
|
|
}
|
|
public void RemoveSpecification(SpecificationSDto specification)
|
|
{
|
|
var spec = Specifications.FirstOrDefault(s => s.Value == specification.Value && s.Title == specification.Title);
|
|
if (spec != null)
|
|
Specifications.Remove(spec);
|
|
}
|
|
|
|
public async Task SelectFileAsync()
|
|
{
|
|
DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true };
|
|
var dialog = await _dialogService.ShowAsync<StorageDialogBox>("انتخاب عکس", maxWidth);
|
|
var result = await dialog.Result;
|
|
var file = result.Data;
|
|
if (file is StorageFileSDto storageFile)
|
|
Files.Add(storageFile);
|
|
}
|
|
public void RemoveFile(StorageFileSDto file)
|
|
{
|
|
Files.Remove(file);
|
|
}
|
|
} |