diff --git a/Back/Common/ExtentionMethods.cs b/Back/Common/ExtentionMethods.cs index 4ca81ee..bbcbd35 100644 --- a/Back/Common/ExtentionMethods.cs +++ b/Back/Common/ExtentionMethods.cs @@ -60,7 +60,7 @@ namespace Back.Common public static DateTime ToMiladi(this string value) { PersianCalendar p = new PersianCalendar(); - return p.ToDateTime(Convert.ToInt32(value.Substring(0, 4)), Convert.ToInt32(value.Substring(4, 2)), Convert.ToInt32(value.Substring(6, 2)), 0, 0, 0, 0); + return p.ToDateTime(Convert.ToInt32(value.Substring(0, 4)), Convert.ToInt32(value.Substring(4, 2)), Convert.ToInt32(value.Substring(6, 2)), DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond); } public static DateTime ToMiladiByTime(this string value) { diff --git a/Back/Controllers/InvoiceController.cs b/Back/Controllers/InvoiceController.cs new file mode 100644 index 0000000..ffe3242 --- /dev/null +++ b/Back/Controllers/InvoiceController.cs @@ -0,0 +1,82 @@ +using Back.Common; +using Back.Data.Models; +using Back.Services; +using Back.Validations; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Shared.DTOs; +using Shared.DTOs.Serch; + +namespace Back.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class InvoiceController : ControllerBase + { + private readonly servInvoice _servInvoice; + private readonly servUser _servUser; + private readonly AddOrUpdateInvoiceValidation _validationInvoice; + public InvoiceController(servInvoice servInvoice, servUser servUser, AddOrUpdateInvoiceValidation validationInvoice) + { + _servInvoice = servInvoice; + _servUser = servUser; + _validationInvoice = validationInvoice; + + } + [HttpPost("GetAll")] + public async Task?>> GetAll([FromBody] ItemSerchGetInvoices itemSerch) + { + var claim = HttpContext.User.Claims.First(c => c.Type == "UserID"); + var UserID = claim.Value; + var user = await _servUser.GetUserByUserID(Convert.ToInt32(UserID)); + + return Ok(await _servInvoice.GetInvoices(user.RolUsers.First().CompanyID, itemSerch)); + + } + [HttpPost("AddORUpdateInvoice/{CompanyID}")]//ok + public async Task> AddORUpdateInvoice(int CompanyID, [FromBody] NUInvoiceDTO item) + { + if (!ModelState.IsValid) + return BadRequest(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 _validationInvoice.ValidateAsync(Tuple.Create(user.RolUsers.First().CompanyID, item, eActionValidation.add)); + if (!resultValidationmodel.IsValid) + return BadRequest(resultValidationmodel.Errors.Select(s => s.ErrorMessage).ToList()); + + + //if (item.BillReference.HasValue) + //{ + // Invoice ReferenceInvoice = await _servInvoice.GetInvoiceByInvoiceID(item.BillReference.Value); + // if (ReferenceInvoice == null) return NotFound("صورتحساب مرجع یافت نشد"); + + // if (await _servCompany.ExsistCompanyByComoanyIDandUserID(UserID, ReferenceInvoice.CompanyID.Value)) return Forbid("صورتحساب مرجع برای شما در دسترس نمی باشد"); + //} + + + return Ok(_servInvoice.AddInvoice(new Invoice() + { + + Title = item.Title, + Des = item.Des, + invoiceType = InvoiceType.Bidding, + CustomerID = item.CustomerID, + CompanyID = CompanyID, + InvoicIssueDate = item.InvoicIssueDate.Replace("/", ""), + InvoiceDate = item.InvoicIssueDate.Replace("/", ""), + LastChangeUserID = Convert.ToInt32(UserID), + BillReference = null, + IsDeleted = false, + PatternID = item.PatternID + })); + + + + } + } +} diff --git a/Back/Data/Models/Invoice.cs b/Back/Data/Models/Invoice.cs index 76bcab7..dc9b803 100644 --- a/Back/Data/Models/Invoice.cs +++ b/Back/Data/Models/Invoice.cs @@ -98,7 +98,7 @@ namespace Back.Data.Models #region fild public string Title { get; set; } - public string Des { get; set; } + public string? Des { get; set; } public InvoiceType invoiceType { get; set; } //شماره منحصر به فرد مالیاتی [MaxLength(22)] diff --git a/Back/Services/ServCOD.cs b/Back/Services/ServCOD.cs index 1f00acc..c79a94b 100644 --- a/Back/Services/ServCOD.cs +++ b/Back/Services/ServCOD.cs @@ -90,9 +90,12 @@ namespace Back.Services if (item.ID == null || item.ID <= 0) { - var ret = await _CODRepo.AddBoolResultAsync(item); - await _checkPermission.ExtensionofAccess(item.CompanyID, 5, "-1"); - return ret; + if (await _checkPermission.ExtensionofAccess(item.CompanyID, 5, "-1")) + return await _CODRepo.AddBoolResultAsync(item); + + return false; + + } else { diff --git a/Back/Services/servCustomer.cs b/Back/Services/servCustomer.cs index 36b3811..8d646f0 100644 --- a/Back/Services/servCustomer.cs +++ b/Back/Services/servCustomer.cs @@ -115,9 +115,10 @@ namespace Back.Services if (item.ID == null || item.ID <= 0) { - var ret = await _repoCus.AddBoolResultAsync(item); - await _checkPermission.ExtensionofAccess(item.CompanyID, 5, "-1"); - return ret; + if(await _checkPermission.ExtensionofAccess(item.CompanyID, 5, "-1")) + return await _repoCus.AddBoolResultAsync(item); + + return false; } else { diff --git a/Back/Services/servInvoice.cs b/Back/Services/servInvoice.cs new file mode 100644 index 0000000..435078e --- /dev/null +++ b/Back/Services/servInvoice.cs @@ -0,0 +1,115 @@ +using Back.Data.Contracts; +using Back.Data.Models; +using Shared.DTOs.Serch; +using Shared.DTOs; +using Back.Common; +using Microsoft.EntityFrameworkCore; + +namespace Back.Services +{ + public class servInvoice + { + private readonly IAsyncRepository _invoiceRepo; + private readonly IAsyncRepository _invoiceItemRepo; + private readonly IAsyncRepository _invoicePaymentRepo; + private readonly CheckPermission _checkPermission; + public servInvoice(IAsyncRepository invoiceRepo + , IAsyncRepository invoiceItemRepo + , IAsyncRepository invoicePaymentRepo, CheckPermission checkPermission) + { + _invoiceItemRepo = invoiceItemRepo; + _invoiceRepo = invoiceRepo; + _invoicePaymentRepo = invoicePaymentRepo; + _checkPermission = checkPermission; + + } + public async Task?> GetInvoices(int CompanyID, ItemSerchGetInvoices itemSerch) + { + #region AdvancedSearch + var invok = _invoiceRepo + .Get(w => w.CompanyID == CompanyID && !w.IsDeleted); + + if (itemSerch.InvoiceID != null) + invok = invok.Where(w => w.ID == itemSerch.InvoiceID); + + if (itemSerch.CustomerID != null) + invok = invok.Where(w => w.CustomerID == itemSerch.CustomerID); + + if (itemSerch.invoiceType != null) + invok = invok.Where(w => w.invoiceType == itemSerch.invoiceType); + + if (itemSerch.Title != null) + invok = invok.Where(w => w.Title.Contains(itemSerch.Title)); + //foreach (InputObj item in inputObjs) + // invok = invok.Where(ExMethod.GetFunc(item.Param, item.Value)); + + #endregion + //----------------------- + return await invok + .Include(inc => inc.invoiceDetails) + .Include(inc => inc.payments) + .Select(s => new InvoiceDTO() + { + PatternID= s.PatternID, + CustomerID = s.CustomerID, + CustomerName = s.Customer.FullName, + ID = s.ID, + InvoiceDate = s.InvoiceDate.ShamciToFormatShamci(), + invoiceTypeTitle = s.invoiceType.GetEnumDisplayName(), + invoiceType = s.invoiceType, + Title = s.Title, + InvoicIssueDate = s.InvoicIssueDate.ShamciToFormatShamci(), + BillReference = s.BillReference, + tbill = s.tbill, + Des = s.Des, + PreparedtoSendtoTax = s.PreparedtoSendtoTax, + tdis = s.tdis, + tvam = s.tvam, + Udate = s.Udate.ShamciToFormatShamci(), + items = s.invoiceDetails.OrderBy(o => o.ID).Select(x => new InvoiceItemDTO() + { + ID = x.ID, + CODID = x.CODID, + adis = x.adis, + am = x.am.Value, + dis = x.dis, + fee = x.fee.Value, + mu = x.mu, + sstt = x.sstt, + tsstam = x.tsstam, + vam = x.am, + vra = x.vra + }).ToList(), + payments = s.payments.OrderBy(o => o.ID).Select(x => new InvoicePaymentDTO() + { + ID = x.ID, + acn = x.acn, + iinn = x.acn, + pcn = x.acn, + pdt = x.pdt, + pid = x.pid, + pmt = x.pmt, + pv = x.pv, + trmn = x.trmn, + trn = x.acn + }).ToList(), + }) + .Paging(itemSerch.PageIndex, itemSerch.PageSize); + } + public async Task ExistInvoiceByInvoiceID(int CompanyID,int InvoiceID) + { + return await _invoiceRepo.Get(w => w.ID == InvoiceID && w.CompanyID == CompanyID && !w.IsDeleted).AnyAsync(); + + } + public async Task AddInvoice(Invoice invoice) + { + invoice.Cdate = DateTime.Now.ConvertMiladiToShamsi(); + invoice.Udate = DateTime.Now.ConvertMiladiToShamsi(); + invoice.PreparedtoSendtoTax = false; + + if(await _checkPermission.ExtensionofAccess(invoice.CompanyID.Value, 3, "-1")) + return await _invoiceRepo.AddBoolResultAsync(invoice); + return false; + } + } +} diff --git a/Back/Validations/AddOrUpdateInvoiceValidation.cs b/Back/Validations/AddOrUpdateInvoiceValidation.cs new file mode 100644 index 0000000..bbdbe59 --- /dev/null +++ b/Back/Validations/AddOrUpdateInvoiceValidation.cs @@ -0,0 +1,84 @@ +using Back.Common; +using Back.Data.Contracts; +using Back.Data.Models; +using Back.Services; +using FluentValidation; +using Microsoft.EntityFrameworkCore; +using Shared.DTOs; + +namespace Back.Validations +{ + public class AddOrUpdateInvoiceValidation : AbstractValidator> + { + public AddOrUpdateInvoiceValidation(IAsyncRepository patternRepo, servCustomer servCustomer + , servInvoice servInvoice, CheckPermission checkPermission) + { + When(m => m.Item3 == eActionValidation.update, () => + { + RuleFor(r => r) + .Custom((model, context) => + { + if (model.Item2.ID == null || model.Item2.ID <= 0) + context.AddFailure("شناسه صورتحساب در حالت ویرایش نمی تواند خالی باشد"); + + else if (!servInvoice.ExistInvoiceByInvoiceID(model.Item1,model.Item2.ID.Value ).Result) + context.AddFailure("ضورتحساب یافت نشد"); + }); + + }); + When(m => m.Item3 == eActionValidation.add, () => + { + RuleFor(r => r.Item1) + .Custom((CompanyID, context) => + { + if (!checkPermission.AllowAddInvoiceInCompany(CompanyID).Result) + context.AddFailure("اضافه کردن صورتحساب محدود شده است"); + + }); + + }); + + RuleFor(r => r.Item2.Title) + .NotNull().WithMessage("عنوان نمی تواند خالی باشد") + .NotEmpty().WithMessage("عنوان نمی تواند خالی باشد") + .MinimumLength(3).WithMessage("عنوان حداقل باید 3 کاراکتر باشد"); + + RuleFor(r => r.Item2.PatternID) + .Custom((PatternID, context) => + { + if (PatternID!=null && PatternID > 0 && !patternRepo.Get(w => w.Status && w.ID == PatternID).AnyAsync().Result) + context.AddFailure("الگوی صورتحساب معتبر نیست"); + }); + + RuleFor(r => r) + .Custom((model, context) => + { + if (model.Item2.CustomerID == null || model.Item2.CustomerID <=0) + context.AddFailure("برای صدور صورتحساب باید مشتری تعریف شود"); + + else if (!servCustomer.ExistCustomerByCustomerID(model.Item2.CustomerID, model.Item1).Result) + context.AddFailure("مشتری یافت نشد"); + }); + + RuleFor(r => r.Item2.InvoiceDate) + .Custom((InvoiceDate, context) => + { + if (string.IsNullOrEmpty(InvoiceDate)) + context.AddFailure("تاریخ ایجاد صورتحساب نمی تواند خالی باشد"); + + else if (InvoiceDate.Trim().ToMiladi() > DateTime.Now) + context.AddFailure("تاریخ ایجاد صورتحساب نمی تواند از امروز جلوتر باشد"); + }); + + RuleFor(r => r.Item2.InvoicIssueDate) + .Custom((InvoicIssueDate, context) => + { + if (string.IsNullOrEmpty(InvoicIssueDate)) + context.AddFailure("تاریخ صدور صورتحساب نمی تواند خالی باشد"); + + else if (InvoicIssueDate.Trim().ToMiladi() > DateTime.Now) + context.AddFailure("تاریخ صدور صورتحساب نمی تواند از امروز جلوتر باشد"); + }); + } + } +} diff --git a/Shared/DTOs/InvoiceDtos.cs b/Shared/DTOs/InvoiceDtos.cs index c1ada47..607e34c 100644 --- a/Shared/DTOs/InvoiceDtos.cs +++ b/Shared/DTOs/InvoiceDtos.cs @@ -7,19 +7,29 @@ using System.Threading.Tasks; namespace Shared.DTOs { + public class NUInvoiceDTO + { + public int? ID { get; set; } + public string Title { get; set; } + public int? PatternID { get; set; } + public int CustomerID { get; set; } + public string InvoicIssueDate { get; set; } + public string InvoiceDate { get; set; } + public string? Des { get; set; } + } public class InvoiceDTO { public int ID { get; set; } public InvoiceType? invoiceType { get; set; } + public int? PatternID { get; set; } public string? invoiceTypeTitle { get; set; } - public int? CompanyID { get; set; } public int CustomerID { get; set; } - public int CustomerName { get; set; } + public string CustomerName { get; set; } public string? Udate { get; set; } - public string? InvoicIssueDate { get; set; } - public string? InvoiceDate { get; set; } - public bool? PreparedtoSendtoTax { get; set; } - public string? Title { get; set; } + public string InvoicIssueDate { get; set; } + public string InvoiceDate { get; set; } + public bool PreparedtoSendtoTax { get; set; } + public string Title { get; set; } public string? Des { get; set; } //مجموع تخفیفات public decimal? tdis { get; set; } diff --git a/Shared/DTOs/Serch/ItemSerchGetInvoices.cs b/Shared/DTOs/Serch/ItemSerchGetInvoices.cs new file mode 100644 index 0000000..9f71b7c --- /dev/null +++ b/Shared/DTOs/Serch/ItemSerchGetInvoices.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Shared.DTOs.Serch +{ + public class ItemSerchGetInvoices : IFildGlobalItemSerch + { + public string? Title { get; set; } + public int? InvoiceID { get; set; } + public int? CustomerID { get; set; } + public InvoiceType? invoiceType { get; set; } + public int PageIndex { get; set; } = 1; + public int PageSize { get; set; } = 5; + } +}