add financial statement controller
This commit is contained in:
@@ -68,7 +68,6 @@ public class CustomExceptionHandler : IExceptionHandler
|
||||
|
||||
problemDetails.Extensions.Add("traceId", context.TraceIdentifier);
|
||||
|
||||
|
||||
await context.Response.WriteAsJsonAsync(problemDetails, cancellationToken: cancellationToken);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -13,4 +13,6 @@ public interface IFinancialStatmentRepository : IRepository<long, FinancialStatm
|
||||
|
||||
FinancialStatmentViewModel GetDetailsByContractingPartyId(long contractingPartyId);
|
||||
List<FinancialStatmentViewModel> Search(FinancialStatmentSearchModel searchModel);
|
||||
Task<ClientFinancialStatementViewModel> GetClientFinancialStatement(long accountId,
|
||||
ClientFinancialStatementSearchModel searchModel);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using _0_Framework.Application;
|
||||
using CompanyManagment.App.Contracts.FinancilTransaction;
|
||||
|
||||
namespace CompanyManagment.App.Contracts.FinancialStatment;
|
||||
|
||||
@@ -13,4 +14,123 @@ public interface IFinancialStatmentApplication
|
||||
|
||||
List<FinancialStatmentViewModel> Search(FinancialStatmentSearchModel searchModel);
|
||||
FinancialStatmentViewModel GetDetailsByContractingPartyId(long contractingPartyId);
|
||||
|
||||
/// <summary>
|
||||
/// نمایش اطلاعات صورت حساب مالی کلاینت
|
||||
/// </summary>
|
||||
/// <param name="searchModel"></param>
|
||||
/// <param name="accountId"></param>
|
||||
/// <returns>مدل صورت حساب مالی کلاینت</returns>
|
||||
Task<ClientFinancialStatementViewModel> GetClientFinancialStatement(ClientFinancialStatementSearchModel searchModel,
|
||||
long accountId);
|
||||
}
|
||||
|
||||
public class ClientFinancialStatementSearchModel
|
||||
{
|
||||
/// <summary>
|
||||
/// از تاریخ
|
||||
/// </summary>
|
||||
public string FromDate { get; set; }
|
||||
/// <summary>
|
||||
/// تا تاریخ
|
||||
/// </summary>
|
||||
public string ToDate { get; set; }
|
||||
/// <summary>
|
||||
/// از مبلغ
|
||||
/// </summary>
|
||||
public double FromAmount { get; set; }
|
||||
/// <summary>
|
||||
/// تا مبلغ
|
||||
/// </summary>
|
||||
public double ToAmount { get; set; }
|
||||
/// <summary>
|
||||
/// نوع عملیات تراکنش
|
||||
/// </summary>
|
||||
public FinancialTransactionType? Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// صفحه بندی
|
||||
/// </summary>
|
||||
public int PageIndex { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public enum FinancialTransactionType
|
||||
{
|
||||
/// <summary>
|
||||
/// ایجاد درآمد
|
||||
/// </summary>
|
||||
Debt,
|
||||
/// <summary>
|
||||
/// دریافت درآمد
|
||||
/// </summary>
|
||||
Credit
|
||||
}
|
||||
|
||||
public class ClientFinancialStatementViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// آیدی FinancialStatement
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// جمع بدهکاری
|
||||
/// </summary>
|
||||
public double TotalDebt { get; set; }
|
||||
/// <summary>
|
||||
/// جمع بستانکاری
|
||||
/// </summary>
|
||||
public double TotalCredit { get; set; }
|
||||
/// <summary>
|
||||
/// مبلغ قابل پرداخت
|
||||
/// </summary>
|
||||
public double TotalAmountPayable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// تراکنش ها
|
||||
/// </summary>
|
||||
public List<ClientFinancialTransactionViewModel> Transactions { get; set; }
|
||||
}
|
||||
|
||||
public class ClientFinancialTransactionViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// زمان و تاریخ میلادی
|
||||
/// </summary>
|
||||
public DateTime DateTimeGr { get; set; }
|
||||
/// <summary>
|
||||
/// تاریخ
|
||||
/// </summary>
|
||||
public string DateFa { get; set; }
|
||||
/// <summary>
|
||||
/// زمان
|
||||
/// </summary>
|
||||
public string TimeFa { get; set; }
|
||||
/// <summary>
|
||||
/// شرح
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
/// <summary>
|
||||
/// نوع عملیات پرداخت
|
||||
/// </summary>
|
||||
public FinancialTransactionType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// نوع عملیات پرداخت به صورت استرینگ
|
||||
/// </summary>
|
||||
public string TypeStr { get; set; }
|
||||
/// <summary>
|
||||
/// بدهکار
|
||||
/// </summary>
|
||||
public double Debtor { get; set; }
|
||||
/// <summary>
|
||||
/// بستانکار
|
||||
/// </summary>
|
||||
public double Creditor { get; set; }
|
||||
/// <summary>
|
||||
/// باقی مانده
|
||||
/// </summary>
|
||||
public double Balance { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using _0_Framework.Application;
|
||||
using Company.Domain.FinancialStatmentAgg;
|
||||
using CompanyManagment.App.Contracts.FinancialStatment;
|
||||
@@ -110,4 +111,10 @@ public class FinancialStatmentApplication : IFinancialStatmentApplication
|
||||
{
|
||||
return _financialStatmentRepository.GetDetailsByContractingPartyId(contractingPartyId);
|
||||
}
|
||||
|
||||
public async Task<ClientFinancialStatementViewModel> GetClientFinancialStatement(
|
||||
ClientFinancialStatementSearchModel searchModel, long accountId)
|
||||
{
|
||||
return await _financialStatmentRepository.GetClientFinancialStatement(accountId, searchModel);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using _0_Framework.Application;
|
||||
using _0_Framework.Application;
|
||||
using _0_Framework.Exceptions;
|
||||
using _0_Framework.InfraStructure;
|
||||
using Company.Domain.FinancialStatmentAgg;
|
||||
using CompanyManagment.App.Contracts.FinancialStatment;
|
||||
using CompanyManagment.App.Contracts.FinancilTransaction;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using AccountManagement.Application.Contracts.SubAccount;
|
||||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
|
||||
|
||||
namespace CompanyManagment.EFCore.Repository;
|
||||
|
||||
@@ -44,16 +48,16 @@ public class FinancialStatmentRepository : RepositoryBase<long, FinancialStatmen
|
||||
TdateGr = t.TdateGr,
|
||||
Description = t.TypeOfTransaction == "debt" ? "ایجاد درآمد" + " " + t.DescriptionOption + " " + t.Description : "دریافت درآمد" + " " + t.DescriptionOption + " " + t.Description,
|
||||
Deptor = t.Deptor,
|
||||
DeptorString = t.Deptor!=0?t.Deptor.ToMoney():"",
|
||||
DeptorString = t.Deptor != 0 ? t.Deptor.ToMoney() : "",
|
||||
Creditor = t.Creditor,
|
||||
CreditorString = t.Creditor!=0?t.Creditor.ToMoney():"",
|
||||
CreditorString = t.Creditor != 0 ? t.Creditor.ToMoney() : "",
|
||||
Balance = t.Balance,
|
||||
MessageText = t.MessageText,
|
||||
SentSms = t.SentSms,
|
||||
SentSmsDateFa = t.SentSmsDateFa,
|
||||
FinancialStatementId = t.FinancialStatementId,
|
||||
TypeOfTransaction = t.TypeOfTransaction
|
||||
}).OrderBy(t=>t.TdateGr).ToList(),
|
||||
}).OrderBy(t => t.TdateGr).ToList(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -63,4 +67,83 @@ public class FinancialStatmentRepository : RepositoryBase<long, FinancialStatmen
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<ClientFinancialStatementViewModel> GetClientFinancialStatement(long accountId,
|
||||
ClientFinancialStatementSearchModel searchModel)
|
||||
{
|
||||
var contractingPartyId = _context.ContractingPartyAccounts.Any(x => x.AccountId == accountId) ?
|
||||
_context.ContractingPartyAccounts.FirstOrDefault(x => x.AccountId == accountId)!.PersonalContractingPartyId : 0;
|
||||
|
||||
if (contractingPartyId == 0)
|
||||
throw new BadRequestException("طرف حساب مورد نظر یافت نشد");
|
||||
|
||||
var resStatement = await _context.FinancialStatments.Include(x=>x.FinancialTransactionList)
|
||||
.FirstOrDefaultAsync(x => x.ContractingPartyId == contractingPartyId);
|
||||
|
||||
if (resStatement == null)
|
||||
throw new BadRequestException("صورت حساب مالی شخص یافت نشد");
|
||||
|
||||
var resTransaction = resStatement.FinancialTransactionList.ToList();
|
||||
|
||||
#region Search
|
||||
|
||||
//if (searchModel.FromAmount > 0 || searchModel.ToAmount > 0)
|
||||
//{
|
||||
// if (searchModel.FromAmount > 0 && searchModel.ToAmount > 0)
|
||||
// {
|
||||
// resTransaction = resTransaction.Where(x => x.>= searchModel.FromAmount && x.Amount <= searchModel);
|
||||
// }
|
||||
// else if (searchModel.FromAmount > 0)
|
||||
// {
|
||||
// query = query.Where(x => x.Amount >= searchModel.FromAmount);
|
||||
// }
|
||||
// else if (searchModel.ToAmount > 0)
|
||||
// {
|
||||
// query = query.Where(x => x.Amount <= searchModel.ToAmount);
|
||||
// }
|
||||
//}
|
||||
if (!string.IsNullOrWhiteSpace(searchModel.FromDate) && !string.IsNullOrWhiteSpace(searchModel.ToDate))
|
||||
{
|
||||
if (searchModel.FromDate.TryToGeorgianDateTime(out var fromDate) == false)
|
||||
throw new BadRequestException("تاریخ وارد شده نامعتبر است");
|
||||
|
||||
if (searchModel.FromDate.TryToGeorgianDateTime(out var toDate) == false)
|
||||
throw new BadRequestException("تاریخ وارد شده نامعتبر است");
|
||||
|
||||
resTransaction = resTransaction.Where(x => x.TdateGr >= fromDate && x.TdateGr <= toDate).ToList();
|
||||
}
|
||||
|
||||
if (searchModel.Type != null)
|
||||
{
|
||||
var type = searchModel.Type switch
|
||||
{
|
||||
FinancialTransactionType.Credit => "credit",
|
||||
FinancialTransactionType.Debt => "debt"
|
||||
};
|
||||
|
||||
resTransaction = resTransaction.Where(x => x.TypeOfTransaction == type).ToList();
|
||||
}
|
||||
#endregion
|
||||
|
||||
return new ClientFinancialStatementViewModel()
|
||||
{
|
||||
Id = resStatement.id,
|
||||
TotalAmountPayable = resStatement.FinancialTransactionList.Sum(x=>x.Deptor) - resStatement.FinancialTransactionList.Sum(x=>x.Creditor),
|
||||
TotalCredit = resTransaction.Sum(x=>x.Creditor),
|
||||
TotalDebt = resTransaction.Sum(x=>x.Deptor),
|
||||
Transactions = resTransaction.Select(t => new ClientFinancialTransactionViewModel()
|
||||
{
|
||||
DateTimeGr = t.TdateGr,
|
||||
DateFa = t.TdateGr.ToFarsi(),
|
||||
TimeFa = $"{t.TdateGr:HH:mm}",
|
||||
Description = t.DescriptionOption + " " + t.Description,
|
||||
Debtor = t.Deptor,
|
||||
Creditor = t.Creditor,
|
||||
Balance = t.Balance,
|
||||
Type = t.TypeOfTransaction =="debt"? FinancialTransactionType.Debt :FinancialTransactionType.Credit,
|
||||
TypeStr = t.TypeOfTransaction =="debt"? "ایجاد درآمد" : "دریافت درآمد"
|
||||
}).OrderByDescending(t => t.DateTimeGr).ToList(),
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
26
ServiceHost/Areas/Client/Controllers/FinancialController.cs
Normal file
26
ServiceHost/Areas/Client/Controllers/FinancialController.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using _0_Framework.Application;
|
||||
using CompanyManagment.App.Contracts.FinancialStatment;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ServiceHost.BaseControllers;
|
||||
|
||||
namespace ServiceHost.Areas.Client.Controllers;
|
||||
|
||||
public class FinancialController : ClientBaseController
|
||||
{
|
||||
private readonly IFinancialStatmentApplication _financialStatementApplication;
|
||||
private readonly IAuthHelper _authHelper;
|
||||
|
||||
public FinancialController(IFinancialStatmentApplication financialStatementApplication, IAuthHelper authHelper)
|
||||
{
|
||||
_financialStatementApplication = financialStatementApplication;
|
||||
_authHelper = authHelper;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<ClientFinancialStatementViewModel>> GetList(ClientFinancialStatementSearchModel searchModel)
|
||||
{
|
||||
var accountId = _authHelper.CurrentAccountId();
|
||||
var result =await _financialStatementApplication.GetClientFinancialStatement(searchModel,accountId);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace ServiceHost.BaseControllers;
|
||||
|
||||
//[Authorize(Policy = "ClientArea")]
|
||||
[Authorize(Policy = "ClientArea")]
|
||||
[Area("Client")]
|
||||
[ApiExplorerSettings(GroupName = "Client")]
|
||||
[Route("api/[area]/[controller]")]
|
||||
|
||||
@@ -14,48 +14,52 @@ public class RazorJsonEnumOverrideMiddleware
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
// نگهدار خروجی
|
||||
var originalBody = context.Response.Body;
|
||||
using var newBody = new MemoryStream();
|
||||
context.Response.Body = newBody;
|
||||
|
||||
await _next(context); // اجرای مرحله بعدی
|
||||
|
||||
// فقط برای مسیرهای غیر /api و وقتی Content-Type = application/json
|
||||
if (!context.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase) &&
|
||||
context.Response.ContentType?.Contains("application/json", StringComparison.OrdinalIgnoreCase) == true)
|
||||
try
|
||||
{
|
||||
newBody.Seek(0, SeekOrigin.Begin);
|
||||
using var reader = new StreamReader(newBody);
|
||||
var originalJson = await reader.ReadToEndAsync();
|
||||
await _next(context);
|
||||
|
||||
// JSON رو deserialize و دوباره serialize میکنیم بدون EnumConverter
|
||||
try
|
||||
if (!context.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase) &&
|
||||
context.Response.ContentType?.Contains("application/json", StringComparison.OrdinalIgnoreCase) == true)
|
||||
{
|
||||
var obj = JsonSerializer.Deserialize<object>(originalJson);
|
||||
var newJson = JsonSerializer.Serialize(obj, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
});
|
||||
|
||||
context.Response.Body = originalBody;
|
||||
context.Response.ContentLength = Encoding.UTF8.GetByteCount(newJson);
|
||||
await context.Response.WriteAsync(newJson);
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// fallback if deserialization fails
|
||||
context.Response.Body = originalBody;
|
||||
newBody.Seek(0, SeekOrigin.Begin);
|
||||
await newBody.CopyToAsync(originalBody);
|
||||
return;
|
||||
}
|
||||
}
|
||||
var originalJson = await new StreamReader(newBody).ReadToEndAsync();
|
||||
|
||||
// اگر شرط نداشت، همون خروجی قبلی رو منتقل کن
|
||||
context.Response.Body = originalBody;
|
||||
newBody.Seek(0, SeekOrigin.Begin);
|
||||
await newBody.CopyToAsync(originalBody);
|
||||
try
|
||||
{
|
||||
var obj = JsonSerializer.Deserialize<object>(originalJson);
|
||||
var newJson = JsonSerializer.Serialize(obj, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
});
|
||||
|
||||
context.Response.Body = originalBody;
|
||||
context.Response.ContentLength = Encoding.UTF8.GetByteCount(newJson);
|
||||
if (!context.Response.HasStarted)
|
||||
await context.Response.WriteAsync(newJson);
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
context.Response.Body = originalBody;
|
||||
newBody.Seek(0, SeekOrigin.Begin);
|
||||
if (!context.Response.HasStarted)
|
||||
await newBody.CopyToAsync(originalBody);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
context.Response.Body = originalBody;
|
||||
newBody.Seek(0, SeekOrigin.Begin);
|
||||
if (!context.Response.HasStarted)
|
||||
await newBody.CopyToAsync(originalBody);
|
||||
}
|
||||
finally
|
||||
{
|
||||
context.Response.Body = originalBody;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,8 @@ using System.Text.Json;
|
||||
using Microsoft.AspNetCore.CookiePolicy;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Diagnostics;
|
||||
|
||||
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
@@ -291,6 +293,7 @@ builder.Services.AddCors(options =>
|
||||
|
||||
builder.Services.AddExceptionHandler<CustomExceptionHandler>();
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
app.UseCors("AllowSpecificOrigins");
|
||||
|
||||
@@ -323,6 +326,8 @@ if (app.Environment.IsDevelopment())
|
||||
//Create Http Pipeline
|
||||
|
||||
#region Create Http Pipeline
|
||||
|
||||
|
||||
if (builder.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
@@ -333,17 +338,23 @@ else
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseExceptionHandler(options => { }); // این خط CustomExceptionHandler رو فعال میکنه
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseCookiePolicy();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
#region Mahan
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Areas\Client\Controllers\" />
|
||||
<Folder Include="Storage\Task\" />
|
||||
<Folder Include="Storage\Ticket\" />
|
||||
<Folder Include="wwwroot\AdminTheme\js\faceApi\" />
|
||||
@@ -387,7 +388,6 @@
|
||||
<None Include="Areas\Client\Pages\Shared\_ValidationScriptsPartial.cshtml" />
|
||||
<None Include="Areas\Client\Pages\_ViewImports.cshtml" />
|
||||
<None Include="Areas\Client\Pages\_ViewStart.cshtml" />
|
||||
<None Include="Pages\error\403.cshtml" />
|
||||
<None Include="Pages\error\404.cshtml" />
|
||||
<None Include="wwwroot\AdminTheme\assets\datatables-new\js\dataTables.bootstrap4.min.js" />
|
||||
<None Include="wwwroot\AdminTheme\assets\datatables-new\js\dataTables.responsive.min.js" />
|
||||
|
||||
Reference in New Issue
Block a user