using DS.Module.Core; using DS.Module.Core.Extensions; using DS.Module.SqlSugar; using DS.Module.UserModule; using DS.WMS.ContainerManagement.Info.Dtos; using DS.WMS.ContainerManagement.Info.Entity; using DS.WMS.ContainerManagement.Info.Interface; using DS.WMS.Core.Application.Dtos; using DS.WMS.Core.Application.Entity; using DS.WMS.Core; using DS.WMS.Core.Info.Dtos; using DS.WMS.Core.Info.Entity; using DS.WMS.Core.Info.Interface; using DS.WMS.Core.Invoice.Dtos; using DS.WMS.Core.Op.View; using DS.WMS.Core.Sys.Entity; using Mapster; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using SqlSugar; using DS.WMS.Core.Fee.Entity; using DS.WMS.Core.Op.Entity; using AngleSharp.Dom; using NPOI.Util; using DS.WMS.Core.Sys.Method; using DS.WMS.Core.Sys.Interface; using DS.WMS.Core.Op.Dtos; using DS.Module.Core.Enums; using Masuit.Tools.Models; using NPOI.SS.Formula.Functions; using DS.WMS.Core.Fee.Interface; using DS.WMS.Core.Fee.Method; using DS.WMS.Core.Fee.Dtos; using LanguageExt; namespace DS.WMS.ContainerManagement.Info.Method; // : FeeServiceBase, ISettlementService where TEntity : SettlementBase, new () public class CM_CustFeeDuiService : CMServiceBase, ICM_CustFeeDuiService { private readonly IServiceProvider _serviceProvider; private readonly ISqlSugarClient db; private readonly IUser user; private readonly ISaasDbService saasService; private readonly ICommonService commonService; private readonly IFeeCurrencyExchangeService feeCurrencyExchangeService; /// /// /// /// public CM_CustFeeDuiService(IServiceProvider serviceProvider) : base(serviceProvider) { _serviceProvider = serviceProvider; db = _serviceProvider.GetRequiredService(); user = _serviceProvider.GetRequiredService(); saasService = _serviceProvider.GetRequiredService(); commonService = _serviceProvider.GetRequiredService(); feeCurrencyExchangeService = _serviceProvider.GetRequiredService(); } /// /// 列表 /// /// /// public async Task>> GetListByPage(PageRequest request) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); //序列化查询条件 var whereList = db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition); var data = tenantDb.Queryable() .InnerJoin((a, b) => a.Id == b.BusinessId) //.LeftJoin((a, b, c) => a.SaleOrgId == c.Id, "shippingweb8_dev.sys_org") .LeftJoin((a, b, c) => a.OrgId == c.Id, "shippingweb8_dev.sys_org") .Select((a, b, c) => new CM_CustFeeDuiRes() { OrgName = c.OrgName, }, true) .Where(whereList) //.Select() .ToQueryPage(request.PageCondition); return data; } /// /// 编辑 /// /// /// public async Task EditCM_CustFeeDui(CM_CustFeeDuiReq req) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); if (req.Id == 0) { var data = req.Adapt(); var sequence = commonService.GetSequenceNext(); if (!sequence.Succeeded) { return await Task.FromResult(DataResult.Failed(sequence.Message, MultiLanguageConst.SequenceSetNotExist)); } data.Billno = sequence.Data; //var entity = tenantDb.Insertable(data).ExecuteReturnEntity(); var entity = await tenantDb.Insertable(data).ExecuteReturnEntityAsync(); InitBusiness(entity.Id); //return DataResult.Successed("添加成功!", entity.Id, MultiLanguageConst.DataCreateSuccess); return await Task.FromResult(DataResult.Successed("添加成功!", entity.Id, MultiLanguageConst.DataCreateSuccess)); } else { var info = await tenantDb.Queryable().Where(x => x.Id == req.Id).FirstAsync(); info = req.Adapt(info); await tenantDb.Updateable(info).ExecuteCommandAsync(); return await Task.FromResult(DataResult.Successed("更新成功!", MultiLanguageConst.DataUpdateSuccess)); } } /// /// 详情 /// /// /// public DataResult GetCM_CustFeeDui(string id) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var data = tenantDb.Queryable() .Where(a => a.Id == long.Parse(id)) .Select() .First(); return DataResult.Success(data, MultiLanguageConst.DataQuerySuccess); } #region 删除 /// /// 删除 /// /// 费用记录ID /// public async Task DeleteCM_CustFeeDuiAsync(params long[] ids) { foreach (var _id in ids) { if (await IsLockedAsync(_id, BusinessType.CM_CustFeeDui)) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.FeeLocked)); } //如果包含费用 不允许删除 var feeCount = await TenantDb.Queryable().Where(x => ids.Contains(x.BusinessId)).CountAsync(); if (feeCount > 0) { return DataResult.FailedWithDesc(nameof(MultiLanguageConst.CM_FeeExist)); } int result = await TenantDb.Deleteable(x => ids.Contains(x.Id)).ExecuteCommandAsync(); if (result > 0) { //删除所有明细 await TenantDb.Deleteable(x => ids.Contains(x.Pid)).ExecuteCommandAsync(); await TenantDb.Deleteable(x => ids.Contains(x.Pid)).ExecuteCommandAsync(); } //await WriteBackStatusAsync(model.BusinessId, model.BusinessType); return result > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); } #endregion #region 待添加业务明细 /// /// 待添加业务明细 /// /// 箱当前状态ID /// public async Task>> GetVW_CM_FeeBase_Detail(PageRequest request) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); //序列化查询条件 var whereList = db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition); var data = tenantDb.Queryable() .Where(whereList) //.Where(x=>x.ctn) .Select() .ToQueryPage(request.PageCondition); return data; } /// /// 加入账单 /// /// 箱当前状态ID /// public async Task AddVW_CM_FeeBase_Detail(long Id, params long[] ids) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var head = await tenantDb.Queryable().Where(x => x.Id == Id).FirstAsync() ; var addDetailList = await tenantDb.Queryable() .Where(x => ids.Contains(x.Id)) .Select() .ToListAsync(); //var addDetailList = tenantDb.Queryable().Where(x => ids.Contains(x.Id)).ToList(); //根据账单开始和结束日期 逐个循环范围内(>=开始日期 小于结束日期+1)的日期 //遍历日期 搞清每天的费率 和计费数量 var FeeCalendarList = new List(); var FeeDuiDetailList = new List(); var 当前明细=await tenantDb.Queryable().Where(x => x.Pid == Id).ToListAsync(); var amount = 0M; if (当前明细 != null && 当前明细.Count > 0) { amount = (decimal)当前明细.Sum(x => x.FeeType== FeeType.Receivable? x.Amount:-x.Amount); } for (DateTime _currday = (DateTime)head.BillStartDate; _currday <= head.BillEndDate; _currday = _currday.AddDays(1)) { foreach (var detail in addDetailList) { if (当前明细.Exists(x => x.Cntrno == detail.Cntrno)) continue; //防止重复添加 //如果开始日期小于等于当前日期_currday 并且结束日期为空或者小于_currday 这天就要算钱 if (detail.FeeStartDate <= _currday && (detail.DropoffDate == null || detail.DropoffDate > _currday.AddDays(1))) { var feetype = FeeType.Receivable; if (detail.RentDirectId == CMRentDirectEnum.租入) { feetype = FeeType.Payable; } if (detail.RentDirectId == CMRentDirectEnum.租出) { feetype = FeeType.Receivable; } var addrec = new CM_CustFeeDui_Calendar(Id,_currday,feetype, detail); FeeCalendarList.Add(addrec); if (FeeDuiDetailList.Exists(x => x.Cntrno == detail.Cntrno)) { var _detail = FeeDuiDetailList.First(x => x.Cntrno == detail.Cntrno); _detail.BillEndDate = _currday; _detail.DAYS += 1; _detail.Amount += detail.DailyRate; } else { var newdetail = new CM_CustFeeDui_Detail(); newdetail.Pid = Id; newdetail.Cntrno= detail.Cntrno; newdetail.Ctnall= detail.Ctnall; newdetail.CtnCode= detail.CtnCode; newdetail.FeeStartDate=detail.FeeStartDate; newdetail.DailyRate= detail.DailyRate; newdetail.Currency= detail.Currency; newdetail.BillStartDate = _currday ; newdetail.BillEndDate = _currday; newdetail.DAYS = 1; newdetail.FeeType = feetype; newdetail.Amount = detail.DailyRate; FeeDuiDetailList.Add(newdetail); } } } } if (FeeDuiDetailList.Count > 0) { //保存新加的明细 amount += (decimal)FeeDuiDetailList.Sum(x => x.FeeType == FeeType.Receivable ? x.Amount : -x.Amount); head.AMOUNT = amount; if(head.AMOUNT>0) head.FeeType = FeeType.Payable; if (head.AMOUNT < 0) { head.AMOUNT = -head.AMOUNT; head.FeeType = FeeType.Receivable; } } await tenantDb.Updateable(head).ExecuteCommandAsync(); await tenantDb.Insertable(FeeDuiDetailList).ExecuteCommandAsync(); await tenantDb.Insertable(FeeCalendarList).ExecuteCommandAsync(); return await Task.FromResult(DataResult.Successed("添加成功!", head.Id, MultiLanguageConst.DataCreateSuccess)); } #endregion public async Task CM_CustFeeDui_MakeFee(long Id) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); //根据明细生成费用 var head = await tenantDb.Queryable().Where(x => x.Id == Id).FirstAsync(); var body = await tenantDb.Queryable().Where(x => x.Pid == Id).ToListAsync(); //按箱型和币别和单价分组 var groupList = new List(); foreach (var item in body) { if (groupList.Exists(x => x.Ctnall == item.Ctnall && x.DailyRate == item.DailyRate && x.Currency == item.Currency && x.FeeType==item.FeeType)) { groupList.First(x => x.Ctnall == item.Ctnall && x.DailyRate == item.DailyRate && x.Currency == item.Currency && x.FeeType == item.FeeType).DAYS += item.DAYS; groupList.First(x => x.Ctnall == item.Ctnall && x.DailyRate == item.DailyRate && x.Currency == item.Currency && x.FeeType == item.FeeType).Amount += item.Amount; } else { groupList.Add(item); } } var savefeeList = new List(); if (groupList != null && groupList.Count > 0) { savefeeList = await GetFeeList(head, groupList); if (savefeeList != null && savefeeList.Count > 0) { await tenantDb.Insertable(savefeeList).ExecuteCommandAsync(); } } return await Task.FromResult(DataResult.Successed("添加成功!", head.Id, MultiLanguageConst.DataCreateSuccess)); } /// /// /// /// /// /// public async Task> GetFeeList(CM_CustFeeDui head, List 租箱月结明细List) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var result = new List(); if (!租箱月结明细List.Exists(x=>x.Amount>0)) {//如果没有大于0的费用 return result; } //根据租箱费寻找feecode var feecode = await tenantDb.Queryable().FirstAsync(x => x.Name == "租箱费"); if (feecode == null) { return result; } foreach (var 租箱月结明细 in 租箱月结明细List) { var newfee = new FeeRecord(); newfee.FeeId = feecode.Id; newfee.FeeName = feecode.Name; newfee.FeeCode = feecode.Code; newfee.TaxRate = feecode.TaxRate == null ? 0 : (decimal)feecode.TaxRate; newfee.BusinessId = 租箱月结明细.Pid; newfee.BusinessType = BusinessType.CM_CustFeeDui; newfee.CustomerId = head.CustomerId; newfee.CustomerName = head.CustomerName; newfee.FeeType = FeeType.Payable; //租箱月结明细.FeeType; newfee.Unit = 租箱月结明细.CtnCode; newfee.UnitText = 租箱月结明细.Ctnall; newfee.Currency = 租箱月结明细.Currency; newfee.TaxUnitPrice = 租箱月结明细.DailyRate == null ? 0 : (decimal)租箱月结明细.DailyRate; newfee.Quantity = 租箱月结明细.DAYS == null ? 0 : (decimal)租箱月结明细.DAYS; newfee.Amount = 租箱月结明细.Amount == null ? 0 : (decimal)租箱月结明细.Amount; var feecurrencyinfo = await feeCurrencyExchangeService.GetExchangeRateAsync(new ExchangeRate { CurrencyFrom = newfee.Currency, CurrencyTo = "", FeeType = newfee.FeeType }); newfee.ExchangeRate = feecurrencyinfo.Data.Rate; newfee.SetTax(); if (newfee.Amount > 0) { result.Add(newfee); } } return result; } }