采购订单下推付款申请单的保存金额控制(采购订单下游有财务应付单)原创
金蝶云社区-约翰_冯_诺依曼
约翰_冯_诺依曼
6人赞赏了该文章 708次浏览 未经作者许可,禁止转载编辑于2022年05月17日 14:43:53

业务背景:企业的采购订单,已入库,确认应付,未付款给对方,财务认为生成财务应付后需要控制申请付款的金额,但是系统的金额控制在付款单。

二开解决方案:在付款申请单保存按钮增加一个金额的校验。校验逻辑:申请付款最大金额=采购预付-(财务应付+付款申请关联金额-已结算金额)


场景A

采购订单预付100

处理前:

采购订单 → 入库80 → 暂估应付80 → 财务应付80

采购订单 → 付款申请A 100

财务应付80 → 付款申请B 80

 

处理后:

采购订单 → 入库80 → 暂估应付80 → 财务应付80

采购订单 → 付款申请20(Max)

控制逻辑:申请付款最大金额=采购预付-(财务应付+付款申请关联金额-已结算金额)

此时由于财务应付未继续下推付款申请和付款,已结算金额为0

即申请付款金额<=100-(80+0-0)=20

 

 

场景B

采购订单预付100

处理前:

采购订单 → 入库80 → 暂估应付80 → 财务应付80

采购订单 → 付款申请A 10

采购订单 → 付款申请B 90(Max)

 

采购订单预付100

处理后:

采购订单 → 入库80 → 暂估应付80 → 财务应付80

采购订单 → 付款申请A 10

采购订单 → 付款申请B 10(Max)

控制逻辑:申请付款最大金额=采购预付-(财务应付+付款申请关联金额-已结算金额)

此时由于财务应付未继续下推付款申请和付款,已结算金额为0

即申请付款金额<=100-(80+10-0)=10

后续流程1:财务应付80 → 付款申请C 80 → 付款80(与财务应付核销80)

此时付款申请关联金额为80,已结算金额为80申请付款最大金额为10不变

后续流程2:付款申请A 10 → 付款 10(与财务应付核销10)

此时付款申请关联金额为10,已结算金额为10申请付款最大金额为100-(80+10-10)=20

 

 

场景C

采购订单预付100

处理前:

采购订单 → 付款申请A 10

采购订单 → 入库80 → 暂估应付80 → 财务应付80

采购订单 → 付款申请B 90(Max)

 

处理后:

采购订单 → 付款申请A 10

采购订单 → 入库80 → 暂估应付80 → 财务应付80

采购订单 → 付款申请B 10(Max)

控制逻辑与场景B相同


二开参考代码实现:

using Kingdee.BOS.Core.Validation;

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Linq;

using System.Text;

using Kingdee.BOS.Core;

using Kingdee.BOS.Orm.DataEntity;

using Kingdee.BOS.Core.Metadata.ConvertElement;

using Kingdee.K3.FIN.Core;

using Kingdee.BOS.App.Data;

using Kingdee.BOS;


namespace MyPlugin.ServicePlugIn

{

    public class MyOperationPlugin : AbstractOperationServicePlugIn

    {


        /// <summary>

        /// 添加校验器

        /// </summary>

        /// <param name="e"></param>

        public override void OnAddValidators(AddValidatorsEventArgs e)

        {

            var saveValidatorForAPAndApply = new SaveValidatorForAPAndApply();

            operValidator.AlwaysValidate = true;

            operValidator.EntityKey = "FBillHead";

            e.Validators.Add(saveValidatorForAPAndApply);

        }





        /// <summary>

        /// 当前操作的校验器

        /// </summary>

        private class SaveValidatorForAPAndApply : AbstractValidator

        {

            public override void Validate(ExtendedDataEntity[] dataEntities, ValidateContext validateContext, BOS.Context ctx)

