You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

362 lines
13 KiB
C#

using DS.Module.Core;
using DS.Module.Core.Extensions;
using DS.Module.UserModule;
using DS.WMS.Core.FeeModule.Entity;
using DS.WMS.Core.FeeModule.Interface;
using DS.WMS.Core.WmsModule.Entity;
using Mapster;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
namespace DS.WMS.Core.FeeModule.Method;
/// <summary>
/// 费用公共方法
/// </summary>
public class WmsFeeComonService:IWmsFeeComonService
{
private readonly IServiceProvider _serviceProvider;
private readonly ISqlSugarClient db;
private readonly IUser user;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="serviceProvider"></param>
public WmsFeeComonService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
db = _serviceProvider.GetRequiredService<ISqlSugarClient>();
user = _serviceProvider.GetRequiredService<IUser>();
}
public DataResult<List<OP_WMS_FEERATE_STORE_DETAIL>> InitOpWmsStoreRate(Guid wmsId, List<OP_WMS_FEERATE_DO_DETAIL> doFees, Guid? feeTypeGid)
{
var res = new List<OP_WMS_FEERATE_STORE_DETAIL>();
if (feeTypeGid.IsNull())
{
feeTypeGid = doFees.Where(x => x.GoodsFeeTypeGID.IsNotNull()).First().GoodsFeeTypeGID;
}
foreach (var item in doFees)
{
if (item.GOODSFEETYPE.IsNullOrEmpty() || item.GoodsFeeTypeGID == feeTypeGid)
{
var newfeerate = item.Adapt<OP_WMS_FEERATE_STORE_DETAIL>();
newfeerate.PID = wmsId;
res.Add(newfeerate);
}
}
return DataResult<List<OP_WMS_FEERATE_STORE_DETAIL>>.Success(res);
}
public DataResult<OP_WMS_FEEPAYINFO> InitOpWmsPayInfo(OP_WMS_IN_DO inDo, OP_WMS wms)
{
var res = new OP_WMS_FEEPAYINFO();
// res.GID = Guid.NewGuid();
res.WMSID = wms.WMSID;
res.WMSBASEID = wms.WMSBASEID==null?Guid.Empty: (Guid)wms.WMSBASEID;
res.FEESTARTDATE = (DateTime)wms.FEESTARTDATE;
res.ARCLIENTWMSOUT = wms.ARCLIENTWMSOUT;
res.ARCLIENTWMSIN = wms.ARCLIENTWMSOUT;
res.ARCLIENTWMS_OUTDO = wms.ARCLIENTWMSOUT;
res.APCLIENTWMSOUT = inDo.APCLIENTWMSOUT;
res.APCLIENTWMSIN = inDo.APCLIENTWMSOUT;
res.APCLIENTWMS_OUTDO = inDo.APCLIENTWMSOUT;
res.STORAGEUNITCOUNT = wms.STORAGEUNITCOUNT;
res.FEERATEWMSID = wms.WMSID;
res.SOURCEDOID = wms.WMSID;
return DataResult<OP_WMS_FEEPAYINFO>.Success(res);
}
public DataResult<OP_WMS_FEEPAYINFO> InitOpWmsPayInfo(OP_WMS wms)
{
var res = new OP_WMS_FEEPAYINFO();
// res.GID = Guid.NewGuid();
res.WMSID = wms.WMSID;
res.WMSBASEID = wms.WMSBASEID==null?Guid.Empty: (Guid)wms.WMSBASEID;
res.FEESTARTDATE = (DateTime)wms.FEESTARTDATE;
res.ARCLIENTWMSOUT = wms.ARCLIENTWMSOUT;
res.ARCLIENTWMSIN = wms.ARCLIENTWMSOUT;
res.ARCLIENTWMS_OUTDO = wms.ARCLIENTWMSOUT;
res.APCLIENTWMSOUT = wms.APCLIENTWMSOUT;
res.APCLIENTWMSIN = wms.APCLIENTWMSOUT;
res.APCLIENTWMS_OUTDO = wms.APCLIENTWMSOUT;
res.STORAGEUNITCOUNT = wms.STORAGEUNITCOUNT;
res.FEERATEWMSID = wms.WMSID;
res.SOURCEDOID = wms.WMSID;
return DataResult<OP_WMS_FEEPAYINFO>.Success(res);
}
public DataResult<List<Fee>> InitOpWmsFee(List<OP_WMS_FEERATE_DO_DETAIL> doFees, List<OP_WMS_IN_DO_GOODS> details, OP_WMS_IN_DO inDo,List<CodeFee> codeFees)
{
var res = new List<Fee>();
foreach (var item in doFees)
{
if (item.FEEMAKETYPE=="入库现结")
{
decimal num = 0.0m;
if (item.DEFAULTUNIT == "计费单位")
{
foreach (var detail in details)
{
num += (decimal)(detail.STORAGEUNITCOUNT);
}
};
if (item.DEFAULTUNIT == "单票") num = 1;
if (item.DEFAULTUNIT == "单柜")
{
//遍历入库执行明细 看看有几个箱号
var cntrnolist = new List<string>();
foreach (var detail in details)
{
if (!cntrnolist.Exists(x => x == detail.CNTRNO))
{
cntrnolist.Add(detail.CNTRNO);
}
}
num = cntrnolist.Count();
};
decimal amount = num * item.FEEPRICE.ToDecimal();
if (amount != 0)
{
if (res.Count == 0 || !res.Any(e => e.FeeId == item.FeeId))
{
var codefee = codeFees.First(x => x.GID == item.FeeId);
//给列表增加一条费用
var newfee = new Fee()
{
GID = Guid.NewGuid().ToString(),
ClientId = inDo.ClientId,
FeeId = codefee.GID,
SETTLEMENT = 0,
ORDERAMOUNT = 0,
ORDERINVOICE = 0,
ORDERINVSETTLEMENT = 0,
INVOICE = 0,
CURRENCY = "RMB",
EXCHANGERATE = 1,
ENTERDATE = DateTime.Now,
ENTEROPERATOR = user.GetUserGID(),
FEESTATUS = 1,
TAXRATE = 0,
ISADVANCEDPAY = false,
ISINVOICE = false,
ISCRMORDERFEE = false,
INPUTMODE = "月结",
};
newfee.BSNO = inDo.WMSDOID.ToString().ToUpper();
//newfee.SetCreateDefaultVal();
newfee.FEENAME = item.FEENAME;
newfee.UNITPRICE = item.FEEPRICE;
newfee.QUANTITY = num;
newfee.AMOUNT = amount;
newfee.CUSTOMERNAME = inDo.CUSTOMERNAME;
newfee.FEETYPE = item.FEETYPE;
newfee.setTax(ref newfee);
res.Add(newfee);
}
else
{
var fee = res.First(e => e.FEENAME == item.FEENAME);
var index = res.IndexOf(fee);
fee.QUANTITY = fee.QUANTITY + num;
fee.AMOUNT = fee.AMOUNT + amount;
fee.setTax(ref fee);
res[index] = fee;
}
}
}
}
return DataResult<List<Fee>>.Success(res);
}
public DataResult<List<OP_WMS_FEERATE_STORE_DETAIL>> InitMoveOpWmsStoreRate(Guid wmsId, List<OP_WMS_FEERATE_STORE_DETAIL> storeRate)
{
var res = new List<OP_WMS_FEERATE_STORE_DETAIL>();
foreach (var item in storeRate)
{
var newfeerate = item.Adapt<OP_WMS_FEERATE_STORE_DETAIL>();
newfeerate.PID = wmsId;
newfeerate.GID = Guid.NewGuid();
res.Add(newfeerate);
}
return DataResult<List<OP_WMS_FEERATE_STORE_DETAIL>>.Success(res);
}
public DataResult<List<OP_WMS_CHANGE>> GetWmsChangeList(DateTime _currday, List<OP_WMS_CHANGE> wmsChangelist)
{
var data = new List<OP_WMS_CHANGE>();
//如果存在日期相同的 则取相同的
//如果不存在 则_currday之前最后一个日期的
data = wmsChangelist.Where(x => (DateTime)x.DODATE == _currday).ToList();
if (data.Count > 0)
{
//在当日 如有入库 只取入库这条
if (data.Any(x => x.CHANGETYPE == WMSCHANGTYPE.))
{
var res = data.First(x => x.CHANGETYPE == WMSCHANGTYPE.);
data.Clear();
data.Add(res);
}
else
{
//如没有 那就是只有出库或货转出库
//取其中变动前最大的
var maxValue = data.Max(x => x.STORAGEUNITCOUNT2);
var res = data.First(x => x.STORAGEUNITCOUNT2 == maxValue);
data.Clear();
data.Add(res);
}
}
else
{
//取用往日数据 此时需使用那天最后的结果
wmsChangelist.OrderBy(x => x.DODATE);
foreach (var item in wmsChangelist)
{
if (_currday < item.DODATE) continue;
if (data.Any(x => x.DODATE < item.DODATE))
{
data.Clear();
}
if (_currday >= item.DODATE)
{
data.Add(item);
}
}
//取用往日数据 此时需使用那天最后的结果
//如有清库 取清库
//如无 取变动后值最小的
if (data != null && data.Count > 0)
{
if (data.Any(x => x.CHANGETYPE == WMSCHANGTYPE.))
{
var res = data.First(x => x.CHANGETYPE == WMSCHANGTYPE.);
data.Clear();
data.Add(res);
}
else
{
//如没有 那就是只有出库或货转出库
//取其中变动前最大的
var minValue = data.Min(m => m.STORAGEUNITCOUNT3);
var res = data.First(x => x.STORAGEUNITCOUNT3 == minValue);
data.Clear();
data.Add(res);
}
}
}
if (data.Count == 0)
{
//说明该业务最早的计费日期早于第一条物理库存变动,取最早的物理库存变动
//通常这是一条入库或货转入库 但不需要判断 第一条肯定是对的
var _dodate_0 = wmsChangelist.Min(x => x.DODATE);
if (_currday < _dodate_0)
{
var _templist = wmsChangelist.Where(x => x.DODATE == x.DODATE).OrderBy(o => o.CreateDate).ToList();
data.Add(_templist[0]);
}
}
return DataResult<List<OP_WMS_CHANGE>>.Success(data);
}
/// 根据两个日期差 求得 较早日期与较晚日期之差+1 = 时间长度
/// 然后根据这个时间长度 查找费率明细 按顺序找到一个适合的费率等级的费率
public DataResult<decimal> GetWmsFeeRate(List<OP_WMS_FEERATE_STORE_DETAIL> feeList, DateTime _currday,
DateTime startDay)
{
decimal price = 0M;
if (feeList == null || feeList.Count == 0)
{
price = 0M;
return DataResult<decimal>.Success(price);
}
TimeSpan ts = startDay.Subtract(_currday);
if (ts.TotalDays < 0) ts = _currday.Subtract(startDay);
var sumDays = decimal.Parse(Math.Floor(ts.TotalDays + 1).ToString());
var fees = feeList.Where(x => x.FEEGRADE != null).ToList();
fees.Sort((x, y) => x.FEEGRADE.Value.CompareTo(y.FEEGRADE.Value));
var firstFee = fees[0];
var lastFee = fees[fees.Count() - 1];
if (lastFee.ADDPRICE == null)
{
lastFee.ADDPRICE = 0;
}
if (sumDays == 0)
{
price = fees[0].FEEPRICE.ToDecimal();
return DataResult<decimal>.Success(price);
}
else
{
var days = 0;
foreach (var item in fees)
{
if (item.FEESCALE == null) item.FEESCALE = 1;
days = (int)(days + item.FEESCALE);
if (sumDays > days)
{
continue;
}
else
{
price = item.FEEPRICE.ToDecimal();
return DataResult<decimal>.Success(price);
}
}
//循环结束仍未返回 说明日期已经超过最后一条仓储费率
//此时 按最后一条费率的费率区间和增值价计算费率
var result = lastFee.FEEPRICE;
if (lastFee.FEESCALE == null || lastFee.FEESCALE == 0) lastFee.FEESCALE = 1;
if (lastFee.ADDPRICE == null || lastFee.ADDPRICE == 0) lastFee.ADDPRICE = 0;
if (lastFee.ENDPRICE == null || lastFee.ENDPRICE == 0)
lastFee.ENDPRICE = lastFee.FEEPRICE + lastFee.ADDPRICE;
// if (lastFee.ENDPRICE ==0 && lastFee.FEESCALE ==0)
// {
// price = result.ToDecimal();
// return DataResult<decimal>.Success(price);
// }
while (sumDays > days)
{
result = (decimal)(result + lastFee.ADDPRICE);
days = (int)(days + lastFee.FEESCALE);
if (lastFee.ENDPRICE != null && lastFee.ENDPRICE >= lastFee.FEEPRICE)
{
if (result > lastFee.ENDPRICE)
{
result = (decimal)lastFee.ENDPRICE;
}
}
}
price = result.ToDecimal();
return DataResult<decimal>.Success(price);
}
}
}