Add brand-specific discount feature

-  Add `MudAutocomplete` for brand selection in UI
  Introduced a new component in `DiscountActionDialogBox.razor`.
- 🆕 Introduce `IsBrandEnable` property in ViewModel
  Added to manage the state of brand-specific discounts.
- 🔄 Update ViewModel logic for `IsBrandEnable`
  Ensured mutual exclusivity with other discount types.
- 🛠️ Handle brand selection in `SubmitEditAsync`
  Added logic for brand selection and validation.
- 🔍 Modify `SearchBrand` method in ViewModel
  Fetch and return brand data for selection.
- 📦 Change target framework to `net5.0`
  Updated `Netina.Common.csproj` and `Netina.Domain.csproj`.
- 🆙 Update `UpdateDiscountCommand` and `DiscountLDto`
  Included `BrandId` and `BrandName` properties.
- 🛠️ Modify `UpdateDiscountCommandHandler`
  Handle brand-specific discount updates.
- 🆕 Add `SubmitEditAsync` method in ViewModel
  For handling discount edits.

Changes made by Amir.H Khademi
master
Amir Hossein Khademi 2025-04-14 18:02:07 +03:30
parent 7ff0a1307f
commit 6b8eaac49c
2 changed files with 93 additions and 3 deletions

View File

@ -136,6 +136,32 @@
<MudSwitch @bind-Value="@ViewModel.IsProductEnable" class="mt-2" Size="Size.Large" T="bool" Label="تخفیف برای محصول خاص" Color="Color.Info" />
</MudItem>
<MudItem sm="7">
<MudAutocomplete Disabled="@ViewModel.IsProductEnable.Not()" ToStringFunc="dto => dto.PersianName" @bind-Value="@ViewModel.SelectedBrand"
SearchFunc="ViewModel.SearchBrand"
T="BrandSDto"
Label="برندها"
Variant="Variant.Outlined">
<ProgressIndicatorInPopoverTemplate>
<MudList Clickable="false">
<MudListItem>
<div class="flex flex-row w-full mx-auto">
<MudProgressCircular class="my-auto mr-1 -ml-4" Size="Size.Small" Indeterminate="true" />
<p class="font-bold my-1 mx-auto text-md">منتظر بمانید</p>
</div>
</MudListItem>
</MudList>
</ProgressIndicatorInPopoverTemplate>
<ItemTemplate Context="e">
<p>@e.PersianName</p>
</ItemTemplate>
</MudAutocomplete>
</MudItem>
<MudItem sm="5">
<MudSwitch @bind-Value="@ViewModel.IsProductEnable" class="mt-2" Size="Size.Large" T="bool" Label="تخفیف برای برند خاص" Color="Color.Info" />
</MudItem>
<MudItem sm="7">
</MudItem>
<MudItem sm="5">

View File

@ -40,8 +40,23 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
IsEditing = true;
}
private bool _isProductEnable;
private bool _isBrandEnable;
public bool IsBrandEnable
{
get => _isBrandEnable;
set
{
_isBrandEnable = value;
if (_isBrandEnable)
{
IsCategoryEnable = false;
IsProductEnable = false;
IsAllEnable = false;
}
}
}
private bool _isProductEnable;
public bool IsProductEnable
{
get => _isProductEnable;
@ -51,10 +66,12 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
if (_isProductEnable)
{
IsCategoryEnable = false;
IsBrandEnable = false;
IsAllEnable = false;
}
}
}
private bool _isCategoryEnable;
public bool IsCategoryEnable
{
@ -65,6 +82,7 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
if (_isCategoryEnable)
{
IsProductEnable = false;
IsBrandEnable = false;
IsAllEnable = false;
}
}
@ -79,6 +97,7 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
if (_isAllEnable)
{
IsCategoryEnable = false;
IsBrandEnable = false;
IsProductEnable = false;
}
}
@ -123,6 +142,10 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
if (PageDto.CategoryId != default)
SelectedCategory = new ProductCategorySDto { Id = PageDto.CategoryId, Name = PageDto.CategoryName };
if (PageDto.ProductId != default)
SelectedProduct = new ProductSDto { Id = PageDto.ProductId, PersianName = PageDto.ProductName };
if (PageDto.ProductId != default)
SelectedProduct = new ProductSDto { Id = PageDto.ProductId, PersianName = PageDto.ProductName };
@ -185,6 +208,13 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
throw new Exception("کالا مورد نظر را برای تخفیف انتخاب نمایید");
PageDto.ProductId = SelectedProduct.Id;
}
else if (IsBrandEnable)
{
PageDto.Type = DiscountType.Brand;
if (SelectedBrand == null)
throw new Exception("برند مورد نظر را برای تخفیف انتخاب نمایید");
PageDto.BrandId = SelectedBrand.Id;
}
var token = await _userUtility.GetBearerTokenAsync();
if (token == null)
@ -216,7 +246,7 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
PageDto.IsForFirstPurchase,
PageDto.ProductId,
PageDto.CategoryId,
default);
PageDto.BrandId);
await _restWrapper.CrudDtoApiRest<Discount,DiscountLDto, Guid>(Address.DiscountController).Create<CreateDiscountCommand>(request, token);
_snackbar.Add($"ساخت تخفیف با موفقیت انجام شد", Severity.Success);
@ -244,6 +274,7 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
IsProcessing = false;
}
}
public async Task SubmitEditAsync()
{
try
@ -270,6 +301,13 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
throw new Exception("کالا مورد نظر را برای تخفیف انتخاب نمایید");
PageDto.ProductId = SelectedProduct.Id;
}
else if (IsBrandEnable)
{
PageDto.Type = DiscountType.Brand;
if (SelectedBrand == null)
throw new Exception("برند مورد نظر را برای تخفیف انتخاب نمایید");
PageDto.BrandId = SelectedBrand.Id;
}
var token = await _userUtility.GetBearerTokenAsync();
if (token == null)
@ -298,7 +336,8 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
PageDto.IsSpecialOffer,
PageDto.IsForFirstPurchase,
PageDto.ProductId,
PageDto.CategoryId);
PageDto.CategoryId,
PageDto.BrandId);
await _restWrapper.CrudApiRest<Discount, Guid>(Address.DiscountController).Update<UpdateDiscountCommand>(request, token);
_snackbar.Add($"ویرایش تخفیف با موفقیت انجام شد", Severity.Success);
_mudDialog.Close(true);
@ -379,4 +418,29 @@ public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
return _products;
}
}
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;
}
}
}