news 2026/10/24 2:21:56

ERP看板别把订单额当销售额:出入库、退货与收付款如何分开统计?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ERP看板别把订单额当销售额:出入库、退货与收付款如何分开统计?

ERP看板别把订单额当销售额:出入库、退货与收付款如何分开统计?

一张订单已经审核,货还没发出去,能不能计入首页“销售”?货已经出库,但客户没有结清,销售数字要不要跟着变?上个月发出的货,这个月退回来,又该扣在哪一期?

这些问题都发生在同一条业务链上,却不能交给同一个金额字段回答。订单记录承诺,出入库记录履约,收付款记录结算。管理者需要把它们放在一起看,系统则需要把来源分开存、把计算分开做。

下面结合RuoYi Office的真实界面和统计实现,沿一批已有演示数据核对。看板使用PC页面,单据使用独立移动端H5详情;两类界面都只读查看,没有创建、审批或修改业务记录。H5截图不代表原生APP真机验证。

▲ 订单、出入库与退货、收付款属于三类事实。主图中的历史界面用于表达产品链路,下面的数字核对以本次开发演示样本为准。

先看清首页上同时出现了什么

经营看板把销售、采购、库存和待办放在一个入口里。金额卡帮助判断期间业务规模,待出库、待入库帮助定位履约积压,待收款、待付款帮助找到尚未结清的单据。

▲ 本次开发演示数据:今年销售1,197,559.31,待出库2,待收款7。三个数字的单位和范围不同;整屏小字可点开放大。

“今年销售”在当前实现中来自销售出库减销售退货;“待出库2”是符合条件的订单笔数;“待收款7”是符合条件的出库单笔数。它们不是把同一批订单换三个名字展示。

尤其要注意,首页切换今日、本月、本年时,前端只重新加载概览金额。工作台里的待收款、待付款是当前未结清状态,不跟随期间切换;概览中的待出入库计数本身也没有加期间条件。

这样的组合适合同时回答“这一期发生了多少”和“现在还有什么没处理”,但产品说明必须把两种范围讲清。不能因为卡片相邻,就把所有数字都理解成“本年新增”。

从订单到出库:承诺兑现了,结算可能还没完成

先看同一张单据的两种身份。订单ERP-HOME-SO-202609-01在已有样本中已审核,总数量58,出库数量也是58,含税金额232,149.46。

▲ 独立H5页面,430×932完整视口。订单数量与出库进度用来判断履约,金额字段用来表达订单规模,不能据此认定款项已经到账。

对应出库单ERP-HOME-SX-202609-01的orderId指向这张订单,出库数量58,应收金额232,149.46,已收金额0。它的出库时间是9月3日15:30,订单时间则是当天10:00。

▲ 同一开发样本的出库单已审核,已收仍为0,未收232,149.46。完整履约和完成结算是两个判断;本次没有执行收款。

同一张单内部也有金额口径:本例产品金额为205,442.00,税额26,707.46,两者合计才是232,149.46,优惠和其它费用均为0。拿产品金额与含税应收比较,即便日期、客户、单号完全相同,仍会出现差额。对账前应先确认比较的是产品金额、含税金额还是优惠后的最终金额,不能只看字段名称中都有一个“金额”。

这张单已经完成了订单对应的出库,却仍满足待收款条件。反过来,订单上即使有订金,也不能把订金字段直接当作出库净额的一部分;预收、履约、核销需要各自明确关联。

数据模型也保留了这种分工:订单与出库通过order_id关联,退货也关联订单;收款单下面还有收款项,收款项通过业务类型与业务ID指向销售出库或销售退货。

▲ 虚线表示由biz_type与biz_id决定的业务关联,不是一个同时指向两张表的物理外键。收款分配关系用于解释源码模型,不代表本次有完整收退款样本。

为什么收款要多一层明细?因为一次收款可能分配给多张出库单,一张出库单也可能分多次结清。总账式地给客户记一个金额,无法准确回答某张业务单还欠多少。

两笔未出库,怎样解释68,682.53的差额

把视角从一张单拉回本次开发演示数据。固定租户、未删除数据和2026年起的业务时间,读取到:

核对项金额或数量
已审核销售订单16笔,1,266,241.84
销售出库14笔,1,197,559.31
尚未出库的已审核订单2笔,68,682.53

两张待出库订单金额分别是40,675.48和28,007.05,出库数量均为0。于是这份样本中有一条可核对的等式:

1,266,241.84 − 1,197,559.31 = 40,675.48 + 28,007.05 = 68,682.53。

这说明差额来自尚未兑现的订单,而不是首页少算了两张单。本次样本的出库均为已审核,且没有销售退货,因此看板净额恰好等于出库合计。另有两笔未审核订单,不包含在上表的“已审核订单”里。

这条等式只解释当前样本,不能升级成所有企业的固定公式。部分出库、订单变更、跨期履约、折扣及退货,都可能让“订单额减出库额”不再直接等于剩余订单的整单金额。

