using Microsoft.AspNetCore.Mvc;
using NCC.Common.Filter;
using NCC.Dependency;
using NCC.DynamicApiController;
using NCC.Extend.Entitys.Dto.LqShareStatisticsTechDept;
using NCC.Extend.Entitys.lq_share_statistics_tech_dept;
using NCC.Extend.Entitys.lq_mdxx;
using NCC.Extend.Entitys.lq_kd_pxmx;
using NCC.Extend.Entitys.lq_kd_kdjlb;
using NCC.Extend.Entitys.lq_hytk_jksyj;
using NCC.Extend.Entitys.lq_xh_jksyj;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Yitter.IdGenerator;
namespace NCC.Extend
{
///
/// 科技部股份统计服务
///
[ApiDescriptionSettings(Tag = "科技部股份统计服务", Name = "LqShareStatisticsTechDept", Order = 401)]
[Route("api/Extend/[controller]")]
public class LqShareStatisticsTechDeptService : IDynamicApiController, ITransient
{
private readonly ISqlSugarClient _db;
public LqShareStatisticsTechDeptService(ISqlSugarClient db)
{
_db = db;
}
///
/// 生成科技部股份统计数据
///
/// 生成参数
/// 生成结果
[HttpPost("generate")]
public async Task GenerateStatistics([FromBody] ShareStatisticsTechDeptGenerateInput 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 departments = new List();
if (!string.IsNullOrEmpty(input.DepartmentName))
{
departments.Add(input.DepartmentName);
}
else
{
departments.Add("科技一部");
departments.Add("科技二部");
}
var generatedCount = 0;
var updatedCount = 0;
foreach (var deptName in departments)
{
// 检查是否已存在
var existing = await _db.Queryable()
.FirstAsync(x => x.DepartmentName == deptName && x.StatisticsMonth == input.StatisticsMonth);
var entity = existing ?? new LqShareStatisticsTechDeptEntity
{
Id = YitIdHelper.NextId().ToString(),
DepartmentName = deptName,
StatisticsMonth = input.StatisticsMonth,
IsEffective = 1,
CreateTime = DateTime.Now,
CreateUser = "System"
};
// 计算各项数据
await CalculateIncome(entity, deptName, startDate, endDate);
await CalculateCost(entity, deptName, startDate, endDate, input.StatisticsMonth);
CalculateProfit(entity);
entity.UpdateTime = DateTime.Now;
entity.UpdateUser = "System";
if (existing == null)
{
await _db.Insertable(entity).ExecuteCommandAsync();
generatedCount++;
}
else
{
await _db.Updateable(entity).ExecuteCommandAsync();
updatedCount++;
}
}
return new
{
code = 200,
msg = "生成成功",
data = new
{
generatedCount,
updatedCount,
totalCount = departments.Count
}
};
}
///
/// 查询科技部股份统计列表
///
/// 查询参数
/// 统计列表
[HttpGet("list")]
public async Task GetList([FromQuery] ShareStatisticsTechDeptQueryInput input)
{
var query = _db.Queryable()
.Where(x => x.IsEffective == 1);
if (!string.IsNullOrEmpty(input.StatisticsMonth))
{
query = query.Where(x => x.StatisticsMonth == input.StatisticsMonth);
}
if (!string.IsNullOrEmpty(input.DepartmentName))
{
query = query.Where(x => x.DepartmentName == input.DepartmentName);
}
var list = await query.OrderBy(x => x.StatisticsMonth, OrderByType.Desc)
.OrderBy(x => x.DepartmentName)
.Select(x => new ShareStatisticsTechDeptOutput
{
Id = x.Id,
DepartmentName = x.DepartmentName,
StatisticsMonth = x.StatisticsMonth,
Income = x.Income,
CostReimbursement = x.CostReimbursement,
CostTeacherBase = x.CostTeacherBase,
CostTeacherManual = x.CostTeacherManual,
CostTeacherBillingComm = x.CostTeacherBillingComm,
CostTeacherConsumeComm = x.CostTeacherConsumeComm,
CostTeacherExpertComm = x.CostTeacherExpertComm,
CostTeacherOvertime = x.CostTeacherOvertime,
CostGMBase = x.CostGMBase,
CostGMComm = x.CostGMComm,
RewardTechDept = x.RewardTechDept,
CostOther1 = x.CostOther1,
CostOther2 = x.CostOther2,
Profit = x.Profit,
CreateTime = x.CreateTime,
UpdateTime = x.UpdateTime
})
.ToListAsync();
return new { code = 200, msg = "查询成功", data = list };
}
#region 私有计算方法
///
/// 计算收入部分
///
private async Task CalculateIncome(LqShareStatisticsTechDeptEntity entity, string deptName, DateTime startDate, DateTime endDate)
{
// 1. 找到该科技部管辖的所有门店
var stores = await _db.Queryable()
.Where(x => x.Kjb == deptName)
.Select(x => x.Id)
.ToListAsync();
if (stores.Count == 0)
{
entity.Income = 0;
return;
}
// 2. 统计这些门店的科美项目开单实付业绩
// 需要关联 lq_kd_kdjlb 来获取门店信息
var kemeiIncome = await _db.Queryable((px, kd) => new JoinQueryInfos(
JoinType.Inner, px.Glkdbh == kd.Id))
.Where((px, kd) => stores.Contains(kd.Djmd) && px.Yjsj >= startDate && px.Yjsj <= endDate && px.IsEffective == 1)
.Where((px, kd) => px.ItemCategory == "科美")
.SumAsync((px, kd) => px.TotalPrice);
// 3. 减去对应的科美项目实退金额
var kemeiRefund = await _db.Queryable()
.Where(x => stores.Contains(x.StoreId) && x.Tksj >= startDate && x.Tksj <= endDate && x.IsEffective == 1)
.Where(x => x.ItemCategory == "科美")
.SumAsync(x => x.Jksyj ?? 0);
// 4. 结果 * 30%
entity.Income = (kemeiIncome - kemeiRefund) * 0.3m;
}
///
/// 计算成本部分
///
private async Task CalculateCost(LqShareStatisticsTechDeptEntity entity, string deptName, DateTime startDate, DateTime endDate, string statisticsMonth)
{
// 1. 成本-报销 (TODO: 需要确认报销分类的具体判定方式)
entity.CostReimbursement = 0;
// 2. 成本-人工-科技部老师底薪 (TODO: 需要确认科技部老师工资表名和字段)
entity.CostTeacherBase = 0;
// 3. 成本-人工-科技部手工费
// 从消耗表中统计科技部老师的手工费
// TODO: 需要确认如何识别科技部老师
entity.CostTeacherManual = 0;
// 4. 成本-人工-科技部开单提成 (TODO: 需要确认字段名)
entity.CostTeacherBillingComm = 0;
// 5. 成本-人工-科技部消耗提成 (TODO: 需要确认字段名)
entity.CostTeacherConsumeComm = 0;
// 6. 成本-人工-科技部总经理 (TODO: 需要确认科技部总经理工资表)
entity.CostGMBase = 0;
entity.CostGMComm = 0;
// 保留字段
entity.CostTeacherExpertComm = 0;
entity.CostTeacherOvertime = 0;
entity.RewardTechDept = 0;
entity.CostOther1 = 0;
entity.CostOther2 = 0;
}
///
/// 计算利润
///
private void CalculateProfit(LqShareStatisticsTechDeptEntity entity)
{
// 科技部利润 = 收入 - 成本报销 - 成本人工 - 其他
var totalCost = entity.CostReimbursement
+ entity.CostTeacherBase
+ entity.CostTeacherManual
+ entity.CostTeacherBillingComm
+ entity.CostTeacherConsumeComm
+ entity.CostTeacherExpertComm
+ entity.CostTeacherOvertime
+ entity.CostGMBase
+ entity.CostGMComm
+ entity.RewardTechDept
+ entity.CostOther1
+ entity.CostOther2;
entity.Profit = entity.Income - totalCost;
}
#endregion
}
}