diff --git a/Back/Back.csproj b/Back/Back.csproj index 18bc412..7cd4417 100644 --- a/Back/Back.csproj +++ b/Back/Back.csproj @@ -6,6 +6,13 @@ enable + + + + + + + @@ -24,10 +31,6 @@ - - - - diff --git a/Back/Common/eActionValidation.cs b/Back/Common/eActionValidation.cs new file mode 100644 index 0000000..a2a7e75 --- /dev/null +++ b/Back/Common/eActionValidation.cs @@ -0,0 +1,8 @@ +namespace Back.Common +{ + public enum eActionValidation + { + add, + update + } +} diff --git a/Back/Controllers/CustomerController.cs b/Back/Controllers/CustomerController.cs index fc84c4d..61a8ccf 100644 --- a/Back/Controllers/CustomerController.cs +++ b/Back/Controllers/CustomerController.cs @@ -1,8 +1,12 @@ -using Back.Services; +using Back.Common; +using Back.Services; using Back.Validations; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Service; using Shared.DTOs; +using System.Net; +using System.Reflection.Emit; namespace Back.Controllers { @@ -14,11 +18,11 @@ namespace Back.Controllers private readonly CheckPermission _checkPermission; private readonly servUser _servUser; private readonly servCustomer _servCus; - private readonly AddCustomerValidation _addCustomerValidation; + private readonly AddOrCustomerValidation _addorupdateCustomerValidation; public CustomerController(CheckPermission checkPermission, servUser servUser - , servCustomer servCus, AddCustomerValidation addCustomerValidation) + , servCustomer servCus, AddOrCustomerValidation addorupdateCustomerValidation) { - _addCustomerValidation = addCustomerValidation; + _addorupdateCustomerValidation = addorupdateCustomerValidation; _checkPermission = checkPermission; _servUser = servUser; _servCus = servCus; @@ -30,7 +34,7 @@ namespace Back.Controllers var UserID = claim.Value; var user = await _servUser.GetUserByUserID(Convert.ToInt32(UserID)); - if (!await _checkPermission.AllowSYSGetCustomer(Convert.ToInt32(UserID), user.RolUsers.First().CompanyID)) return Forbid( "شما دسترسی به خواندن اطلاعات مشتری را نداربد"); + if (!await _checkPermission.AllowSYSGetCustomer(Convert.ToInt32(UserID), user.RolUsers.First().CompanyID)) return Forbid("شما دسترسی به خواندن اطلاعات مشتری را نداربد"); return Ok(await _servCus.GetCustomers(user.RolUsers.First().CompanyID, itemSerch)); @@ -43,11 +47,11 @@ namespace Back.Controllers var UserID = claim.Value; var user = await _servUser.GetUserByUserID(Convert.ToInt32(UserID)); - var resultValidationmodel = await _addCustomerValidation.ValidateAsync(Tuple.Create(user.RolUsers.First().CompanyID,item)); + var resultValidationmodel = await _addorupdateCustomerValidation.ValidateAsync(Tuple.Create(user.RolUsers.First().CompanyID, item, eActionValidation.add)); if (!resultValidationmodel.IsValid) return BadRequest(resultValidationmodel.Errors.Select(s => s.ErrorMessage).ToList()); - return Ok(_servCus.AddCustomer(new Data.Models.Customer + return Ok(await _servCus.AddOrUpdateCustomer(new Data.Models.Customer { Address = item.Address, BranchID = item.BranchID, @@ -62,7 +66,59 @@ namespace Back.Controllers Phone = item.Phone, ZipCode = item.ZipCode, IsDeleted = false - })) ; + })); + } + [HttpPut("Update")] + public async Task> Update(RCustomer item) + { + //-----GetUserAndCompany + var claim = HttpContext.User.Claims.First(c => c.Type == "UserID"); + var UserID = claim.Value; + var user = await _servUser.GetUserByUserID(Convert.ToInt32(UserID)); + + //-----Validaton + var resultValidationmodel = await _addorupdateCustomerValidation.ValidateAsync(Tuple.Create(user.RolUsers.First().CompanyID, item, eActionValidation.update)); + if (!resultValidationmodel.IsValid) + return BadRequest(resultValidationmodel.Errors.Select(s => s.ErrorMessage).ToList()); + + //-----Get Cus + var cus = await _servCus.GetCustomerByCustomerID(item.ID.Value, user.RolUsers.First().CompanyID); + if (cus == null) + return BadRequest(new List { "Cus notFound..." }); + + //-----change Cus + cus.Address = item.Address; + cus.BranchID = item.BranchID; + cus.CompanyID = user.RolUsers.First().CompanyID; + cus.CustomerType = item.CustomerType; + cus.EconomicCode = item.EconomicCode; + cus.Email = item.Email; + cus.FullName = item.FullName; + cus.Info = item.Info; + cus.MeliCode = item.MeliCode; + cus.PassportNumber = item.PassportNumber; + cus.Phone = item.Phone; + cus.ZipCode = item.ZipCode; + cus.IsDeleted = false; + + //----Update and sendResult + return Ok(await _servCus.AddOrUpdateCustomer(cus)); + } + [HttpDelete("Delete/{ID}")] + public async Task> Delete(int ID) + { + //-----GetUserAndCompany + var claim = HttpContext.User.Claims.First(c => c.Type == "UserID"); + var UserID = claim.Value; + var user = await _servUser.GetUserByUserID(Convert.ToInt32(UserID)); + + //-----Get Cus + var cus = await _servCus.GetCustomerByCustomerID(ID, user.RolUsers.First().CompanyID); + if (cus == null) + return NotFound(); + + //----Update and sendResult + return Ok(await _servCus.DeleteCustomer(cus)); } } } diff --git a/Back/Program.cs b/Back/Program.cs index 60d9175..1beb178 100644 --- a/Back/Program.cs +++ b/Back/Program.cs @@ -39,7 +39,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(c => new mpNuget.RestClient("09119660045", "C54S2")); string origins = "OriginTaxPayer"; diff --git a/Back/Services/servCustomer.cs b/Back/Services/servCustomer.cs index 41138b1..36b3811 100644 --- a/Back/Services/servCustomer.cs +++ b/Back/Services/servCustomer.cs @@ -58,24 +58,24 @@ namespace Back.Services PassportNumber = s.PassportNumber, CustomerType= s.CustomerType // CompanyID=s.CompanyID - }) + }).OrderByDescending(o=>o.ID) .Paging(itemSerch.PageIndex, itemSerch.PageSize); } - //public async Task GetCustomerByCustomerID(int CustomerID, int CompanyID) - //{ - // return await _repositores.GET() - // .Where(w => w.ID == CustomerID && w.CompanyID==CompanyID && !w.IsDeleted).FirstOrDefaultAsync(); - //} + public async Task GetCustomerByCustomerID(int CustomerID, int CompanyID) + { + return await _repoCus + .Get(w => w.ID == CustomerID && w.CompanyID == CompanyID && !w.IsDeleted).FirstOrDefaultAsync(); + } //public async Task GetCustomerByCustomerID(int CustomerID) //{ // return await _repositores.GET() // .Where(w => w.ID == CustomerID && !w.IsDeleted).FirstOrDefaultAsync(); //} - //public async Task ExistCustomerByCustomerID(int CustomerID, int CompanyID) - //{ - // return await _repositores.GET() - // .AnyAsync(w => w.ID == CustomerID && w.CompanyID == CompanyID && !w.IsDeleted); - //} + public async Task ExistCustomerByCustomerID(int CustomerID, int CompanyID) + { + return await _repoCus + .Get(w => w.ID == CustomerID && w.CompanyID == CompanyID && !w.IsDeleted).AnyAsync(); + } //public async Task GetCustomerByCustomerIDByDTO(int CustomerID) //{ // return await _repositores.GET() @@ -98,7 +98,7 @@ namespace Back.Services // }) // .FirstOrDefaultAsync(); //} - public async Task AddCustomer(Customer item) + public async Task AddOrUpdateCustomer(Customer item) { try { @@ -113,7 +113,7 @@ namespace Back.Services //}; //_contextMongodb.InsertItem(log); - if (item.ID == null || item.ID == 0) + if (item.ID == null || item.ID <= 0) { var ret = await _repoCus.AddBoolResultAsync(item); await _checkPermission.ExtensionofAccess(item.CompanyID, 5, "-1"); @@ -140,41 +140,40 @@ namespace Back.Services } } - //public async Task DeleteCustomer(Customer item) - //{ + public async Task DeleteCustomer(Customer item) + { - // try - // { - // item.IsDeleted = true; - // _repositores.UPDATE(item); - // SysLog log = new SysLog() - // { - // TraceIdentifierID = _httpContextAccessor.HttpContext.TraceIdentifier, - // Datetime = DateTime.Now.ConvertMiladiToShamsi(), - // Method = $"{_httpContextAccessor.HttpContext.Request.Method}/{this.GetType().FullName}/DeleteCustomer", - // Value = JsonConvert.SerializeObject(item.ID), - // Route = _httpContextAccessor.HttpContext.Request.Path, - // Type = "User" - // }; - // _contextMongodb.InsertItem(log); - // return true; - // } - // catch (Exception ex) - // { - // SysLog log = new SysLog() - // { - // TraceIdentifierID = _httpContextAccessor.HttpContext.TraceIdentifier, - // Datetime = DateTime.Now.ConvertMiladiToShamsi(), - // Method = $"{_httpContextAccessor.HttpContext.Request.Method}/{this.GetType().FullName}/DeleteCustomer", - // Value = ex.Message, - // Route = _httpContextAccessor.HttpContext.Request.Path, - // Type = "catch" - // }; - // _contextMongodb.InsertItem(log); - // return false; + try + { + item.IsDeleted = true; + return await _repoCus.UpdateAsync(item); + //SysLog log = new SysLog() + //{ + // TraceIdentifierID = _httpContextAccessor.HttpContext.TraceIdentifier, + // Datetime = DateTime.Now.ConvertMiladiToShamsi(), + // Method = $"{_httpContextAccessor.HttpContext.Request.Method}/{this.GetType().FullName}/DeleteCustomer", + // Value = JsonConvert.SerializeObject(item.ID), + // Route = _httpContextAccessor.HttpContext.Request.Path, + // Type = "User" + //}; + //_contextMongodb.InsertItem(log); + } + catch (Exception ex) + { + //SysLog log = new SysLog() + //{ + // TraceIdentifierID = _httpContextAccessor.HttpContext.TraceIdentifier, + // Datetime = DateTime.Now.ConvertMiladiToShamsi(), + // Method = $"{_httpContextAccessor.HttpContext.Request.Method}/{this.GetType().FullName}/DeleteCustomer", + // Value = ex.Message, + // Route = _httpContextAccessor.HttpContext.Request.Path, + // Type = "catch" + //}; + //_contextMongodb.InsertItem(log); + return false; - // } - //} + } + } } diff --git a/Back/Validations/AddCustomerValidation.cs b/Back/Validations/AddCustomerValidation.cs deleted file mode 100644 index 400e16c..0000000 --- a/Back/Validations/AddCustomerValidation.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Back.Services; -using FluentValidation; -using Shared.DTOs; - -namespace Back.Validations -{ - public class AddCustomerValidation : AbstractValidator> - { - public AddCustomerValidation(CheckPermission _checkPermission) - { - CascadeMode = CascadeMode.Stop; - RuleFor(r => r.Item1) - .Custom((CompanyID, context) => { - if (! _checkPermission.AllowAddCustomerInCompany(CompanyID).Result) - context.AddFailure("اضافه کردن مشتری محدود شده است"); - }); - - - RuleFor(r => r.Item2.FullName) - .NotNull().WithMessage("نام نمی تواند خالی باشذ") - .NotEmpty().WithMessage("نام نمی تواند خالی باشذ") - .MinimumLength(5).WithMessage("حداقل کارکتر مجار نام 5 می باشد"); - - RuleFor(r => r.Item2.Phone) - .NotNull().WithMessage("تلفن نمی تواند خالی باشذ") - .NotEmpty().WithMessage("تلفن نمی تواند خالی باشذ") - .MinimumLength(8).WithMessage("حداقل کارکتر مجار تلفن 8 می باشد"); - - RuleFor(r => r.Item2.Email) - .Custom((model, context) => { - if (!string.IsNullOrEmpty(model) && (!model.Contains("@") || !model.Contains("."))) - context.AddFailure("فرمت پست الکترونیک صحبح نمی باشد"); - }); - RuleFor(r => r.Item2.EconomicCode) - .Custom((model, context) => { - if (!string.IsNullOrEmpty(model) && (model.Length<11 || model.Length > 14)) - context.AddFailure("تعداد شماره اقتصادی صحبح نمی باشد"); - }); - RuleFor(r => r.Item2.BranchID) - .Custom((model, context) => { - if (!string.IsNullOrEmpty(model) && (model.Length > 10 )) - context.AddFailure("تعداد کد شعبه صحبح نمی باشد"); - }); - RuleFor(r => r.Item2.ZipCode) - .Custom((model, context) => { - if (!string.IsNullOrEmpty(model) && (model.Length !=10)) - context.AddFailure("تعداد کد پستی صحبح نمی باشد"); - }); - RuleFor(r => r.Item2.MeliCode) - .Custom((model, context) => { - if (!string.IsNullOrEmpty(model) && (model.Length < 10 || model.Length > 12)) - context.AddFailure("تعداد شناسه ملی صحبح نمی باشد"); - }); - RuleFor(r => r.Item2.PassportNumber) - .Custom((model, context) => { - if (!string.IsNullOrEmpty(model) && (model.Length!=9)) - context.AddFailure("تعداد شماره گذرنامه صحبح نمی باشد"); - }); - } - } -} diff --git a/Back/Validations/AddOrCustomerValidation.cs b/Back/Validations/AddOrCustomerValidation.cs new file mode 100644 index 0000000..4581cf2 --- /dev/null +++ b/Back/Validations/AddOrCustomerValidation.cs @@ -0,0 +1,97 @@ +using Back.Common; +using Back.Services; +using FluentValidation; +using Shared.DTOs; + +namespace Back.Validations +{ + public class AddOrCustomerValidation : AbstractValidator> + { + public AddOrCustomerValidation(CheckPermission _checkPermission, servCustomer servCustomer) + { + CascadeMode = CascadeMode.Stop; + When(r => r.Item3 == eActionValidation.add, () => + { + RuleFor(r => r.Item1) + .Custom((CompanyID, context) => + { + if (!_checkPermission.AllowAddCustomerInCompany(CompanyID).Result) + context.AddFailure("اضافه کردن مشتری محدود شده است"); + }); + }); + + When(r => r.Item3 == eActionValidation.update, () => + { + RuleFor(r => r) + .Custom((model, context) => + { + var companyid = model.Item1; + if (!model.Item2.ID.HasValue || model.Item2.ID <= 0) + context.AddFailure("شناسه مشتری نمی تواند خالی باشذ"); + else + { + var customerid = model.Item2.ID.Value; + if (!servCustomer.ExistCustomerByCustomerID(customerid, companyid).Result) + context.AddFailure("مشتری با این شناسه یافت نشد"); + } + }); + }); + + + RuleFor(r => r.Item2.FullName) + .NotNull().WithMessage("نام نمی تواند خالی باشذ") + .NotEmpty().WithMessage("نام نمی تواند خالی باشذ") + .MinimumLength(5).WithMessage("حداقل کارکتر مجار نام 5 می باشد"); + + RuleFor(r => r.Item2.Phone) + .Custom((model, context) => + { + if (!string.IsNullOrEmpty(model) && model.Length <8) + context.AddFailure("حداقل کارکتر مجار تلفن 8 می باشد"); + }); + + RuleFor(r => r.Item2.Email) + .Custom((model, context) => + { + if (!string.IsNullOrEmpty(model) && (!model.Contains("@") || !model.Contains("."))) + context.AddFailure("فرمت پست الکترونیک صحبح نمی باشد"); + }); + RuleFor(r => r.Item2.EconomicCode) + .Custom((model, context) => + { + if (!string.IsNullOrEmpty(model) && (model.Length < 11 || model.Length > 14)) + context.AddFailure("تعداد کارکتر شماره اقتصادی صحبح نمی باشد"); + }); + RuleFor(r => r.Item2.BranchID) + .Custom((model, context) => + { + if (!string.IsNullOrEmpty(model) && (model.Length > 10)) + context.AddFailure("تعداد کارکتر کد شعبه صحبح نمی باشد"); + }); + RuleFor(r => r.Item2.ZipCode) + .Custom((model, context) => + { + if (!string.IsNullOrEmpty(model) && (model.Length != 10)) + context.AddFailure("تعداد کارکتر کد پستی صحبح نمی باشد"); + }); + RuleFor(r => r.Item2.MeliCode) + .Custom((model, context) => + { + if (!string.IsNullOrEmpty(model) && (model.Length < 10 || model.Length > 12)) + context.AddFailure("تعداد کارکتر شناسه ملی صحبح نمی باشد"); + }); + RuleFor(r => r.Item2.PassportNumber) + .Custom((model, context) => + { + if (!string.IsNullOrEmpty(model) && (model.Length != 9)) + context.AddFailure("تعداد کارکتر شماره گذرنامه صحبح نمی باشد"); + }); + RuleFor(r => r.Item2.Info) + .Custom((model, context) => + { + if (!string.IsNullOrEmpty(model) && model.Length > 50) + context.AddFailure("تعداد کارکتر توضیحات بیش از 50 می باشد"); + }); + } + } +} diff --git a/Shared/DTOs/RCustomer.cs b/Shared/DTOs/RCustomer.cs index 9dcd399..5630cb9 100644 --- a/Shared/DTOs/RCustomer.cs +++ b/Shared/DTOs/RCustomer.cs @@ -16,16 +16,16 @@ namespace Shared.DTOs [Display(Name = "نوع مشتری")] public string? CustomerTypeTitle { get; set; } [Display(Name = "تلفن")] - public string Phone { get; set; } - [Display(Name = "پست الکترونیک")] + public string? Phone { get; set; } + //[Display(Name = "پست الکترونیک")] public string? Email { get; set; } [Display(Name = "آدرس")] public string? Address { get; set; } [Display(Name = "کد اقتصادی")] public string? EconomicCode { get; set; } - [Display(Name = "کد شعبه")] + //[Display(Name = "کد شعبه")] public string? BranchID { get; set; }// - [Display(Name = "توضیحات")] + //[Display(Name = "توضیحات")] public string? Info { get; set; }// //------------ diff --git a/TaxPayerFull/CUSComponent/CustomerItem.razor b/TaxPayerFull/CUSComponent/CustomerItem.razor index c331708..d100437 100644 --- a/TaxPayerFull/CUSComponent/CustomerItem.razor +++ b/TaxPayerFull/CUSComponent/CustomerItem.razor @@ -13,8 +13,8 @@
- -
+ +
- +
- +
- +
-
+
- +
- +
-
+
- +
- +
- +
- +
@@ -74,14 +74,14 @@ - - + + - + -@if (Cus.ID==-1) +@if (Cus.ID == 0) { } @@ -111,11 +111,19 @@ else public ActionInResultComponent result { get; set; } protected override Task OnParametersSetAsync() { - result = new ActionInResultComponent(); + if (Cus.CustomerType != null) + ItemSearchCustomertype = (int)Cus.CustomerType; + + result = new ActionInResultComponent() + { + Status = ComponentStatus.fild + }; + Hidealert = true; + alertMessage = ""; return base.OnParametersSetAsync(); } } -@functions{ +@functions { private void ShowSuccessAlert(string msg) { Hidealert = false; @@ -130,38 +138,88 @@ else alertIconName = IconName.ExclamationTriangleFill; alertMessage = msg; } - public async Task OnClickDelete(){ - result.Action = ComponentAction.delete; - await OnMultipleOfThree.InvokeAsync(result); - } - public async Task OnClickUpdate() + public async Task OnClickDelete() { - result.Action = ComponentAction.update; - await OnMultipleOfThree.InvokeAsync(result); - } - public async Task OnClickAdd() - { - if (ItemSearchCustomertype > 0) - Cus.CustomerType = (CustomerType)ItemSearchCustomertype; - Cus.ID = null; - - var rsp = await hc.Post("Customer/Add", Cus); + var rsp = await hc.Delete($"Customer/Delete/{Cus.ID}"); if (rsp.IsSuccessStatusCode) { - var request = await rsp.Content.ReadFromJsonAsync(); + var request = await rsp.Content.ReadFromJsonAsync(); if (request) { - result.Action = ComponentAction.add; + result.Status = ComponentStatus.success; + result.Action = ComponentAction.delete; await OnMultipleOfThree.InvokeAsync(result); } else ShowDangerAlert("خطایی در اجرای عملیات رخ داده"); } - else + + else if (rsp.StatusCode == System.Net.HttpStatusCode.NotFound) { - var request = await rsp.Content.ReadFromJsonAsync>(); - ShowDangerAlert(request[0]); + ShowDangerAlert("مشتری با این شناسه یافت نشد"); } + else ShowDangerAlert("خطایی در اجرای عملیات رخ داده"); + + + + } + public async Task OnClickUpdate() + { + if (ItemSearchCustomertype > 0 && !string.IsNullOrEmpty(Cus.FullName)) + { + if (ItemSearchCustomertype > 0) + Cus.CustomerType = (CustomerType)ItemSearchCustomertype; + + var rsp = await hc.Put("Customer/Update", Cus); + if (rsp.IsSuccessStatusCode) + { + var request = await rsp.Content.ReadFromJsonAsync(); + if (request) + { + result.Status = ComponentStatus.success; + result.Action = ComponentAction.update; + await OnMultipleOfThree.InvokeAsync(result); + } + else ShowDangerAlert("خطایی در اجرای عملیات رخ داده"); + } + else + { + var request = await rsp.Content.ReadFromJsonAsync>(); + ShowDangerAlert(request[0]); + } + } + else ShowDangerAlert("فیلدهای قرمز باید مقدار دهی شوند"); + } + public async Task OnClickAdd() + { + if (ItemSearchCustomertype > 0 && !string.IsNullOrEmpty(Cus.FullName)) + { + if (ItemSearchCustomertype > 0) + Cus.CustomerType = (CustomerType)ItemSearchCustomertype; + Cus.ID = null; + + + var rsp = await hc.Post("Customer/Add", Cus); + if (rsp.IsSuccessStatusCode) + { + var request = await rsp.Content.ReadFromJsonAsync(); + + if (request) + { + result.Status = ComponentStatus.success; + result.Action = ComponentAction.add; + await OnMultipleOfThree.InvokeAsync(result); + } + else ShowDangerAlert("خطایی در اجرای عملیات رخ داده"); + } + else + { + + var request = await rsp.Content.ReadFromJsonAsync>(); + ShowDangerAlert(request[0]); + } + } + else ShowDangerAlert("فیلدهای قرمز باید مقدار دهی شوند"); } } \ No newline at end of file diff --git a/TaxPayerFull/CUSComponent/LTable.razor b/TaxPayerFull/CUSComponent/LTable.razor index effc844..bf838d8 100644 --- a/TaxPayerFull/CUSComponent/LTable.razor +++ b/TaxPayerFull/CUSComponent/LTable.razor @@ -23,8 +23,9 @@ @item.CustomAttributes.Where(w => w.AttributeType.Name == "DisplayAttribute").Select(s => s.NamedArguments.Where(w => w.MemberName == "Name").Select(ss => ss.TypedValue.Value).First()).First().ToString() } - + } + عملیات } @@ -32,20 +33,34 @@ @{ foreach (var item in ModelinComponent) { - + @{ properties = item.GetType().GetProperties(); + int id = 0; foreach (PropertyInfo property in properties) { + if (property.Name.ToLower()=="id") + id =Convert.ToInt32(property.GetValue(item, null)); + if (property.CustomAttributes.Any(w => w.AttributeType.Name == "DisplayAttribute")) { @property.GetValue(item, null) } } - } + if (id>0) + { + + } + else + { + + } + + } } + } @@ -62,5 +77,5 @@ @code { [Parameter] public List ModelinComponent { get; set; } = new List(); - + [Parameter] public EventCallback OnMultipleOfThree { get; set; } } diff --git a/TaxPayerFull/Pages/UserPanel/Customer.razor b/TaxPayerFull/Pages/UserPanel/Customer.razor index fafbc0a..2837604 100644 --- a/TaxPayerFull/Pages/UserPanel/Customer.razor +++ b/TaxPayerFull/Pages/UserPanel/Customer.razor @@ -57,7 +57,7 @@
- +
@@ -77,7 +77,7 @@ @* data *@ @if (request != null) { - + @* pagination *@

@request?.RowCount آیتم یافت شد