2025-07-26 17:31:00 +08:00
|
|
|
|
using GZ_LTHPilot_ORDER.Service;
|
|
|
|
|
|
using Kingdee.BOS.Core.DynamicForm;
|
|
|
|
|
|
using Kingdee.BOS.Core.DynamicForm.PlugIn;
|
|
|
|
|
|
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
|
|
|
|
|
|
using Kingdee.BOS.Orm.DataEntity;
|
|
|
|
|
|
using Kingdee.BOS.Util;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.ComponentModel;
|
2025-10-27 23:16:14 +08:00
|
|
|
|
using System.Diagnostics.Contracts;
|
2025-07-26 17:31:00 +08:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
|
|
namespace GZ_LTHPilot_ORDER.T_IV_SALESIC.ServicePlugIn
|
|
|
|
|
|
{
|
|
|
|
|
|
[Description("服务插件:发票提交,校验销售订单累计开票金额加开票金额不能大于销售订单价税合计本币"), HotUpdate]
|
|
|
|
|
|
public class Submit : AbstractOperationServicePlugIn
|
|
|
|
|
|
{
|
|
|
|
|
|
public override void OnPreparePropertys(PreparePropertysEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
base.OnPreparePropertys(e);
|
2025-08-07 15:47:30 +08:00
|
|
|
|
e.FieldKeys.Add("F_contractno");
|
|
|
|
|
|
e.FieldKeys.Add("FALLAMOUNTFOR");
|
2025-07-26 17:57:34 +08:00
|
|
|
|
e.FieldKeys.Add("FSALEORGID");
|
2025-07-26 17:31:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-27 23:16:14 +08:00
|
|
|
|
private class SALESIC
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 组织Id
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string OrgId { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 纸质合同号
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string ContractNo { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 价税合计原币
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public decimal AllAmountFor { get; set; }
|
2025-10-27 23:51:36 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 单据Id
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string BillId { get; set; }
|
2025-10-27 23:16:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-26 17:31:00 +08:00
|
|
|
|
|
|
|
|
|
|
public override void BeforeExecuteOperationTransaction(BeforeExecuteOperationTransaction e)
|
|
|
|
|
|
{
|
|
|
|
|
|
base.BeforeExecuteOperationTransaction(e);
|
2025-10-27 23:16:14 +08:00
|
|
|
|
var entryListUnion = new List<SALESIC>();
|
2025-07-26 17:31:00 +08:00
|
|
|
|
foreach (var bill in e.SelectedRows)
|
|
|
|
|
|
{
|
2025-10-27 23:51:36 +08:00
|
|
|
|
var billId = bill["Id"].ToString();
|
2025-07-26 17:31:00 +08:00
|
|
|
|
var org = bill["SALEORGID"] as DynamicObject;
|
2025-08-28 10:35:38 +08:00
|
|
|
|
var orgId = org["Id"].ToString(); // 销售组织
|
2025-08-07 15:47:30 +08:00
|
|
|
|
var entryList = bill["SALESICENTRY"] as DynamicObjectCollection;
|
2025-10-27 23:16:14 +08:00
|
|
|
|
// 添加所有分录到集合
|
|
|
|
|
|
foreach (var item in entryList)
|
2025-07-26 17:31:00 +08:00
|
|
|
|
{
|
2025-10-27 23:16:14 +08:00
|
|
|
|
entryListUnion.Add(new SALESIC()
|
2025-08-28 10:35:38 +08:00
|
|
|
|
{
|
2025-10-27 23:51:36 +08:00
|
|
|
|
BillId = billId,
|
2025-10-27 23:16:14 +08:00
|
|
|
|
OrgId = orgId,
|
|
|
|
|
|
ContractNo = item["F_contractno"].ToString(),
|
|
|
|
|
|
AllAmountFor = Convert.ToDecimal(item["ALLAMOUNTFOR"])
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
var entryGrouped = entryListUnion.GroupBy(n => new
|
|
|
|
|
|
{
|
|
|
|
|
|
n.ContractNo,
|
|
|
|
|
|
n.OrgId
|
|
|
|
|
|
});
|
|
|
|
|
|
foreach (var item in entryGrouped)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 纸质合同号
|
|
|
|
|
|
var contractNo = item.Key.ContractNo;
|
|
|
|
|
|
var orgId = item.Key.OrgId;
|
|
|
|
|
|
// 校验原单是否超额
|
|
|
|
|
|
var srcVerifResult = SrcExcessVerification(orgId, contractNo);
|
|
|
|
|
|
if (srcVerifResult != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
//有错误信息
|
|
|
|
|
|
e.Cancel = true;
|
|
|
|
|
|
IOperationResult operationResult = new OperationResult();
|
|
|
|
|
|
operationResult.OperateResult.Add(srcVerifResult);
|
|
|
|
|
|
this.OperationResult.MergeResult(operationResult);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 发票单体价税合计原币
|
|
|
|
|
|
var SumALLAMOUNTFOR = item.Sum(n => n.AllAmountFor);
|
2025-10-27 23:51:36 +08:00
|
|
|
|
var billIds = item.Select(n => n.BillId).ToList();
|
2025-10-27 23:16:14 +08:00
|
|
|
|
// TODO 校验是否超额
|
2025-10-27 23:51:36 +08:00
|
|
|
|
var verifResult = ExcessVerification(orgId, contractNo, SumALLAMOUNTFOR, billIds);
|
2025-10-27 23:16:14 +08:00
|
|
|
|
if (verifResult != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
//有错误信息
|
|
|
|
|
|
e.Cancel = true;
|
|
|
|
|
|
IOperationResult operationResult = new OperationResult();
|
|
|
|
|
|
operationResult.OperateResult.Add(verifResult);
|
|
|
|
|
|
this.OperationResult.MergeResult(operationResult);
|
2025-07-26 17:31:00 +08:00
|
|
|
|
}
|
2025-08-28 10:35:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-28 11:03:35 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 校验源头单据是否超额
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="orgId"></param>
|
|
|
|
|
|
/// <param name="contractNo"></param>
|
|
|
|
|
|
/// <param name="amount"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private OperateResult SrcExcessVerification(string orgId, string contractNo)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 销售订单服务
|
|
|
|
|
|
var saleOrderService = new SaleOrderService(this.Context);
|
|
|
|
|
|
// TODO 根据组织和纸质合同号查找销售订单
|
|
|
|
|
|
var saleOrderList = saleOrderService.GetSaleOrderByOrgIdAndContractNo(orgId, contractNo);
|
|
|
|
|
|
if (saleOrderList.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var saleOrder = saleOrderList[0];
|
|
|
|
|
|
// 源纸质合同号
|
|
|
|
|
|
var srcContractNo = saleOrder["F_SOURPAPERCONTRACT"]?.ToString();
|
2025-08-28 11:06:55 +08:00
|
|
|
|
// 如果原纸质合同号为空,则认为是源头单, 加上源单合同号 = 纸质合同号 是防止纸质合同号变更出错导致死递归
|
|
|
|
|
|
if (srcContractNo.IsNullOrEmptyOrWhiteSpace() || srcContractNo.Trim() == contractNo.Trim())
|
2025-08-28 11:03:35 +08:00
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 校验源单是否超额
|
2025-10-27 23:51:36 +08:00
|
|
|
|
var srcVerifResult = ExcessVerification(orgId, srcContractNo, 0, null);
|
2025-08-28 11:03:35 +08:00
|
|
|
|
if (srcVerifResult != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return srcVerifResult;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 递归校验
|
|
|
|
|
|
return SrcExcessVerification(orgId, srcContractNo);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-07 15:47:30 +08:00
|
|
|
|
|
2025-08-28 10:35:38 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 超额校验,如果校验不通过会返回OperateResult实例,通过返回null
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="orgId">销售组织</param>
|
|
|
|
|
|
/// <param name="contractNo">合同号</param>
|
|
|
|
|
|
/// <param name="amount">开票金额</param>
|
2025-10-27 23:51:36 +08:00
|
|
|
|
/// <param name="billIds">本次操作单据ID</param>
|
2025-08-28 10:35:38 +08:00
|
|
|
|
/// <returns></returns>
|
2025-10-27 23:51:36 +08:00
|
|
|
|
private OperateResult ExcessVerification(string orgId, string contractNo, decimal amount, List<string> billIds)
|
2025-08-28 10:35:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 销售订单服务
|
|
|
|
|
|
var saleOrderService = new SaleOrderService(this.Context);
|
|
|
|
|
|
// TODO 根据组织和纸质合同号查找销售订单
|
|
|
|
|
|
var saleOrderList = saleOrderService.GetSaleOrderByOrgIdAndContractNo(orgId, contractNo);
|
|
|
|
|
|
if (saleOrderList.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
var saleOrderNoList = saleOrderList.Select(n => n["FBILLNO"].ToString()).ToList();
|
|
|
|
|
|
var saleOrderNoString = string.Join(",\n\r", saleOrderNoList);
|
|
|
|
|
|
var saleOrder = saleOrderList[0];
|
2025-11-21 20:06:25 +08:00
|
|
|
|
// 已提交发票金额(原币)
|
2025-10-27 23:51:36 +08:00
|
|
|
|
var submitedAmount = saleOrderService.GetSubmitedAmount(orgId, contractNo, billIds);
|
2025-11-21 20:06:25 +08:00
|
|
|
|
// 销售订单价税合计(原币)
|
2025-08-28 10:35:38 +08:00
|
|
|
|
var saleOrderAmount = saleOrderService.GetSaleOrderAmount(orgId, contractNo);
|
2025-11-21 20:06:25 +08:00
|
|
|
|
// 销售订单累计开票金额(原币)
|
2025-08-28 10:35:38 +08:00
|
|
|
|
var saleOrderINVOICEAMOUNT = Convert.ToDecimal(saleOrder["F_INVOICEAMOUNT"]);
|
2025-11-21 20:06:25 +08:00
|
|
|
|
// 销售订单退货金额(原币)
|
2025-08-28 10:35:38 +08:00
|
|
|
|
var saleOrderReturnAmountK3Cloud = saleOrderService.GetSaleOrderRetrunAmount(orgId, contractNo);
|
|
|
|
|
|
var saleOrderReturnAmountK3 = saleOrderService.GetK3SaleOrderRetrunAmount(orgId, contractNo);
|
2025-11-21 20:06:25 +08:00
|
|
|
|
// 销售订单退货金额(原币)
|
2025-08-28 10:35:38 +08:00
|
|
|
|
var saleOrderReturnAmount = saleOrderReturnAmountK3 + saleOrderReturnAmountK3Cloud;
|
2025-10-27 23:16:14 +08:00
|
|
|
|
// 校验销售订单累计开票金额 + 本次开票金额 + 已提交发票金额 <= 销售订单价税合计
|
2025-10-31 13:47:27 +08:00
|
|
|
|
if ((saleOrderAmount - saleOrderReturnAmount < saleOrderINVOICEAMOUNT + amount + submitedAmount) && amount >= 0)
|
2025-08-28 10:35:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
return new OperateResult()
|
|
|
|
|
|
{
|
|
|
|
|
|
PKValue = "1",
|
|
|
|
|
|
Name = "检查开票金额是否超额",
|
|
|
|
|
|
MessageType = MessageType.FatalError,
|
|
|
|
|
|
Message = string.Format($@" 销售纸质合同号:'{contractNo}',
|
|
|
|
|
|
销售订单:'{saleOrderNoString}' , 开票超额。
|
2025-10-27 23:16:14 +08:00
|
|
|
|
不满足条件:整单可开票金额 >= 累计开票金额 + 本次开票金额 + 已提交发票金额。
|
2025-08-28 10:35:38 +08:00
|
|
|
|
整单可开票金额:{(saleOrderAmount - saleOrderReturnAmountK3Cloud - saleOrderReturnAmountK3).ToString("0.00")},
|
|
|
|
|
|
累计开票金额:{saleOrderINVOICEAMOUNT.ToString("0.00")},
|
2025-10-27 23:16:14 +08:00
|
|
|
|
本次开票金额:{amount.ToString("0.00")},
|
|
|
|
|
|
已提交金额:{submitedAmount.ToString("0.00")}"),
|
2025-08-28 10:35:38 +08:00
|
|
|
|
SuccessStatus = false
|
|
|
|
|
|
};
|
2025-07-26 17:31:00 +08:00
|
|
|
|
}
|
2025-08-28 10:35:38 +08:00
|
|
|
|
return null;
|
2025-07-26 17:31:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|