实现统计时应先明确要核对的集合,再找差额原因。直接要求订单列表合计必须等于首页销售,往往会把两个本来合理的数字一起改错。

退货扣在哪一期,要看退货事实的日期

当前销售统计分别汇总出库与退货,然后相减。下面摘录实际MyBatis查询的金额与日期部分;为突出主线,省略两处分支中原有的可信租户上下文条件,实际使用时必须保留租户限制。

<selectid="getSalePrice"resultType="java.math.BigDecimal">SELECT (SELECT COALESCE(SUM(total_price), 0) FROM erp_sale_out WHERE out_time >= #{beginTime}<iftest="endTime != null">AND out_time&lt;#{endTime}</if>AND deleted = 0) - (SELECT COALESCE(SUM(total_price), 0) FROM erp_sale_return WHERE return_time >= #{beginTime}<iftest="endTime != null">AND return_time&lt;#{endTime}</if>AND deleted = 0)</select>

出库使用out_time,退货使用return_time。按这个定义,上月出库、本月退货,会影响本月净额,并不会因为关联的订单在上个月,就自动回改上个月的统计。

如果某个月退货金额大于当月出库,按发生期计算的净额可以为负。这不是一定要被前端修成0的异常值,它可能反映前期业务在本期集中退回。若管理上需要同时观察正向规模与退货压力,可以分别展示出库额、退货额和净额,不能让一个被截断的数字掩盖负向业务。

两个集合分别聚合,还有一个实际好处:避免把订单、出库明细、收款项一起JOIN后再SUM主单金额。一张出库有三行产品、两条收款分配时,未经去重的关联可能把金额重复累计。指标需要哪个事实,就在正确粒度上先计算哪个事实。

采购方向与此对称:按in_time汇总采购入库,再按return_time扣除采购退货。采购订单额不直接当作采购入库净额,付款金额也不混入该公式。

▲ 金额走出库与退货的期间汇总,待办走当前状态判断。它们可以由首页统一返回,但仍保留各自的来源与范围。

这里还有一个现状边界:当前销售、采购净额SQL未显式增加审核状态过滤,不能将其介绍为“仅已审核口径”。本次出库样本恰好都已审核,不能证明未审核数据一定不会计入。若业务要求审核后才进入经营指标,应同步调整统计与核对规则,而不能只修改卡片名称。

另外,“出库减退货”是这里的业务净额,不能直接等同于会计收入确认或利润。

待收款是找单据,实际收款是看分配

首页判断待出库与待收款,使用的是两个不同字段关系。下面是实际实现的核心条件:

privatelongcountPendingOut(){returnnvl(saleOrderMapper.selectCount(newLambdaQueryWrapperX<ErpSaleOrderDO>().eq(ErpSaleOrderDO::getStatus,ErpAuditStatus.APPROVE.getStatus()).apply("out_count < total_count")));}privatelongcountPendingReceipt(){returnnvl(saleOutMapper.selectCount(newLambdaQueryWrapperX<ErpSaleOutDO>().eq(ErpSaleOutDO::getStatus,ErpAuditStatus.APPROVE.getStatus()).apply("receipt_price < total_price")));}

第一段数的是尚未出完的已审核订单,第二段数的是尚未结清的已审核出库单。一张欠100的单和一张欠10万的单,在“待收款笔数”里都只算一笔。

本次开发样本符合待收款条件的出库单是7笔,对应total_price - receipt_price合计1,077,643.71。这是业务单余额核对结果,不是首页已经展示的待收款金额,更不是银行账户余额;当前开发样本未找到相应收款单及收款项,不能据此验证完整资金流水。

收款服务则需要识别分配对象。实际校验中,销售出库取正向应收,销售退货取负向金额,并检查客户一致:

returnconvertList(list,o->BeanUtils.toBean(o,ErpFinanceReceiptItemDO.class,item->{if(ObjectUtil.equal(item.getBizType(),ErpBizTypeEnum.SALE_OUT.getType())){ErpSaleOutDOout=saleOutService.validateSaleOut(item.getBizId());Assert.equals(out.getCustomerId(),customerId,"客户必须相同");item.setTotalPrice(out.getTotalPrice()).setBizNo(out.getNo());}elseif(ObjectUtil.equal(item.getBizType(),ErpBizTypeEnum.SALE_RETURN.getType())){ErpSaleReturnDOret=saleReturnService.validateSaleReturn(item.getBizId());Assert.equals(ret.getCustomerId(),customerId,"客户必须相同");item.setTotalPrice(ret.getTotalPrice().negate()).setBizNo(ret.getNo());}else{thrownewIllegalArgumentException("业务类型不正确:"+item.getBizType());}}));

业务类型与业务ID共同决定查哪张单,单号是可读标识;后端从业务单重新取应收值,并验证客户一致,避免仅凭前端传来的金额完成分配。源码中收款单的合计来自分配项之和,实付字段还会扣除优惠金额,因此“核销了多少应收”和“本次实际收了多少”也需要区分,不能让优惠悄悄消失在总数里。

不能把退货本身录成负数后,又不检查约定地再次取负,否则方向会反转。金额符号、优惠金额与实际收付金额的关系,需要作为结算规则统一定义。

当前实现还会在创建收款单及明细后更新业务单的累计收款字段,而收款单初始状态是未审核;累计查询也没有关联收款主单审核状态。因此,业务单上的“已收金额”不能自动解释成已审核、已银行对账的现金到账额。若要做资金日报,应另按收付款发生时间、有效状态和账户核对,不能直接把这个累计字段求和代替期间现金流。

采购与付款,也要分别看履约和结算

采购侧使用同样的分工:入库表达货物已接收,付款表达对供应商的结算。当前看板的待付款条件,是已审核采购入库单的payment_price < total_price,数的是单据笔数;不能拿它与本期采购净额直接相减。

付款服务按采购入库或采购退货识别分配对象,校验供应商一致,采购退货金额取负向参与分配。创建付款单后也会更新采购业务单累计,因而“已付”字段同样不自动等于已审核、已银行对账的期间付款。

要做现金收支分析,应从收付款单据的发生时间和有效状态出发,再追溯其分配项;要看采购履约规模,则从入库与退货出发。统一页面可以共用组件和筛选表达,不能共用一个含义不明的金额总数。本次采购入库合计999,033.00与看板一致,付款回写规则依据源码核对,未另行执行付款实验。

日期相同,也不一定在比较同一个期间

首页期间解析同时返回本期与对比期,关键分支如下,省略时间起点的取得:

returnswitch(period){case"today"->newLocalDateTime[]{today,null,LocalDateTimeUtils.getYesterday(),today};case"year"->newLocalDateTime[]{year,null,year.minusYears(1),year};default->newLocalDateTime[]{month,null,LocalDateTimeUtils.beginOfMonth(month.minusMonths(1)),month};};

本期结束传null时,SQL不增加上界,严格说是“从本期起点开始”,不是由数据库条件保证“截至此刻”。若存在未来日期单据,也需要明确是否计入。对比期则使用结束边界;本月尚未结束时直接对比完整上月,也不等于相同已过天数的比较。

业务若需要截至某个时点,就应显式传入截止时间;需要同进度同比或环比,则计算同进度的对比区间。固定期间可采用左闭右开的[开始, 下一期间开始),避免对月末最后一秒及小数精度作隐含假设。

让看板可解释,关键在于把每个数字的来源、日期、状态、方向和单位一起交代清楚。订单增长、出库增长、未结清单据增加,分别提示接单、履约和结算上的不同变化。把这些事实正确连接起来,企业管理一体化平台才能同时支持业务办理与经营判断。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/24 2:20:58

Zend联合创始人Zeev离职,背后真相揭秘

昨日的消息显示, 联合创始人Zeev已经在推特上宣布说自己已经离职了, 原因是他在工作长达20年之后离开了公司。Zeev 他在推特这个平台上面用来做自我介绍的话说, 他是叫做 PHP 的联席架构师的职位的人, 他也是 Zend 这个公司的联合创始人, 这两个头衔里面有个细节要注意, 原文写…

作者头像 李华
网站建设 2026/10/24 2:20:57

注释不是累赘,而是代码的说明书

在代码里面, 那些以#开头的单行文字, 或者是被三引号包裹起来的文本内容, 这些统统都叫做注释。注释有一个非常明显的特点, 那就是它只会被人用来阅读, 主要作用就是解释说明, 等到解释器去运行代码的时候, 会直接把它忽略掉, 完全不会参与程序的执行过程, 当然也不会对代码的运…

作者头像 李华
网站建设 2026/10/24 2:20:46

从零开始学 UI 第一篇:Figma 快速上手实战指南(上)

&#x1f539;博主名称&#xff1a;_Doubletful大家好&#xff0c;欢迎来到Doubletful的博客&#x1faa2;博主的GitHub&#xff1a;Go to git_hub&#x1f4a0;移动应用开发专栏&#x1f537;路漫漫其修远兮&#xff0c;吾将上下而求索文章目录序言什么是 UI 设计&#xff1f;…

作者头像 李华
网站建设 2026/10/24 2:19:47

Can Large Language Models Detect Errors in Long Chain-of-Thought Reasoning?

### 摘要 最近,类似 o1 的模型备受关注,这些模型通过生成冗长的思维链(CoT)推理步骤来提升现有大语言模型(LLMs)的推理能力。在本文中,为了理解这些长思维链的质量,并衡量现有大语言模型对这些长思维链的批判能力,我们引入了 DeltaBench。它包含了不同类似 o1 的模型…

作者头像 李华
网站建设 2026/10/24 2:19:21

什么是AI引用率?从计算口径到监测方法的完整拆解

AI 引用率&#xff08;AI Citation Rate&#xff09;&#xff0c;指在一组既定问题下&#xff0c;AI 生成的答案中实际采用了你的内容作为来源的那部分答案所占的比例。它衡量内容有没有被 AI 答案调用&#xff0c;与页面排名无关。下面说清 AI 引用率的定义、计算口径、与提及…

作者头像 李华