using Microsoft.AspNetCore.Mvc;
using NCC.Common.Filter;
using NCC.Dependency;
using NCC.DynamicApiController;
using NCC.Extend.Entitys.Dto.LqShareStatisticsHq;
using NCC.Extend.Entitys.lq_share_statistics_hq;
using NCC.Extend.Entitys.lq_kd_kdjlb;
using NCC.Extend.Entitys.lq_hytk_hytk;
using NCC.Extend.Entitys.lq_kd_pxmx;
using NCC.Extend.Entitys.lq_contract_rent_detail;
using NCC.Extend.Entitys.lq_contract;
using NCC.Extend.Entitys;
using SqlSugar;
using System;
using System.Linq;
using System.Threading.Tasks;
using Yitter.IdGenerator;
namespace NCC.Extend
{
///
/// 总部股份统计服务
///
[ApiDescriptionSettings(Tag = "总部股份统计服务", Name = "LqShareStatisticsHq", Order = 402)]
[Route("api/Extend/[controller]")]
public class LqShareStatisticsHqService : IDynamicApiController, ITransient
{
private readonly ISqlSugarClient _db;
public LqShareStatisticsHqService(ISqlSugarClient db)
{
_db = db;
}
///
/// 生成总部股份统计数据
///
/// 生成参数
/// 生成结果
[HttpPost("generate")]
public async Task GenerateStatistics([FromBody] ShareStatisticsHqGenerateInput input)
{
if (string.IsNullOrEmpty(input.StatisticsMonth) || input.StatisticsMonth.Length != 6)
{
return new { code = 500, msg = "统计月份格式错误,应为 YYYYMM" };
}
var year = int.Parse(input.StatisticsMonth.Substring(0, 4));
var month = int.Parse(input.StatisticsMonth.Substring(4, 2));
var startDate = new DateTime(year, month, 1);
var endDate = startDate.AddMonths(1).AddDays(-1);
// 检查是否已存在
var existing = await _db.Queryable()
.FirstAsync(x => x.StatisticsMonth == input.StatisticsMonth);
var entity = existing ?? new LqShareStatisticsHqEntity
{
Id = YitIdHelper.NextId().ToString(),
StatisticsMonth = input.StatisticsMonth,
IsEffective = 1,
CreateTime = DateTime.Now,
CreateUser = "System"
};
// 计算各项数据
await CalculateIncome(entity, startDate, endDate);
await CalculateCost(entity, startDate, endDate, input.StatisticsMonth);
CalculateProfit(entity);
entity.UpdateTime = DateTime.Now;
entity.UpdateUser = "System";
if (existing == null)
{
await _db.Insertable(entity).ExecuteCommandAsync();
return new { code = 200, msg = "生成成功", data = new { generated = true } };
}
else
{
await _db.Updateable(entity).ExecuteCommandAsync();
return new { code = 200, msg = "更新成功", data = new { updated = true } };
}
}
///
/// 查询总部股份统计列表
///
/// 查询参数
/// 统计列表
[HttpGet("list")]
public async Task GetList([FromQuery] ShareStatisticsHqQueryInput input)
{
var query = _db.Queryable()
.Where(x => x.IsEffective == 1);
if (!string.IsNullOrEmpty(input.StatisticsMonth))
{
query = query.Where(x => x.StatisticsMonth == input.StatisticsMonth);
}
var list = await query.OrderBy(x => x.StatisticsMonth, OrderByType.Desc)
.Select(x => new ShareStatisticsHqOutput
{
Id = x.Id,
StatisticsMonth = x.StatisticsMonth,
IncomeGeneral = x.IncomeGeneral,
IncomeTechDept = x.IncomeTechDept,
CostReimbursement = x.CostReimbursement,
CostLabor = x.CostLabor,
CostEducationRent = x.CostEducationRent,
CostWarehouseRent = x.CostWarehouseRent,
CostHQRent = x.CostHQRent,
OperationalProfit = x.OperationalProfit,
CreateTime = x.CreateTime,
UpdateTime = x.UpdateTime
})
.ToListAsync();
return new { code = 200, msg = "查询成功", data = list };
}
#region 私有计算方法
///
/// 计算收入部分
///
private async Task CalculateIncome(LqShareStatisticsHqEntity entity, DateTime startDate, DateTime endDate)
{
// 1. 收入-全部 = (所有门店的总开单实付业绩 - 所有门店的总实退金额) * 9%
var totalBilling = await _db.Queryable()
.Where(x => x.Kdrq >= startDate && x.Kdrq <= endDate && x.IsEffective == 1)
.SumAsync(x => x.Sfyj);
var totalRefund = await _db.Queryable()
.Where(x => x.Tksj >= startDate && x.Tksj <= endDate && x.IsEffective == 1)
.SumAsync(x => x.Tkje ?? 0);
entity.IncomeGeneral = (totalBilling - totalRefund) * 0.09m;
// 2. 收入-科技部 = (总科美业绩 - 总科美退款) * 0.3 * 0.09
var kemeiPerformance = await _db.Queryable()
.Where(x => x.Yjsj >= startDate && x.Yjsj <= endDate && x.IsEffective == 1)
.Where(x => x.ItemCategory == "科美")
.SumAsync(x => x.TotalPrice);
// TODO: 需要确认科美退款的统计方式
entity.IncomeTechDept = kemeiPerformance * 0.3m * 0.09m;
}
///
/// 计算成本部分
///
private async Task CalculateCost(LqShareStatisticsHqEntity entity, DateTime startDate, DateTime endDate, string statisticsMonth)
{
// 1. 成本-报销:筛选一级分类为"总部费用"的申请,审批状态为"已通过"
var reimbursementAmount = await _db.Queryable(
(app, purchase, category) => app.PurchaseRecordsId == purchase.Id && purchase.ReimbursementCategoryId == category.Id)
.Where((app, purchase, category) =>
category.Level1Name == "总部费用"
&& app.ApprovalStatus == "已通过"
&& app.ApplicationTime >= startDate
&& app.ApplicationTime <= endDate.AddDays(1))
.SumAsync((app, purchase, category) => purchase.Amount);
entity.CostReimbursement = reimbursementAmount;
// 2. 成本-人工 (保留)
entity.CostLabor = 0;
// 3. 成本-教育部房租
// 从合同月租明细表获取:门店是总部,分类是教育,统计月份匹配
// 使用月份字符串匹配,避免时区问题
var educationRent = await _db.Ado.SqlQuerySingleAsync(
$@"SELECT COALESCE(SUM(d.F_DueAmount), 0)
FROM lq_contract_rent_detail d
INNER JOIN lq_contract c ON d.F_ContractId = c.F_Id
WHERE c.F_StoreId = '1649328471923847168'
AND c.F_Category = '教育'
AND DATE_FORMAT(d.F_PaymentMonth, '%Y%m') = @StatisticsMonth
AND c.F_IsEffective = 1
AND d.F_IsEffective = 1",
new { StatisticsMonth = statisticsMonth });
entity.CostEducationRent = educationRent;
// 4. 成本-仓库房租
// 从合同月租明细表获取:门店是总部,分类是仓库,统计月份匹配
// 使用月份字符串匹配,避免时区问题
var warehouseRent = await _db.Ado.SqlQuerySingleAsync(
$@"SELECT COALESCE(SUM(d.F_DueAmount), 0)
FROM lq_contract_rent_detail d
INNER JOIN lq_contract c ON d.F_ContractId = c.F_Id
WHERE c.F_StoreId = '1649328471923847168'
AND c.F_Category = '仓库'
AND DATE_FORMAT(d.F_PaymentMonth, '%Y%m') = @StatisticsMonth
AND c.F_IsEffective = 1
AND d.F_IsEffective = 1",
new { StatisticsMonth = statisticsMonth });
entity.CostWarehouseRent = warehouseRent;
// 5. 成本-总部房租
// 从合同月租明细表获取:门店是总部,分类是总部,统计月份匹配
// 使用月份字符串匹配,避免时区问题
var hqRent = await _db.Ado.SqlQuerySingleAsync(
$@"SELECT COALESCE(SUM(d.F_DueAmount), 0)
FROM lq_contract_rent_detail d
INNER JOIN lq_contract c ON d.F_ContractId = c.F_Id
WHERE c.F_StoreId = '1649328471923847168'
AND c.F_Category = '总部'
AND DATE_FORMAT(d.F_PaymentMonth, '%Y%m') = @StatisticsMonth
AND c.F_IsEffective = 1
AND d.F_IsEffective = 1",
new { StatisticsMonth = statisticsMonth });
entity.CostHQRent = hqRent;
}
///
/// 计算利润
///
private void CalculateProfit(LqShareStatisticsHqEntity entity)
{
// 总部运营利润 = 收入(门店9%) + 收入(科技部9%) - 成本(报销) - 成本(人工) - 成本(房租)
var totalIncome = entity.IncomeGeneral + entity.IncomeTechDept;
var totalCost = entity.CostReimbursement
+ entity.CostLabor
+ entity.CostEducationRent
+ entity.CostWarehouseRent
+ entity.CostHQRent;
entity.OperationalProfit = totalIncome - totalCost;
}
#endregion
}
}