添加功能

This commit is contained in:
李鹏宇
2026-08-24 19:12:10 +08:00
parent a5f626458a
commit fa354afbc1
4 changed files with 86 additions and 21 deletions
@@ -233,6 +233,16 @@ class PropertyAccountsReceivable(models.Model):
next_year = due_year if due_month < 12 else due_year + 1
penalty_start_date = date(next_year, next_month, 1)
contract = record.contract_id
renewal = self.env['property.lease.renewal'].search([
('contract_id', '=', contract.id),
('renewal_type', '=', 'early_checkout'),
('work_end', '=', True),
], limit=1)
if renewal:
penalty_start_date = renewal.early_quitting_date
# 1. 获取正常支付明细
modify_lines = self.env['receivable.modify.line'].search([
('receivable_id', '=', record.id),
@@ -258,18 +268,11 @@ class PropertyAccountsReceivable(models.Model):
penalty_pay_count = len(penalty_lines.filtered(lambda l: l.is_penalty))
deposit_penalty_count = 0
contract = record.contract_id
if contract:
renewal = self.env['property.lease.renewal'].search([
('contract_id', '=', contract.id),
('renewal_type', '=', 'early_checkout'),
('work_end', '=', True),
], limit=1)
if renewal:
if not renewal.is_full_refund:
penalty_amount = renewal.deposit - renewal.refund_amount - renewal.total_receivables
if penalty_amount > 0:
deposit_penalty_count = 1
if renewal:
if renewal.deposit_treatment != 'refund':
penalty_amount = renewal.deposit - renewal.refund_amount - renewal.total_receivables
if penalty_amount > 0:
deposit_penalty_count = 1
if record.management_type_id.name == '押金':
record.number_of_payments = rent_pay_count + deposit_penalty_count
@@ -61,7 +61,6 @@ class PropertyLeaseRenewal(models.Model):
work_end = fields.Boolean(string="结束")
deposit = fields.Float(string="原押金")
is_full_refund = fields.Boolean(string="是否全额退押", default=True)
refund_amount = fields.Float(string="退款金额")
deposit_treatment = fields.Selection([('refund', '全额退押'), ('part_refund', '部分退租'), ('no_refund', '全额没收')], string="押金处理方式", default='refund')
total_receivables = fields.Float(string="应收金额", compute="_compute_total_receivables")
@@ -349,7 +348,7 @@ class PropertyLeaseRenewal(models.Model):
('workflow_record_id', '=', workflow_record_id.id),
], limit=1)
if not exist_bill:
self.env['property.bills.list'].create({
bill = self.env['property.bills.list'].create({
'lessor_id': rec.contract_id.lessor_id.id,
'due_date': operation_date,
'management_type_id': deposit_management_type.id,
@@ -358,6 +357,8 @@ class PropertyLeaseRenewal(models.Model):
'remake': rec.early_explain,
'workflow_record_id': workflow_record_id.id,
})
else:
bill = exist_bill
start_time = datetime.combine(rec.early_quitting_date, datetime.min.time().replace(hour=8, minute=00))
existing_bank_statement = self.env['property.bank.statements'].sudo().search([
@@ -388,6 +389,8 @@ class PropertyLeaseRenewal(models.Model):
'your_own_account': lessor_id.rent_account,
})
bank_id._compute_property_employee_id()
else:
bank_id = existing_bank_statement
management_type_id = self.env['yuthon.management.type'].search([
('name', '=', '违约金')
@@ -407,6 +410,57 @@ class PropertyLeaseRenewal(models.Model):
'remark': rec.early_explain,
})
# ===== 触发 action_pay + button_reconciliation 的真实逻辑 =====
# 说明:action_pay / button_reconciliation 按钮本身只是返回向导弹窗的方法,
# 真正的业务在各自 wizard 的 confirm / 对账逻辑里。这里不再手工 write 子集字段,
# 而是直接调用 property.bills.wizard 的 _do_pay()(与弹窗 confirm 共用同一份支付逻辑),
# 以及复现银行流水对账的核心效果,保证与人工点“核销/对账”完全一致。
deposit_receivable = self.env['property.accounts.receivable'].search([
('contract_id', '=', rec.contract_id.id),
('management_type_id', '=', deposit_management_type.id),
], limit=1)
# 1) 支付效果(action_pay):调用支付弹窗的真实逻辑 —— 实付日期=应付日期、标记已付、
# 回写押金应收单实付日期与支付状态、结清合同。全额没收场景下跳过 confirm 的未对账校验。
if bill and not bill.actual_date:
bill.amount_actual = bill.amount
pay_wizard = self.env['property.bills.wizard'].create({
'bills_list_id': bill.id,
'actual_date': bill.due_date,
'receivables_id': deposit_receivable.id if deposit_receivable else False,
})
pay_wizard._do_pay()
# 2) 对账效果(button_reconciliation):bank.statements 与押金应收对账
if bank_id and bank_id.bank_state != 'reconciled':
bank_id.bank_state = 'reconciled'
bank_id.yes_amount = bank_id.original_amount
bank_id.reconciliation_time = fields.Datetime.now() - timedelta(hours=8)
# 自动核销违约金
if exist_receivable:
exist_receivable.write({
'has_date': bill.due_date if bill else operation_date,
'is_reconciliation': True,
'payout_date': operation_date,
'delivered1': rec.deposit,
'deposit_state': 'paid',
'reconciliation_time': fields.Datetime.now(),
'bank_id': bank_id.id,
})
self.env['receivable.modify.line'].create({
'bank_id': bank_id.id,
'not_collected': rec.deposit,
'reconciliation_date': operation_date,
'receivable_id': exist_receivable.id,
'is_write': True,
'operation_date': fields.Date.today(),
'is_penalty': True,
'remake1': rec.early_explain,
'amount': rec.deposit,
})
rec.contract_id.contact_state = 'settle'
rec.contract_id.compute_is_has()
# 原有作废/减免逻辑保留
for receivable_id in rec.receivables_ids:
if receivable_id.void:
@@ -173,7 +173,7 @@ class PenaltyLineWizard(models.Model):
], limit=1)
if renewal:
# 2. 判断条件:未全额退款
if not renewal.is_full_refund:
if renewal.deposit_treatment != 'refund':
# 3. 计算没收押金金额
penalty_amount = renewal.deposit - renewal.refund_amount - renewal.total_receivables
if penalty_amount > 0:
@@ -20,19 +20,27 @@ class PropertyBillsWizard(models.TransientModel):
if any(not receivable.is_reconciliation for receivable in receivable_ids):
raise UserError("该合同下存在未对账的应收单,无法退金额")
self._do_pay()
def _do_pay(self):
"""实际支付业务效果:实付日期=所选日期、标记账单已付、回写对应应收单(实付日期/支付状态)、结清合同。
从 confirm 抽出,供正常支付弹窗与程序化支付(如退租全额没收)共用,确保支付逻辑只有一份。
注意:全额没收等程序化场景直接调用本方法,会跳过 confirm 的“未对账应收单”校验。"""
if self.receivables_id:
self.receivables_id.deposit_state = 'yes'
if self.actual_date:
self.bills_list_id.actual_date = self.actual_date
self.bills_list_id.pay_state = 'paid'
receivable = self.env['property.accounts.receivable'].search([('contract_id', '=', self.bills_list_id.contract_id.id),
('management_type_id', '=', self.bills_list_id.management_type_id.id)
])
receivable = self.env['property.accounts.receivable'].search([
('contract_id', '=', self.bills_list_id.contract_id.id),
('management_type_id', '=', self.bills_list_id.management_type_id.id),
], limit=1)
if receivable:
receivable.write({'has_date': self.actual_date,
'deposit_state': 'yes'
})
receivable.write({
'has_date': self.actual_date,
'deposit_state': 'yes',
})
self.bills_list_id.contract_id.contact_state = 'settle'
self.bills_list_id.contract_id.compute_is_has()