添加功能

This commit is contained in:
李鹏宇
2025-10-15 16:41:06 +08:00
parent 9acd8479c2
commit 6afe7d896e
19 changed files with 266 additions and 159 deletions
@@ -27,3 +27,18 @@ class YuthonBreastfeedLeave(models.Model):
name_title = fields.Char(default=_get_default_name_title)
self_users_ids = fields.Many2many('res.users', string="当前经办人",
default=lambda self: [(6, 0, [self.env.user.id])])
def end_approval(self):
self.ensure_one()
employee = self.users_id.employee_id
breastfeeding_type = '1' if self.time_slot_selection == 'morning' else '2'
self.env['breastfeeding.holiday'].create({
'resource_calendar_id': employee.resource_calendar_id.id,
'employee_id': employee.id,
'breastfeeding_type': breastfeeding_type,
'calendar_start_time': self.start_date,
'calendar_end_time': self.end_date,
'check_in': 9,
'check_out': 16,
})
self.write({'work_end': True})
@@ -43,7 +43,7 @@ class YuthonFixesApproval(models.Model):
@api.onchange('holiday_status')
def _onchange_holiday_status(self):
if self.holiday_status:
if self.holiday_status and self.vacation_id:
if self.holiday_status == 'annual':
self.original_hours = self.vacation_id.leave
else:
+37 -8
View File
@@ -489,20 +489,49 @@ class HrAttendance(models.Model):
"view_mode": "form",
"target": "new",
"context": {
"default_attendance_id": self.id
"default_attendance_ids": [(6, 0, [self.id])]
}
}
def button_compensatory_leave(self):
form_id = self.env.ref('yuthon_hr_attendance.view_yuthon_adjustments_approval_form').id
def all_button_correct_wizard(self):
self.approval_check_in = self.check_in
self.approval_check_out = self.check_out
self.is_approval_no = self.is_no_card
self.is_approval_early = self.is_early_card
self.is_approval_late = self.is_late_card
self.is_approval_abnormal = self.is_abnormal
self.is_approval_abs = self.absenteeism_card
return {
"type": "ir.actions.act_window",
"name": "调休申请",
"res_model": "yuthon.adjustments.approval",
"views": [[form_id, "form"]],
"name": "修正弹窗",
"res_model": "attendance.correct.wizard",
"view_mode": "form",
"target": "new",
"context": {
'default_users_id': self.employee_id.user_id.id,
"default_attendance_ids": [(6, 0, [self.id])]
}
}
def button_compensatory_leave(self):
attendance_ids = self.env["hr.attendance"].browse(
self._context.get('active_ids', self._context.get('active_id'))
)
for record in attendance_ids:
record.approval_check_in = record.check_in
record.approval_check_out = record.check_out
record.is_approval_no = record.is_no_card
record.is_approval_early = record.is_early_card
record.is_approval_late = record.is_late_card
record.is_approval_abnormal = record.is_abnormal
record.is_approval_abs = record.absenteeism_card
return {
"type": "ir.actions.act_window",
"name": "修正弹窗",
"res_model": "attendance.correct.wizard",
"view_mode": "form",
"target": "new",
"context": {
"default_attendance_ids": [(6, 0, attendance_ids.ids)]
}
}
@@ -18,7 +18,9 @@
btn-primary"/>-->
<button name="compute_attendance_ids" string="重新计算" type="object"
class="btn btn-primary" />
<button name="state_fix" string="状态修正" type="object" class="btn btn-primary"
<!-- <button name="state_fix" string="状态修正" type="object" class="btn btn-primary"-->
<!-- groups="yuthon_hr_attendance.group_he_attendance_sign_manager" />-->
<button name="button_compensatory_leave" string="修正" type="object" class="btn btn-primary"
groups="yuthon_hr_attendance.group_he_attendance_sign_manager" />
<button name="unlink"
string="删除"
@@ -12,14 +12,15 @@ class AttendanceCorrectWizard(models.TransientModel):
_name = "attendance.correct.wizard"
_description = "考勤修正弹窗"
attendance_id = fields.Many2one('hr.attendance', string="考勤记录")
attendance_ids = fields.Many2many('hr.attendance', string="考勤记录")
correct_interval = fields.Selection([('half', '上半天'), ('second_half', '下半天'), ('day', '全天')], string="时间")
correct_result = fields.Text(string="修正原因")
def confirm(self):
for record in self:
# 准备更新的值
# 准备更新的基础值
values = {
'correct_result': self.correct_result,
'correct_result': record.correct_result,
'is_approval': True,
'is_abnormal': False,
'is_no_card': False,
@@ -30,85 +31,115 @@ class AttendanceCorrectWizard(models.TransientModel):
'absenteeism_card': False,
}
if not record.attendance_id.shift_id:
year = record.attendance_id.current_data.year
month = record.attendance_id.current_data.month
day = record.attendance_id.current_data.day
current_date = datetime.today()
min_hour_from = record.attendance_id.employee_id.resource_id.calendar_id.attendance_ids[0].hour_from
min_hour = int(min_hour_from)
min_minute = int(min_hour_from * 10 % min_hour_from)
will_datetime_start = current_date.replace(year=year, month=month, day=day, hour=min_hour, minute=min_minute) - timedelta(hours=8)
max_hour_to = record.attendance_id.employee_id.resource_id.calendar_id.attendance_ids[-1].hour_to
max_hour = int(max_hour_to)
max_minute = int(max_hour_to * 10 % max_hour_to)
will_datetime_end = current_date.replace(year=year, month=month, day=day, hour=max_hour, minute=max_minute) - timedelta(hours=8)
# 处理上班打卡
if not self.attendance_id.check_in:
values['check_in'] = will_datetime_start
values['is_check_in_red'] = True
values['is_no_card'] = False
elif self.attendance_id.check_in > will_datetime_start:
values['check_in'] = will_datetime_start
values['is_check_in_red'] = True
values['is_late_card'] = False
# 处理下班打卡
if not self.attendance_id.check_out:
values['check_out'] = will_datetime_end
values['is_check_out_red'] = True
values['is_no_card'] = False
elif self.attendance_id.check_out < will_datetime_end:
values['check_out'] = will_datetime_end
values['is_check_out_red'] = True
values['is_early_card'] = False
# 应用修改
self.attendance_id.write(values)
for attendance in record.attendance_ids:
if not attendance.shift_id:
year = attendance.current_data.year
month = attendance.current_data.month
day = attendance.current_data.day
current_date = datetime.today()
calendar = attendance.employee_id.resource_id.calendar_id
attendances = calendar.attendance_ids
# 计算正常上下班时间
min_attendance = attendances[0]
max_attendance = attendances[-1]
else:
shift = self.attendance_id.shift_id
start_time = shift.template_id.start_time
end_time = shift.template_id.end_time
the_time = shift.template_id.end_time2
start_hour = int(start_time)
start_minute = int((start_time - start_hour) * 60)
end_hour = int(end_time)
end_minute = int((end_time - end_hour) * 60)
the_hour = int(the_time)
the_minute = int((the_time - the_hour) * 60)
# 从 planning.slot 对象中获取日期
shift_date = shift.start_datetime.date() # 获取班次开始日期
# 拼接成 datetime 对象
normal_check_in = datetime.combine(shift_date, datetime.min.time()).replace(
hour=start_hour, minute=start_minute, second=0, microsecond=0
) - timedelta(hours=8)
# 上半天时间
half_day_start = current_date.replace(
year=year, month=month, day=day,
hour=int(min_attendance.hour_from),
minute=int((min_attendance.hour_from % 1) * 60)
) - timedelta(hours=8)
normal_check_out = datetime.combine(shift_date, datetime.min.time()).replace(
hour=end_hour , minute=end_minute, second=0, microsecond=0
) - timedelta(hours=8)
# 下半天时间
second_half_end = current_date.replace(
year=year, month=month, day=day,
hour=int(max_attendance.hour_to),
minute=int((max_attendance.hour_to % 1) * 60)
) - timedelta(hours=8)
# 如果是次日班次,调整下班时间
if shift.template_id.day2 == '次日' and shift.template_id.planning_name != '中夜':
normal_check_out = datetime.combine(shift_date, datetime.min.time()).replace(hour=the_hour, minute=the_minute, second=0, microsecond=0) - timedelta(hours=8)+ timedelta(days=1)
# 处理上班打卡
if not self.attendance_id.check_in:
values['check_in'] = normal_check_in
values['is_check_in_red'] = True
values['is_no_card'] = False
elif self.attendance_id.check_in > normal_check_in:
values['check_in'] = normal_check_in
values['is_check_in_red'] = True
values['is_late_card'] = False
# 处理下班打卡
if not self.attendance_id.check_out:
values['check_out'] = normal_check_out
values['is_check_out_red'] = True
values['is_no_card'] = False
elif self.attendance_id.check_out < normal_check_out:
values['check_out'] = normal_check_out
values['is_check_out_red'] = True
values['is_early_card'] = False
# 应用修改
self.attendance_id.write(values)
# 根据选择的时间区间处理
if record.correct_interval == 'half':
if not attendance.check_in:
values['check_in'] = half_day_start
values['is_check_in_red'] = True
elif attendance.check_in > half_day_start:
values['check_in'] = half_day_start
values['is_check_in_red'] = True
elif record.correct_interval == 'second_half':
if not attendance.check_out:
values['check_out'] = second_half_end
values['is_check_out_red'] = True
elif attendance.check_out < second_half_end:
values['check_out'] = second_half_end
values['is_check_out_red'] = True
else:
if not attendance.check_in:
values['check_in'] = half_day_start
values['is_check_in_red'] = True
elif attendance.check_in > half_day_start:
values['check_in'] = half_day_start
values['is_check_in_red'] = True
if not attendance.check_out:
values['check_out'] = second_half_end
values['is_check_out_red'] = True
elif attendance.check_out < second_half_end:
values['check_out'] = second_half_end
values['is_check_out_red'] = True
else:
shift = attendance.shift_id
template = shift.template_id
shift_date = shift.start_datetime.date()
# 计算正常上下班时间
normal_check_in = datetime.combine(shift_date, datetime.min.time()).replace(
hour=int(template.start_time),
minute=int((template.start_time % 1) * 60)
) - timedelta(hours=8)
normal_check_out = datetime.combine(shift_date, datetime.min.time()).replace(
hour=int(template.end_time),
minute=int((template.end_time % 1) * 60)
) - timedelta(hours=8)
# 处理次日班次
if template.day2 == '次日' and template.planning_name != '中夜':
normal_check_out = datetime.combine(shift_date, datetime.min.time()).replace(
hour=int(template.end_time2),
minute=int((template.end_time2 % 1) * 60)
) - timedelta(hours=8) + timedelta(days=1)
# 根据选择的时间区间处理
if record.correct_interval == 'half':
if not attendance.check_in:
values['check_in'] = normal_check_in
values['is_check_in_red'] = True
elif attendance.check_in > normal_check_in:
values['check_in'] = normal_check_in
values['is_check_in_red'] = True
elif record.correct_interval == 'second_half':
if not attendance.check_out:
values['check_out'] = normal_check_out
values['is_check_out_red'] = True
elif attendance.check_out < normal_check_out:
values['check_out'] = normal_check_out
values['is_check_out_red'] = True
else: # 全天
# 处理上班打卡
if not attendance.check_in:
values['check_in'] = normal_check_in
values['is_check_in_red'] = True
elif attendance.check_in > normal_check_in:
values['check_in'] = normal_check_in
values['is_check_in_red'] = True
# 处理下班打卡
if not attendance.check_out:
values['check_out'] = normal_check_out
values['is_check_out_red'] = True
elif attendance.check_out < normal_check_out:
values['check_out'] = normal_check_out
values['is_check_out_red'] = True
attendance.write(values)
@@ -7,6 +7,7 @@
<form string="修正">
<div>你确定要修正吗?</div>
<group>
<field name="correct_interval"/>
<field name="correct_result" placeholder="请填写备注原因"/>
</group>
<footer>
@@ -7,6 +7,7 @@ import logging
from odoo.osv import expression
_logger = logging.getLogger(__name__)
class PropertyBankStatements(models.Model):
_name = 'property.bank.statements'
_description = '银行流水'
@@ -31,6 +32,7 @@ class PropertyBankStatements(models.Model):
contract_account = fields.Char(string="合同累计应收")
contract_penalty = fields.Char(string="合同累计违约金")
original_amount = fields.Float(string='交易金额')
lending_direction = fields.Selection([('borrow', '借'), ('loan', '贷')], string='借贷方向')
yes_amount = fields.Float(stringo='已对')
no_amount = fields.Float(string='未对')
reconciliation_time = fields.Datetime('对账时间')
@@ -261,8 +261,6 @@ class MeterArchivesLine(models.Model):
unit = fields.Float(string="当月单价", group_operator=None, digits=(16, 4))
line_loss = fields.Float(string="线损", default=0.02)
type = fields.Selection([("public", "公共"), ("fees", "收费")], string="类型")
start_time = fields.Date(string="安装日期")
end_time = fields.Date(string="拆除日期")
employee_ids = fields.Many2many("hr.employee", string="抄表人")
remarks = fields.Text(string="备注")
archives_state = fields.Selection(
@@ -353,7 +351,7 @@ class MeterArchivesLine(models.Model):
if record.current_read < record.last_read:
if record.current_meter>= 10000:
raise ValidationError(
f"输入错误:当前读数 {record.current_read} 必须大于上次读数 {record.last_read} "
f"输入错误:仪表编号为{record.archives_id.name}当前读数 {record.current_read} 必须大于上次读数 {record.last_read} "
)
@api.onchange("yuthon_property_ids")
@@ -33,7 +33,7 @@ class PropertyMeterWater(models.Model):
epitope_values = fields.Char(string="表位置")
epitope_values_id = fields.Many2one("yuthon.epitope.values", string="表位置")
other = fields.Char(string="其他")
unit = fields.Float(string="当月单价", igits=(6, 4))
unit = fields.Float(string="当月单价", digits=(16, 4))
start_time = fields.Date(string="安装日期")
end_time = fields.Date(string="拆除日期")
line_loss = fields.Float(string="线损", default=0.05)
@@ -174,6 +174,7 @@ class MeterWaterLine(models.Model):
water_id = fields.Many2one(
"property.meter.water", string="水表库", required=True, ondelete="cascade"
)
initial_value = fields.Float(string="初始值")
number = fields.Integer(
related="epitope_values_id.sequence", string="序号", store=True
)
@@ -181,12 +182,12 @@ class MeterWaterLine(models.Model):
epitope_values_id = fields.Many2one("yuthon.epitope.values", string="表位置")
lessee_id = fields.Many2one("property.tenant.information", string="承租方")
yuthon_property_ids = fields.Many2many("yuthon.property", string="物业信息")
last_meter = fields.Date(string="上次抄表日期")
last_meter = fields.Date(string="上次抄表日期", compute="_compute_last")
last_dosage = fields.Float(
string="上次用量", store=True, group_operator=None
string="上次用量", store=True, group_operator=None, compute="_compute_last"
)
last_read = fields.Float(
string="上次读数", store=True, group_operator=None
string="上次读数", store=True, group_operator=None, compute="_compute_last"
)
meter_date = fields.Date(string="任务日期")
@@ -199,14 +200,12 @@ class MeterWaterLine(models.Model):
current_meter = fields.Float(string="本次用量", store=True, group_operator=None)
current_read = fields.Float(string='本次读数', group_operator=None)
unit_number = fields.Char(string='单元编号/用途')
unit = fields.Float(string='当月单价', group_operator=None)
receivables = fields.Float(string="应收", store=True, group_operator=None, help="应收金额=本次用量*单价*(1+线损)")
unit = fields.Float(string='当月单价', group_operator=None, digits=(16, 4))
receivables = fields.Float(string="应收", store=True, help="应收金额=本次用量*单价*(1+线损)")
gauge_magnification = fields.Integer(string='仪表倍率', default=1)
last_reading_time = fields.Date(string="最后读数时间")
type = fields.Selection([("public", "公共"), ("fees", "收费")], string="类型")
start_time = fields.Date(string="安装日期")
line_loss = fields.Float(string="线损", default=0.02)
end_time = fields.Date(string="拆除日期")
water_state = fields.Selection([('stop', '停用'), ('use', '使用'), ('rent', '出租')], string='状态')
state = fields.Selection([('reading', '已抄'), ('unreading', '未抄')], string='抄表状态', default='unreading')
remarks = fields.Text(string='备注')
@@ -272,7 +271,7 @@ class MeterWaterLine(models.Model):
else:
i.current_meter = 0
else:
i.last_dosage = 0
i.last_read = i.initial_value
i.last_read = 0
i.last_meter = i.meter_date
i.current_meter = 0
@@ -21,7 +21,7 @@
<field name="name">property.bank.statements.tree</field>
<field name="model">property.bank.statements</field>
<field name="arch" type="xml">
<tree string="银行流水" editable="bottom" js_class="custom_bank_statements_button" edit="false" delete="false" default_order="start_time desc" limit="15">
<tree string="银行流水" editable="bottom" js_class="custom_bank_statements_button" delete="false" default_order="start_time desc" limit="15">
<field name="your_own_account" optional="hide"/>
<field name="your_own_unit" optional="hide"/>
<header>
@@ -32,6 +32,7 @@
<field name="bank_name" />
<field name="bank_branch"/>
<field name="name_account" />
<field name="lending_direction"/>
<field name="original_amount"/>
<field name="yes_amount" string="已对"/>
<field name="no_amount" />
@@ -70,8 +70,6 @@
<field name="gauge_magnification"/>
<field name="last_reading_time"/>
<field name="type"/>
<field name="start_time"/>
<field name="end_time"/>
<field name="remarks"/>
<field name="archives_state"/>
<field name="maximum_count"/>
@@ -96,7 +94,7 @@
<field name="archives_id" string="电表名"/>
<field name="unit_number"/>
<field name="gauge_magnification"/>
<field name="initial_value"/>
<field name="initial_value" column_invisible="1"/>
<field name="last_read" readonly="1"/>
<field name="current_read"/>
<field name="current_meter" readonly="1"/>
@@ -20,7 +20,7 @@
<field name="lessee_id" options="{'no_create': True, 'no_open': True}"/>
<field name="yuthon_property_ids" string="物业信息" widget="many2many_tags" options="{'no_open': True}"/>
<field name="unit_number" />
<field name="gauge_magnification" readonly="1" />
<field name="gauge_magnification" />
<field name="type" />
<field name="start_time" />
<field name="end_time" />
@@ -43,7 +43,7 @@
<field name="name" />
<field name="unit_number" />
<field name="type" />
<field name="gauge_magnification" readonly="1" />
<field name="gauge_magnification"/>
<field name="maximum_count" />
<field name="lessee_id" options="{'no_create': True, 'no_open': True}"/>
<field name="employee_ids" widget="many2many_tags"
@@ -74,11 +74,9 @@
<field name="current_meter" readonly="1" />
<field name="current_read" />
<field name="unit_number" />
<field name="gauge_magnification" readonly="1" />
<field name="gauge_magnification"/>
<field name="last_reading_time" />
<field name="type" />
<field name="start_time" />
<field name="end_time" />
<field name="water_state" />
<field name="remarks" />
<field name="employee_ids" widget="many2many_tags"
@@ -102,7 +100,7 @@
<field name="meter_date" readonly="1"/>
<field name="water_id" string="水表名"/>
<field name="unit_number"/>
<field name="gauge_magnification" readonly="1"/>
<field name="gauge_magnification"/>
<field name="last_read" readonly="1"/>
<field name="current_read"/>
<field name="current_meter" readonly="1"/>
@@ -92,7 +92,7 @@
<field name="house_type_id" options="{'no_open': True}"/>
<field name="property_source"/>
<field name="district"/>
<field name="live_room"/>
<field name="live_room" options="{'no_open': True}"/>
<field name="rental_conditions"/>
<field name="feature_ids" widget="many2many_tags"/>
<field name="is_done_split" invisible="1"/>
@@ -14,11 +14,20 @@ class ElectricWaterWizard(models.TransientModel):
# 处理电表推送
if self.meter_ids:
for meter in self.meter_ids:
# 查找上个月的记录
# 查找上个月的记录,上次用量,上次读数,上次抄表日期
if meter.start_time:
if meter.start_time > self.push_date:
raise UserError(
f"电表 {meter.name} 安装日期({meter.start_time})晚于推送日期({self.push_date}),无法推送")
if meter.end_time:
if meter.end_time and meter.end_time < self.push_date:
raise UserError(
f"电表 {meter.name} 拆除日期({meter.end_time})早于推送日期({self.push_date}),无法推送")
# 查找上个月的记录
# 查找上个月的记录,上次用量,上次读数,上次抄表日期
last_month_line = meter.line_ids.search([('meter_date', '<', self.push_date)]).sorted('meter_date')[-1]
# 如果当前数据不存在,则新建任务,按照天的纬度
self_month_line = meter.line_ids.search([('meter_date', '=', self.push_date), ('archives_id', '=', meter.id)])
self_month_line = meter.line_ids.search(
[('meter_date', '=', self.push_date), ('archives_id', '=', meter.id)])
if not self_month_line:
meter.line_ids.create({
'archives_id': meter.id,
@@ -26,7 +35,6 @@ class ElectricWaterWizard(models.TransientModel):
'last_read': last_month_line.last_read,
'last_dosage': last_month_line.last_dosage,
'meter_date': self.push_date,
'epitope_values_id': meter.epitope_values_id.id,
'lessee_id': meter.lessee_id.id,
'yuthon_property_ids': [(6, 0, meter.yuthon_property_ids.ids)],
@@ -44,6 +52,14 @@ class ElectricWaterWizard(models.TransientModel):
# 处理水表推送
if self.water_ids:
for water in self.water_ids:
if water.start_time:
if water.start_time > self.push_date:
raise UserError(
f"水表 {water.name} 安装日期({water.start_time})晚于推送日期({self.push_date}),无法推送")
if water.end_time:
if water.end_time and water.end_time < self.push_date:
raise UserError(
f"水表 {water.name} 拆除日期({water.end_time})早于推送日期({self.push_date}),无法推送")
# 查找上个月的记录,上次用量,上次读数,上次抄表日期
last_month_line = water.line_ids.search([('meter_date', '<', self.push_date)]).sorted('meter_date')[-1]
# 如果当前数据不存在,则新建任务,按照天的纬度
+21 -11
View File
@@ -6,6 +6,7 @@ import xlrd
import base64
import datetime
from datetime import datetime
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
class PropertyMeterWizard(models.Model):
@@ -31,13 +32,12 @@ class PropertyMeterWizard(models.Model):
# 按行处理数据
for rx in range(1, sh.nrows): # 跳过表头行
row = sh.row(rx)
last_read = 0.0 # 初始读数,第一个月的上次读数为0
# 处理1-9月份数据
for month in range(1, 10):
last_read = self.property_meter_data(row, last_read, month)
self.property_meter_data(row, month)
def property_meter_data(self, row, last_read, month):
def property_meter_data(self, row, month):
"""
处理单月数据,查找主记录并创建/更新明细行
"""
@@ -46,7 +46,17 @@ class PropertyMeterWizard(models.Model):
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 ''
excel_start_date = datetime(1899, 12, 30)
# 计算目标日期
if row[19].value:
start_date = excel_start_date + timedelta(days=row[19].value)
else:
start_date = None
if row[20].value:
end_date = excel_start_date + timedelta(days=row[20].value)
else:
end_date = None
# 处理仪表倍率
gauge_magnification = None
if len(row) > 5 and row[5].value:
@@ -77,13 +87,10 @@ class PropertyMeterWizard(models.Model):
if property_search:
property_id = property_search
# 确定当前读数列索引(1-8月正常,9月特殊处理)
current_read_index = month + 9 if month < 9 else 9
# 处理当月数据
meter_date = datetime(2025, month, 15) if month < 9 else None
current_read_index = month + 9
meter_date = datetime(2025, month, 15)
current_read = None
if month < 9 and len(row) > current_read_index and row[current_read_index].value:
if len(row) > current_read_index and row[current_read_index].value:
try:
current_read = float(row[current_read_index].value)
except ValueError:
@@ -96,6 +103,8 @@ class PropertyMeterWizard(models.Model):
archives = self.env['property.meter.archives'].create({
'name': name,
'epitope_values': epitope_values,
'start_time': start_date,
'end_time': end_date,
'unit_number': unit_number,
'installation_location': installation_location,
'type': meter_type,
@@ -107,6 +116,8 @@ class PropertyMeterWizard(models.Model):
# 更新已有记录的部分字段
archives.write({
'epitope_values': epitope_values,
'start_time': start_date,
'end_time': end_date,
'unit_number': unit_number,
'installation_location': installation_location,
'type': meter_type,
@@ -129,8 +140,7 @@ class PropertyMeterWizard(models.Model):
'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
# if property_id:
# clear_entries = [(5,)]
+30 -24
View File
@@ -6,6 +6,7 @@ import xlrd
import base64
import datetime
from datetime import datetime
from datetime import datetime, timedelta
class PropertyWaterWizard(models.Model):
@@ -29,9 +30,8 @@ class PropertyWaterWizard(models.Model):
for rx in range(1, sh.nrows):
row = sh.row(rx)
last_read = 0.0
for month in range(1, 10):
last_read = self.property_water_data(row, last_read, month)
self.property_water_data(row, month)
return {
'type': 'ir.actions.client',
@@ -43,7 +43,7 @@ class PropertyWaterWizard(models.Model):
}
}
def property_water_data(self, row, last_read, month):
def property_water_data(self, row, month):
epitope_values = row[0].value
name = row[3].value # 仪表编号
unit_number = row[1].value
@@ -65,20 +65,35 @@ class PropertyWaterWizard(models.Model):
if property_search:
property_id = property_search[0]
# 读数索引
current_read_index = month + 9 if month < 9 else 9
# 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
current_read_index = month + 9
meter_date = datetime(2025, month, 15)
current_read = None
if 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
# 查找或创建水表主记录
water = self.env['property.meter.water'].search([('name', '=', name),
('is_push', '=', False)
], limit=1)
excel_start_date = datetime(1899, 12, 30)
if row[19].value:
start_date = excel_start_date + timedelta(days=row[19].value)
else:
start_date = None
if row[20].value:
end_date = excel_start_date + timedelta(days=row[20].value)
else:
end_date = None
if not water:
water = self.env['property.meter.water'].create({
'name': name,
'epitope_values': epitope_values,
'start_time': start_date,
'end_time': end_date,
'unit_number': unit_number,
'installation_location': installation_location,
'type': meter_type,
@@ -89,6 +104,8 @@ class PropertyWaterWizard(models.Model):
else:
water.write({
'epitope_values': epitope_values,
'start_time': start_date,
'end_time': end_date,
'unit_number': unit_number,
'installation_location': installation_location,
'type': meter_type,
@@ -97,27 +114,16 @@ class PropertyWaterWizard(models.Model):
'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,
'initial_value': row[9].value,
'meter_date': meter_date,
'water_id': water.id,
'unit_number': unit_number,
'type': meter_type,
'gauge_magnification': gauge_magnification,
'gauge_magnification': gauge_magnification or 1,
'maximum_count': maximum_count,
'last_read': last_read,
'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)]})
# 返回当前读数作为下月上次读数
return float(current_read) if (month < 9 and current_read is not None) else last_read
@@ -105,7 +105,7 @@ class MeterWaterLine(models.Model):
@api.onchange('current_read')
def onchange_current_read(self):
tariff_list = self.env['property.water.list'].search(
[('name', '=', self.archives_id.name),
[('name', '=', self.water_id.name),
('meter_date', '=', self.meter_date)
], limit=1
)
@@ -114,8 +114,8 @@ class MeterWaterLine(models.Model):
'contract_id': self.contract_id,
'lessee_id': self.lessee_id.id,
'dosage': self.current_meter,
'tariff_meter_reading': self.current_read,
'name': self.archives_id.name,
'water_meter_reading': self.current_read,
'name': self.water_id.name,
'meter_date': self.meter_date,
'unit': self.unit,
'remarks': self.remarks,
@@ -53,7 +53,7 @@ class PropertyLeaseContract(models.Model):
property_name = fields.Char(string='物业信息')
code = fields.Char(string="流水号", default=lambda self: self.env['ir.sequence'].next_by_code('property_lease_contract_code'))
admin_id = fields.Many2one('res.users', string="管理员", compute="_compute_admin_id", store=True)
tenure_type = fields.Selection([('self', '自有'), ('agency', '代管')], string='权属类型')
tenure_type = fields.Selection([('self', '自有'), ('agency', '代管')], string='权属类型', compute="_compute_admin_id", store=True)
contract_code = fields.Char(string="合同编号")
contract_date = fields.Date(string="合同签订日期")
property_documents_ids = fields.Many2many(
@@ -288,11 +288,12 @@ class PropertyLeaseContract(models.Model):
unique_titles.append(title)
record.title_information = ', '.join(unique_titles)
@api.depends('lease_ids.address_id.admin_id', 'lease_ids.address_id.admin_id.department_id')
@api.depends('lease_ids.address_id.admin_id', 'lease_ids.address_id.admin_id.department_id', 'lease_ids.address_id.tenure_type')
def _compute_admin_id(self):
for record in self:
if record.lease_ids:
record.admin_id = record.lease_ids[0].address_id.admin_id.id
record.tenure_type = record.lease_ids[0].address_id.tenure_type
def contract_signature(self):
return {
@@ -69,7 +69,7 @@
</div>
</group>
<group>
<field name="rental_purposes"/>
<field name="rental_purposes" options="{'no_open': True}"/>
</group>
<group>
<field name="contract_sort"/>
@@ -467,7 +467,7 @@
</div>
</group>
<group>
<field name="rental_purposes" invisible="contract_sort != 'property'"/>
<field name="rental_purposes" invisible="contract_sort != 'property'" options="{'no_open': True}"/>
</group>
<group>
<field name="contract_sort"/>
@@ -546,7 +546,7 @@
<field name="name"/>
<field name="contract_id" options="{'no_open': True}"/>
<field name="lessee_id" options="{'no_open': True}"/>
<field name="rental_purposes"/>
<field name="rental_purposes" options="{'no_open': True}"/>
</tree>
</field>
</page>