Add Financial Invoice Management System

Refactored `FinancialInvoice` to include new properties (`Description`, `PublicId`, `IsActive`) and methods for managing items and statuses. Introduced `FinancialInvoiceItem` for invoice itemization. Updated `PaymentTransaction` to reference `FinancialInvoice`.

Enhanced repository and application layers with CRUD operations, advanced search functionality, and integration with contracts. Updated `CompanyContext` with `DbSet<FinancialInvoices>` and `DbSet<FinancialInvoiceItem>`.

Created new database tables for `FinancialInvoices` and `FinancialInvoiceItem`, and updated relationships with `PaymentTransactions`. Added DTOs for invoice creation, editing, and searching. Registered `IFinancialInvoiceRepository` for dependency injection.
This commit is contained in:
2025-11-13 12:49:30 +03:30
parent f3470de8b6
commit ba2b402c04
23 changed files with 12150 additions and 88 deletions

View File

@@ -1,49 +1,97 @@
using System;
using System.Collections.Generic;
using System.Runtime;
using _0_Framework.Domain;
using Company.Domain.FinancialStatmentAgg;
using Company.Domain.FinancialTransactionAgg;
using Company.Domain.PaymentTransactionAgg;
using CompanyManagment.App.Contracts.FinancialInvoice;
namespace Company.Domain.FinancialInvoiceAgg;
public class FinancialInvoice:EntityBase
public class FinancialInvoice : EntityBase
{
public int Month { get; private set; }
public int Year { get; private set; }
public FinancialInvoiceStatus Status { get; private set; }
public DateTime? PaidAt { get; private set; }
public double Amount { get; private set; }
public Guid InvoiceId { get; private set; }
public string Description { get; set; }
public FinancialInvoiceStatus Status { get; private set; }
public DateTime? PaidAt { get; private set; }
public double Amount { get; private set; }
public Guid PublicId { get; private set; }
public bool IsActive { get; set; }
public List<PaymentTransaction> PaymentTransactions { get; private set; }
public long ContractingPartyId { get; private set; }
public FinancialInvoice(int month, int year, FinancialInvoiceStatus status, double amount)
{
Month = month;
Year = year;
Status = status;
Amount = amount;
InvoiceId = Guid.NewGuid();
}
public void SetPaid(DateTime paidAt)
{
Status = FinancialInvoiceStatus.Paid;
PaidAt = paidAt;
}
public void SetUnpaid()
{
Status = FinancialInvoiceStatus.Unpaid;
PaidAt = null;
}
public void SetCancelled()
{
Status = FinancialInvoiceStatus.Cancelled;
PaidAt = null;
}
public void SetRefunded()
{
Status = FinancialInvoiceStatus.Refunded;
PaidAt = null;
}
public List<FinancialInvoiceItem> Items { get; private set; }
public FinancialInvoice(double amount, long contractingPartyId, string description)
{
Status = FinancialInvoiceStatus.Unpaid;
Amount = amount;
PublicId = Guid.NewGuid();
ContractingPartyId = contractingPartyId;
Description = description;
IsActive = true;
Items = [];
PaymentTransactions = [];
}
public void AddItem(FinancialInvoiceItem item)
{
Items ??= [];
Items.Add(item);
}
public void SetItems(List<FinancialInvoiceItem> items)
{
Items = items;
}
public void SetPaid(DateTime paidAt)
{
Status = FinancialInvoiceStatus.Paid;
PaidAt = paidAt;
}
public void SetUnpaid()
{
Status = FinancialInvoiceStatus.Unpaid;
PaidAt = null;
}
public void SetCancelled()
{
Status = FinancialInvoiceStatus.Cancelled;
PaidAt = null;
}
public void SetRefunded()
{
Status = FinancialInvoiceStatus.Refunded;
PaidAt = null;
}
public void DeActivate()
{
IsActive = false;
}
}
public class FinancialInvoiceItem : EntityBase
{
public string Description { get; private set; }
public double Amount { get; private set; }
public FinancialInvoiceItemType Type { get; set; }
public long EntityId { get; set; }
public FinancialInvoice FinancialInvoice { get; set; }
public long FinancialInvoiceId { get; set; }
public FinancialInvoiceItem(string description, double amount, long financialInvoiceId, FinancialInvoiceItemType type, long entityId)
{
Description = description;
Amount = amount;
FinancialInvoiceId = financialInvoiceId;
Type = type;
EntityId = entityId;
}
}

View File

@@ -1,8 +1,11 @@
using _0_Framework.Domain;
using System.Collections.Generic;
using _0_Framework.Domain;
using CompanyManagment.App.Contracts.FinancialInvoice;
namespace Company.Domain.FinancialInvoiceAgg;
public interface IFinancialInvoiceRepository:IRepository<long,FinancialInvoice>
public interface IFinancialInvoiceRepository : IRepository<long, FinancialInvoice>
{
EditFinancialInvoice GetDetails(long id);
List<FinancialInvoiceViewModel> Search(FinancialInvoiceSearchModel searchModel);
}

View File

@@ -33,7 +33,6 @@ public class FinancialStatment : EntityBase
public string PublicIdStr => PublicId.ToString("N");
public List<FinancialTransaction> FinancialTransactionList { get; set; }
public List<FinancialInvoice> FinancialInvoices { get; set; }
public void SetPublicId()

View File

