!5260 添加功能

Merge pull request !5260 from 李鹏宇/zhou
This commit is contained in:
李鹏宇
2025-09-20 10:07:00 +00:00
committed by Gitee
8 changed files with 290 additions and 133 deletions
@@ -168,12 +168,12 @@ class MeterArchivesLine(models.Model):
archives_id = fields.Many2one('property.meter.archives', string='电表库', required=True, ondelete='cascade')
name = fields.Char(string='仪表编号')
epitope_values = fields.Char(string='表位置')
lessee_id = fields.Many2one('property.tenant.information', string='承租方')
lessee_id = fields.Many2one('property.tenant.information', string='承租方', compute='_compute_lessee_id')
yuthon_property_ids = fields.Many2many('yuthon.property', string='物业信息')
last_meter = fields.Date(string='上次抄表日期')
last_dosage = fields.Float(string='上次用量')
last_dosage = fields.Float(string='上次用量', compute="_compute_last_dosage")
last_read = fields.Float(string='上次读数', readonly=True)
current_meter = fields.Float(string='本次用量', readonly=True)
current_meter = fields.Float(string='本次用量', readonly=True, compute='_compute_current_meter')
current_read = fields.Float(string='本次读数')
unit_number = fields.Char(string='单元编号/用途')
gauge_magnification = fields.Integer(string='仪表倍率', readonly=True, default=1)
@@ -186,6 +186,39 @@ class MeterArchivesLine(models.Model):
default='use')
maximum_count = fields.Integer(string='最大位数')
@api.depends('current_read', 'last_read')
def _compute_current_meter(self):
for record in self:
record.current_meter = record.current_read - record.last_read
@api.depends('yuthon_property_ids')
def _compute_lessee_id(self):
for record in self:
if record.yuthon_property_ids:
record.lessee_id = record.yuthon_property_ids[0].lessee_id
else:
record.lessee_id = False
@api.depends('current_read', 'last_read')
def _compute_last_dosage(self):
"""上次用量 = 上个月的本次读数 - 上个月的上次读数"""
for line in self:
# 获取同仪表的所有明细行并按抄表日期排序
lines = self.search([
('archives_id', '=', line.archives_id.id),
('last_meter', '!=', False)
], order='last_meter asc')
if line in lines:
idx = lines.ids.index(line.id)
if idx > 0:
prev_line = lines[idx - 1]
line.last_dosage = (prev_line.current_read or 0) - (prev_line.last_read or 0)
else:
line.last_dosage = 0.0
else:
# 当前记录没有抄表日期,无法计算上次用量
line.last_dosage = 0.0
class PropertyElectricReading(models.Model):
_name = 'property.electric.reading'
+36 -3
View File
@@ -158,12 +158,12 @@ class MeterWaterLine(models.Model):
water_id = fields.Many2one('property.meter.water', string='水表库', required=True, ondelete='cascade')
name = fields.Char(string='仪表编号')
epitope_values = fields.Char(string='表位置')
lessee_id = fields.Many2one('property.tenant.information', string='承租方')
lessee_id = fields.Many2one('property.tenant.information', string='承租方', compute='_compute_lessee_id')
yuthon_property_ids = fields.Many2many('yuthon.property', string='物业信息')
last_meter = fields.Date(string='上次抄表日期')
last_dosage = fields.Float(string='上次用量')
last_dosage = fields.Float(string='上次用量', compute="_compute_last_dosage")
last_read = fields.Float(string='上次读数', readonly=True)
current_meter = fields.Float(string='本次用量', readonly=True)
current_meter = fields.Float(string='本次用量', readonly=True, compute='_compute_current_meter')
current_read = fields.Float(string='本次读数')
unit_number = fields.Char(string='单元编号/用途')
gauge_magnification = fields.Integer(string='仪表倍率', readonly=True, default=1)
@@ -176,6 +176,39 @@ class MeterWaterLine(models.Model):
employee_ids = fields.Many2many('hr.employee', string='抄表人')
maximum_count = fields.Integer(string='最大位数')
@api.depends('current_read', 'last_read')
def _compute_current_meter(self):
for record in self:
record.current_meter = record.current_read - record.last_read
@api.depends('yuthon_property_ids')
def _compute_lessee_id(self):
for record in self:
if record.yuthon_property_ids:
record.lessee_id = record.yuthon_property_ids[0].lessee_id
else:
record.lessee_id = False
@api.depends('current_read', 'last_read')
def _compute_last_dosage(self):
"""上次用量 = 上个月的本次读数 - 上个月的上次读数"""
for line in self:
# 获取同仪表的所有明细行并按抄表日期排序
lines = self.search([
('archives_id', '=', line.archives_id.id),
('last_meter', '!=', False)
], order='last_meter asc')
if line in lines:
idx = lines.ids.index(line.id)
if idx > 0:
prev_line = lines[idx - 1]
line.last_dosage = (prev_line.current_read or 0) - (prev_line.last_read or 0)
else:
line.last_dosage = 0.0
else:
# 当前记录没有抄表日期,无法计算上次用量
line.last_dosage = 0.0
class PropertyWaterReading(models.Model):
@@ -13,7 +13,7 @@
</field>
</record>
<record id="view_hydropower_logs_action" model="ir.actions.act_window">
<field name="name">水电单价”</field>
<field name="name">水电单价</field>
<field name="res_model">hydropower.logs</field>
<field name="view_mode">tree</field>
</record>
@@ -15,14 +15,14 @@
<field name="lessee_id" options="{'no_create': True}"/>
<field name="yuthon_property_ids" string="物业信息" widget="many2many_tags"/>
<!-- <field name="meter_date" />-->
<field name="last_meter" />
<field name="last_dosage"/>
<field name="last_read" readonly="1"/>
<field name="current_meter" readonly="1"/>
<field name="current_read"/>
<!-- <field name="last_meter" />-->
<!-- <field name="last_dosage"/>-->
<!-- <field name="last_read" readonly="1"/>-->
<!-- <field name="current_meter" readonly="1"/>-->
<!-- <field name="current_read"/>-->
<field name="unit_number"/>
<field name="gauge_magnification" readonly="1"/>
<field name="last_reading_time"/>
<!-- <field name="last_reading_time"/>-->
<field name="type"/>
<field name="start_time"/>
<field name="end_time"/>
@@ -58,12 +58,12 @@
<field name="yuthon_property_ids" string="物业信息" widget="many2many_tags"/>
</group>
<group>
<field name="last_meter"/>
<field name="last_dosage"/>
<field name="last_read" readonly="1"/>
<field name="current_meter" readonly="1"/>
<field name="current_read"/>
<field name="last_reading_time"/>
<!-- <field name="last_meter"/>-->
<!-- <field name="last_dosage"/>-->
<!-- <field name="last_read" readonly="1"/>-->
<!-- <field name="current_meter" readonly="1"/>-->
<!-- <field name="current_read"/>-->
<!-- <field name="last_reading_time"/>-->
<field name="start_time"/>
<field name="end_time"/>
<field name="archives_state"/>
@@ -16,14 +16,14 @@
<field name="lessee_id" options="{'no_create': True}"/>
<field name="yuthon_property_ids" string="物业信息" widget="many2many_tags"/>
<!-- <field name="meter_date" />-->
<field name="last_meter" />
<field name="last_dosage"/>
<field name="last_read" readonly="1"/>
<field name="current_meter" readonly="1"/>
<field name="current_read"/>
<!-- <field name="last_meter" />-->
<!-- <field name="last_dosage"/>-->
<!-- <field name="last_read" readonly="1"/>-->
<!-- <field name="current_meter" readonly="1"/>-->
<!-- <field name="current_read"/>-->
<field name="unit_number"/>
<field name="gauge_magnification" readonly="1"/>
<field name="last_reading_time"/>
<!-- <field name="last_reading_time"/>-->
<field name="type"/>
<field name="start_time"/>
<field name="end_time"/>
@@ -61,12 +61,12 @@
<field name="yuthon_property_ids" string="物业信息" widget="many2many_tags"/>
</group>
<group>
<field name="last_meter"/>
<field name="last_dosage"/>
<field name="last_read" readonly="1"/>
<field name="current_meter" readonly="1"/>
<field name="current_read"/>
<field name="last_reading_time"/>
<!-- <field name="last_meter"/>-->
<!-- <field name="last_dosage"/>-->
<!-- <field name="last_read" readonly="1"/>-->
<!-- <field name="current_meter" readonly="1"/>-->
<!-- <field name="current_read"/>-->
<!-- <field name="last_reading_time"/>-->
<field name="start_time"/>
<field name="end_time"/>
<field name="water_state"/>
+115 -54
View File
@@ -16,78 +16,139 @@ class PropertyMeterWizard(models.Model):
def confirm(self):
"""
导入excel文件,按行读取数据并处理
导入excel文件,按行读取数据并处理,将1-9月数据写入明细行
"""
if not self.excel_file:
raise ValidationError('请上传文件。')
book = xlrd.open_workbook(file_contents=base64.decodebytes(self.excel_file))
sh = book.sheet_by_index(0)
for rx in range(1, sh.nrows):
# 解码并打开Excel文件
try:
book = xlrd.open_workbook(file_contents=base64.decodebytes(self.excel_file))
sh = book.sheet_by_index(0)
except Exception as e:
raise ValidationError(f'文件解析错误: {str(e)}')
# 按行处理数据
for rx in range(1, sh.nrows): # 跳过表头行
row = sh.row(rx)
last_read = 0
last_read = 0.0 # 初始读数,第一个月的上次读数为0
# 处理1-9月份数据
for month in range(1, 10):
last_read = self.property_meter_data(row, last_read, month)
def property_meter_data(self, row, last_read, month):
epitope_values = row[0].value
name = row[3].value
type_dict = {'水表': 'water', '电表': 'electric', '电表(电子表)': 'smart', '': ''}
unit_number = row[1].value
installation_location = row[2].value
if row[5].value:
gauge_magnification = float(row[5].value)
else:
gauge_magnification = None
maximum_count = float(row[6].value) if row[6].value else None
type_dict = {'公共': 'public', '收费': 'fees', '': ''}
type = type_dict.get(row[7].value)
property_id = None
if row[2].value:
property_search = self.env['yuthon.property'].search([('name', '=', row[2].value)])
if property_search:
property_id = property_search[0]
"""
处理单月数据,查找主记录并创建/更新明细行
"""
# 从Excel行获取基础数据
epitope_values = row[0].value if len(row) > 0 else ''
unit_number = row[1].value if len(row) > 1 else ''
installation_location = row[2].value if len(row) > 2 else ''
name = row[3].value if len(row) > 3 else '' # 仪表编号(关键标识)
# 处理仪表倍率
gauge_magnification = None
if len(row) > 5 and row[5].value:
try:
gauge_magnification = float(row[5].value)
except ValueError:
gauge_magnification = 1 # 默认为1
# 处理最大位数
maximum_count = None
if len(row) > 6 and row[6].value:
try:
maximum_count = float(row[6].value)
except ValueError:
maximum_count = None
# 处理类型转换
type_dict = {'公共': 'public', '收费': 'fees', '': ''}
meter_type = type_dict.get(row[7].value if len(row) > 7 else '', '')
# 处理物业信息
property_id = None
if installation_location: # 使用安装位置匹配物业
property_search = self.env['yuthon.property'].search(
[('name', '=', installation_location)],
limit=1
)
if property_search:
property_id = property_search
# 确定当前读数列索引(1-8月正常,9月特殊处理)
current_read_index = month + 9 if month < 9 else 9
meter_date = None
# 处理当月数据
meter_date = datetime(2025, month, 15) if month < 9 else None
current_read = None
# 1-8月份设置正常数据,9月份留空
if month < 9:
meter_date = datetime(2025, month, 15)
current_read = row[current_read_index].value
is_push = month < 9 # 9月份依然保持is_push为False
additional_data = {
if month < 9 and len(row) > current_read_index and row[current_read_index].value:
try:
current_read = float(row[current_read_index].value)
except ValueError:
current_read = None
# 查找或创建主表记录(按仪表编号)
archives = self.env['property.meter.archives'].search([('name', '=', name),
('is_push', '=', False)
], limit=1)
if not archives:
archives = self.env['property.meter.archives'].create({
'name': name,
'epitope_values': epitope_values,
'unit_number': unit_number,
'installation_location': installation_location,
'type': meter_type,
'gauge_magnification': gauge_magnification,
'maximum_count': maximum_count,
'yuthon_property_ids': [(4, property_id.id)] if property_id else [],
})
else:
# 更新已有记录的部分字段
archives.write({
'epitope_values': epitope_values,
'unit_number': unit_number,
'installation_location': installation_location,
'type': meter_type,
'gauge_magnification': gauge_magnification,
'maximum_count': maximum_count,
'yuthon_property_ids': [(4, property_id.id)] if property_id else [],
})
# 准备明细行数据
line_vals = {
'name': name,
'archives_id': archives.id,
'epitope_values': epitope_values,
'maximum_count': maximum_count,
'unit_number': unit_number,
'installation_location': installation_location,
'type':type,
'gauge_magnification': gauge_magnification,
'meter_date': meter_date,
'current_read': current_read,
'type': meter_type,
'gauge_magnification': gauge_magnification or 1,
'maximum_count': maximum_count,
'last_read': last_read,
'is_push': is_push,
'current_read': current_read,
'last_meter': meter_date,
'last_reading_time': meter_date,
'yuthon_property_ids': [(4, property_id.id)] if property_id else [],
}
self.env['meter.archives.line'].sudo().create(line_vals)
# 返回当前读数作为下个月的上次读数
return current_read if (month < 9 and current_read is not None) else last_read
# 处理数据逻辑...
combined_data = {**additional_data}
meter_id = self.env['property.meter.archives'].create(combined_data)
# if property_id:
# clear_entries = [(5,)]
# new_meter_entry = (0, 0, {
# 'property_meter_archives_id': meter_id.id,
# })
# updated_meters = clear_entries + [new_meter_entry]
# property_id.write({
# 'is_electricity_meter': True,
# 'energy_meter_ids': updated_meters
# })
if property_id:
clear_entries = [(5,)]
new_meter_entry = (0, 0, {
'property_meter_archives_id': meter_id.id,
})
updated_meters = clear_entries + [new_meter_entry]
property_id.write({
'is_electricity_meter': True,
'energy_meter_ids': updated_meters
})
if month < 9 and current_read is not None:
return current_read
else:
return last_read
# if month < 9 and current_read is not None:
# return current_read
# else:
# return last_read
+76 -47
View File
@@ -16,79 +16,108 @@ class PropertyWaterWizard(models.Model):
def confirm(self):
"""
导入excel文件,按行读取数据并处理
导入excel文件,按行读取数据并处理,将1-9月数据写入明细行
"""
if not self.excel_file:
raise ValidationError('请上传文件。')
book = xlrd.open_workbook(file_contents=base64.decodebytes(self.excel_file))
sh = book.sheet_by_index(0)
try:
book = xlrd.open_workbook(file_contents=base64.decodebytes(self.excel_file))
sh = book.sheet_by_index(0)
except Exception as e:
raise ValidationError(f'文件解析错误: {str(e)}')
for rx in range(1, sh.nrows):
row = sh.row(rx)
last_read = 0
last_read = 0.0
for month in range(1, 10):
last_read = self.property_water_data(row, last_read, month)
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'message': f'成功导入 {sh.nrows - 1} 条水表数据及明细',
'type': 'success',
'sticky': False,
}
}
def property_water_data(self,row, last_read, month):
def property_water_data(self, row, last_read, month):
epitope_values = row[0].value
name = row[3].value
type_dict = {'水表': 'water', '电表': 'electric', '电表(电子表)': 'smart', '': ''}
meter_type = type_dict.get(row[4].value)
name = row[3].value # 仪表编号
unit_number = row[1].value
installation_location = row[2].value
if row[5].value:
gauge_magnification = float(row[5].value)
else:
gauge_magnification = None
# 仪表倍率
gauge_magnification = float(row[5].value) if row[5].value else None
# 最大位数
maximum_count = float(row[6].value) if row[6].value else None
# 类型转换
type_dict = {'公共': 'public', '收费': 'fees', '': ''}
type = type_dict.get(row[7].value)
meter_type = type_dict.get(row[7].value)
# 物业信息
property_id = None
if row[2].value:
property_search = self.env['yuthon.property'].search([('name', '=', row[2].value)])
property_search = self.env['yuthon.property'].search([('name', '=', row[2].value)], limit=1)
if property_search:
property_id = property_search[0]
# 读数索引
current_read_index = month + 9 if month < 9 else 9
meter_date = None
current_read = None
# 1-8月份设置正常数据,9月份留空
if month < 9:
meter_date = datetime(2025, month, 15)
current_read = row[current_read_index].value
is_push = month < 9 # 9月份依然保持is_push为False
additional_data = {
# 1-8月正常数据,9月留空
meter_date = datetime(2025, month, 15) if month < 9 else None
current_read = row[current_read_index].value if (month < 9 and row[current_read_index].value) else None
# 查找或创建水表主记录
water = self.env['property.meter.water'].search([('name', '=', name),
('is_push', '=', False)
], limit=1)
if not water:
water = self.env['property.meter.water'].create({
'name': name,
'epitope_values': epitope_values,
'unit_number': unit_number,
'installation_location': installation_location,
'type': meter_type,
'gauge_magnification': gauge_magnification,
'maximum_count': maximum_count,
'yuthon_property_ids': [(4, property_id.id)] if property_id else [],
})
else:
water.write({
'epitope_values': epitope_values,
'unit_number': unit_number,
'installation_location': installation_location,
'type': meter_type,
'gauge_magnification': gauge_magnification,
'maximum_count': maximum_count,
'yuthon_property_ids': [(4, property_id.id)] if property_id else [],
})
# 计算用量
last_dosage = None
if last_read is not None and current_read is not None:
last_dosage = float(current_read) - float(last_read)
# 准备明细行数据
line_vals = {
'name': name,
'epitope_values': epitope_values,
'maximum_count': maximum_count,
'unit_number': unit_number,
'installation_location': installation_location,
'type': type,
'type': meter_type,
'gauge_magnification': gauge_magnification,
'meter_date': meter_date,
'current_read': current_read,
'maximum_count': maximum_count,
'last_read': last_read,
'is_push': is_push,
'current_read': current_read,
'last_dosage': last_dosage,
'last_meter': meter_date,
'last_reading_time': meter_date,
'yuthon_property_ids': [(4, property_id.id)] if property_id else [],
}
water.write({'line_ids': [(0, 0, line_vals)]})
# 处理数据逻辑...
combined_data = {**additional_data}
meter_id = self.env['property.meter.water'].create(combined_data)
if property_id:
clear_entries = [(5,)]
new_meter_entry = (0, 0, {
'property_meter_water_id': meter_id.id,
})
updated_meters = clear_entries + [new_meter_entry]
property_id.write({
'is_meter': True,
'water_meter_ids': updated_meters
})
if month < 9 and current_read is not None:
return current_read
else:
return last_read
# 返回当前读数作为下月上次读数
return float(current_read) if (month < 9 and current_read is not None) else last_read
@@ -66,6 +66,7 @@
force_save="1"/>
</div>
<field name="contract_amount"/>
<field name="state" invisible="1"/>
<field name="business_type"/>
<field name="payment_methods"/>
<field name="work_end" invisible="1"/>
@@ -74,7 +75,7 @@
<field name="department_id" invisible="1"/>
</group>
<notebook>
<page string="物业信息">
<page string="物业信息" invisible="state not in ['申请人']">
<button name="build_pop" string="添加物业" type="object"
class="btn-primary"/>
<field name="lease_ids">