添加功能
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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]
|
||||
# 如果当前数据不存在,则新建任务,按照天的纬度
|
||||
|
||||
@@ -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,)]
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user