LqShareStatisticsHqService.cs 7.24 KB
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 SqlSugar;
using System;
using System.Linq;
using System.Threading.Tasks;
using Yitter.IdGenerator;

namespace NCC.Extend
{
    /// <summary>
    /// 总部股份统计服务
    /// </summary>
    [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;
        }

        /// <summary>
        /// 生成总部股份统计数据
        /// </summary>
        /// <param name="input">生成参数</param>
        /// <returns>生成结果</returns>
        [HttpPost("generate")]
        public async Task<dynamic> 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<LqShareStatisticsHqEntity>()
                .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 } };
            }
        }

        /// <summary>
        /// 查询总部股份统计列表
        /// </summary>
        /// <param name="input">查询参数</param>
        /// <returns>统计列表</returns>
        [HttpGet("list")]
        public async Task<dynamic> GetList([FromQuery] ShareStatisticsHqQueryInput input)
        {
            var query = _db.Queryable<LqShareStatisticsHqEntity>()
                .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 私有计算方法

        /// <summary>
        /// 计算收入部分
        /// </summary>
        private async Task CalculateIncome(LqShareStatisticsHqEntity entity, DateTime startDate, DateTime endDate)
        {
            // 1. 收入-全部 = (所有门店的总开单实付业绩 - 所有门店的总实退金额) * 9%
            var totalBilling = await _db.Queryable<LqKdKdjlbEntity>()
                .Where(x => x.Kdrq >= startDate && x.Kdrq <= endDate && x.IsEffective == 1)
                .SumAsync(x => x.Sfyj);

            var totalRefund = await _db.Queryable<LqHytkHytkEntity>()
                .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<LqKdPxmxEntity>()
                .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;
        }

        /// <summary>
        /// 计算成本部分
        /// </summary>
        private async Task CalculateCost(LqShareStatisticsHqEntity entity, DateTime startDate, DateTime endDate, string statisticsMonth)
        {
            // 1. 成本-报销 (TODO: 需要确认总部报销的判定方式)
            entity.CostReimbursement = 0;

            // 2. 成本-人工 (保留)
            entity.CostLabor = 0;

            // 3. 成本-教育部房租
            // TODO: 需要确认如何识别教育部合同
            entity.CostEducationRent = 0;

            // 4. 成本-仓库房租
            // TODO: 需要确认如何识别仓库合同
            entity.CostWarehouseRent = 0;

            // 5. 成本-总部房租
            // TODO: 需要确认如何识别总部合同
            entity.CostHQRent = 0;
        }

        /// <summary>
        /// 计算利润
        /// </summary>
        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
    }
}