diff --git a/soong_workflow/models/soong_workflow_node.py b/soong_workflow/models/soong_workflow_node.py index ffc3167ba..a20bd4f9c 100644 --- a/soong_workflow/models/soong_workflow_node.py +++ b/soong_workflow/models/soong_workflow_node.py @@ -161,7 +161,7 @@ class SoongWorkflowNode(models.Model): "name": _("结束"), "node_id": record.id, "sequence": sequence + 1, - "action_type": "end", + "action_type": "code", "btn_hide": False, "has_comment": True, "review_type": "end", diff --git a/yuthon_property_approval/models/inherit_yuthon_property.py b/yuthon_property_approval/models/inherit_yuthon_property.py index aea4651c5..da1e624ce 100644 --- a/yuthon_property_approval/models/inherit_yuthon_property.py +++ b/yuthon_property_approval/models/inherit_yuthon_property.py @@ -758,6 +758,46 @@ class PropertyAccountsReceivable(models.Model): record.discount_amount = record.submitted record.discount_date = datetime(2026, 1, 1) + def action_clear_legacy_unpaid(self): + """一次性历史欠费清理(应收日期 < 2026-01-01 且 未对账,不限收款状态): + 1) 应收类型 = 租金 → 关闭「生成违约金」(is_liquidated_damages = False) + 2) 应收类型 = 违约金 → 作废 (is_invalid = True,作废日期 = 当天) + + 作废后汇总视图 property.accounts.receivable.summary 与「未收明细」跳转都会自动排除。 + """ + cutoff = date(2026, 1, 1) + today = fields.Date.context_today(self) + base_domain = [ + ('due_date', '<', cutoff), + ('is_reconciliation', '=', False), + ] + + # 1) 租金:关闭生成违约金(只处理当前还开着的,避免无谓写入) + rent_records = self.search(base_domain + [ + ('management_type_id.name', '=', '租金'), + ('is_liquidated_damages', '=', True), + ]) + rent_records.write({'is_liquidated_damages': False}) + + # 2) 违约金:作废 + 填当天作废日期(已作废的不动,保留原作废日期) + penalty_records = self.search(base_domain + [ + ('management_type_id.name', '=', '违约金'), + ('is_invalid', '=', False), + ]) + penalty_records.write({'is_invalid': True, 'void_date': today}) + + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'type': 'success', + 'title': '清理完成', + 'message': '租金关闭「生成违约金」%s 条;违约金作废 %s 条。' + % (len(rent_records), len(penalty_records)), + 'sticky': False, + }, + } + def verification_wizard(self): receivable_lines = self.env['property.accounts.receivable'].search([ ('contract_id', '=', self.contract_id.id), diff --git a/yuthon_property_approval/models/property_accounts_receivable_summary.py b/yuthon_property_approval/models/property_accounts_receivable_summary.py index f081ef17a..09c9094c8 100644 --- a/yuthon_property_approval/models/property_accounts_receivable_summary.py +++ b/yuthon_property_approval/models/property_accounts_receivable_summary.py @@ -54,13 +54,14 @@ class PropertyAccountsReceivableSummary(models.Model): WHERE r.contract_id IS NOT NULL AND r.deposit_state IN ('unpaid', 'no_paid') AND COALESCE(r.is_reconciliation, false) = false + AND COALESCE(r.is_invalid, false) = false GROUP BY r.contract_id, c.use_address, c.admin_id HAVING COALESCE(SUM(r.submitted), 0) > 0 ) """ % {'table': self._table, 'main_cols': main_cols, 'excluded': excluded}) def action_open_unpaid_detail(self): - """未收明细:打开该合同下 未收/收部分 且 未对账 的应收账单, + """未收明细:打开该合同下 未收/收部分 且 未对账 且 未作废 的应收账单, 复用 view_property_accounts_receivable_tree,不做分组,按应收类型倒序""" self.ensure_one() tree_view = self.env.ref('yuthon_property.view_property_accounts_receivable_tree') @@ -77,6 +78,7 @@ class PropertyAccountsReceivableSummary(models.Model): ('contract_id', '=', self.contract_id.id), ('deposit_state', 'in', ['unpaid', 'no_paid']), ('is_reconciliation', '=', False), + ('is_invalid', '=', False), ], 'context': { 'order': 'management_type_id desc', diff --git a/yuthon_property_approval/views/inherit_yuthon_property_views.xml b/yuthon_property_approval/views/inherit_yuthon_property_views.xml index 3424f7610..74c9106ca 100644 --- a/yuthon_property_approval/views/inherit_yuthon_property_views.xml +++ b/yuthon_property_approval/views/inherit_yuthon_property_views.xml @@ -828,6 +828,14 @@ code action = model.contract_context() + + + 清理2026年前旧账 + + + code + action = model.action_clear_legacy_unpaid() + property.penalty.list.tree diff --git a/yuthon_work_brand/views/receivable_type_menus.xml b/yuthon_work_brand/views/receivable_type_menus.xml index f8814f4bc..a62907493 100644 --- a/yuthon_work_brand/views/receivable_type_menus.xml +++ b/yuthon_work_brand/views/receivable_type_menus.xml @@ -127,6 +127,9 @@ + + +