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