文本讲述了应收应付单核销后的结算金额计算方式,包括按到期日、订单、物料明细的收款条件,以及异常情况下(如收款条件被修改)的数据修复方法。修复方法包括使用SQL语句修改已完全核销单据的已结算金额和未结算金额,以及处理部分核销单据的逻辑。
应收应付单做了收付款核销后,会按比例计算明细行对应的已结算金额和未结算金额进行反写,已结算金额的计算方式和单据的收付款条件的收款方式有关。
以应收单为例,收款条件的收款方式分为按到期日收款、按订单收款、按物料明细收款。
1. 按到期日收款或收款条件为空时,应收单的收款计划仅有一行,且不会携带订单号,分配方式是每行明细占总金额的比例*已核销金额计算;
2. 按订单收款时,应收单的收款计划根据明细的销售订单号(FORDERNUMBER)分组汇总生成,每个订单对应一行计划,且会携带订单号,在这一行计划分录核销后,仅反写相同订单的明细,按每行价税合计占该订单总金额的比例*已核销金额计算;
3. 按物料明细收款时,应收单的收款计划根据明细的订单分录内码(FORDERENTRYID)和物料(FMATERIALID)分组汇总生成(订单号默认是一致的所以作为分组字段),相同订单分录内码和物料才生成一行收款计划,且会携带订单号、订单分录内码、物料这三个字段,在这一计划分录核销后,仅反写相同订单分录内码、物料内码的明细,按每行价税合计占该订单分录物料总金额的比例*已核销金额计算。
异常情况:历史收款条件不符合业务需求,所以自行放开了已使用的收款条件基础资料的收款方式的锁定性(一般已经创建的收款条件就不允许修改收款方式)做了修改,或修改了历史单据的收款条件,使应收单的计划分录和单据现在的收款方式不匹配了,即不符合上述的逻辑关系,比如从按到期日收款修改为按订单收款,明细有多个订单或多个物料,而收款计划只有一行分录且没有订单号,因订单号不匹配,就会影响已结算金额的反写。此时就需要做数据修复。
但部分核销的单据分摊逻辑略复杂,所以建议是只针对已完全收付款核销的单据,将明细分录的已结算金额修改为和价税合计一致,未结算金额修改为0,部分核销的单据待完全核销后再统一修复。
--修改已完全核销的应收单的已结算金额=价税合计 merge into t_ar_receivableentry t1 using ( select a.fbillno,a.fwrittenoffstatus,b.fentryid,b.freceiveamount 已结算金额,b.fnoreceiveamount 未结算金额,b.fallamountfor 明细价税合计,b.fordernumber 采购订单号 from t_ar_receivable a left join t_ar_receivableentry b on a.fid=b.fid where a.fwrittenoffstatus='C' and b.freceiveamount<>b.fallamountfor ) t2 on (t1.fentryid=t2.fentryid) when matched then update set t1.freceiveamount=t1.fallamountfor,t1.fnoreceiveamount=0; --修改已完全核销的应付单的已结算金额=价税合计 merge into t_ap_payableentry t1 using( select a.fbillno,a.fdate,a.fwrittenoffstatus,b.fallamountfor 明细价税合计,b.fpaymentamount 已结算金额,b.fnoreceiveamount 未结算金额,b.fordernumber 采购订单号,b.fentryid from t_ap_payable a left join t_ap_payableentry b on a.fid=b.fid where a.fwrittenoffstatus='C' and b.fpaymentamount<>b.fallamountfor ) t2 on (t1.fentryid=t2.fentryid) when matched then update set t1.fpaymentamount=t1.fallamountfor,t1.fnoreceiveamount=0;
核销记录为空的单据修复sql:
--更新未核销的单据 已结算金额=0 未结算金额=价税合计 --应收单 merge into t_ar_receivableentry t1 using ( select a.fbillno,a.fid,a.fwrittenoffstatus,b.fallamountfor,b.freceiveamount,b.fnoreceiveamount,b.fentryid from t_ar_receivable a inner join t_ar_receivableentry b on a.fid=b.fid where a.fwrittenoffstatus='A' and b.freceiveamount<>0 ) t2 on (t1.fentryid=t2.fentryid) when matched then update set t1.freceiveamount=0,t1.fnoreceiveamount=t1.fallamountfor; --应付单 merge into t_ap_payableentry t1 using ( select a.fbillno,a.fid,a.fwrittenoffstatus,b.fallamountfor,b.fpaymentamount,b.fnoreceiveamount,b.fentryid from t_ap_payable a inner join t_ap_payableentry b on a.fid=b.fid where a.fwrittenoffstatus='A' and b.fpaymentamount<>0 ) t2 on (t1.fentryid=t2.fentryid) when matched then update set t1.fpaymentamount=0,t1.fnoreceiveamount=t1.fallamountfor;
部分核销的单据修复参考:
示例:修改前收款条件为按到期日收款
--更新部分核销的应收单 --修改前为按到期日收款,计划就只有一行 --先根据比例计算每行分录的已结算金额和未结算金额 merge into t_ar_Receivableentry t1 using ( select a.fbillno,a.fid,a.fallamountfor,c.fpayamountfor,c.fwrittenoffamountfor,c.fwrittenoffstatus from t_ar_Receivable a left join t_ar_receivableplan c on a.fid=c.fid where c.fwrittenoffstatus ='B' and exists (select 1 from t_ar_receivableentry where fid=a.fid and fallamountfor<>0 and freceiveamount=0) and not exists (select 1 from t_ar_receivableplan where fid=a.fid and fseq<>1) ) t2 on (t1.fid=t2.fid) when matched then update set t1.freceiveamount=round(t1.fallamountfor/t2.fallamountfor*t2.fwrittenoffamountfor,2),fnoreceiveamount=t1.fallamountfor-round(t1.fallamountfor/t2.fallamountfor*t2.fwrittenoffamountfor,2); --找到异常单据的最大行分录调整尾差 merge into t_ar_receivableentry t1 using ( select a.fbillno 单据编号,a.fwrittenoffstatus,a.fid,a.fallamountfor 单据头价税合计,b.fallamountfor 明细价税合计汇总,b.freceiveamount 已结算金额,b.fnoreceiveamount 未结算金额,b.fentryid,c.diff from t_ar_Receivable a inner join t_ar_Receivableentry b on a.fid=b.fid inner join ( --查询已结算金额合计是否有尾差 Select a.fid,(select max(fentryid) from t_ar_Receivableentry where fid=a.fid) fmaxentryid,freceiveamount 已结算金额汇总,c.fwrittenoffamountfor 已核销金额汇总,b.freceiveamount-c.fwrittenoffamountfor diff from t_ar_receivable a left join (select fid,sum(fallamountfor) fallamountfor,sum(freceiveamount) freceiveamount from t_ar_Receivableentry group by fid) b on a.fid=b.fid left join (select fid,sum(fpayamountfor) fpayamountfor,sum(fwrittenoffamountfor) fwrittenoffamountfor from t_ar_receivableplan group by fid) c on a.fid=c.fid where a.fwrittenoffstatus='B' and b.fallamountfor=c.fpayamountfor and b.freceiveamount<>c.fwrittenoffamountfor and c.fwrittenoffamountfor<>0 ) c on b.fentryid=c.fmaxentryid ) t2 on (t1.fentryid=t2.fentryid) when matched then update set t1.freceiveamount=freceiveamount-diff,t1.fnoreceiveamount=fnoreceiveamount+diff;
推荐阅读