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 } }