|
|
@ -10,6 +10,7 @@ using EFCore.BulkExtensions; |
|
|
|
using Microsoft.AspNetCore.Mvc; |
|
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax; |
|
|
|
using Microsoft.EntityFrameworkCore; |
|
|
|
using Minio.DataModel; |
|
|
|
using SettleAccount.Bases; |
|
|
|
using SettleAccount.Domain.BQ; |
|
|
|
using ShardingCore.Sharding.MergeContexts; |
|
|
@ -148,7 +149,7 @@ namespace Win.Sfs.SettleAccount.Entities.BQ.Syncs |
|
|
|
PartCode = p.PartCode |
|
|
|
|
|
|
|
}).ToList();//不能结算
|
|
|
|
var invs = FirstInvoice(entitys, new List<PUB_ADJ_DETAIL>(), dtos, notlist, main.Version, main.InvGroupNum, string.Empty, main.BusinessType); |
|
|
|
var invs = FirstInvoiceExtend(entitys, new List<PUB_ADJ_DETAIL>(), dtos, notlist, main.Version, main.InvGroupNum, string.Empty, main.BusinessType); |
|
|
|
//var invs = SecInvoice(entitys, new List<PUB_ADJ_DETAIL>(), dtos, main.Version, main.InvGroupNum, string.Empty, main.BusinessType, query.ToList());
|
|
|
|
if (invs.Count > 0) |
|
|
|
{ |
|
|
@ -563,6 +564,7 @@ namespace Win.Sfs.SettleAccount.Entities.BQ.Syncs |
|
|
|
List<string> List = new List<string>(); |
|
|
|
decimal sum = itm.Value;//初始分组合计金额
|
|
|
|
//List<string> luList = dtos.Where(p => p.GroupNum == itm.Key).Select(p => p.LU).Distinct().ToList(); //初始LU种类
|
|
|
|
|
|
|
|
if (copyDic.ContainsKey(itm.Key) == true)//是否存在分组
|
|
|
|
{ |
|
|
|
if (first.BusinessType == EnumBusinessType.JisBBAC || first.BusinessType == EnumBusinessType.ZhiGongJianHBPO) |
|
|
@ -864,8 +866,415 @@ namespace Win.Sfs.SettleAccount.Entities.BQ.Syncs |
|
|
|
return _invls; |
|
|
|
} |
|
|
|
|
|
|
|
public List<string> FirstInvoiceExtend<TDetail>(List<TDetail> p_list, List<PUB_ADJ_DETAIL> p_adjlist, List<TEMP_CAN_SA_DETAIL> dtos, List<TEMP_NOT_SA_DETAIL> p_notlist, int p_version, string p_InvGroupNum, string p_parentInvBillNum, EnumBusinessType businessType) |
|
|
|
where TDetail : SA_CAN_BASE |
|
|
|
{ |
|
|
|
List<string> _invls = new List<string>(); |
|
|
|
var _query = dtos.GroupBy(p => new { p.GroupNum }).Select(p => new { GroupNum = p.Key.GroupNum, Amt = p.Sum(itm => itm.Amt) }); |
|
|
|
Dictionary<string, decimal> dic = new Dictionary<string, decimal>();//原本
|
|
|
|
Dictionary<string, decimal> copyDic = new Dictionary<string, decimal>();//变换数组副本
|
|
|
|
var group= p_list.GroupBy(p => new { p.GroupNum, p.LU }).Select(p => new { GroupNum = p.Key.GroupNum, LU = p.Key.LU, Count = p.Count() }); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var itm in _query.ToList()) |
|
|
|
{ |
|
|
|
dic.Add(itm.GroupNum, itm.Amt); |
|
|
|
copyDic.Add(itm.GroupNum, itm.Amt); |
|
|
|
} |
|
|
|
|
|
|
|
Dictionary<string, List<string>> invoiceMap = new Dictionary<string, List<string>>(); |
|
|
|
var first = p_list.FirstOrDefault(); |
|
|
|
foreach (var itm in dic) |
|
|
|
{ |
|
|
|
string invoiceBillNum = OrderNumberGenerator.GenerateOrderNumber("INV"); |
|
|
|
List<string> invoiceGroupNumList = new List<string>();//每个发票对应的结算分组号
|
|
|
|
List<string> List = new List<string>(); |
|
|
|
decimal sum = itm.Value;//初始分组合计金额
|
|
|
|
|
|
|
|
List<string> luList = group.Where(p => p.GroupNum == itm.Key).Select(p => p.LU).ToList(); //初始LU种类
|
|
|
|
|
|
|
|
if (copyDic.ContainsKey(itm.Key) == true)//是否存在分组
|
|
|
|
{ |
|
|
|
//if (first.BusinessType == EnumBusinessType.JisBBAC || first.BusinessType == EnumBusinessType.ZhiGongJianHBPO)
|
|
|
|
//{
|
|
|
|
foreach (var _itm1 in copyDic) |
|
|
|
{ |
|
|
|
if (itm.Key == _itm1.Key)//相同结算分组项不计算,已初始化
|
|
|
|
{ |
|
|
|
invoiceGroupNumList.Add(itm.Key); |
|
|
|
continue; |
|
|
|
} |
|
|
|
var grouplist = group.Where(p => p.GroupNum == _itm1.Key).Select(p => p.LU).ToList();//每项LU种类
|
|
|
|
luList.AddRange(grouplist); |
|
|
|
luList = luList.Distinct().ToList(); |
|
|
|
if (luList.Count > 15)//累加零件不超过20种
|
|
|
|
{ |
|
|
|
break; |
|
|
|
} |
|
|
|
sum += _itm1.Value; |
|
|
|
if (sum > 10000000) |
|
|
|
{ |
|
|
|
break; |
|
|
|
} |
|
|
|
invoiceGroupNumList.Add(_itm1.Key);//所有条件都满足添加发票和结算分组对应关系
|
|
|
|
} |
|
|
|
invoiceMap.Add(invoiceBillNum, invoiceGroupNumList);//记录发票对应关系
|
|
|
|
foreach (var rem in invoiceGroupNumList)//移除
|
|
|
|
{ |
|
|
|
copyDic.Remove(rem); |
|
|
|
} |
|
|
|
//}
|
|
|
|
//else
|
|
|
|
//{
|
|
|
|
// int count = 1;
|
|
|
|
// foreach (var _itm1 in copyDic)
|
|
|
|
// {
|
|
|
|
// if (itm.Key == _itm1.Key)//相同结算分组项不计算,已初始化
|
|
|
|
// {
|
|
|
|
// invoiceGroupNumList.Add(itm.Key);
|
|
|
|
// continue;
|
|
|
|
// }
|
|
|
|
// if (count > 14)
|
|
|
|
// {
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// //var grouplist = dtos.Where(p => p.GroupNum == _itm1.Key).Select(p => p.LU).Distinct().ToList();//每项LU种类
|
|
|
|
// //luList.AddRange(grouplist);
|
|
|
|
// //luList = luList.Distinct().ToList();
|
|
|
|
// //if (luList.Count > 20)//累加零件不超过20种
|
|
|
|
// //{
|
|
|
|
// // continue;
|
|
|
|
// //}
|
|
|
|
// sum += _itm1.Value;
|
|
|
|
// if (sum > 10000000)
|
|
|
|
// {
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// invoiceGroupNumList.Add(_itm1.Key);//所有条件都满足添加发票和结算分组对应关系
|
|
|
|
// //count++;
|
|
|
|
// }
|
|
|
|
// invoiceMap.Add(invoiceBillNum, invoiceGroupNumList);//记录发票对应关系
|
|
|
|
// foreach (var rem in invoiceGroupNumList)//移除
|
|
|
|
// {
|
|
|
|
// copyDic.Remove(rem);
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
} |
|
|
|
} |
|
|
|
if (invoiceMap.Keys.Count > 0) |
|
|
|
{ |
|
|
|
var groupList = new List<INVOICE_MAP_GROUP>(); |
|
|
|
var notDetialList = new List<INVOICE_NOT_SETTLE>(); |
|
|
|
var detailList = new List<INVOICE_WAIT_DETAIL>(); |
|
|
|
var invlist = new List<INVOICE_GRP>(); |
|
|
|
var salist = new List<TDetail>(); |
|
|
|
var adjlist = new List<PUB_ADJ_DETAIL>(); |
|
|
|
List<string> lsby = new List<string>(); |
|
|
|
var grouplist = p_list.Select(p => p.GroupNum).Distinct().ToList();//可结分组
|
|
|
|
lsby.AddRange(grouplist); |
|
|
|
var nolist = p_notlist.Where(p => !grouplist.Contains(p.GroupNum)).Select(p => p.GroupNum).ToList();//不可结分组
|
|
|
|
int count = invoiceMap.Keys.Count;//计算第几张发票计数器
|
|
|
|
int i = 1; |
|
|
|
foreach (var itm in invoiceMap)//分组影响和
|
|
|
|
{ |
|
|
|
var key = itm.Key;//发票票号
|
|
|
|
var ls = itm.Value;//结算分组号列表
|
|
|
|
//反向查找结算数据
|
|
|
|
var invdetails = p_list.Where(p => ls.Contains(p.GroupNum)).ToList(); |
|
|
|
foreach (var detail in invdetails) |
|
|
|
{ |
|
|
|
detail.InvbillNum = key; |
|
|
|
salist.Add(detail); |
|
|
|
} |
|
|
|
if (!string.IsNullOrEmpty(p_parentInvBillNum)) |
|
|
|
{ |
|
|
|
//反向查找调整数据
|
|
|
|
var adjdetails = p_adjlist.Where(p => ls.Contains(p.GroupNum)).ToList(); |
|
|
|
foreach (var detail in adjdetails) |
|
|
|
{ |
|
|
|
detail.InvBillNum = key; |
|
|
|
adjlist.Add(detail); |
|
|
|
} |
|
|
|
} |
|
|
|
var detailDtos = dtos.Where(p => ls.Contains(p.GroupNum)).GroupBy(p => new { p.InvGroupNum, p.PartCode, p.Price, p.BeginDate, p.EndDate, p.ContractDocID, p.LU })//明细
|
|
|
|
.Select(itm => new |
|
|
|
{ |
|
|
|
PartCode = itm.Key.PartCode, |
|
|
|
InvGroupNum = itm.Key.InvGroupNum, |
|
|
|
LU = itm.Key.LU, |
|
|
|
ContactDocID = itm.Key.ContractDocID, |
|
|
|
Price = itm.Key.Price, |
|
|
|
Amt = Math.Round(itm.Sum(k => k.Qty) * itm.Key.Price, 2),//税前
|
|
|
|
Tax = Math.Round(Math.Round(itm.Sum(k => k.Qty) * itm.Key.Price, 2) * 0.13m, 2),//税
|
|
|
|
TaxAmt = Math.Round(Math.Round(itm.Sum(k => k.Qty) * itm.Key.Price, 2) * 0.13m, 2) + Math.Round(itm.Sum(k => k.Qty) * itm.Key.Price, 2),//税后进
|
|
|
|
Qty = itm.Sum(k => k.Qty), |
|
|
|
BeginDate = itm.Key.BeginDate, |
|
|
|
EndDate = itm.Key.EndDate |
|
|
|
}).ToList(); |
|
|
|
|
|
|
|
decimal amt = detailDtos.Sum(k => k.Amt);//金额
|
|
|
|
decimal txtAmt = detailDtos.Sum(k => k.TaxAmt);//税后金额
|
|
|
|
decimal realAmt = detailDtos.Sum(k => k.Tax);//税额
|
|
|
|
|
|
|
|
var mapList = new List<INVOICE_MAP_GROUP>(); |
|
|
|
foreach (var groupnum in ls) |
|
|
|
{ |
|
|
|
mapList.Add(new INVOICE_MAP_GROUP( |
|
|
|
guid: GuidGenerator.Create(), |
|
|
|
version: p_version, |
|
|
|
invbillNum: key, |
|
|
|
invGroupNum: p_InvGroupNum, |
|
|
|
settleGroupNum: groupnum, |
|
|
|
amt: 0, |
|
|
|
extend1: string.Empty, |
|
|
|
extend2: string.Empty |
|
|
|
) |
|
|
|
); |
|
|
|
} |
|
|
|
if (mapList.Count > 0) |
|
|
|
{ |
|
|
|
groupList.AddRange(mapList); |
|
|
|
} |
|
|
|
List<INVOICE_WAIT_DETAIL> _entityDetailList = new List<INVOICE_WAIT_DETAIL>(); |
|
|
|
foreach (var detail in detailDtos) |
|
|
|
{ |
|
|
|
_entityDetailList.Add( |
|
|
|
new INVOICE_WAIT_DETAIL( |
|
|
|
guid: GuidGenerator.Create(), |
|
|
|
version: p_version, |
|
|
|
invbillNum: key, |
|
|
|
invGroupNum: p_InvGroupNum, |
|
|
|
lU: detail.LU, |
|
|
|
qty: detail.Qty, |
|
|
|
bussiessType: businessType, |
|
|
|
amt: detail.Amt, |
|
|
|
pRICE: detail.Price, |
|
|
|
extend1: detail.ContactDocID, |
|
|
|
extend2: string.Empty, |
|
|
|
beginDate: detail.BeginDate, |
|
|
|
endDate: detail.EndDate, |
|
|
|
partcode: detail.PartCode |
|
|
|
)); |
|
|
|
} |
|
|
|
if (_entityDetailList.Count > 0) |
|
|
|
{ |
|
|
|
detailList.AddRange(_entityDetailList); |
|
|
|
} |
|
|
|
var innotls = new List<INVOICE_NOT_SETTLE>(); |
|
|
|
var sq = dtos.Where(p => itm.Value.Contains(p.GroupNum)).GroupBy(p => new { p.LU, p.GroupNum }) |
|
|
|
.Select(p => new { version = p_version, LU = p.Key.LU, Qty = p.Sum(itm => itm.Qty), InvBillNum = itm.Key, GroupNum = p.Key.GroupNum }); |
|
|
|
|
|
|
|
foreach (var sitm in sq) |
|
|
|
{ |
|
|
|
innotls.Add(new INVOICE_NOT_SETTLE( |
|
|
|
guid: GuidGenerator.Create(), |
|
|
|
version: p_version, |
|
|
|
invGroupNum: p_InvGroupNum, |
|
|
|
settleGroupNum: sitm.GroupNum, |
|
|
|
lU: sitm.LU, |
|
|
|
lU1: sitm.LU, |
|
|
|
extend1: "可结算", |
|
|
|
extend2: string.Empty, |
|
|
|
qty: sitm.Qty, |
|
|
|
p_invbillnum: itm.Key |
|
|
|
)); |
|
|
|
} |
|
|
|
if (innotls.Count > 0) |
|
|
|
{ |
|
|
|
notDetialList.AddRange(innotls); |
|
|
|
} |
|
|
|
if (p_notlist != null && p_notlist.Count > 0) |
|
|
|
{ |
|
|
|
var innotls1 = new List<INVOICE_NOT_SETTLE>(); |
|
|
|
var groupnum = itm.Value; |
|
|
|
if (count == i)//最后一张发票追加
|
|
|
|
{ |
|
|
|
groupnum.AddRange(nolist);//追加完全不可结
|
|
|
|
} |
|
|
|
var notls = p_notlist.Where(p => groupnum.Contains(p.GroupNum)).GroupBy(p => new { p.GroupNum, p.LU }) |
|
|
|
.Select(p => new { GroupNum = p.Key.GroupNum, LU = p.Key.LU, Qty = p.Sum(itm => itm.Qty), InvBillNum = itm.Key }); |
|
|
|
foreach (var nitm in notls) |
|
|
|
{ |
|
|
|
innotls1.Add(new INVOICE_NOT_SETTLE( |
|
|
|
guid: GuidGenerator.Create(), |
|
|
|
version: p_version, |
|
|
|
invGroupNum: p_InvGroupNum, |
|
|
|
settleGroupNum: nitm.GroupNum, |
|
|
|
lU: nitm.LU, |
|
|
|
lU1: nitm.LU, |
|
|
|
extend1: "不可结算", |
|
|
|
extend2: string.Empty, |
|
|
|
qty: nitm.Qty, |
|
|
|
p_invbillnum: itm.Key |
|
|
|
)); |
|
|
|
} |
|
|
|
if (innotls.Count > 0) |
|
|
|
{ |
|
|
|
notDetialList.AddRange(innotls1); |
|
|
|
} |
|
|
|
} |
|
|
|
var invbill = new INVOICE_GRP |
|
|
|
(guid: GuidGenerator.Create(), |
|
|
|
realnvBillNum: string.Empty, |
|
|
|
invbillNum: key, |
|
|
|
amt: amt, |
|
|
|
taxAmt: txtAmt, |
|
|
|
fileName: string.Empty, |
|
|
|
businessType: businessType, |
|
|
|
invGroupNum: p_InvGroupNum, |
|
|
|
state: SettleBillState.已开票, |
|
|
|
invoiceBillState: InvoiceBillState.正常, |
|
|
|
tax: 0.13m, |
|
|
|
parent: !string.IsNullOrEmpty(p_parentInvBillNum) ? p_parentInvBillNum : string.Empty, |
|
|
|
preTaxDiff: 0, |
|
|
|
taxDiff: 0, |
|
|
|
clientCode: string.Empty, |
|
|
|
realAmt: realAmt |
|
|
|
|
|
|
|
); |
|
|
|
string site = dtos.Where(p => !string.IsNullOrEmpty(p.Site)).FirstOrDefault().Site; |
|
|
|
string clientCode = string.Empty; |
|
|
|
switch (site) |
|
|
|
{ |
|
|
|
case "1040": |
|
|
|
clientCode = "C001"; |
|
|
|
break; |
|
|
|
case "1046": |
|
|
|
clientCode = "C171"; |
|
|
|
break; |
|
|
|
default: |
|
|
|
clientCode = "C004"; |
|
|
|
break; |
|
|
|
} |
|
|
|
invbill.ClientCode = clientCode; |
|
|
|
invbill.Site = dtos.FirstOrDefault().Site; |
|
|
|
invbill.CreationTime = DateTime.MinValue; |
|
|
|
invbill.LastModificationTime = DateTime.Now; |
|
|
|
invlist.Add(invbill); |
|
|
|
i++; |
|
|
|
} |
|
|
|
//using (var transaction = _repository.DbContext.Database.BeginTransaction())
|
|
|
|
//{
|
|
|
|
// try
|
|
|
|
// {
|
|
|
|
// 执行批量数据操作
|
|
|
|
if (salist.Count > 0) |
|
|
|
{ |
|
|
|
_dbcontext.BulkUpdate(salist); |
|
|
|
} |
|
|
|
_dbcontext.BulkInsert(invlist); |
|
|
|
_dbcontext.BulkInsert(groupList); |
|
|
|
_dbcontext.BulkInsert(detailList); |
|
|
|
if (adjlist.Count > 0) |
|
|
|
{ |
|
|
|
_dbcontext.BulkInsert(adjlist); |
|
|
|
} |
|
|
|
if (notDetialList.Count > 0) |
|
|
|
{ |
|
|
|
_dbcontext.BulkInsert(notDetialList); |
|
|
|
} |
|
|
|
// 提交事务
|
|
|
|
// transaction.Commit();
|
|
|
|
// }
|
|
|
|
// catch (Exception)
|
|
|
|
// {
|
|
|
|
// // 回滚事务
|
|
|
|
// transaction.Rollback();
|
|
|
|
// throw;
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
_invls = invlist.Select(p => p.InvbillNum).ToList(); |
|
|
|
|
|
|
|
} |
|
|
|
return _invls; |
|
|
|
} |
|
|
|
public List<string> FirstInvoiceExtend1<TDetail>(List<TDetail> p_list, List<PUB_ADJ_DETAIL> p_adjlist, List<TEMP_CAN_SA_DETAIL> dtos, List<TEMP_NOT_SA_DETAIL> p_notlist, int p_version, string p_InvGroupNum, string p_parentInvBillNum, EnumBusinessType businessType) |
|
|
|
where TDetail : SA_CAN_BASE, new() |
|
|
|
{ |
|
|
|
var gener = new InvoiceGenerator(); |
|
|
|
gener.GenerateInvoices(p_list); |
|
|
|
var invList = gener.Invoices; |
|
|
|
if (invList.Count > 0) |
|
|
|
{ |
|
|
|
foreach (var inv in invList) |
|
|
|
{ |
|
|
|
var partlist = inv.Parts; |
|
|
|
if (partlist.Count > 0) |
|
|
|
{ |
|
|
|
partlist.GroupBy(p => new { p.InvGroupNum, p.PartCode, p.Price, p.BeginDate, p.EndDate, p.ContractDocID, p.LU }) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return new List<string>(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
public class InvoiceExtend |
|
|
|
{ |
|
|
|
public string InvBillNum { set; get; } |
|
|
|
public InvoiceExtend() { } |
|
|
|
private List<SA_CAN_BASE> parts = new List<SA_CAN_BASE>(); |
|
|
|
public IReadOnlyList<SA_CAN_BASE> Parts => parts.AsReadOnly(); |
|
|
|
public decimal TotalAmount => parts.Sum(p => p.Price); |
|
|
|
public int PartCount => parts.Count; |
|
|
|
public bool CanAddPart(SA_CAN_BASE part) |
|
|
|
{ |
|
|
|
return TotalAmount + part.Price <= 10000000 && PartCount < 15; |
|
|
|
} |
|
|
|
|
|
|
|
public void AddPart(SA_CAN_BASE part) |
|
|
|
{ |
|
|
|
if (!CanAddPart(part)) |
|
|
|
{ |
|
|
|
//throw new InvalidOperationException("Cannot add part to invoice. Check constraints.");
|
|
|
|
} |
|
|
|
part.InvbillNum = InvBillNum; |
|
|
|
parts.Add(part); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public class InvoiceGenerator |
|
|
|
{ |
|
|
|
private List<InvoiceExtend> invoices = new List<InvoiceExtend>(); |
|
|
|
|
|
|
|
public IReadOnlyList<InvoiceExtend> Invoices => invoices.AsReadOnly(); |
|
|
|
|
|
|
|
public void GenerateInvoices<TDetail>(List<TDetail> parts) where TDetail : SA_CAN_BASE, new() |
|
|
|
{ |
|
|
|
InvoiceExtend currentInvoice = new InvoiceExtend(); |
|
|
|
invoices.Add(currentInvoice); |
|
|
|
currentInvoice.InvBillNum = OrderNumberGenerator.GenerateOrderNumber("INV"); |
|
|
|
foreach (var part in parts) |
|
|
|
{ |
|
|
|
if (!currentInvoice.CanAddPart(part)) |
|
|
|
{ |
|
|
|
currentInvoice = new InvoiceExtend(); |
|
|
|
currentInvoice.InvBillNum = OrderNumberGenerator.GenerateOrderNumber("INV"); |
|
|
|
invoices.Add(currentInvoice); |
|
|
|
} |
|
|
|
currentInvoice.AddPart(part); |
|
|
|
} |
|
|
|
} |
|
|
|
public InvoiceGenerator() |
|
|
|
{ |
|
|
|
|
|
|
|
} |
|
|
|
public InvoiceGenerator(List<InvoiceExtend> invoices) |
|
|
|
{ |
|
|
|
this.invoices = invoices; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|