如何在 OpenERP v6.1 中创建并抵扣 credit note?
结论
在 OpenERP v6.1 中,Supplier Refund 是独立的供应商贷项凭证。即使供应商相同或退款单关联了原发票,Payment Order 也不会自动抵扣。
正确的处理流程如下:
- 创建并确认 Supplier Refund;
- 在应付账款科目中核销退款单与原 Supplier Invoice;
- 核销完成后,原发票的未付余额会相应减少;
- 创建 Payment Order,支付核销后的剩余金额。
例如,供应商发票金额为 1,000,退款单金额为 200。核销 200 后,发票的剩余应付金额为 800,Payment Order 应按 800 处理。
为什么 Payment Order 没有自动扣除
两张单据的会计分录方向相反:
Supplier Invoice
借:费用或采购科目 1,000
贷:应付账款 1,000
Supplier Refund
借:应付账款 200
贷:费用或采购科目 200
退款单会在应付账款科目中形成 200 的借方余额,但在完成核销前,它仍是一笔独立的未核销项目。
Payment Order 用于选取待付款项目并生成付款指令,不负责判断某张退款单应抵扣哪张发票。因此,未核销的 Invoice 和 Refund 通常会作为两笔独立项目存在,付款单不会自动将两者相减。
推荐操作步骤
1. 从原发票创建 Credit Note
如果界面提供退款或 Credit Note 功能,建议从原 Supplier Invoice 发起,不要单独新建 Supplier Refund。这样通常能保留原发票引用,并复制供应商、币种、税项和明细。
根据安装配置,按钮名称可能是:
Refund
Credit Note
Create Refund
退款向导可能包含以下处理方式:
- 只创建退款单;
- 创建退款单并取消原发票;
- 创建退款单、取消原发票,并生成一张可以修改的新发票。
如果只是部分折让,应选择创建退款单,并填写需要抵扣的金额,不要取消整张原发票。
如果界面中没有从发票创建退款的入口,也可以通过以下菜单手工创建:
Accounting → Suppliers → Supplier Refunds
手工创建时,需要逐项确认供应商、应付科目、税额、币种及原始单据引用是否正确。
2. 确认退款单
退款单必须完成确认或过账。处于 Draft 状态的退款单不会生成正式会计分录,也不能参与核销。
确认后检查以下内容:
- Supplier 与原发票一致;
- Payable Account 与原发票一致;
- Company 和 Currency 一致;
- 会计期间处于开放状态;
- 退款金额和税额正确;
- 两张单据均已生成会计分录。
3. 核销发票和退款单
进入会计核销功能。OpenERP v6.1 的菜单名称可能因已安装模块、用户权限和界面语言而异,常见位置如下:
Accounting
└── Periodical Processing
└── Reconciliation
└── Manual Reconciliation
选择对应的供应商和应付账款科目,同时选中:
- Supplier Invoice 的应付分录行;
- Supplier Refund 的反向应付分录行。
金额相同时可以完全核销;退款金额小于发票金额时,应进行部分核销。
示例:
原发票未付金额:1,000
退款单金额: 200
本次核销金额: 200
核销后发票余额: 800
退款单余额: 0
不要将 800 的差额作为 write-off 注销。这部分金额仍是需要实际支付给供应商的应付款。
4. 再创建 Payment Order
核销完成后,重新打开或创建 Payment Order,并重新加载待付款项目。
此时,系统通常会显示原发票的 residual amount,也就是 800,而不是原始金额 1,000。如果 Payment Order 在核销前已经创建,原有付款明细可能不会自动刷新。遇到这种情况,通常需要删除旧明细,再重新选择待付款项目。
旧版 API 示例
下面是 OpenERP 6.x 旧式 ORM 的处理思路:查找同一供应商、同一应付科目中的发票和退款分录行,再执行部分核销。具体字段和方法签名可能受已安装模块影响,使用前应先在测试数据库中确认。
invoice = invoice_obj.browse(cr, uid, invoice_id, context=context)
refund = invoice_obj.browse(cr, uid, refund_id, context=context)
line_ids = []
for move_line in invoice.move_id.line_id:
if (
move_line.account_id.type == 'payable'
and move_line.partner_id.id == invoice.partner_id.id
and not move_line.reconcile_id
):
line_ids.append(move_line.id)
for move_line in refund.move_id.line_id:
if (
move_line.account_id.type == 'payable'
and move_line.partner_id.id == invoice.partner_id.id
and not move_line.reconcile_id
):
line_ids.append(move_line.id)
move_line_obj.reconcile_partial(
cr,
uid,
line_ids,
context=context
)
这段代码说明了核销对象:系统真正核销的是 account.move.line,并非直接修改 account.invoice 的金额。
不要通过 SQL 修改 amount_total、residual 或付款状态。OpenERP 的余额和状态取决于会计分录及其核销关系。直接修改字段,容易导致总账、供应商余额和付款状态不一致。
如果核销后仍显示原金额
按顺序检查以下项目:
- Refund 是否仍处于 Draft 状态;
- Refund 是否使用了不同的 Payable Account;
- 两张单据是否属于不同的供应商、公司或币种;
- 核销时是否误选了费用明细行,而不是应付账款分录行;
- 是否只创建了退款单,尚未执行 reconciliation;
- Payment Order 是否仍保留核销前生成的旧明细;
- 自定义付款模块是否按原始金额取数,而不是使用 residual amount。
判断的依据不是退款单是否存在,而是原发票的应付分录是否已经与退款分录完成核销。核销完成后,OpenERP 才会将 credit note 计入原发票未付余额,使其相应减少。
备注:内容仅供参考。
