Commit 5c05422e by 陶然

增加自动认领流水功能

parent ff44da47
using Com.Bocom.OpenApi; using Com.Bocom.OpenApi;
using Kivii; using Kivii;
using Kivii.Finances.Entities; using Kivii.Finances.Entities;
using Kivii.Finances;
using Kivii.Linq; using Kivii.Linq;
using Njzj.Finances.Bocoms.Extensions; using Njzj.Finances.Bocoms.Extensions;
using System; using System;
...@@ -295,4 +296,274 @@ namespace Njzj.Bocoms.Openapis ...@@ -295,4 +296,274 @@ namespace Njzj.Bocoms.Openapis
return true; return true;
} }
} }
public class WriteOffJob2 : IJob
{
public string Name => "智慧记账账单核销";
public string Description => "智慧记账账单自动核销";
public IJobContext TaskContext { get; set; }
public void Dispose()
{
}
public bool Execution()
{
#region 获取通知,且过滤哪些通知已经作废或者匹配不上的
var connE = KiviiContext.GetOpenedDbConnection<WriteOffResultNotify>();
var query = connE.From<WriteOffResultNotify>();
query.Where(o => o.BizKvid != Guid.Empty && o.Status != int.MaxValue);
var writeOffs = connE.Select(query);
if (writeOffs.IsNullOrEmpty())
{
TaskContext.Message = "暂无核销通知需处理!";
return true;
}
var kvids = writeOffs.ConvertAll(o => o.Kvid).Distinct().ToList();
var bizKvids = writeOffs.ConvertAll(o => o.BizKvid).Distinct().ToList();
bizKvids.RemoveAll(o => o == Guid.Empty);
if (bizKvids.IsNullOrEmpty())
{
var updateWriteOffs = connE.From<WriteOffResultNotify>();
updateWriteOffs = updateWriteOffs.Update(o => o.Status);
updateWriteOffs = updateWriteOffs.Where(o => Sql.In(o.Kvid, kvids));
connE.UpdateOnly(new WriteOffResultNotify { Status = int.MaxValue }, updateWriteOffs);
TaskContext.Message = "暂无核销通知需处理!";
return true;
}
var connF = KiviiContext.GetOpenedDbConnection<Settlement>();
var settlements = connF.Select<Settlement>(o => Sql.In(o.Kvid, bizKvids));
if (settlements.IsNullOrEmpty())
{
var updateWriteOffs = connE.From<WriteOffResultNotify>();
updateWriteOffs = updateWriteOffs.Update(o => o.Status);
updateWriteOffs = updateWriteOffs.Where(o => Sql.In(o.Kvid, kvids));
connE.UpdateOnly(new WriteOffResultNotify { Status = int.MaxValue }, updateWriteOffs);
TaskContext.Message = "暂无核销通知需处理!";
return true;
}
var preSettlements = settlements.Where(o => o.AmountPayment == 0).ToList();//需要进行匹配核销的结算
var notMatchBizKvids = new List<Guid>();
foreach (var kvid in bizKvids)
{
if (!preSettlements.Exists(o => o.Kvid == kvid)) notMatchBizKvids.Add(kvid);
}
var err = string.Empty;
writeOffs.RemoveAll(o => Sql.In(o.BizKvid, notMatchBizKvids));
var matchWriteOffs = new List<WriteOffResultNotify>();
var breakWriteOffs = new List<WriteOffResultNotify>();//错误消息队列 要移除的
var payments = new List<Payment>();
List<string> serialNumbers = new List<string>();
foreach (var item in writeOffs)
{
if (item.biz_content.bill_wo_state != "03")
{
TaskContext.Message = $"Error:10001,[{item.BillId}]账单核销状态不是03-全额核销!";
err += TaskContext.Message + Environment.NewLine;
continue;
}
bool matched = false;
foreach (var pay in item.biz_content.pay_detail_list)
{
if (pay.jnl_write_off_amt.IsNullOrEmpty() || pay.jnl_write_off_amt.ToLower() == "null")
{
if (!notMatchBizKvids.Exists(o => o == item.BizKvid)) notMatchBizKvids.Add(item.BizKvid);
matched = false;
break;
}
var split = pay.vch_no.Split('-');//vch_no一般16位,正常流水号是17位,例如EBG00000334545512
if (split.Length < 2)
{
TaskContext.Message = $"Error:10002,[{item.BillId}]vch_no号[{pay.vch_no}]格式不符合Split规则!";
err += TaskContext.Message + Environment.NewLine;
continue;
}
var serialNumber = split[1];
if (split.Length > 2)
{
var number = split[2].Substring(split[2].Length - 1, 1);
serialNumber = $"{serialNumber}{number}";
}
if (serialNumber.IsNullOrEmpty())
{
TaskContext.Message = $"Error:10003,[{item.BillId}]vch_no截取的流水号是空!";
err += TaskContext.Message + Environment.NewLine;
continue;
}
var payment = connF.Single<Payment>(o => o.SerialNumber.StartsWith(serialNumber) && o.OffsetKvid == Guid.Empty && o.Type == PaymentType.Bank);
if (payment == null)
{
TaskContext.Message = $"Error:20001,[{item.BillId}]未找到此流水号[{serialNumber}]的到账信息!";
err += TaskContext.Message + Environment.NewLine;
continue;
}
serialNumbers.Add(payment.SerialNumber);
payments.Add(payment);
matched = true;
}
if (matched)
{
matchWriteOffs.Add(item);
}
}
if (!notMatchBizKvids.IsNullOrEmpty())
{
var updateWriteOffs = connE.From<WriteOffResultNotify>();
updateWriteOffs = updateWriteOffs.Update(o => o.Status);
updateWriteOffs = updateWriteOffs.Where(o => Sql.In(o.BizKvid, notMatchBizKvids));
connE.UpdateOnly(new WriteOffResultNotify { Status = int.MaxValue }, updateWriteOffs);
}
if (matchWriteOffs.IsNullOrEmpty())
{
TaskContext.Message = $"{writeOffs.Count}条待处理通知,尚未匹配到流水信息!";
err += TaskContext.Message + Environment.NewLine;
return true;
}
#endregion
#region 合并数据库连接,并启用事务
if (connE == connF)
{
//两个连接是同一个,缓存生效,不做任何操作
}
else if (connE.ConnectionString == connF.ConnectionString)//连接对象不同,但连接字符串是一样的,因为在本环节中,连接没有被污染,可以关了一个连接
{
connF.Close();
connF = connE;
}
#endregion
foreach (var settlement in preSettlements)
{
var writeOff = matchWriteOffs.FirstOrDefault(o => o.BizKvid == settlement.Kvid);
if (writeOff == null)
{
TaskContext.Message = $"Error:10004,[{settlement.Kvid}]未找到此账单通知信息,WO:{matchWriteOffs.Count},ST:{preSettlements.Count},CST:{preSettlements.FindIndex(o => o.Kvid == settlement.Kvid)}!";
err += TaskContext.Message + Environment.NewLine;
continue;
}
var currentPayments = new List<Payment>();
var payingMethods = new List<PayingMethod>();
foreach (var pay in writeOff.biz_content.pay_detail_list)
{
var splitSerial = pay.vch_no.Split('-');
if (splitSerial.Length < 2)
{
TaskContext.Message = $"Error:10005,[{writeOff.BillId}]vch_no号格式不符合Split规则,WO:{matchWriteOffs.Count},ST:{preSettlements.Count},CST:{preSettlements.FindIndex(o => o.Kvid == settlement.Kvid)}!";
err += TaskContext.Message + Environment.NewLine;
continue;
}
//var serialNumber = splitSerial[1];
var serialNumber = splitSerial[1];
if (splitSerial.Length > 2)
{
var number = splitSerial[2].Substring(splitSerial[2].Length - 1, 1);
serialNumber = $"{serialNumber}{number}";
}
//var number = splitSerial[2].Substring(splitSerial[2].Length - 1, 1);
//serialNumber = $"{serialNumber}{number}";
if (serialNumber.IsNullOrEmpty())
{
TaskContext.Message = $"Error:10006,[{writeOff.BillId}]vch_no截取的流水号是空,WO:{matchWriteOffs.Count},ST:{preSettlements.Count},CST:{preSettlements.FindIndex(o => o.Kvid == settlement.Kvid)}";
err += TaskContext.Message + Environment.NewLine;
continue;
}
var payment = payments.FirstOrDefault(o => o.SerialNumber.StartsWith(serialNumber));
if (payment == null)
{
TaskContext.Message = $"Error:20002,[{writeOff.BillId}]未找到此流水号[{serialNumber}]的到账信息,WO:{matchWriteOffs.Count},ST:{preSettlements.Count},CST:{preSettlements.FindIndex(o => o.Kvid == settlement.Kvid)}";
err += TaskContext.Message + Environment.NewLine;
continue;
}
var amountTotal = pay.jnl_write_off_amt.ToDecimal();
if (payment.Amount - payment.AmountUsed < amountTotal)
{
TaskContext.Message = $"Error:20003,流水[{payment.SerialNumber}]可用金额不足,WO:{matchWriteOffs.Count},ST:{preSettlements.Count},CST:{preSettlements.FindIndex(o => o.Kvid == settlement.Kvid)}";
err += TaskContext.Message + Environment.NewLine;
continue;
}
//var splits = connF.Select<Payment>(o => o.RootKvid==payment.Kvid && o.OwnerKvid == settlement.OwnerKvid && o.OffsetKvid == Guid.Empty && o.Type == PaymentType.Split && o.Currency == settlement.Currency);
var splits = connF.Select<Payment>(o => o.Type == PaymentType.Split && o.Currency == settlement.Currency && o.OffsetKvid == Guid.Empty && o.ParentKvid == payment.Kvid);
if (splits.IsNullOrEmpty())
{
var split = payment.BizSplit(payment.Amount, "智慧记账自动认领", settlement.OwnerKvid, settlement.OwnerName, connF, "市场业务收入", settlement.OperatorKvid, settlement.OperatorName);
var tranF1 = connF.OpenTransaction();
try
{
connF.Insert(split);
payment.RecalculateAmountSplit(connF);
tranF1.Commit();
}
catch (Exception ex)
{
tranF1.Rollback();
TaskContext.Message = $"流水:{payment.SerialNumber}认领失败:{ex.Message}!";
err += TaskContext.Message + Environment.NewLine;
continue;
}
splits = new List<Payment>();
splits.Add(split);
}
foreach (var split in splits)
{
if (amountTotal <= 0) continue;
var amountSplit = split.Amount - split.AmountUsed;
if (amountSplit <= 0) continue;
if (amountSplit >= amountTotal)
{
var payingMethod = new PayingMethod();
payingMethod.Amount = amountTotal;
payingMethod.Type = PayType.Payment;
payingMethod.Kvid = split.Kvid;
payingMethod.Remark = $"智慧记账自动核销,核销订单号:{writeOff.BillId}";
payingMethods.Add(payingMethod);
currentPayments.Add(split);
amountTotal -= amountTotal;
}
else
{
var payingMethod = new PayingMethod();
payingMethod.Amount = amountSplit;
payingMethod.Type = PayType.Payment;
payingMethod.Kvid = split.Kvid;
payingMethod.Remark = $"智慧记账自动核销,核销订单号:{writeOff.BillId}";
payingMethods.Add(payingMethod);
currentPayments.Add(split);
amountTotal -= amountSplit;
}
}
}
if (!currentPayments.IsNullOrEmpty())
{
if (Extension.AutoPay(currentPayments, settlement, payingMethods))
{
writeOff.Status = int.MaxValue;
writeOff.AddOnlyProperties(o => o.Status);
connE.UpdateOnly(writeOff);
}
}
}
Console.WriteLine("----------------------------------------------------------------------------------------");
Console.WriteLine(err);
Console.WriteLine("----------------------------------------------------------------------------------------");
if (!serialNumbers.IsNullOrEmpty())
{
var th = KiviiContext.NewThread(() =>
{
serialNumbers.AutoBizMark(50, "智慧记账自动标记");
});
th.Start();
}
return true;
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment