diff --git a/yuthon_property_approval/models/inherit_yuthon_property.py b/yuthon_property_approval/models/inherit_yuthon_property.py
index e7a5935b3..32994dfd7 100644
--- a/yuthon_property_approval/models/inherit_yuthon_property.py
+++ b/yuthon_property_approval/models/inherit_yuthon_property.py
@@ -342,7 +342,6 @@ class PropertyBankStatements(models.Model):
def _get_reconciliation_vals(self, record):
if record.name:
- dt = datetime.strptime(str(self.start_time), '%Y-%m-%d %H:%M:%S').date()
total_rent_month = 0
# 应收租金
rent_ids = self.env['property.accounts.receivable'].search([
@@ -366,6 +365,21 @@ class PropertyBankStatements(models.Model):
('management_type_id.name', '=', '管理费'),
('is_reconciliation', '=', False),
])
+ # 应收灯箱
+ lightbox_ids = self.env['property.accounts.receivable'].search([
+ ('contract_id', 'in', record.contract_ids.ids),
+ ('contract_id.lessor_id.referred', '=', self.your_own_unit),
+ ('management_type_id.name', '=', '灯箱'),
+ ('is_reconciliation', '=', False),
+ ])
+ # 应收管子间
+ guanzi_ids = self.env['property.accounts.receivable'].search([
+ ('contract_id', 'in', record.contract_ids.ids),
+ ('contract_id.lessor_id.referred', '=', self.your_own_unit),
+ ('management_type_id.name', '=', '管子间'),
+ ('is_reconciliation', '=', False),
+ ])
+
# 应收水费
water_ids = self.env['property.accounts.receivable'].search([
('contract_id', 'in', record.contract_ids.ids),
@@ -447,11 +461,15 @@ class PropertyBankStatements(models.Model):
rent_vals, next_seq = create_reconciliation_vals(rent_ids, 'rent', 1)
deposit_vals, next_seq = create_reconciliation_vals(deposit_ids, 'deposit', 100)
management_vals, next_seq = create_reconciliation_vals(management_ids, 'management_fee', 200)
+ lightbox_vals, next_seq = create_reconciliation_vals(lightbox_ids, 'lightbox', 220)
+ guanzi_vals, next_seq = create_reconciliation_vals(guanzi_ids, 'guanzijian', 230)
water_vals, next_seq = create_reconciliation_vals(water_ids, 'water_fee', 300)
electricity_vals, next_seq = create_reconciliation_vals(electricity_ids, 'electricity_fee', 400)
all_vals.extend(rent_vals)
all_vals.extend(deposit_vals)
+ all_vals.extend(lightbox_vals)
+ all_vals.extend(guanzi_vals)
all_vals.extend(management_vals)
all_vals.extend(water_vals)
all_vals.extend(electricity_vals)
@@ -598,6 +616,36 @@ class PropertyAccountsReceivable(models.Model):
pre_collection = fields.Float(string="预收金额")
actual_coping = fields.Float(string="实际应付", compute='_compute_actual_coping', store=True)
+ charging_range = fields.Text(string="收费区间")
+
+ def update_charging_range(self):
+ accounts = self.env["property.accounts.receivable"].browse(
+ self._context.get('active_ids', self._context.get('active_id', []))
+ )
+ for account in accounts:
+ type_name = account.management_type_id.name or ""
+ def get_charging_range(start, end):
+ if not start or not end:
+ return "" # 日期不全时返回空
+ return f"{start.strftime('%Y-%m-%d')} 到 {end.strftime('%Y-%m-%d')}"
+
+ # 按类型计算收费区间
+ if type_name == "租金":
+ if account.due_date_end:
+ contract_actual_end = account.contract_id.actual_end_time
+ min_end_date = min(contract_actual_end, account.due_date_end) if contract_actual_end else account.due_date_end
+ account.charging_range = get_charging_range(account.due_date, min_end_date)
+
+ elif type_name == "押金":
+ start_date = account.due_date
+ if start_date:
+ end_date = start_date + relativedelta(months=1)
+ account.charging_range = get_charging_range(start_date, end_date)
+
+ elif type_name == "违约金":
+ if account.due_date_end:
+ account.charging_range = get_charging_range(account.due_date, account.due_date_end)
+
@api.depends('company_id')
def _compute_company_id2(self):
@@ -1123,11 +1171,48 @@ class PropertyManagementList(models.Model):
)
if not management_type_id:
management_type_id = self.env['yuthon.management.type'].create({'name': target_name})
+
+ due_date = rec.due_date
+ due_date_end = False
+ theoretical_end = False
+ contract = rec.contract_id
+ if contract and contract.cycle_mode and due_date:
+ due_date_obj = fields.Date.from_string(due_date)
+ contract_actual_end = fields.Date.from_string(
+ contract.actual_end_time) if contract.actual_end_time else None
+ # 处理合同月
+ if contract.cycle_mode == 'fixed_monthly':
+ # 计算理论应收结束日(当月最后一天)
+ next_month_first = (due_date_obj + relativedelta(months=1))
+ theoretical_end = next_month_first - timedelta(days=1)
+ # 处理自然月
+ elif contract.cycle_mode == 'floating_monthly':
+ breakdown_line = self.env['property.rent.breakdown.line'].search([
+ ('breakdown_id', '=', contract.id),
+ ('start_data', '<=', due_date),
+ ('end_data', '>=', due_date)
+ ], limit=1)
+ if breakdown_line:
+ start_data_obj = fields.Date.from_string(breakdown_line.start_data)
+ if not (due_date_obj.year == start_data_obj.year and
+ due_date_obj.month == start_data_obj.month):
+ due_date = fields.Date.to_string(due_date_obj.replace(day=1))
+ due_date_obj = fields.Date.from_string(due_date)
+
+ last_day = calendar.monthrange(due_date_obj.year, due_date_obj.month)[1]
+ theoretical_end = date(due_date_obj.year, due_date_obj.month, last_day)
+
+ if contract_actual_end:
+ due_date_end = fields.Date.to_string(min(theoretical_end, contract_actual_end))
+ else:
+ due_date_end = fields.Date.to_string(theoretical_end)
+
self.env['property.accounts.receivable'].create({
'contract_id': rec.contract_id.id,
'lessee_id': rec.contract_id.lessee_id.id if rec.contract_id.lessee_id else None,
'original_amount': rec.original_amount,
'due_date': rec.due_date,
+ 'due_date_end': due_date_end,
'create_time': datetime.now(),
'management_type_id': management_type_id.id,
})
diff --git a/yuthon_property_approval/views/inherit_yuthon_property_views.xml b/yuthon_property_approval/views/inherit_yuthon_property_views.xml
index 159e3f57a..086b1a765 100644
--- a/yuthon_property_approval/views/inherit_yuthon_property_views.xml
+++ b/yuthon_property_approval/views/inherit_yuthon_property_views.xml
@@ -405,6 +405,9 @@
+
+
+
diff --git a/yuthon_property_approval/wizard/property_reconciliation_wizard.py b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
index 9dfd1636b..0b09e5bb5 100644
--- a/yuthon_property_approval/wizard/property_reconciliation_wizard.py
+++ b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
@@ -366,6 +366,8 @@ class PropertyReconciliationWizard(models.Model):
collection_type_mapping = {
'deposit': '押金',
'rent': '租金',
+ 'lightbox': '灯箱',
+ 'guanzijian': '管子间',
'water_fee': '水费',
'electricity_fee': '电费',
'penalty': '违约金',
@@ -430,6 +432,27 @@ class PropertyReconciliationWizard(models.Model):
domain.append(('contract_id', '=', line.contract_id.id))
receivable_ids = self.env['property.accounts.receivable'].search(domain)
for receivable in receivable_ids:
+ charging_range = receivable.charging_range
+ type_name = receivable.management_type_id.name or ""
+ if receivable.due_date_end:
+ def get_range(start, end):
+ if start and end:
+ return f"{start.strftime('%Y-%m-%d')} 到 {end.strftime('%Y-%m-%d')}"
+ return ""
+ if type_name in ["租金", "管理费", '灯箱', '管子间']:
+ contract_actual_end = receivable.contract_id.actual_end_time
+ min_end = min(contract_actual_end, receivable.due_date_end) if contract_actual_end else receivable.due_date_end
+ charging_range = get_range(receivable.due_date, min_end)
+ elif type_name == "押金":
+ if receivable.due_date:
+ end_date = receivable.due_date + relativedelta(months=1)
+ charging_range = get_range(receivable.due_date, end_date)
+ elif type_name in ["水费", "电费"]:
+ if receivable.due_date:
+ start_date = (receivable.due_date - relativedelta(months=2)).replace(day=16)
+ end_date = (start_date + relativedelta(months=1)).replace(day=15)
+ charging_range = get_range(start_date, end_date)
+
if line.rent == line.amount:
is_reconciliation = True
else:
@@ -440,13 +463,16 @@ class PropertyReconciliationWizard(models.Model):
final_remark = line.remake
if line.collection_type != 'penalty':
receivable.delivered1 = receivable.delivered1 + line.amount
- receivable.write({
+ write_vals = {
'is_reconciliation': is_reconciliation,
'payout_date': rec.actual_date,
'remark': final_remark,
'reconciliation_time': fields.Datetime.now(),
'receivable_log': f'当前登录人{rec.env.user.name}于{fields.Datetime.now()}对户名为{rec.bank_id.name_account}进行对账操作,对账应收金额为{rec.receivable_total},实际金额为{rec.amount_water}'
- })
+ }
+ if charging_range:
+ write_vals['charging_range'] = charging_range
+ receivable.write(write_vals)
self.env['receivable.modify.line'].create({
'bank_id': rec.bank_id.id,
'not_collected': line.rent,
@@ -489,6 +515,7 @@ class PropertyReconciliationWizard(models.Model):
'payout_date': rec.actual_date if (line.rent == line.amount and line.rent != 0) else None,
'original_amount': line.rent,
'remark': line.remake,
+ 'charging_range': f"{extract_start_date.strftime('%Y-%m-%d')} 到 {extract_end_date.strftime('%Y-%m-%d')}",
'reconciliation_time': fields.Datetime.now(),
})
else:
@@ -542,6 +569,7 @@ class PropertyReconciliationWizard(models.Model):
rec.contract_ids = [(6, 0, remaining_contract_ids)]
rec.contract_ids1 = [(6, 0, removed_contract_ids)]
+
class PropertyReconciliationLine(models.Model):
_name = 'property.reconciliation.line'
_description = '对账明细'
@@ -556,7 +584,7 @@ class PropertyReconciliationLine(models.Model):
due_date = fields.Date(string='应收日期')
rent = fields.Float(string='未收')
amount = fields.Float(string='金额', store=True)
- collection_type = fields.Selection([('deposit', '押金'), ('rent', '租金'), ('water_fee', '水费'),
+ collection_type = fields.Selection([('deposit', '押金'), ('rent', '租金'), ('water_fee', '水费'), ('lightbox', '灯箱'), ('guanzijian', '管子间'),
('electricity_fee', '电费'), ('penalty', '违约金'), ('management_fee', '管理费'), ('repair_fee', '维修费'),
('other', '其他')], string='收款类型', store=True)
remake = fields.Text(string='备注')