添加功能
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user