From 4fc7a00d1018dbdb035aa0ea86b33ea82ef9c8bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Mon, 20 Oct 2025 14:35:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/overtime_approval.py | 2 + .../views/overtime_approval.xml | 9 ++++ .../models/property_meter_archives.py | 1 + .../models/property_meter_water.py | 1 + yuthon_property/models/yuthon_property.py | 15 +++++- .../views/property_meter_archives_views.xml | 7 +++ .../views/property_meter_water_views.xml | 7 +++ .../wizard/electric_water_wizard.py | 12 +++++ yuthon_property/wizard/task_push_wizard.py | 38 ++++++++------- .../models/inherit_yuthon_property.py | 48 ++++++++++--------- .../models/property_lease_contract.py | 48 ++++++++++++++----- .../views/inherit_yuthon_property_views.xml | 5 +- .../views/property_lease_contract.xml | 3 +- 13 files changed, 139 insertions(+), 57 deletions(-) diff --git a/yuthon_hr_attendance/models/overtime_approval.py b/yuthon_hr_attendance/models/overtime_approval.py index 240b8f44c..eccd2eb46 100644 --- a/yuthon_hr_attendance/models/overtime_approval.py +++ b/yuthon_hr_attendance/models/overtime_approval.py @@ -34,6 +34,8 @@ class OvertimeApprovals(models.Model): attendance_id = fields.Many2one('hr.attendance', string="当天考勤") start_week = fields.Char(string="星期", compute='_compute_weekday') end_time = fields.Datetime(string="结束时间") + rest_start_time = fields.Datetime(string="开始时间") + rest_end_time = fields.Datetime(string="结束时间") end_week = fields.Char(string="星期", compute='_compute_weekday') type_overtime = fields.Selection([('work', '工作日加班'), ('weekend', '周末加班'), ('holiday', '节假日加班')], string="加班类型", compute="_compute_overtime_type", store=True) diff --git a/yuthon_hr_attendance/views/overtime_approval.xml b/yuthon_hr_attendance/views/overtime_approval.xml index 1adbbd00c..c9a9a7a1f 100644 --- a/yuthon_hr_attendance/views/overtime_approval.xml +++ b/yuthon_hr_attendance/views/overtime_approval.xml @@ -84,6 +84,15 @@ + + + + + + + + + diff --git a/yuthon_property/models/property_meter_archives.py b/yuthon_property/models/property_meter_archives.py index 5e1cf647d..4849e6615 100644 --- a/yuthon_property/models/property_meter_archives.py +++ b/yuthon_property/models/property_meter_archives.py @@ -33,6 +33,7 @@ class PropertyMeterArchives(models.Model): yuthon_property_ids = fields.Many2many("yuthon.property", string="物业信息") line_ids = fields.One2many("meter.archives.line", "archives_id", string="明细行") remarks = fields.Text(string="备注") + fixed_receivables = fields.Float(string="固定应收", digits=(16, 4)) state = fields.Selection([("reading", "已抄"), ("unreading", "未抄")], string="抄表状态", default="unreading") # 一次性更改仪表位置 diff --git a/yuthon_property/models/property_meter_water.py b/yuthon_property/models/property_meter_water.py index 2131595fd..cf9af1037 100644 --- a/yuthon_property/models/property_meter_water.py +++ b/yuthon_property/models/property_meter_water.py @@ -45,6 +45,7 @@ class PropertyMeterWater(models.Model): ) standards_id = fields.Many2one("yuthon.electricity.setting", string="标准") yuthon_property_ids = fields.Many2many("yuthon.property", string="物业信息") + fixed_receivables = fields.Float(string="固定应收", digits=(16, 4)) line_ids = fields.One2many("meter.water.line", "water_id", string="水表明细行") state = fields.Selection( [("reading", "已抄"), ("unreading", "未抄")], diff --git a/yuthon_property/models/yuthon_property.py b/yuthon_property/models/yuthon_property.py index c1987c3c3..774289a5a 100644 --- a/yuthon_property/models/yuthon_property.py +++ b/yuthon_property/models/yuthon_property.py @@ -594,8 +594,13 @@ class YuthonPropertyWater(models.Model): "target": "new" } - # 补充删除取消关联的逻辑 def unlink(self): + for record in self: + if record.property_meter_water_id and record.yuthon_property_id: + if record.yuthon_property_id in record.property_meter_water_id.yuthon_property_ids: + record.property_meter_water_id.write({ + 'yuthon_property_ids': [(3, record.yuthon_property_id.id)] + }) return super().unlink() @@ -611,7 +616,7 @@ class YuthonPropertyEnergy(models.Model): epitope_values_id = fields.Many2one(related='property_meter_archives_id.epitope_values_id', string="位置") yuthon_property_id = fields.Many2one('yuthon.property', string="物业管理") - # 水表跳转 + # 电表跳转 def detail(self): return { "type": "ir.actions.act_window", @@ -624,6 +629,12 @@ class YuthonPropertyEnergy(models.Model): # 补充删除取消关联的逻辑 def unlink(self): + for record in self: + if record.property_meter_archives_id and record.yuthon_property_id: + if record.yuthon_property_id in record.property_meter_archives_id.yuthon_property_ids: + record.property_meter_archives_id.write({ + 'yuthon_property_ids': [(3, record.yuthon_property_id.id)] + }) return super().unlink() diff --git a/yuthon_property/views/property_meter_archives_views.xml b/yuthon_property/views/property_meter_archives_views.xml index 630d26b01..4aa01127b 100644 --- a/yuthon_property/views/property_meter_archives_views.xml +++ b/yuthon_property/views/property_meter_archives_views.xml @@ -49,6 +49,7 @@ + @@ -137,6 +138,12 @@ + + + + + + diff --git a/yuthon_property/views/property_meter_water_views.xml b/yuthon_property/views/property_meter_water_views.xml index a476dbbba..535bb8e9f 100644 --- a/yuthon_property/views/property_meter_water_views.xml +++ b/yuthon_property/views/property_meter_water_views.xml @@ -54,6 +54,7 @@ + @@ -145,6 +146,12 @@ + + + + + + diff --git a/yuthon_property/wizard/electric_water_wizard.py b/yuthon_property/wizard/electric_water_wizard.py index e7a7ba174..4d6f32783 100644 --- a/yuthon_property/wizard/electric_water_wizard.py +++ b/yuthon_property/wizard/electric_water_wizard.py @@ -20,6 +20,11 @@ class ElectricWaterWizard(models.TransientModel): if meter.end_time: if meter.end_time and meter.end_time < self.push_date: continue + first_property = meter.yuthon_property_ids[0] + contract_line = self.env['property.lease.contract.line'].search([ + ('address_id', '=', first_property.id), + ('lease_id.contact_state', '=', 'ing') + ], limit=1) # 查找上个月的记录 # 查找上个月的记录,上次用量,上次读数,上次抄表日期 last_month_line = meter.line_ids.search([('meter_date', '<', self.push_date)]).sorted('meter_date')[-1] @@ -43,6 +48,7 @@ class ElectricWaterWizard(models.TransientModel): 'type': meter.type, 'archives_state': meter.archives_state, 'maximum_count': meter.maximum_count, + 'contract_id': contract_line.lease_id if contract_line else False, }) # 处理水表推送 @@ -54,6 +60,11 @@ class ElectricWaterWizard(models.TransientModel): if water.end_time: if water.end_time and water.end_time < self.push_date: continue + first_property = water.yuthon_property_ids[0] + contract_line = self.env['property.lease.contract.line'].search([ + ('address_id', '=', first_property.id), + ('lease_id.contact_state', '=', 'ing') + ], limit=1) # 查找上个月的记录,上次用量,上次读数,上次抄表日期 last_month_line = water.line_ids.search([('meter_date', '<', self.push_date)]).sorted('meter_date')[-1] # 如果当前数据不存在,则新建任务,按照天的纬度 @@ -75,4 +86,5 @@ class ElectricWaterWizard(models.TransientModel): 'type': water.type, 'water_state': water.water_state, 'maximum_count': water.maximum_count, + 'contract_id': contract_line.lease_id if contract_line else False, }) diff --git a/yuthon_property/wizard/task_push_wizard.py b/yuthon_property/wizard/task_push_wizard.py index ed96e48bb..370dd45ed 100644 --- a/yuthon_property/wizard/task_push_wizard.py +++ b/yuthon_property/wizard/task_push_wizard.py @@ -20,24 +20,26 @@ class TaskPushWizard(models.TransientModel): if self.meter_ids: management_type_id = self.env['yuthon.management.type'].search([('name', '=', '电费')], limit=1) for meter in self.meter_ids: - self.env['property.accounts.receivable'].create({ - 'contract_id': meter.contract_id.id, - 'lessee_id': meter.lessee_id.id if meter.lessee_id else None, - 'original_amount': meter.receivables, - 'due_date': self.push_date, - 'create_time': datetime.now(), - 'management_type_id': management_type_id.id, - }) - meter.is_push = True + if meter.unit and meter.contract_id: + self.env['property.accounts.receivable'].create({ + 'contract_id': meter.contract_id.id, + 'lessee_id': meter.lessee_id.id if meter.lessee_id else None, + 'original_amount': meter.archives_id.fixed_receivables if meter.archives_id.fixed_receivables else meter.receivables, + 'due_date': self.push_date, + 'create_time': datetime.now(), + 'management_type_id': management_type_id.id, + }) + meter.is_push = True if self.water_ids: management_type_id = self.env['yuthon.management.type'].search([('name', '=', '水费')], limit=1) for water in self.water_ids: - self.env['property.accounts.receivable'].create({ - 'contract_id': water.contract_id.id, - 'lessee_id': water.lessee_id.id if water.lessee_id else None, - 'original_amount': water.receivables, - 'due_date': self.push_date, - 'create_time': datetime.now(), - 'management_type_id': management_type_id.id, - }) - water.is_push = True + if water.unit and water.contract_id: + self.env['property.accounts.receivable'].create({ + 'contract_id': water.contract_id.id, + 'lessee_id': water.lessee_id.id if water.lessee_id else None, + 'original_amount': water.water_id.fixed_receivables if water.water_id.fixed_receivables else water.receivables, + 'due_date': self.push_date, + 'create_time': datetime.now(), + 'management_type_id': management_type_id.id, + }) + water.is_push = True diff --git a/yuthon_property_approval/models/inherit_yuthon_property.py b/yuthon_property_approval/models/inherit_yuthon_property.py index 550d4bc8f..2e4d94e9a 100644 --- a/yuthon_property_approval/models/inherit_yuthon_property.py +++ b/yuthon_property_approval/models/inherit_yuthon_property.py @@ -47,7 +47,7 @@ class PropertyMeterArchives(models.Model): class MeterArchivesLine(models.Model): _inherit = 'meter.archives.line' - contract_id = fields.Many2one('property.lease.contract', string="合同", compute="compute_contract_id") + contract_id = fields.Many2one('property.lease.contract', string="合同") lessee_id = fields.Many2one(related="contract_id.lessee_id", string="承租方") contract_name = fields.Char(string='合同名称', store=True, index=True, compute="_compute_name") lessee_name = fields.Char(string='承租方名称', store=True, index=True, compute="_compute_name") @@ -60,23 +60,24 @@ class MeterArchivesLine(models.Model): if name.lessee_id: name.lessee_name = name.lessee_id.name - @api.depends('yuthon_property_ids') - def compute_contract_id(self): - for record in self: + def update_contract(self): + archives_ids = self.env["meter.archives.line"].browse( + self._context.get('active_ids', self._context.get('active_id'))) + for record in archives_ids: if record.yuthon_property_ids: - lease_contract = self.env['property.lease.contract.line'].search([('address_id', '=', record.yuthon_property_ids[0].id)], limit=1) - if lease_contract: - record.contract_id = lease_contract.lease_id.id - else: - record.contract_id = False - else: - record.contract_id = False + contract_line = self.env['property.lease.contract.line'].search([ + ('address_id', '=', record.yuthon_property_ids[0].id), + ('lease_id.actual_start_time', '<=', record.meter_date), + ('lease_id.actual_end_time', '>=', record.meter_date) + ], limit=1) + if contract_line: + record.contract_id = contract_line.lease_id.id class MeterWaterLine(models.Model): _inherit = 'meter.water.line' - contract_id = fields.Many2one('property.lease.contract', string="合同", compute="compute_contract_id") + contract_id = fields.Many2one('property.lease.contract', string="合同") lessee_id = fields.Many2one(related="contract_id.lessee_id", string="承租方") contract_name = fields.Char(string='合同名称', store=True, index=True, compute="_compute_name") lessee_name = fields.Char(string='承租方名称', store=True, index=True, compute="_compute_name") @@ -89,18 +90,19 @@ class MeterWaterLine(models.Model): if name.lessee_id: name.lessee_name = name.lessee_id.name - @api.depends('yuthon_property_ids') - def compute_contract_id(self): - for record in self: + def update_contract(self): + water_ids = self.env["meter.water.line"].browse( + self._context.get('active_ids', self._context.get('active_id'))) + for record in water_ids: if record.yuthon_property_ids: - lease_contract = self.env['property.lease.contract.line'].search( - [('address_id', '=', record.yuthon_property_ids[0].id)], limit=1) - if lease_contract: - record.contract_id = lease_contract.lease_id.id - else: - record.contract_id = False - else: - record.contract_id = False + contract_line = self.env['property.lease.contract.line'].search([ + ('address_id', '=', record.yuthon_property_ids[0].id), + ('lease_id.actual_start_time', '<=',record.meter_date), + ('lease_id.actual_end_time', '>=',record.meter_date) + ], limit=1) + if contract_line: + record.contract_id = contract_line.lease_id.id + class YuthonProperty(models.Model): _inherit = 'yuthon.property' diff --git a/yuthon_property_approval/models/property_lease_contract.py b/yuthon_property_approval/models/property_lease_contract.py index 814aa13a4..fafacac13 100644 --- a/yuthon_property_approval/models/property_lease_contract.py +++ b/yuthon_property_approval/models/property_lease_contract.py @@ -127,7 +127,7 @@ class PropertyLeaseContract(models.Model): return default_rate.id if default_rate else False percentage_liquidated_damages = fields.Many2one('yuthon.penalty.setting', string="违约金比例", default=_get_percentage_liquidated_damages) - percentage_damages= fields.Float(string="违约金") + percentage_damages= fields.Float(string="违约金", compute="_compute_contract_count") date_of_payment = fields.Selection([('five', '5'), ('fifteen', '15'), ('twenty', '20'), ('twentyfive', '25')], string="支付日期") first_pay = fields.Date(string="首次付款日") unit_price = fields.Float(string="单价", store=True, digits=(16, 4)) @@ -156,7 +156,7 @@ class PropertyLeaseContract(models.Model): ele_price = fields.Float(string="电费单价") number = fields.Integer(string="次数", default=0) total_area = fields.Float(string="总面积", digits=(16, 4)) - not_received = fields.Float(string="未收", compute="_compute_not_received", store=True) + not_received = fields.Float(string="未收", compute="_compute_contract_count") actual_receivable = fields.Float(string="实际应收") now_receivable = fields.Float(string="当期应收") total_receivable = fields.Float(string="总已收") @@ -249,7 +249,7 @@ class PropertyLeaseContract(models.Model): contract_count = fields.Integer(string="联系人数量", compute='_compute_contract_count') reconciliation_count = fields.Integer(string="对账数量", compute='_compute_reconciliation_count') process_count = fields.Integer(string="流程数量", compute='_compute_process_count') - + is_overdue = fields.Boolean(string="是否逾期", compute='_compute_contract_count', store=True) is_issues = fields.Boolean(string='是否上会') issues_result = fields.Html(string="会议结果") related_issues_id = fields.Many2one('issue.library', string="关联议题") @@ -307,7 +307,40 @@ class PropertyLeaseContract(models.Model): def _compute_contract_count(self): for record in self: + current_date = datetime.now() + current_month_start = datetime(current_date.year, current_date.month, 1) + if current_date.month == 12: + next_month = 1 + next_year = current_date.year + 1 + else: + next_month = current_date.month + 1 + next_year = current_date.year + current_month_end = datetime(next_year, next_month, 1) - timedelta(days=1) record.contract_count = self.env['property.accounts.receivable'].search_count([('contract_id', '=', record.id)]) + overdue_domain = [ + ('contract_id', '=', record.id), + ('due_date', '<', current_month_start), + ('submitted', '!=', 0) + ] + has_overdue = self.env['property.accounts.receivable'].search_count(overdue_domain) > 0 + record.is_overdue = has_overdue + not_received_domain = [ + ('contract_id', '=', record.id), + ('submitted', '!=', 0), + ('due_date', '<=', current_month_end), + ('management_type_id.name', '!=', '违约金') + ] + receivable_records = self.env['property.accounts.receivable'].search(not_received_domain) + record.not_received = sum(receivable_records.mapped('submitted')) + + percentage_damages_domain = [ + ('contract_id', '=', record.id), + ('submitted', '!=', 0), + ('management_type_id.name', '=', '违约金'), + ('due_date', '<=', current_month_end), + ] + receivable_records = self.env['property.accounts.receivable'].search(percentage_damages_domain) + record.percentage_damages = sum(receivable_records.mapped('submitted')) def _compute_reconciliation_count(self): for record in self: @@ -339,15 +372,6 @@ class PropertyLeaseContract(models.Model): action.update({'domain': [('code', '=', self.code)]}) return action - - @api.depends() - def _compute_not_received(self): - not_reconciled_records = self.env['property.accounts.receivable'].search([ - ('contract_id', '=', self.id), - ('is_reconciliation', '=', False) - ]) - self.not_received = sum(record.submitted for record in not_reconciled_records) - def update_contract(self): contract_ids = self.env["property.lease.contract"].browse( self._context.get('active_ids', self._context.get('active_id'))) diff --git a/yuthon_property_approval/views/inherit_yuthon_property_views.xml b/yuthon_property_approval/views/inherit_yuthon_property_views.xml index 5edc0f17c..3ba7c6723 100644 --- a/yuthon_property_approval/views/inherit_yuthon_property_views.xml +++ b/yuthon_property_approval/views/inherit_yuthon_property_views.xml @@ -643,7 +643,10 @@ property.bank.statements - + + diff --git a/yuthon_property_approval/views/property_lease_contract.xml b/yuthon_property_approval/views/property_lease_contract.xml index b44adcba8..e0ab4ceb1 100644 --- a/yuthon_property_approval/views/property_lease_contract.xml +++ b/yuthon_property_approval/views/property_lease_contract.xml @@ -425,7 +425,7 @@