            {

                if (dataEntities == null)

                {

                    return;

                }

                string strErrorMsg = string.Empty;

                foreach (ExtendedDataEntity entityData in dataEntities)

                {

                    DynamicObjectCollection entryList = entityData["FPAYAPPLYENTRY"] as DynamicObjectCollection;

                    if (entryList == null)

                    {

                        continue;

                    }


                    foreach (var entry in entryList)

                    {

                        //申请付款金额

                        decimal applyAmountFor = Convert.ToDecimal(entry["FAPPLYAMOUNTFOR"]);

                        string purBillNo = Convert.ToString(entry["FSRCBILLNO"]);

                        string entryId = Convert.ToString(entry["Id"]);

                        if (!Convert.ToString(entry["FSOURCETYPE"]).Equals("PUR_PurchaseOrder") || purBillNo == "")

                        {

                            continue;

                        }


                        decimal[] amount = new decimal[4];

                        if (applyAmountFor > getDecimal(ctx, purBillNo, entryId, out amount))

                        {

                            ValidationErrorInfo validationErrorInfo = new ValidationErrorInfo(

                                string.Empty,

                                Convert.ToString(entityData["id"]),

                                entityData.DataEntityIndex,

                                entityData.RowIndex,

                                Convert.ToString(entityData["id"]),

                                string.Format("第{0}行分录申请付款金额{1}>采购预付金额{2}-(财务应付金额{3}+(付款申请关联金额{4}-当前分录付款关联金额{5})-财务应付已结算金额{6})",

                                entry["seq"], applyAmountFor, amount[0], amount[1], amount[2], amount[4], amount[3]),

                                string.Empty);

                            validateContext.AddError(entityData, validationErrorInfo);

                        }

                    }

                }

            }


            /// <summary>

            /// 

            /// </summary>

            /// <param name="ctx"></param>

            /// <param name="purBillNo"></param>

            /// <param name="entryId"></param>

            /// <param name="amount"></param>

            /// <returns></returns>

            public decimal getDecimal(Context ctx, string purBillNo, string entryId, out decimal[] amount)

            {

                string sql1 = string.Format(@"select sum(apEntry.FALLAMOUNTFOR) as AmountAPAll,sum(apEntry.FPAYMENTAMOUNT) as AmountPayMent from T_AP_PAYABLEENTRY apEntry 

inner join T_AP_PAYABLE apMain on apEntry.fid = apMain.fid

where FORDERNUMBER = '{0}' and apMain.FSETACCOUNTTYPE = '3'", purBillNo);


                string sql2 = string.Format(@"select payPlan.FAPPLYAMOUNT as AmountApply,payPlan.FYFAMOUNT as AmountAll from T_PUR_POORDERINSTALLMENT payPlan 

inner join t_PUR_POOrder purMain on payPlan.FID = purMain.FID

where purMain.FBILLNO = '{0}'", purBillNo);


                string sql3 = string.Format(@"select FAPPLYAMOUNTFOR from T_CN_PayApplyentry where fentryid={0} and FSRCBILLNO='{1}'", entryId, purBillNo);



                var amountAP = DBUtils.ExecuteDynamicObject(ctx, sql1);

                decimal amountAPAll = 0, amountPayMent = 0;

                if (amountAP.Count > 0)

                {

                    amountAPAll = Convert.ToDecimal(DBUtils.ExecuteDynamicObject(ctx, sql1).FirstOrDefault()["AmountAPAll"]);

                    amountPayMent = Convert.ToDecimal(DBUtils.ExecuteDynamicObject(ctx, sql1).FirstOrDefault()["AmountPayMent"]);

                }


                var amountPurPlan = DBUtils.ExecuteDynamicObject(ctx, sql2);

                decimal amountApply = 0, amountAll = 0;

                if (amountPurPlan.Count > 0)

                {

                    amountApply = Convert.ToDecimal(amountPurPlan.FirstOrDefault()["AmountApply"]);

                    amountAll = Convert.ToDecimal(amountPurPlan.FirstOrDefault()["AmountAll"]);

                }

                //当前分录付款关联金额

                var amountPayApply = DBUtils.ExecuteDynamicObject(ctx, sql3);

                decimal amountThis = 0;

                if (amountPayApply.Count > 0)

                {

                    amountThis = Convert.ToDecimal(amountPayApply.FirstOrDefault()["FAPPLYAMOUNTFOR"]);

                }



                amount = new decimal[5];

                amount[0] = amountAll;

                amount[1] = amountAPAll;

                amount[2] = amountApply;

                amount[3] = amountPayMent;

                amount[4] = amountThis;

                return amountAll - (amountAPAll + (amountApply - amountThis) - amountPayMent);

            }

        }

    }


附件↓

图标赞 6
6人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!