添加功能

This commit is contained in:
李鹏宇
2025-11-05 18:18:31 +08:00
parent a6b7d4df3a
commit 18b81bd184
6 changed files with 92 additions and 110 deletions
@@ -59,36 +59,33 @@
<field name="department_id" invisible="1"/>
</group>
</group>
<group col="4">
<group>
<field name="resource_id" domain="[('company_id', '=', company_id)]" options="{'no_create': True, 'no_edit':True}"/>
</group>
<group>
<field name="transferees_id" invisible="alternate_shifts != 'transferees'"/>
<field name="alternate_id" invisible="alternate_shifts != 'alternate'"/>
</group>
<group/>
<group/>
</group>
<group string="班次1" invisible="alternate_shifts == 'alternate'">
<label for="shift_date"/>
<group string="换班1" invisible="alternate_shifts == 'alternate'">
<label for="resource_id"/>
<div>
<field name="resource_id" class="oe_inline"/>日期
<field name="shift_date" class="oe_inline"/>我的班次:
<field name="shift_id" class="oe_inline" invisible="shift_rest" readonly="1"/>
<field name="shift_rest" class="oe_inline" invisible="shift_id or shift_date == False"/>
</div>
</group>
<group>
<label for="return_date"/>
<div>
<field name="shift_rest" class="oe_inline" invisible="shift_id or shift_date == False"/>换班对象
<field name="transferees_id" class="oe_inline"/>日期
<field name="return_date" class="oe_inline"/>对方班次:
<field name="return_id" class="oe_inline" invisible="return_rest" readonly="1"/>
<field name="return_rest" class="oe_inline" invisible="return_id or return_date == False"/>
</div>
</group>
<group string="班次2" invisible="alternate_shifts == 'alternate'">
<label for="shift_two_date"/>
<group invisible="alternate_shifts == 'transferees'">
<label for="resource_id"/>
<div>
<field name="resource_id" class="oe_inline"/>顶
<field name="alternate_id" class="oe_inline"/>日期:
<field name="return_date" class="oe_inline"/>对方班次:
<field name="return_id" class="oe_inline" invisible="return_rest" readonly="1"/>
<field name="return_rest" class="oe_inline" invisible="return_id or return_date == False"/>
</div>
</group>
<group string="换班2" invisible="alternate_shifts == 'alternate'">
<label for="resource_id"/>
<div>
<field name="resource_id" class="oe_inline"/>日期
<field name="shift_two_date" class="oe_inline"/>我的班次:
<field name="shift_two_id" class="oe_inline" readonly="1" invisible="shift_two_rest"
context="{'tree_view_ref': 'yuthon_hr_attendance.view_yuthon_shift_context',
@@ -96,10 +93,8 @@
'order': 'start_datetime desc',
'search_default_group_by_month': True,}" options="{'no_create': True, 'no_edit':True}"
/>
<field name="shift_two_rest" class="oe_inline" invisible="shift_two_id or shift_two_date == False"/>
</div>
<label for="return_two_date"/>
<div>
<field name="shift_two_rest" class="oe_inline" invisible="shift_two_id or shift_two_date == False"/>换班对象
<field name="transferees_id" class="oe_inline"/>日期
<field name="return_two_date" class="oe_inline"/>对方班次:
<field name="return_two_id" class="oe_inline" readonly="1" invisible="return_two_rest"
context="{'tree_view_ref': 'yuthon_hr_attendance.view_yuthon_shift_context',
@@ -296,6 +296,7 @@ class PropertyBankStatements(models.Model):
'res_model': 'binding.information.wizard',
'target': 'new',
'context': {
'default_lessee_ids': [(6, 0, self.lessee_ids.ids)] if self.lessee_ids else False,
'default_bank_id': self.id,
}
}
@@ -9,6 +9,7 @@ class BindingInformationWizard(models.Model):
bank_id = fields.Many2one('property.bank.statements',string="银行")
property_ids = fields.Many2many('yuthon.property', string='物业')
contract_ids = fields.Many2many('property.lease.contract',string="租赁合同审批")
lessee_ids = fields.Many2many('property.tenant.information', string="承租方")
available_property_ids = fields.Many2many(
'yuthon.property',
'binding_information_wizard_available_property_rel',
@@ -18,16 +19,6 @@ class BindingInformationWizard(models.Model):
string='可用物业ID',
store=True
)
available_contract_ids = fields.Many2many(
'property.lease.contract',
'binding_information_wizard_available_contract_rel',
'wizard_id',
'contract_id',
compute='_compute_available_records',
string='可用合同ID',
store = True
)
@api.onchange('property_ids')
def onchange_property_ids(self):
if not self.property_ids:
@@ -60,43 +51,26 @@ class BindingInformationWizard(models.Model):
if new_property_ids:
self.property_ids = [(4, property_id) for property_id in new_property_ids]
@api.onchange('bank_id')
def _onchange_bank_id(self):
"""计算可用的物业和合同ID"""
for record in self:
# 搜索未对账的应收记录
unreconciled_records = self.env['property.accounts.receivable'].search([
('is_reconciliation', '=', False)
])
contract_ids = list(set(record.contract_id.id for record in unreconciled_records if record.contract_id))
# 设置计算字段值
record.available_contract_ids = [(6, 0, contract_ids)] if contract_ids else [(5,)]
def confirm(self):
if self.bank_id.name:
bank_ids = self.env['property.bank.statements'].search([('name', '=', self.bank_id.name)])
for bank_id in bank_ids:
if self.contract_ids:
new_contracts = self.contract_ids - bank_id.contract_ids
if new_contracts:
bank_id.write({
'contract_ids': [(4, cont.id) for cont in new_contracts]
})
# 根据银行账号查找承租方信息
bank_id.write({
'contract_ids': [(6, 0, self.contract_ids.ids)]
})
bank_account = self.env['property.bank.line'].search([
('bank', '=', self.bank_id.name),
('tenant_id.name', '!=', False),
])
if bank_account:
# 获取已存在的合同明细行的合同ID
existing_contract_ids = bank_account.tenant_id.property_contract_ids.mapped('lease_contract_id.id')
all_contracts = self.contract_ids | self.bank_id.contract_ids
# 过滤出需要新增的合同(排除已存在的)
new_contracts = all_contracts.filtered(lambda c: c.id not in existing_contract_ids)
for contract in new_contracts:
existing_lines = self.env['property.tenant.line'].search([
('tenant_id', '=', bank_account.tenant_id.id)
])
if existing_lines:
existing_lines.unlink()
all_contracts = self.contract_ids
for contract in all_contracts:
self.env['property.tenant.line'].sudo().create({
'tenant_id': bank_account.tenant_id.id,
'lease_contract_id': contract.id,
@@ -9,9 +9,9 @@
<group>
<field name="bank_id" invisible="1"/>
<field name="available_property_ids" widget="many2many_tags" invisible="1"/>
<field name="available_contract_ids" widget="many2many_tags" invisible="1"/>
<field name="lessee_ids" widget="many2many_tags"/>
<field name="property_ids" widget="many2many_tags" domain="[('id', 'in', available_property_ids)]" options="{'no_create': True}"/>
<field name="contract_ids" widget="many2many_tags" domain="[('id', 'in', available_contract_ids)]" options="{'no_create': True}"/>
<field name="contract_ids" widget="many2many_tags" domain="[('lessee_id', 'in', lessee_ids)]" options="{'no_create': True}"/>
</group>
</sheet>
<footer>
@@ -75,7 +75,10 @@ class PropertyReconciliationWizard(models.Model):
current_contract_ids = rec.contract_ids.ids
to_delete = []
for line in rec.reconciliation_line_ids:
line_contract_id = line.contract_id.id
if hasattr(line.contract_id.id, 'origin'):
line_contract_id = line.contract_id.id.origin
else:
line_contract_id = line.contract_id.id
if line_contract_id not in current_contract_ids:
to_delete.append((2, line.id, 0))
rec.reconciliation_line_ids = to_delete
@@ -107,49 +110,48 @@ class PropertyReconciliationWizard(models.Model):
start_time = self.bank_id.start_time
first_day_of_last_month = (start_time.replace(day=1) - relativedelta(months=1))
last_day_of_last_month = start_time.replace(day=1) - relativedelta(days=1)
contract_receivables = self.env['property.accounts.receivable'].search([
('contract_id', '=', contract_id.id.origin),
contract_receivables_ids = self.env['property.accounts.receivable'].search([
('contract_id', '=', '租(2024)100号'),
('is_reconciliation', '=', False),
('is_invalid', '=', False),
('due_date', '>=', first_day_of_last_month.strftime('%Y-%m-%d')),
('due_date', '<=', last_day_of_last_month.strftime('%Y-%m-%d')),
('management_type_id.name', '!=', '违约金')
], limit=1)
if contract_receivables:
# 计算应收日期的下月1号
next_month_first = (fields.Date.from_string(contract_receivables.due_date) +
relativedelta(months=1)).replace(day=1)
# 检查是否产生违约
if fields.Date.from_string(self.actual_date) > next_month_first and contract_receivables.original_amount != contract_receivables.delivered1:
# 计算违约天数和违约金
late_days = (fields.Date.from_string(self.actual_date) - next_month_first).days + 1
# 找到符合月份的租金
penalty_amount = late_days * round(
contract_receivables.submitted * float(contract_id.percentage_liquidated_damages.name), 2
)
start_date_str = fields.Date.to_string(next_month_first)
end_date_str = self.actual_date
# 处理新产生的违约金
if penalty_amount > 0:
actual_date_obj = fields.Date.from_string(self.actual_date)
actual_year_month = (actual_date_obj.year, actual_date_obj.month)
exists = any(
# 提取合同违约金记录的年月并比较
(fields.Date.from_string(p['due_date']).year,
fields.Date.from_string(p['due_date']).month) == actual_year_month
and p['contract_id'] == contract_id.id
for p in contract_penalties
])
for contract_receivables in contract_receivables_ids:
if contract_receivables:
# 计算应收日期的下月1号
next_month_first = (fields.Date.from_string(contract_receivables.due_date) +
relativedelta(months=1)).replace(day=1)
# 检查是否产生违约
if fields.Date.from_string(self.actual_date) > next_month_first and contract_receivables.original_amount != contract_receivables.delivered1:
# 计算违约天数和违约金
late_days = (fields.Date.from_string(self.actual_date) - next_month_first).days + 1
# 找到符合月份的租金
penalty_amount = late_days * round(
contract_receivables.submitted * float(contract_id.percentage_liquidated_damages.name), 2
)
if not exists:
contract_penalties.append({
'contract_id': contract_id.id,
'rent_month': 0,
'due_date': self.actual_date,
'rent': penalty_amount,
'amount': 0,
'collection_type': 'penalty',
'remake': f'违约金({start_date_str}至{end_date_str},共{late_days}天)',
})
start_date_str = fields.Date.to_string(next_month_first)
end_date_str = self.actual_date
# 处理新产生的违约金
if penalty_amount > 0:
actual_date_obj = fields.Date.from_string(self.actual_date)
actual_year_month = (actual_date_obj.year, actual_date_obj.month)
exists = any(
# 提取合同违约金记录的年月并比较
(fields.Date.from_string(p['due_date']).year,
fields.Date.from_string(p['due_date']).month) == actual_year_month
and p['contract_id'] == contract_id.id
for p in contract_penalties
)
if not exists:
contract_penalties.append({
'contract_id': contract_id.id,
'rent_month': 0,
'due_date': self.actual_date,
'rent': penalty_amount,
'amount': 0,
'collection_type': 'penalty',
'remake': f'违约金({start_date_str}至{end_date_str},共{late_days}天)',
})
# 查找应收是否有未交全的租金
unpaid_rent_recs = self.env['property.accounts.receivable'].search([
@@ -195,9 +197,6 @@ class PropertyReconciliationWizard(models.Model):
total = sum(line.rent for line in self.reconciliation_line_ids)
self.receivable_total = total
self.create_reconciliation_vals()
all_due_dates = []
for line in self.reconciliation_line_ids:
if line.collection_type == 'rent' and line.due_date:
@@ -461,8 +460,21 @@ class PropertyReconciliationWizard(models.Model):
'is_penalty': False,
'amount': line.amount,
})
management_type_id = self.env['yuthon.management.type'].search([('name', '=', '违约金')])
if line.collection_type == 'penalty':
penalty_date = line.due_date
first_day_of_last_month = (penalty_date.replace(day=1) - relativedelta(days=1)).replace(day=1)
# 上个月最后一天:当前月第一天减1天
last_day_of_last_month = penalty_date.replace(day=1) - relativedelta(days=1)
is_create = self.env['property.reconciliation.line'].search([
('reconciliation_id', '=', self.id),
('contract_id', '=', line.contract_id.id ),
('due_date', '>=', first_day_of_last_month),
('due_date', '<=', last_day_of_last_month),
('collection_type', '!=', 'penalty'),
('amount', '>', 0)
])
# 用备注的的开始日期和结束日期
date_pattern = r'(\d{4}-\d{2}-\d{2})[至-](\d{4}-\d{2}-\d{2})'
date_match = re.search(date_pattern, line.remake or '')
@@ -477,7 +489,7 @@ class PropertyReconciliationWizard(models.Model):
# 检查是否已有相同记录
existing_record = self.env['property.accounts.receivable'].search(check_domain)
is_reconciliation = round(line.amount,2) == round(line.rent, 2)
if not existing_record:
if not existing_record and is_create:
domain2 = [
('due_date', '=', line.due_date),
('contract_id', '=', line.contract_id.id),
@@ -496,7 +508,7 @@ class PropertyReconciliationWizard(models.Model):
'original_amount': line.rent,
'remark': line.remake,
'reconciliation_time': fields.Datetime.now(),
'charging_range': f"{extract_start_date} 到 {extract_end_date}",
'charging_range': f"{extract_start_date} 到 {extract_end_date}共{(extract_end_date - extract_start_date).days + 1}"
})
else:
existing_record.write({
@@ -9,7 +9,7 @@
<div class="oe_title">
<label for="actual_date"/>
<h1>
<field name="actual_date" style="font-weight: bold; color: #000000;" readonly="1"/>
<field name="actual_date" style="font-weight: bold; color: #000000;" readonly="1" force_save="1"/>
</h1>
</div>
<group>