@@ -161,7 +161,7 @@ class SoongWorkflowNode(models.Model):
|
|||||||
"name": _("结束"),
|
"name": _("结束"),
|
||||||
"node_id": record.id,
|
"node_id": record.id,
|
||||||
"sequence": sequence + 1,
|
"sequence": sequence + 1,
|
||||||
"action_type": "end",
|
"action_type": "code",
|
||||||
"btn_hide": False,
|
"btn_hide": False,
|
||||||
"has_comment": True,
|
"has_comment": True,
|
||||||
"review_type": "end",
|
"review_type": "end",
|
||||||
|
|||||||
@@ -758,6 +758,46 @@ class PropertyAccountsReceivable(models.Model):
|
|||||||
record.discount_amount = record.submitted
|
record.discount_amount = record.submitted
|
||||||
record.discount_date = datetime(2026, 1, 1)
|
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):
|
def verification_wizard(self):
|
||||||
receivable_lines = self.env['property.accounts.receivable'].search([
|
receivable_lines = self.env['property.accounts.receivable'].search([
|
||||||
('contract_id', '=', self.contract_id.id),
|
('contract_id', '=', self.contract_id.id),
|
||||||
|
|||||||
@@ -54,13 +54,14 @@ class PropertyAccountsReceivableSummary(models.Model):
|
|||||||
WHERE r.contract_id IS NOT NULL
|
WHERE r.contract_id IS NOT NULL
|
||||||
AND r.deposit_state IN ('unpaid', 'no_paid')
|
AND r.deposit_state IN ('unpaid', 'no_paid')
|
||||||
AND COALESCE(r.is_reconciliation, false) = false
|
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
|
GROUP BY r.contract_id, c.use_address, c.admin_id
|
||||||
HAVING COALESCE(SUM(r.submitted), 0) > 0
|
HAVING COALESCE(SUM(r.submitted), 0) > 0
|
||||||
)
|
)
|
||||||
""" % {'table': self._table, 'main_cols': main_cols, 'excluded': excluded})
|
""" % {'table': self._table, 'main_cols': main_cols, 'excluded': excluded})
|
||||||
|
|
||||||
def action_open_unpaid_detail(self):
|
def action_open_unpaid_detail(self):
|
||||||
"""未收明细:打开该合同下 未收/收部分 且 未对账 的应收账单,
|
"""未收明细:打开该合同下 未收/收部分 且 未对账 且 未作废 的应收账单,
|
||||||
复用 view_property_accounts_receivable_tree,不做分组,按应收类型倒序"""
|
复用 view_property_accounts_receivable_tree,不做分组,按应收类型倒序"""
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
tree_view = self.env.ref('yuthon_property.view_property_accounts_receivable_tree')
|
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),
|
('contract_id', '=', self.contract_id.id),
|
||||||
('deposit_state', 'in', ['unpaid', 'no_paid']),
|
('deposit_state', 'in', ['unpaid', 'no_paid']),
|
||||||
('is_reconciliation', '=', False),
|
('is_reconciliation', '=', False),
|
||||||
|
('is_invalid', '=', False),
|
||||||
],
|
],
|
||||||
'context': {
|
'context': {
|
||||||
'order': 'management_type_id desc',
|
'order': 'management_type_id desc',
|
||||||
|
|||||||
@@ -828,6 +828,14 @@
|
|||||||
<field name="state">code</field>
|
<field name="state">code</field>
|
||||||
<field name="code">action = model.contract_context()</field>
|
<field name="code">action = model.contract_context()</field>
|
||||||
</record>
|
</record>
|
||||||
|
<!-- 一次性历史欠费清理:租金关掉生成违约金、违约金作废(条件见 action_clear_legacy_unpaid) -->
|
||||||
|
<record id="all_clear_legacy_unpaid" model="ir.actions.server">
|
||||||
|
<field name="name">清理2026年前旧账</field>
|
||||||
|
<field name="model_id" ref="yuthon_property.model_property_accounts_receivable"/>
|
||||||
|
<field name="binding_model_id" ref="yuthon_property.model_property_accounts_receivable"/>
|
||||||
|
<field name="state">code</field>
|
||||||
|
<field name="code">action = model.action_clear_legacy_unpaid()</field>
|
||||||
|
</record>
|
||||||
<!-- 违约金 -->
|
<!-- 违约金 -->
|
||||||
<record id="inherit_view_property_penalty_list_tree" model="ir.ui.view">
|
<record id="inherit_view_property_penalty_list_tree" model="ir.ui.view">
|
||||||
<field name="name">property.penalty.list.tree</field>
|
<field name="name">property.penalty.list.tree</field>
|
||||||
|
|||||||
@@ -127,6 +127,9 @@
|
|||||||
<field name="remark"/>
|
<field name="remark"/>
|
||||||
<!-- 仅在行的按钮里使用,不作为列显示 -->
|
<!-- 仅在行的按钮里使用,不作为列显示 -->
|
||||||
<field name="is_penalty" column_invisible="1"/>
|
<field name="is_penalty" column_invisible="1"/>
|
||||||
|
<field name="is_liquidated_damages"/>
|
||||||
|
<field name="is_invalid"/>
|
||||||
|
<field name="void_date"/>
|
||||||
<button name="penalty_wizard" string="收款明细" type="object" class="btn btn-blue" invisible="is_penalty"/>
|
<button name="penalty_wizard" string="收款明细" type="object" class="btn btn-blue" invisible="is_penalty"/>
|
||||||
<button name="button_accounts_wizard" string="操作" type="object" class="btn btn-blue"/>
|
<button name="button_accounts_wizard" string="操作" type="object" class="btn btn-blue"/>
|
||||||
<button name="receivable_log_wizard" string="日志" type="object" class="btn btn-blue"/>
|
<button name="receivable_log_wizard" string="日志" type="object" class="btn btn-blue"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user