@@ -22,6 +22,8 @@ public interface IFinancialStatmentRepository : IRepository<long, FinancialStatm
Task<OperationResult<ClientFinancialStatementViewModel>> GetDetailsByPublicId(string publicId);
Task<GetFinancialStatementBalanceAmount> GetBalanceAmount(long id);
Task<double> GetClientDebtAmount(long accountId);
Task<FinancialStatmentDetailsByContractingPartyViewModel> GetDetailsByContractingParty(long contractingPartyId,FinancialStatementSearchModel searchModel);
Task<double> GetClientDebtAmountByContractingPartyId(long contractingPartyId);
Task<FinancialStatmentDetailsByContractingPartyViewModel> GetDetailsByContractingParty(long contractingPartyId,FinancialStatementSearchModel searchModel);
Task<FinancialStatment> GetByContractingPartyId(long contractingPartyId);
}

View File

@@ -1,5 +1,6 @@
using System;
using _0_Framework.Domain;
using Company.Domain.FinancialInvoiceAgg;
using CompanyManagment.App.Contracts.PaymentTransaction;
namespace Company.Domain.PaymentTransactionAgg;
@@ -9,14 +10,15 @@ namespace Company.Domain.PaymentTransactionAgg;
/// </summary>
public class PaymentTransaction:EntityBase
{
/// <summary>
/// سازنده کلاس PaymentTransaction با دریافت اطلاعات تراکنش.
/// </summary>
/// <param name="contractingPartyId">شناسه طرف قرارداد</param>
/// <param name="amount">مبلغ تراکنش</param>
/// <param name="contractingPartyName"></param>
/// <param name="callBackUrl"></param>
public PaymentTransaction(long contractingPartyId,
/// <summary>
/// سازنده کلاس PaymentTransaction با دریافت اطلاعات تراکنش.
/// </summary>
/// <param name="contractingPartyId">شناسه طرف قرارداد</param>
/// <param name="amount">مبلغ تراکنش</param>
/// <param name="contractingPartyName"></param>
/// <param name="callBackUrl"></param>
/// <param name="gateway"></param>
public PaymentTransaction(long contractingPartyId,
double amount,
string contractingPartyName,string callBackUrl,
PaymentTransactionGateWay gateway)
@@ -74,6 +76,9 @@ public class PaymentTransaction:EntityBase
public string Rrn { get; private set; }
public string DigitalReceipt { get; private set; }
public FinancialInvoice FinancialInvoice { get; set; }
public long? FinancialInvoiceId { get; set; }
public void SetPaid(string cardNumber,string bankName,string rrn,string digitalReceipt)
{

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
namespace CompanyManagment.App.Contracts.FinancialInvoice;
public class CreateFinancialInvoice
{
public double Amount { get; set; }
public long ContractingPartyId { get; set; }
public string Description { get; set; }
public List<CreateFinancialInvoiceItem>? Items { get; set; }
}
public class CreateFinancialInvoiceItem
{
public string Description { get; set; }
public double Amount { get; set; }
public FinancialInvoiceItemType Type { get; set; }
public long EntityId { get; set; }
}

View File

@@ -0,0 +1,19 @@
using System.Collections.Generic;
namespace CompanyManagment.App.Contracts.FinancialInvoice;
public class EditFinancialInvoice
{
public long Id { get; set; }
public string Description { get; set; }
public List<EditFinancialInvoiceItem>? Items { get; set; }
}
public class EditFinancialInvoiceItem
{
public long Id { get; set; }
public string Description { get; set; }
public double Amount { get; set; }
public FinancialInvoiceItemType Type { get; set; }
public long EntityId { get; set; }
}

View File

@@ -0,0 +1,25 @@
namespace CompanyManagment.App.Contracts.FinancialInvoice;
public enum FinancialInvoiceItemType
{
/// <summary>
/// قسط قرارداد خرید از موسسه
/// </summary>
BuyInstitutionContractInstallment,
/// <summary>
/// خرید قرارداد از موسسه
/// </summary>
BuyInstitutionContract,
/// <summary>
///قسط ارتقا قرارداد موسسه
/// </summary>
AmendmentInstitutionContractInstallment,
/// <summary>
/// ارتقا قرارداد موسسه
/// </summary>
AmendmentInstitutionContract,
/// <summary>
/// بدهی قبلی
/// </summary>
PreviousDebt,
}

View File

@@ -0,0 +1,12 @@
namespace CompanyManagment.App.Contracts.FinancialInvoice;
public class FinancialInvoiceSearchModel
{
public string? Description { get; set; }
public FinancialInvoiceStatus? Status { get; set; }
public long? ContractingPartyId { get; set; }
public string? FromDate { get; set; }
public string? ToDate { get; set; }
public double? MinAmount { get; set; }
public double? MaxAmount { get; set; }
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
namespace CompanyManagment.App.Contracts.FinancialInvoice;
public class FinancialInvoiceViewModel
{
public long Id { get; set; }
public string Description { get; set; }
public string Status { get; set; }
public string PaidAt { get; set; }
public double Amount { get; set; }
public Guid PublicId { get; set; }
public long ContractingPartyId { get; set; }
public string ContractingPartyName { get; set; }
public string CreationDate { get; set; }
public int ItemsCount { get; set; }
}

View File

@@ -1,6 +1,17 @@
namespace CompanyManagment.App.Contracts.FinancialInvoice;
using System;
using System.Collections.Generic;
using _0_Framework.Application;
namespace CompanyManagment.App.Contracts.FinancialInvoice;
public interface IFinancialInvoiceApplication
{
OperationResult Create(CreateFinancialInvoice command);
OperationResult Edit(EditFinancialInvoice command);
OperationResult SetPaid(long id, DateTime paidAt);
OperationResult SetUnpaid(long id);
OperationResult SetCancelled(long id);
OperationResult SetRefunded(long id);
EditFinancialInvoice GetDetails(long id);
List<FinancialInvoiceViewModel> Search(FinancialInvoiceSearchModel searchModel);
}

View File

@@ -1,8 +1,214 @@
using CompanyManagment.App.Contracts.FinancialInvoice;
using System;
using System.Collections.Generic;
using System.Linq;
using _0_Framework.Application;
using _0_Framework.InfraStructure;
using Company.Domain.FinancialInvoiceAgg;
using CompanyManagment.App.Contracts.FinancialInvoice;
using CompanyManagment.EFCore;
namespace CompanyManagment.Application;
public class FinancialInvoiceApplication:IFinancialInvoiceApplication
public class FinancialInvoiceApplication : RepositoryBase<long, FinancialInvoice>, IFinancialInvoiceApplication
{
private readonly IFinancialInvoiceRepository _financialInvoiceRepository;
private readonly CompanyContext _context;
public FinancialInvoiceApplication(IFinancialInvoiceRepository financialInvoiceRepository, CompanyContext context) : base(context)
{
_financialInvoiceRepository = financialInvoiceRepository;
_context = context;
}
public OperationResult Create(CreateFinancialInvoice command)
{
var operation = new OperationResult();
if (command.Amount <= 0)
return operation.Failed("مبلغ فاکتور باید بزرگتر از صفر باشد");
if (command.ContractingPartyId <= 0)
return operation.Failed("طرف قرارداد نامعتبر است");
if (string.IsNullOrWhiteSpace(command.Description))
return operation.Failed("توضیحات فاکتور الزامی است");
var financialInvoice = new FinancialInvoice(command.Amount, command.ContractingPartyId, command.Description);
if (command.Items != null && command.Items.Any())
{
foreach (var item in command.Items)
{
if (string.IsNullOrWhiteSpace(item.Description))
return operation.Failed("توضیحات آیتم الزامی است");
if (item.Amount <= 0)
return operation.Failed("مبلغ آیتم باید بزرگتر از صفر باشد");
var invoiceItem = new FinancialInvoiceItem(item.Description, item.Amount,
financialInvoice.id, item.Type, item.EntityId);
financialInvoice.AddItem(invoiceItem);
}
}
_financialInvoiceRepository.Create(financialInvoice);
_financialInvoiceRepository.SaveChanges();
return operation.Succcedded();
}
public OperationResult Edit(EditFinancialInvoice command)
{
var operation = new OperationResult();
var financialInvoice = _financialInvoiceRepository.Get(command.Id);
if (financialInvoice == null)
return operation.Failed("فاکتور مورد نظر یافت نشد");
if (financialInvoice.Status == FinancialInvoiceStatus.Paid)
return operation.Failed("امکان ویرایش فاکتور پرداخت شده وجود ندارد");
if (string.IsNullOrWhiteSpace(command.Description))
return operation.Failed("توضیحات فاکتور الزامی است");
// Update description
financialInvoice.Description = command.Description;
// Update items if provided
if (command.Items != null)
{
// Clear existing items
if (financialInvoice.Items != null)
{
financialInvoice.Items.Clear();
}
else
{
financialInvoice.SetItems([]);
}
// Add updated items
foreach (var item in command.Items)
{
if (string.IsNullOrWhiteSpace(item.Description))
return operation.Failed("توضیحات آیتم الزامی است");
if (item.Amount <= 0)
return operation.Failed("مبلغ آیتم باید بزرگتر از صفر باشد");
var invoiceItem = new FinancialInvoiceItem(item.Description, item.Amount,
financialInvoice.id, item.Type, item.EntityId);
financialInvoice.AddItem(invoiceItem);
}
}
_financialInvoiceRepository.SaveChanges();
return operation.Succcedded();
}
public OperationResult SetPaid(long id, DateTime paidAt)
{
var operation = new OperationResult();
var financialInvoice = _financialInvoiceRepository.Get(id);
if (financialInvoice == null)
return operation.Failed("فاکتور مورد نظر یافت نشد");
if (financialInvoice.Status == FinancialInvoiceStatus.Paid)
return operation.Failed("فاکتور قبلاً پرداخت شده است");
if (financialInvoice.Status == FinancialInvoiceStatus.Cancelled)
return operation.Failed("امکان پرداخت فاکتور لغو شده وجود ندارد");
financialInvoice.SetPaid(paidAt);
_financialInvoiceRepository.SaveChanges();
return operation.Succcedded();
}
public OperationResult SetUnpaid(long id)
{
var operation = new OperationResult();
var financialInvoice = _financialInvoiceRepository.Get(id);
if (financialInvoice == null)
return operation.Failed("فاکتور مورد نظر یافت نشد");
financialInvoice.SetUnpaid();
_financialInvoiceRepository.SaveChanges();
return operation.Succcedded();
}
public OperationResult SetCancelled(long id)
{
var operation = new OperationResult();
var financialInvoice = _financialInvoiceRepository.Get(id);
if (financialInvoice == null)
return operation.Failed("فاکتور مورد نظر یافت نشد");
if (financialInvoice.Status == FinancialInvoiceStatus.Paid)
return operation.Failed("امکان لغو فاکتور پرداخت شده وجود ندارد");
financialInvoice.SetCancelled();
_financialInvoiceRepository.SaveChanges();
return operation.Succcedded();
}
public OperationResult SetRefunded(long id)
{
var operation = new OperationResult();
var financialInvoice = _financialInvoiceRepository.Get(id);
if (financialInvoice == null)
return operation.Failed("فاکتور مورد نظر یافت نشد");
if (financialInvoice.Status != FinancialInvoiceStatus.Paid)
return operation.Failed("فقط فاکتورهای پرداخت شده قابل بازپرداخت هستند");
financialInvoice.SetRefunded();
_financialInvoiceRepository.SaveChanges();
return operation.Succcedded();
}
public EditFinancialInvoice GetDetails(long id)
{
return _financialInvoiceRepository.GetDetails(id);
}
public List<FinancialInvoiceViewModel> Search(FinancialInvoiceSearchModel searchModel)
{
return _financialInvoiceRepository.Search(searchModel);
}
//public OperationResult Remove(long id)
//{
// var operation = new OperationResult();
// try
// {
// var financialInvoice = _financialInvoiceRepository.Get(id);
// if (financialInvoice == null)
// return operation.Failed("فاکتور مورد نظر یافت نشد");
// if (financialInvoice.Status == FinancialInvoiceStatus.Paid)
// return operation.Failed("امکان حذف فاکتور پرداخت شده وجود ندارد");
// // Remove the entity using the context directly since Remove method might not be available
// _context.FinancialInvoiceSet.Remove(financialInvoice);
// _financialInvoiceRepository.SaveChanges();
// return operation.Succcedded();
// }
// catch (Exception ex)
// {
// return operation.Failed("خطا در حذف فاکتور");
// }
//}
}

View File

@@ -13,6 +13,7 @@ using AccountManagement.Application.Contracts.Account;
using Company.Domain.ContarctingPartyAgg;
using Company.Domain.EmployeeAgg;
using Company.Domain.empolyerAgg;
using Company.Domain.FinancialInvoiceAgg;
using Company.Domain.FinancialStatmentAgg;
using Company.Domain.FinancialTransactionAgg;
using Company.Domain.InstitutionContractAgg;
@@ -20,6 +21,7 @@ using Company.Domain.LeftWorkAgg;
using Company.Domain.RepresentativeAgg;
using Company.Domain.TemporaryClientRegistrationAgg;
using Company.Domain.WorkshopAgg;
using CompanyManagment.App.Contracts.FinancialInvoice;
using CompanyManagment.App.Contracts.FinancialStatment;
using CompanyManagment.App.Contracts.InstitutionContract;
using CompanyManagment.App.Contracts.InstitutionContractContactinfo;
@@ -50,6 +52,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication
private readonly IAccountApplication _accountApplication;
private readonly ISmsService _smsService;
private readonly IUidService _uidService;
private readonly IFinancialInvoiceRepository _financialInvoiceRepository;
public InstitutionContractApplication(IInstitutionContractRepository institutionContractRepository,
@@ -59,7 +62,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication
IFinancialStatmentApplication financialStatmentApplication, IWorkshopApplication workshopApplication,
IContractingPartyTempRepository contractingPartyTempRepository,
IFinancialStatmentRepository financialStatmentRepository, IContactInfoApplication contactInfoApplication,
IAccountApplication accountApplication, ISmsService smsService, IUidService uidService)
IAccountApplication accountApplication, ISmsService smsService, IUidService uidService, IFinancialInvoiceRepository financialInvoiceRepository)
{
_institutionContractRepository = institutionContractRepository;
_contractingPartyRepository = contractingPartyRepository;
@@ -75,6 +78,7 @@ public class InstitutionContractApplication : IInstitutionContractApplication
_accountApplication = accountApplication;
_smsService = smsService;
_uidService = uidService;
_financialInvoiceRepository = financialInvoiceRepository;
}
public OperationResult Create(CreateInstitutionContract command)
@@ -1060,11 +1064,16 @@ public class InstitutionContractApplication : IInstitutionContractApplication
await _financialStatmentRepository.CreateAsync(financialStatement);
}
if (command.IsInstallment)
double invoiceAmount;
string invoiceItemDescription;
FinancialInvoiceItemType invoiceItemType;
long invoiceItemEntityId;
if (command.IsInstallment)
{
var installments =
CalculateInstallment(command.TotalAmount, (int)command.Duration, command.ContractStartFa, true);
// دریافت مبلغ اولین قسط
//این کار برای این هست که اولین قسط باید با تاریخ امروز باشد و باید به وضعیت مالی بدهی ایجاد شود که یوزر اولین بدهی را وارد کند
var firstInstallmentAmount = installments.First().Amount;
@@ -1075,25 +1084,41 @@ public class InstitutionContractApplication : IInstitutionContractApplication
// ایجاد قسط جدید با تاریخ امروز
var todayInstallment = new InstitutionContractInstallment(DateTime.Today, firstInstallmentAmount, "");
var financialTransaction = new FinancialTransaction(0, today, today.ToFarsi(),
"قسط اول سرویس", "debt", "بابت خدمات", firstInstallmentAmount, 0, 0);
financialStatement.AddFinancialTransaction(financialTransaction);
// اضافه کردن قسط جدید به ابتدای لیست
installments.Insert(0, todayInstallment);
entity.SetInstallments(installments);
await _institutionContractRepository.SaveChangesAsync();
var financialTransaction = new FinancialTransaction(0, today, today.ToFarsi(),
"قسط اول سرویس", "debt", "بابت خدمات", firstInstallmentAmount, 0, 0);
financialStatement.AddFinancialTransaction(financialTransaction);
invoiceAmount = firstInstallmentAmount;
invoiceItemDescription = $"پرداخت قسط اول قرارداد شماره {entity.ContractNo}";
invoiceItemType = FinancialInvoiceItemType.BuyInstitutionContractInstallment;
invoiceItemEntityId = todayInstallment.Id;
}
else
{
var financialTransaction = new FinancialTransaction(0, today, today.ToFarsi(),
"پرداخت کل سرویس", "debt", "بابت خدمات", command.TotalAmount, 0, 0);
financialStatement.AddFinancialTransaction(financialTransaction);
}
invoiceAmount = command.TotalAmount;
invoiceItemDescription = $"پرداخت کل قرارداد شماره {entity.ContractNo}";
invoiceItemType = FinancialInvoiceItemType.BuyInstitutionContract;
invoiceItemEntityId = 0;
}
var financialInvoice = new FinancialInvoice(invoiceAmount, contractingParty.id, $"خرید قرارداد مالی شماره {entity.ContractNo}");
var financialInvoiceItem = new FinancialInvoiceItem(invoiceItemDescription, invoiceAmount, 0,invoiceItemType, invoiceItemEntityId);
financialInvoice.AddItem(financialInvoiceItem);
await _institutionContractRepository.CreateAsync(entity);
await _financialInvoiceRepository.CreateAsync(financialInvoice);
await _institutionContractRepository.CreateAsync(entity);
await _institutionContractRepository.SaveChangesAsync();
var mainContactInfo = new CreateContactInfo
@@ -1256,6 +1281,9 @@ public class InstitutionContractApplication : IInstitutionContractApplication
return op.Failed("کد وارد شده صحیح نمی باشد");
var transaction = await _institutionContractRepository.BeginTransactionAsync();
institutionContract.SetPendingWorkflow();
var phone = institutionContract.ContactInfoList.FirstOrDefault(x =>

View File

@@ -45,6 +45,7 @@ using Company.Domain.FileEmployerAgg;
using Company.Domain.FileState;
using Company.Domain.FileTiming;
using Company.Domain.FileTitle;
using Company.Domain.FinancialInvoiceAgg;
using Company.Domain.FinancialStatmentAgg;
using Company.Domain.FinancialTransactionAgg;
using Company.Domain.FineAgg;
@@ -204,12 +205,13 @@ public class CompanyContext : DbContext
public DbSet<AuthorizedBankDetails> AuthorizedBankDetails { get; set; }
#endregion
public DbSet<FinancialInvoice> FinancialInvoices { get; set; }
#region Pooya
#endregion
public DbSet<EmployeeDocumentItem> EmployeeDocumentItems { get; set; }
#region Pooya
public DbSet<EmployeeDocumentItem> EmployeeDocumentItems { get; set; }
public DbSet<EmployeeDocuments> EmployeeDocuments { get; set; }
public DbSet<WorkshopSubAccount> WorkshopSubAccounts { get; set; }

View File

@@ -0,0 +1,17 @@
using Company.Domain.FinancialInvoiceAgg;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace CompanyManagment.EFCore.Mapping;
public class FinancialInvoiceItemMapping : IEntityTypeConfiguration<FinancialInvoiceItem>
{
public void Configure(EntityTypeBuilder<FinancialInvoiceItem> builder)
{
builder.Property(x=>x.Description).HasMaxLength(800);
builder.Property(x => x.Type).HasConversion<string>().HasMaxLength(50);
builder.HasOne(x => x.FinancialInvoice).WithMany(x => x.Items)
.HasForeignKey(x => x.FinancialInvoiceId);
}
}

View File

@@ -12,8 +12,13 @@ public class FinancialInvoiceMapping:IEntityTypeConfiguration<FinancialInvoice>
builder.Property(x => x.Status).HasConversion<string>().HasMaxLength(20);
builder.Property(x => x.PaidAt).IsRequired(false);
builder.Property(x => x.SmsCode).HasMaxLength(122);
builder.HasOne(x => x.FinancialStatement).WithMany(x => x.FinancialInvoices)
.HasForeignKey(x => x.FinancialStatementId).IsRequired(false);
builder.Property(x => x.Description).HasMaxLength(800);
builder.HasMany(x => x.Items).WithOne(x => x.FinancialInvoice)
.HasForeignKey(x => x.FinancialInvoiceId).IsRequired().OnDelete(DeleteBehavior.Cascade);
builder.HasMany(x => x.PaymentTransactions).WithOne(x => x.FinancialInvoice)
.HasForeignKey(x => x.FinancialInvoiceId).IsRequired(false).OnDelete(DeleteBehavior.NoAction);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,226 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace CompanyManagment.EFCore.Migrations
{
/// <inheritdoc />
public partial class addfinancialinvoice : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_FinancialInvoice_FinancialStatments_FinancialStatementId",
table: "FinancialInvoice");
migrationBuilder.DropPrimaryKey(
name: "PK_FinancialInvoice",
table: "FinancialInvoice");
migrationBuilder.DropColumn(
name: "Month",
table: "FinancialInvoice");
migrationBuilder.DropColumn(
name: "SmsCode",
table: "FinancialInvoice");
migrationBuilder.DropColumn(
name: "Year",
table: "FinancialInvoice");
migrationBuilder.RenameTable(
name: "FinancialInvoice",
newName: "FinancialInvoices");
migrationBuilder.RenameColumn(
name: "FinancialStatementId",
table: "FinancialInvoices",
newName: "FinancialStatmentid");
migrationBuilder.RenameIndex(
name: "IX_FinancialInvoice_FinancialStatementId",
table: "FinancialInvoices",
newName: "IX_FinancialInvoices_FinancialStatmentid");
migrationBuilder.AddColumn<long>(
name: "FinancialInvoiceId",
table: "PaymentTransactions",
type: "bigint",
nullable: true);
migrationBuilder.AddColumn<long>(
name: "ContractingPartyId",
table: "FinancialInvoices",
type: "bigint",
nullable: false,
defaultValue: 0L);
migrationBuilder.AddColumn<string>(
name: "Description",
table: "FinancialInvoices",
type: "nvarchar(800)",
maxLength: 800,
nullable: true);
migrationBuilder.AddColumn<bool>(
name: "IsActive",
table: "FinancialInvoices",
type: "bit",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<Guid>(
name: "PublicId",
table: "FinancialInvoices",
type: "uniqueidentifier",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
migrationBuilder.AddPrimaryKey(
name: "PK_FinancialInvoices",
table: "FinancialInvoices",
column: "id");
migrationBuilder.CreateTable(
name: "FinancialInvoiceItem",
columns: table => new
{
id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Description = table.Column<string>(type: "nvarchar(800)", maxLength: 800, nullable: true),
Amount = table.Column<double>(type: "float", nullable: false),
Type = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
EntityId = table.Column<long>(type: "bigint", nullable: false),
FinancialInvoiceId = table.Column<long>(type: "bigint", nullable: false),
CreationDate = table.Column<DateTime>(type: "datetime2", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_FinancialInvoiceItem", x => x.id);
table.ForeignKey(
name: "FK_FinancialInvoiceItem_FinancialInvoices_FinancialInvoiceId",
column: x => x.FinancialInvoiceId,
principalTable: "FinancialInvoices",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_PaymentTransactions_FinancialInvoiceId",
table: "PaymentTransactions",
column: "FinancialInvoiceId");
migrationBuilder.CreateIndex(
name: "IX_FinancialInvoiceItem_FinancialInvoiceId",
table: "FinancialInvoiceItem",
column: "FinancialInvoiceId");
migrationBuilder.AddForeignKey(
name: "FK_FinancialInvoices_FinancialStatments_FinancialStatmentid",
table: "FinancialInvoices",
column: "FinancialStatmentid",
principalTable: "FinancialStatments",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "FK_PaymentTransactions_FinancialInvoices_FinancialInvoiceId",
table: "PaymentTransactions",
column: "FinancialInvoiceId",
principalTable: "FinancialInvoices",
principalColumn: "id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_FinancialInvoices_FinancialStatments_FinancialStatmentid",
table: "FinancialInvoices");
migrationBuilder.DropForeignKey(
name: "FK_PaymentTransactions_FinancialInvoices_FinancialInvoiceId",
table: "PaymentTransactions");
migrationBuilder.DropTable(
name: "FinancialInvoiceItem");
migrationBuilder.DropIndex(
name: "IX_PaymentTransactions_FinancialInvoiceId",
table: "PaymentTransactions");
migrationBuilder.DropPrimaryKey(
name: "PK_FinancialInvoices",
table: "FinancialInvoices");
migrationBuilder.DropColumn(
name: "FinancialInvoiceId",
table: "PaymentTransactions");
migrationBuilder.DropColumn(
name: "ContractingPartyId",
table: "FinancialInvoices");
migrationBuilder.DropColumn(
name: "Description",
table: "FinancialInvoices");
migrationBuilder.DropColumn(
name: "IsActive",
table: "FinancialInvoices");
migrationBuilder.DropColumn(
name: "PublicId",
table: "FinancialInvoices");
migrationBuilder.RenameTable(
name: "FinancialInvoices",
newName: "FinancialInvoice");
migrationBuilder.RenameColumn(
name: "FinancialStatmentid",
table: "FinancialInvoice",
newName: "FinancialStatementId");
migrationBuilder.RenameIndex(
name: "IX_FinancialInvoices_FinancialStatmentid",
table: "FinancialInvoice",
newName: "IX_FinancialInvoice_FinancialStatementId");
migrationBuilder.AddColumn<int>(
name: "Month",
table: "FinancialInvoice",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<string>(
name: "SmsCode",
table: "FinancialInvoice",
type: "nvarchar(122)",
maxLength: 122,
nullable: true);
migrationBuilder.AddColumn<int>(
name: "Year",
table: "FinancialInvoice",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddPrimaryKey(
name: "PK_FinancialInvoice",
table: "FinancialInvoice",
column: "id");
migrationBuilder.AddForeignKey(
name: "FK_FinancialInvoice_FinancialStatments_FinancialStatementId",
table: "FinancialInvoice",
column: "FinancialStatementId",
principalTable: "FinancialStatments",
principalColumn: "id");
}
}
}

View File

@@ -2838,35 +2838,74 @@ namespace CompanyManagment.EFCore.Migrations
b.Property<double>("Amount")
.HasColumnType("float");
b.Property<long>("ContractingPartyId")
.HasColumnType("bigint");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<long?>("FinancialStatementId")
b.Property<string>("Description")
.HasMaxLength(800)
.HasColumnType("nvarchar(800)");
b.Property<long?>("FinancialStatmentid")
.HasColumnType("bigint");
b.Property<int>("Month")
.HasColumnType("int");
b.Property<bool>("IsActive")
.HasColumnType("bit");
b.Property<DateTime?>("PaidAt")
.HasColumnType("datetime2");
b.Property<string>("SmsCode")
.HasMaxLength(122)
.HasColumnType("nvarchar(122)");
b.Property<Guid>("PublicId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("nvarchar(20)");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("id");
b.HasIndex("FinancialStatmentid");
b.ToTable("FinancialInvoices");
});
modelBuilder.Entity("Company.Domain.FinancialInvoiceAgg.FinancialInvoiceItem", b =>
{
b.Property<long>("id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("id"));
b.Property<double>("Amount")
.HasColumnType("float");
b.Property<DateTime>("CreationDate")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasMaxLength(800)
.HasColumnType("nvarchar(800)");
b.Property<long>("EntityId")
.HasColumnType("bigint");
b.Property<long>("FinancialInvoiceId")
.HasColumnType("bigint");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("id");
b.HasIndex("FinancialStatementId");
b.HasIndex("FinancialInvoiceId");
b.ToTable("FinancialInvoice");
b.ToTable("FinancialInvoiceItem");
});
modelBuilder.Entity("Company.Domain.FinancialStatmentAgg.FinancialStatment", b =>
@@ -5036,6 +5075,9 @@ namespace CompanyManagment.EFCore.Migrations
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<long?>("FinancialInvoiceId")
.HasColumnType("bigint");
b.Property<string>("Gateway")
.IsRequired()
.HasMaxLength(35)
@@ -5059,6 +5101,8 @@ namespace CompanyManagment.EFCore.Migrations
b.HasKey("id");
b.HasIndex("FinancialInvoiceId");
b.ToTable("PaymentTransactions", (string)null);
});
@@ -9994,11 +10038,20 @@ namespace CompanyManagment.EFCore.Migrations
modelBuilder.Entity("Company.Domain.FinancialInvoiceAgg.FinancialInvoice", b =>
{
b.HasOne("Company.Domain.FinancialStatmentAgg.FinancialStatment", "FinancialStatement")
b.HasOne("Company.Domain.FinancialStatmentAgg.FinancialStatment", null)
.WithMany("FinancialInvoices")
.HasForeignKey("FinancialStatementId");
.HasForeignKey("FinancialStatmentid");
});
b.Navigation("FinancialStatement");
modelBuilder.Entity("Company.Domain.FinancialInvoiceAgg.FinancialInvoiceItem", b =>
{
b.HasOne("Company.Domain.FinancialInvoiceAgg.FinancialInvoice", "FinancialInvoice")
.WithMany("Items")
.HasForeignKey("FinancialInvoiceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("FinancialInvoice");
});
modelBuilder.Entity("Company.Domain.FinancialTransactionAgg.FinancialTransaction", b =>
@@ -10548,6 +10601,16 @@ namespace CompanyManagment.EFCore.Migrations
b.Navigation("PaymentToEmployee");
});
modelBuilder.Entity("Company.Domain.PaymentTransactionAgg.PaymentTransaction", b =>
{
b.HasOne("Company.Domain.FinancialInvoiceAgg.FinancialInvoice", "FinancialInvoice")
.WithMany("PaymentTransactions")
.HasForeignKey("FinancialInvoiceId")
.OnDelete(DeleteBehavior.NoAction);
b.Navigation("FinancialInvoice");
});
modelBuilder.Entity("Company.Domain.PenaltyTitle.PenaltyTitle", b =>
{
b.HasOne("Company.Domain.Petition.Petition", "Petition")
@@ -10952,6 +11015,13 @@ namespace CompanyManagment.EFCore.Migrations
b.Navigation("FileStates");
});
modelBuilder.Entity("Company.Domain.FinancialInvoiceAgg.FinancialInvoice", b =>
{
b.Navigation("Items");
b.Navigation("PaymentTransactions");
});
modelBuilder.Entity("Company.Domain.FinancialStatmentAgg.FinancialStatment", b =>
{
b.Navigation("FinancialInvoices");

View File

@@ -1,9 +1,14 @@
using _0_Framework.InfraStructure;
using System.Collections.Generic;
using System.Linq;
using _0_Framework.Application;
using _0_Framework.InfraStructure;
using Company.Domain.FinancialInvoiceAgg;
using CompanyManagment.App.Contracts.FinancialInvoice;
using Microsoft.EntityFrameworkCore;
namespace CompanyManagment.EFCore.Repository;
public class FinancialInvoiceRepository:RepositoryBase<long,FinancialInvoice>,IFinancialInvoiceRepository
public class FinancialInvoiceRepository : RepositoryBase<long, FinancialInvoice>, IFinancialInvoiceRepository
{
private readonly CompanyContext _context;
@@ -11,4 +16,76 @@ public class FinancialInvoiceRepository:RepositoryBase<long,FinancialInvoice>,IF
{
_context = context;
}
public EditFinancialInvoice GetDetails(long id)
{
var financialInvoice = _context.FinancialInvoices
.Include(x => x.Items)
.FirstOrDefault(x => x.id == id);
if (financialInvoice == null)
return null;
return new EditFinancialInvoice
{
Id = financialInvoice.id,
Description = financialInvoice.Description,
Items = financialInvoice.Items?.Select(x => new EditFinancialInvoiceItem
{
Id = x.id,
Description = x.Description,
Amount = x.Amount,
Type = x.Type,
EntityId = x.EntityId
}).ToList()
};
}
public List<FinancialInvoiceViewModel> Search(FinancialInvoiceSearchModel searchModel)
{
var query = _context.FinancialInvoices
.Include(x => x.Items)
.AsQueryable();
if (!string.IsNullOrWhiteSpace(searchModel.Description))
query = query.Where(x => x.Description.Contains(searchModel.Description));
if (searchModel.Status.HasValue)
query = query.Where(x => x.Status == searchModel.Status.Value);
if (searchModel.ContractingPartyId.HasValue)
query = query.Where(x => x.ContractingPartyId == searchModel.ContractingPartyId.Value);
if (!string.IsNullOrWhiteSpace(searchModel.FromDate))
{
var fromDate = searchModel.FromDate.ToGeorgianDateTime();
query = query.Where(x => x.CreationDate >= fromDate);
}
if (!string.IsNullOrWhiteSpace(searchModel.ToDate))
{
var toDate = searchModel.ToDate.ToGeorgianDateTime();
query = query.Where(x => x.CreationDate <= toDate);
}
if (searchModel.MinAmount.HasValue)
query = query.Where(x => x.Amount >= searchModel.MinAmount.Value);
if (searchModel.MaxAmount.HasValue)
query = query.Where(x => x.Amount <= searchModel.MaxAmount.Value);
return query.OrderByDescending(x => x.id)
.Select(x => new FinancialInvoiceViewModel
{
Id = x.id,
Description = x.Description,
Status = x.Status.ToString(),
PaidAt = x.PaidAt.HasValue ? x.PaidAt.Value.ToFarsi() : "",
Amount = x.Amount,
PublicId = x.PublicId,
ContractingPartyId = x.ContractingPartyId,
CreationDate = x.CreationDate.ToFarsi(),
ItemsCount = x.Items != null ? x.Items.Count : 0
}).ToList();
}
}

View File

@@ -265,7 +265,21 @@ public class FinancialStatmentRepository : RepositoryBase<long, FinancialStatmen
}
public async Task<FinancialStatmentDetailsByContractingPartyViewModel> GetDetailsByContractingParty(long contractingPartyId,FinancialStatementSearchModel searchModel)
public async Task<double> GetClientDebtAmountByContractingPartyId(long contractingPartyId)
{
var resStatement = await _context.FinancialStatments.Include(x => x.FinancialTransactionList)
.FirstOrDefaultAsync(x => x.ContractingPartyId == contractingPartyId);
if (resStatement == null)
return 0;
return resStatement.FinancialTransactionList.Sum(x => x.Deptor) -
resStatement.FinancialTransactionList.Sum(x => x.Creditor);
}
public async Task<FinancialStatmentDetailsByContractingPartyViewModel> GetDetailsByContractingParty(long contractingPartyId,FinancialStatementSearchModel searchModel)
{
var contractingParty = await _context.PersonalContractingParties
.FirstOrDefaultAsync(x=>x.id == contractingPartyId);
@@ -413,6 +427,6 @@ public class FinancialStatmentRepository : RepositoryBase<long, FinancialStatmen
public async Task<FinancialStatment> GetByContractingPartyId(long contractingPartyId)
{
return await _context.FinancialStatments.FirstOrDefaultAsync(x => x.ContractingPartyId == contractingPartyId);
return await _context.FinancialStatments.Include(x=>x.FinancialTransactionList).FirstOrDefaultAsync(x => x.ContractingPartyId == contractingPartyId);
}
}

View File

@@ -483,7 +483,7 @@ public class PersonalBootstrapper
services.AddTransient<IAuthorizedBankDetailsApplication, AuthorizedBankDetailsApplication>();
services
.AddTransient<IInstitutionContractExtenstionTempRepository, InstitutionContractExtenstionTempRepository>();
.AddTransient<IInstitutionContractExtenstionTempRepository, InstitutionContractExtenstionTempRepository>();
services.AddTransient<IEmployeeFaceEmbeddingRepository, EmployeeFaceEmbeddingRepository>();
services.AddTransient<IEmployeeFaceEmbeddingApplication, EmployeeFaceEmbeddingApplication>();

View File

@@ -93,7 +93,7 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
_context.PaymentTransactions.Add(transaction);
await _context.SaveChangesAsync();
var command = new CreatePaymentGatewayRequest()
var command = new CreatePaymentGatewayRequest()
{
InvoiceId = transaction.id.ToString(),
Amount = amount,
@@ -104,7 +104,10 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk
if (createRes.IsSuccess)
{
var payUrl = _paymentGateway.GetStartPayUrl(createRes.Token);
transaction.SetTransactionId(createRes.Token);
await _context.SaveChangesAsync();
var payUrl = _paymentGateway.GetStartPayUrl(createRes.Token);
return Redirect(payUrl);
}
else