Merge branch 'dev' of https://gitee.com/jinan-pengyusen-data/gzth into dev
This commit is contained in:
@@ -8,15 +8,16 @@ class PropertyMeterArchives(models.Model):
|
||||
_description = '电表库'
|
||||
|
||||
name = fields.Char(string='仪表编号')
|
||||
unit_number = fields.Char(string='单元编号')
|
||||
unit_number = fields.Char(string='单元编号/用途')
|
||||
installation_location = fields.Char(string='安装位置')
|
||||
is_state = fields.Boolean(string='是否启用')
|
||||
type = fields.Selection([('public', '公共'), ('fees', '收费')], string='类型')
|
||||
gauge_magnification = fields.Integer(string='仪表倍率', default=1)
|
||||
maximum_count = fields.Integer(string='标准用量', default=999999)
|
||||
lessee_id = fields.Many2one(related='yuthon_property_id.lessee_id', string='承租方', store=True)
|
||||
maximum_count = fields.Integer(string='最大位数')
|
||||
lessee_id = fields.Many2one('property.tenant.information', string='承租方', store=True, compute='_compute_lessee_id')
|
||||
employee_ids = fields.Many2many('hr.employee', string='抄表人')
|
||||
meter_type = fields.Selection([('electric', '电表'), ('water', '水表')], string='仪表类型')
|
||||
epitope_values = fields.Char(string='表位置')
|
||||
meter_type = fields.Selection([('electric', '电表'), ('water', '水表'), ('smart', '智能电表')], string='仪表类型')
|
||||
other = fields.Char(string='其他')
|
||||
meter_date = fields.Date(string='任务日期')
|
||||
last_dosage = fields.Float(string='上次用量')
|
||||
@@ -33,7 +34,15 @@ class PropertyMeterArchives(models.Model):
|
||||
receivables = fields.Float(string="应收", compute='_compute_receivables', store=True)
|
||||
last_reading_time = fields.Date(string="最后读数时间")
|
||||
standards_id = fields.Many2one('yuthon.electricity.setting', string='标准')
|
||||
yuthon_property_id = fields.Many2one('yuthon.property', string='关联物业信息')
|
||||
yuthon_property_ids = fields.Many2many('yuthon.property', string='物业信息')
|
||||
|
||||
@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('line_loss', 'current_meter', 'unit')
|
||||
def _compute_receivables(self):
|
||||
@@ -52,6 +61,14 @@ class PropertyMeterArchives(models.Model):
|
||||
record.write({'maximum_count': 99999,
|
||||
})
|
||||
|
||||
def open_record(self):
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'property.meter.archives',
|
||||
'res_id': self.id,
|
||||
'view_mode': 'form',
|
||||
}
|
||||
|
||||
@api.depends('lessee_id')
|
||||
def _compute_archives_state(self):
|
||||
for record in self:
|
||||
@@ -95,19 +112,24 @@ class PropertyMeterArchives(models.Model):
|
||||
if record.current_read > record.last_read:
|
||||
record.current_meter = record.current_read - record.last_read
|
||||
else:
|
||||
record.current_meter = record.maximum_count - record.last_read + record.current_read
|
||||
if record.maximum_count > 0:
|
||||
max_value = 10 ** record.maximum_count - 1
|
||||
record.current_meter = max_value - record.last_read + record.current_read
|
||||
else:
|
||||
record.current_meter = 0
|
||||
|
||||
@api.onchange('yuthon_property_id')
|
||||
@api.onchange('yuthon_property_ids')
|
||||
def _onchange_property(self):
|
||||
if self.yuthon_property_id:
|
||||
if self.yuthon_property_ids:
|
||||
meter_list = []
|
||||
property_id = self.env['yuthon.property'].search([('id', '=', self.yuthon_property_id.id)])
|
||||
property_id.is_electricity_meter = True
|
||||
meter_list.append((0, 0, {
|
||||
'yuthon_property_id':property_id.id,
|
||||
'property_meter_archives_id':self.id.origin,
|
||||
}))
|
||||
property_id.energy_meter_ids = meter_list
|
||||
for yuthon_property_id in self.yuthon_property_ids:
|
||||
property_id = self.env['yuthon.property'].search([('id', '=', yuthon_property_id.origin.id)])
|
||||
property_id.is_meter = True
|
||||
meter_list.append((0, 0, {
|
||||
'yuthon_property_id': property_id.id,
|
||||
'property_meter_water_id': self.id.origin,
|
||||
}))
|
||||
property_id.water_meter_ids = meter_list
|
||||
|
||||
def action_property_meter_wizard(self):
|
||||
return {
|
||||
|
||||
@@ -7,15 +7,16 @@ class PropertyMeterWater(models.Model):
|
||||
_description = '水表库'
|
||||
|
||||
name = fields.Char(string='仪表编号')
|
||||
unit_number = fields.Char(string='单元编号')
|
||||
unit_number = fields.Char(string='单元编号/用途')
|
||||
installation_location = fields.Char(string='安装位置')
|
||||
is_state = fields.Boolean(string='是否启用')
|
||||
type = fields.Selection([('public', '公共'), ('fees', '收费')], string='类型')
|
||||
gauge_magnification = fields.Integer(string='仪表倍率', default=1)
|
||||
maximum_count = fields.Integer(string='标准用量', default=99999)
|
||||
lessee_id = fields.Many2one(related='yuthon_property_id.lessee_id', string='承租方', store=True)
|
||||
maximum_count = fields.Integer(string='最大位数')
|
||||
lessee_id = fields.Many2one('property.tenant.information', store=True, compute='_compute_lessee_id', string="承租方")
|
||||
employee_ids = fields.Many2many('hr.employee', string='抄表人')
|
||||
meter_type = fields.Selection([('electric', '电表'), ('water', '水表')], string='仪表类型')
|
||||
epitope_values = fields.Char(string='表位置')
|
||||
other = fields.Char(string='其他')
|
||||
meter_date = fields.Date(string='任务日期')
|
||||
last_dosage = fields.Float(string='上次用量')
|
||||
@@ -32,7 +33,23 @@ class PropertyMeterWater(models.Model):
|
||||
last_reading_time = fields.Date(string="最后读数时间")
|
||||
water_state = fields.Selection([('stop', '停用'), ('use', '使用'), ('rent', '出租')], string='状态', compute='_compute_water_state', store=True)
|
||||
standards_id = fields.Many2one('yuthon.electricity.setting', string='标准')
|
||||
yuthon_property_id = fields.Many2one('yuthon.property', string='关联物业信息')
|
||||
yuthon_property_ids = fields.Many2many('yuthon.property', string='物业信息')
|
||||
|
||||
def open_record(self):
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'property.meter.water',
|
||||
'res_id': self.id,
|
||||
'view_mode': 'form',
|
||||
}
|
||||
|
||||
@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('line_loss', 'current_meter', 'unit')
|
||||
def _compute_receivables(self):
|
||||
@@ -95,26 +112,31 @@ class PropertyMeterWater(models.Model):
|
||||
if record.current_read > record.last_read:
|
||||
record.current_meter = record.current_read - record.last_read
|
||||
else:
|
||||
record.current_meter = record.maximum_count - record.last_read + record.current_read
|
||||
if record.maximum_count > 0:
|
||||
max_value = 10 ** record.maximum_count - 1
|
||||
record.current_meter = max_value - record.last_read + record.current_read
|
||||
else:
|
||||
record.current_meter = 0
|
||||
|
||||
|
||||
@api.onchange('yuthon_property_id')
|
||||
@api.onchange('yuthon_property_ids')
|
||||
def _onchange_property(self):
|
||||
if self.yuthon_property_id:
|
||||
if self.yuthon_property_ids:
|
||||
meter_list = []
|
||||
property_id = self.env['yuthon.property'].search([('id', '=', self.yuthon_property_id.id)])
|
||||
property_id.is_meter = True
|
||||
meter_list.append((0, 0, {
|
||||
'yuthon_property_id': property_id.id,
|
||||
'property_meter_water_id': self.id.origin,
|
||||
}))
|
||||
property_id.water_meter_ids = meter_list
|
||||
for yuthon_property_id in self.yuthon_property_ids:
|
||||
property_id = self.env['yuthon.property'].search([('id', '=', yuthon_property_id.id)])
|
||||
property_id.is_meter = True
|
||||
meter_list.append((0, 0, {
|
||||
'yuthon_property_id': property_id.id,
|
||||
'property_meter_water_id': self.id.origin,
|
||||
}))
|
||||
property_id.water_meter_ids = meter_list
|
||||
|
||||
|
||||
def action_property_water_wizard(self):
|
||||
return {
|
||||
"type": "ir.actions.act_window",
|
||||
"name": "批量导入物业电表",
|
||||
"name": "批量导入物业水表",
|
||||
"res_model": "property.water.wizard",
|
||||
"view_mode": "form",
|
||||
"target": "new",
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
<button class="oe_highlight" name="batch_reading_push" string="推送" type="object"/>
|
||||
<button class="oe_highlight" name="button_archives_state" string="停用" type="object"/>
|
||||
</header>
|
||||
<button name="open_record" string="详情" type="object" class="oe_highlight"/>
|
||||
<field name="name"/>
|
||||
<field name="epitope_values"/>
|
||||
<field name="lessee_id" options="{'no_create': True}"/>
|
||||
<field name="yuthon_property_id" string="物业信息"/>
|
||||
<field name="yuthon_property_ids" string="物业信息" widget="many2many_tags"/>
|
||||
<!-- <field name="meter_date" />-->
|
||||
<field name="last_meter" />
|
||||
<field name="last_dosage"/>
|
||||
@@ -30,14 +32,66 @@
|
||||
<field name="maximum_count"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="property_meter_archives_form" model="ir.ui.view">
|
||||
<field name="name">property.meter.archives.form</field>
|
||||
<field name="model">property.meter.archives</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="电表库">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<label for="name"/>
|
||||
<h1>
|
||||
<field name="name"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="unit_number"/>
|
||||
<field name="installation_location"/>
|
||||
<field name="is_state"/>
|
||||
<field name="type"/>
|
||||
<field name="gauge_magnification"/>
|
||||
<field name="maximum_count"/>
|
||||
<field name="lessee_id"/>
|
||||
<field name="employee_ids" widget="many2many_tags"/>
|
||||
<field name="epitope_values"/>
|
||||
<field name="meter_type"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="other"/>
|
||||
<field name="meter_date"/>
|
||||
<field name="last_dosage"/>
|
||||
<field name="last_read"/>
|
||||
<field name="last_meter"/>
|
||||
<field name="current_meter"/>
|
||||
<field name="current_read"/>
|
||||
<field name="unit"/>
|
||||
<field name="archives_state"/>
|
||||
<field name="is_push"/>
|
||||
<field name="start_time"/>
|
||||
<field name="end_time"/>
|
||||
<field name="line_loss"/>
|
||||
<field name="receivables"/>
|
||||
<field name="last_reading_time"/>
|
||||
<field name="standards_id"/>
|
||||
<field name="yuthon_property_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_property_meter_archives_tree1" model="ir.ui.view">
|
||||
<field name="name">property.meter.archives.tree</field>
|
||||
<field name="model">property.meter.archives</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="电表任务" create="False" editable="bottom" js_class="custom_meter_button">
|
||||
<button name="open_record" string="详情" type="object" class="oe_highlight"/>
|
||||
<field name="name" readonly="1"/>
|
||||
<field name="yuthon_property_id" string="地址" readonly="1"/>
|
||||
<field name="epitope_values"/>
|
||||
<field name="yuthon_property_ids" string="地址" readonly="1" widget="many2many_tags"/>
|
||||
<field name="lessee_id" options="{'no_create': True}" readonly="1"/>
|
||||
<field name="meter_date" readonly="1"/>
|
||||
<field name="gauge_magnification"/>
|
||||
@@ -60,7 +114,7 @@
|
||||
<field name="model">property.meter.archives</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="电表">
|
||||
<field name="yuthon_property_id"/>
|
||||
<field name="yuthon_property_ids"/>
|
||||
<field name="lessee_id"/>
|
||||
</search>
|
||||
</field>
|
||||
@@ -68,17 +122,19 @@
|
||||
<record id="action_property_meter_archives" model="ir.actions.act_window">
|
||||
<field name="name">电表库</field>
|
||||
<field name="res_model">property.meter.archives</field>
|
||||
<field name="view_mode">tree,search</field>
|
||||
<field name="view_mode">tree,form,search</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_property.view_property_meter_archives_tree')})]"/>
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_property.view_property_meter_archives_tree')}),
|
||||
(0, 0, {'view_mode': 'form', 'view_id': ref('yuthon_property.property_meter_archives_form')})]"/>
|
||||
</record>
|
||||
<record id="action_property_meter_archives1" model="ir.actions.act_window">
|
||||
<field name="name">电表任务</field>
|
||||
<field name="res_model">property.meter.archives</field>
|
||||
<field name="view_mode">tree,search</field>
|
||||
<field name="view_mode">tree,form,search</field>
|
||||
<field name="domain">[('is_push', '=', True)]</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_property.view_property_meter_archives_tree1')})]"/>
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_property.view_property_meter_archives_tree1')}),
|
||||
(0, 0, {'view_mode': 'form', 'view_id': ref('yuthon_property.property_meter_archives_form')})]"/>
|
||||
</record>
|
||||
<record id="all_data_meter_property" model="ir.actions.server">
|
||||
<field name="name">导入电表</field>
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
<button class="oe_highlight" name="batch_reading_water_push" string="推送" type="object"/>
|
||||
<button class="oe_highlight" name="button_water_state" string="停用" type="object"/>
|
||||
</header>
|
||||
<button name="open_record" string="详情" type="object" class="oe_highlight"/>
|
||||
<field name="name"/>
|
||||
<field name="epitope_values"/>
|
||||
<field name="lessee_id" options="{'no_create': True}"/>
|
||||
<field name="yuthon_property_id" string="物业信息"/>
|
||||
<field name="yuthon_property_ids" string="物业信息" widget="many2many_tags"/>
|
||||
<!-- <field name="meter_date" />-->
|
||||
<field name="last_meter" />
|
||||
<field name="last_dosage"/>
|
||||
@@ -32,14 +34,64 @@
|
||||
<field name="maximum_count"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="property_meter_water_form" model="ir.ui.view">
|
||||
<field name="name">property.meter.water.form</field>
|
||||
<field name="model">property.meter.water</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="水表库">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<label for="name"/>
|
||||
<h1>
|
||||
<field name="name"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="unit_number"/>
|
||||
<field name="installation_location"/>
|
||||
<field name="is_state"/>
|
||||
<field name="type"/>
|
||||
<field name="gauge_magnification"/>
|
||||
<field name="maximum_count"/>
|
||||
<field name="lessee_id"/>
|
||||
<field name="employee_ids" widget="many2many_tags"/>
|
||||
<field name="epitope_values"/>
|
||||
<field name="meter_type"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="other"/>
|
||||
<field name="meter_date"/>
|
||||
<field name="last_dosage"/>
|
||||
<field name="last_read"/>
|
||||
<field name="last_meter"/>
|
||||
<field name="current_meter"/>
|
||||
<field name="current_read"/>
|
||||
<field name="unit"/>
|
||||
<field name="is_push"/>
|
||||
<field name="start_time"/>
|
||||
<field name="end_time"/>
|
||||
<field name="line_loss"/>
|
||||
<field name="receivables"/>
|
||||
<field name="last_reading_time"/>
|
||||
<field name="standards_id"/>
|
||||
<field name="yuthon_property_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_property_meter_water_tree1" model="ir.ui.view">
|
||||
<field name="name">property.meter.water.tree</field>
|
||||
<field name="model">property.meter.water</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="水表任务" create="False" editable="bottom" js_clasee="custom_water_button">
|
||||
<button name="open_record" string="详情" type="object" class="oe_highlight"/>
|
||||
<field name="name" readonly="1"/>
|
||||
<field name="yuthon_property_id" string="地址" readonly="1"/>
|
||||
<field name="yuthon_property_ids" string="地址" readonly="1" widget="many2many_tags"/>
|
||||
<field name="lessee_id" options="{'no_create': True}" readonly="1"/>
|
||||
<field name="meter_date" readonly="1"/>
|
||||
<field name="gauge_magnification"/>
|
||||
@@ -62,7 +114,7 @@
|
||||
<field name="model">property.meter.water</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="水表">
|
||||
<field name="yuthon_property_id"/>
|
||||
<field name="yuthon_property_ids"/>
|
||||
<field name="lessee_id"/>
|
||||
</search>
|
||||
</field>
|
||||
@@ -70,23 +122,26 @@
|
||||
<record id="action_property_meter_water" model="ir.actions.act_window">
|
||||
<field name="name">水表库</field>
|
||||
<field name="res_model">property.meter.water</field>
|
||||
<field name="view_mode">tree,search</field>
|
||||
<field name="view_mode">tree,form,search</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_property.view_property_meter_water_tree')})]"/>
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_property.view_property_meter_water_tree')}),
|
||||
(0, 0, {'view_mode': 'form', 'view_id': ref('yuthon_property.property_meter_water_form')})]"/>
|
||||
</record>
|
||||
<record id="action_property_meter_water1" model="ir.actions.act_window">
|
||||
<field name="name">水表任务</field>
|
||||
<field name="res_model">property.meter.water</field>
|
||||
<field name="view_mode">tree,search</field>
|
||||
<field name="view_mode">tree,form,search</field>
|
||||
<field name="domain">[('is_push', '=', True)]</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_property.view_property_meter_water_tree1')})]"/>
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_property.view_property_meter_water_tree1')}),
|
||||
(0, 0, {'view_mode': 'form', 'view_id': ref('yuthon_property.property_meter_water_form')})]"/>
|
||||
</record>
|
||||
<record id="all_data_meter_water_property" model="ir.actions.server">
|
||||
<field name="name">导入水表</field>
|
||||
<field name="model_id" ref="yuthon_property.model_property_meter_water"/>
|
||||
<field name="binding_model_id" ref="yuthon_property.model_property_meter_water"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.action_property_water_wizard()</field>
|
||||
</record>
|
||||
<record id="all_update_meter" model="ir.actions.server">
|
||||
<field name="name">更新状态</field>
|
||||
|
||||
@@ -26,36 +26,60 @@ class PropertyMeterWizard(models.Model):
|
||||
row = sh.row(rx)
|
||||
self.property_meter_data(row)
|
||||
|
||||
def property_meter_data(self,row):
|
||||
name = row[0].value
|
||||
def property_meter_data(self, row):
|
||||
epitope_values = row[0].value
|
||||
name = row[3].value
|
||||
type_dict = {'水表': 'water', '电表': 'electric', '电表(电子表)': 'smart', '': ''}
|
||||
meter_type = type_dict.get(row[4].value)
|
||||
unit_number = row[1].value
|
||||
installation_location = row[2].value
|
||||
if row[4].value:
|
||||
gauge_magnification = float(row[4].value)
|
||||
if row[5].value:
|
||||
gauge_magnification = float(row[5].value)
|
||||
else:
|
||||
gauge_magnification = None
|
||||
property_id = self.env['yuthon.property'].search([('name', '=', row[8].value)])
|
||||
meter_list = []
|
||||
type_dict = {'公共':'public', '收费':'fees', '':''}
|
||||
type = type_dict.get(row[6].value)
|
||||
state_dict = {'启用': 1, '停用': 0, '': ''}
|
||||
is_state = state_dict.get(row[7].value)
|
||||
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]
|
||||
meter_data = {
|
||||
'name': name,
|
||||
'meter_type': meter_type,
|
||||
'epitope_values': epitope_values,
|
||||
'maximum_count': maximum_count,
|
||||
'unit_number': unit_number,
|
||||
'installation_location': installation_location,
|
||||
'type': type,
|
||||
'gauge_magnification': gauge_magnification,
|
||||
'yuthon_property_id':property_id.id if property_id else None,
|
||||
'is_state':is_state
|
||||
}
|
||||
meter_id = self.env['property.meter.archives'].create(meter_data)
|
||||
if property_id:
|
||||
meter_list.append((0, 0, {
|
||||
'property_meter_archives_id': meter_id.id,
|
||||
}))
|
||||
property_id.write({
|
||||
'is_electricity_meter' : True,
|
||||
})
|
||||
property_id.energy_meter_ids = [(5, 0, 0)]
|
||||
property_id.energy_meter_ids = meter_list
|
||||
meter_data['yuthon_property_ids'] = [(4, property_id.id)]
|
||||
|
||||
meter_id = self.env['property.meter.archives'].search([('name', '=', row[3].value)], limit=1)
|
||||
if meter_id:
|
||||
meter_id.write(meter_data)
|
||||
else:
|
||||
meter_id = self.env['property.meter.archives'].create(meter_data)
|
||||
|
||||
if property_id:
|
||||
# 检查物业是否已关联该电表
|
||||
existing_meter = next((
|
||||
meter for meter in property_id.energy_meter_ids
|
||||
if meter.property_meter_archives_id.id == meter_id.id
|
||||
), None)
|
||||
|
||||
if not existing_meter:
|
||||
existing_entries = [(4, meter.id) for meter in property_id.energy_meter_ids]
|
||||
new_meter_entry = (0, 0, {
|
||||
'property_meter_archives_id': meter_id.id,
|
||||
})
|
||||
updated_meters = existing_entries + [new_meter_entry]
|
||||
property_id.write({
|
||||
'is_electricity_meter': True,
|
||||
'energy_meter_ids': updated_meters
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -27,35 +27,57 @@ class PropertyWaterWizard(models.Model):
|
||||
self.property_water_data(row)
|
||||
|
||||
def property_water_data(self,row):
|
||||
name = row[0].value
|
||||
epitope_values = row[0].value
|
||||
name = row[3].value
|
||||
type_dict = {'水表': 'water', '电表': 'electric', '电表(电子表)': 'smart', '': ''}
|
||||
meter_type = type_dict.get(row[4].value)
|
||||
unit_number = row[1].value
|
||||
installation_location = row[2].value
|
||||
if row[4].value:
|
||||
gauge_magnification = float(row[4].value)
|
||||
if row[5].value:
|
||||
gauge_magnification = float(row[5].value)
|
||||
else:
|
||||
gauge_magnification = None
|
||||
property_id = self.env['yuthon.property'].search([('name', '=', row[8].value)])
|
||||
water_list = []
|
||||
type_dict = {'公共':'public', '收费':'fees', '':''}
|
||||
type = type_dict.get(row[6].value)
|
||||
state_dict = {'启用':1, '停用':0, '':''}
|
||||
is_state = state_dict.get(row[7].value)
|
||||
water_data = {
|
||||
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]
|
||||
meter_data = {
|
||||
'name': name,
|
||||
'meter_type': meter_type,
|
||||
'epitope_values': epitope_values,
|
||||
'maximum_count': maximum_count,
|
||||
'unit_number': unit_number,
|
||||
'installation_location': installation_location,
|
||||
'type': type,
|
||||
'gauge_magnification': gauge_magnification,
|
||||
'yuthon_property_id':property_id.id if property_id else None,
|
||||
'is_state':is_state
|
||||
}
|
||||
water_id = self.env['property.meter.water'].create(water_data)
|
||||
if property_id:
|
||||
water_list.append((0, 0, {
|
||||
'property_meter_water_id': water_id.id,
|
||||
}))
|
||||
property_id.write({
|
||||
'is_meter' : True,
|
||||
})
|
||||
property_id.water_meter_ids = [(5, 0, 0)]
|
||||
property_id.water_meter_ids = water_list
|
||||
meter_data['yuthon_property_ids'] = [(4, property_id.id)]
|
||||
|
||||
meter_id = self.env['property.meter.water'].search([('name', '=', row[3].value)], limit=1)
|
||||
if meter_id:
|
||||
meter_id.write(meter_data)
|
||||
else:
|
||||
meter_id = self.env['property.meter.water'].create(meter_data)
|
||||
|
||||
if property_id:
|
||||
# 检查物业是否已关联该水表
|
||||
existing_meter = next((
|
||||
meter for meter in property_id.water_meter_ids
|
||||
if meter.property_meter_water_id.id == meter_id.id
|
||||
), None)
|
||||
if not existing_meter:
|
||||
existing_entries = [(4, meter.id) for meter in property_id.water_meter_ids]
|
||||
new_meter_entry = (0, 0, {
|
||||
'property_meter_water_id': meter_id.id,
|
||||
})
|
||||
updated_meters = existing_entries + [new_meter_entry]
|
||||
property_id.write({
|
||||
'is_meter': True,
|
||||
'water_meter_ids': updated_meters
|
||||
})
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ class PropertyBankStatements(models.Model):
|
||||
('lessee_id', '=', tenant_id),
|
||||
('contract_id', 'in', rec.contract_ids.ids),
|
||||
('property_id', 'in', rec.property_ids.ids),
|
||||
('original_amount', '=', rec.original_amount),
|
||||
('payout_date', '!=', None),
|
||||
('management_type_id', '!=', penalty_type.id),
|
||||
])
|
||||
if accounts:
|
||||
|
||||
@@ -198,6 +198,18 @@ class PropertyReconciliationWizard(models.Model):
|
||||
|
||||
# 3. 补全缺失的跨月违约金(按合同+物业+年月匹配,缺失则新增)
|
||||
missing_penalty_lines = []
|
||||
year, month = map(int, due_month.split('-'))
|
||||
first_day = datetime(year, month, 1).date()
|
||||
penalty_days = (self.actual_date - first_day).days + 1
|
||||
|
||||
if month == 1:
|
||||
last_month_year = year - 1
|
||||
last_month = 12
|
||||
else:
|
||||
last_month_year = year
|
||||
last_month = month - 1
|
||||
last_month_str = f"{last_month_year}-{last_month:02d}"
|
||||
|
||||
for rent_info in target_rent_months:
|
||||
contract = rent_info['contract_id']
|
||||
property_rec = rent_info['property_id']
|
||||
@@ -212,18 +224,6 @@ class PropertyReconciliationWizard(models.Model):
|
||||
|
||||
if check_key not in existing_penalty_months:
|
||||
# 计算补全违约金的日期范围:当月1号 ~ 当月最后1天
|
||||
year, month = map(int, due_month.split('-'))
|
||||
first_day = datetime(year, month, 1).date()
|
||||
penalty_days = (self.actual_date - first_day).days + 1
|
||||
|
||||
if month == 1:
|
||||
last_month_year = year - 1
|
||||
last_month = 12
|
||||
else:
|
||||
last_month_year = year
|
||||
last_month = month - 1
|
||||
last_month_str = f"{last_month_year}-{last_month:02d}"
|
||||
|
||||
# 查找上个月的租金明细行
|
||||
last_month_rent_line = next((
|
||||
line for line in self.reconciliation_line_ids
|
||||
@@ -233,7 +233,6 @@ class PropertyReconciliationWizard(models.Model):
|
||||
and line.due_date # 有到期日期
|
||||
and fields.Date.from_string(line.due_date).strftime('%Y-%m') == last_month_str
|
||||
), None)
|
||||
|
||||
# 提取上个月租金的rent金额
|
||||
last_month_rent = last_month_rent_line.rent if last_month_rent_line else 0.0
|
||||
penalty_amount = penalty_days * round(
|
||||
@@ -252,6 +251,34 @@ class PropertyReconciliationWizard(models.Model):
|
||||
'remake': f'违约金({fields.Date.to_string(first_day)}至{fields.Date.to_string(self.actual_date)},共{penalty_days}天',
|
||||
}))
|
||||
|
||||
# 查找上个月应收是否有为交全的租金
|
||||
unpaid_rent_recs = self.env['property.accounts.receivable'].search([
|
||||
('management_type_id.name', '=', '租金'),
|
||||
('contract_id', '=', contract_id.id),
|
||||
('property_id', '=', property_id),
|
||||
('submitted', '!=', 0),
|
||||
('payout_date', '!=', None),
|
||||
('due_date', '=like', f'{last_month_str}%')
|
||||
])
|
||||
if unpaid_rent_recs:
|
||||
first_day = (unpaid_rent_recs.payout_date + timedelta(days=1))
|
||||
last_month_rent = unpaid_rent_recs.submitted
|
||||
penalty_days = self.actual_date - first_day
|
||||
penalty_amount = (penalty_days.days +1) * round(last_month_rent * float(contract.percentage_liquidated_damages.name), 2
|
||||
) if contract else 0.0
|
||||
if penalty_amount > 0:
|
||||
missing_penalty_lines.append((0, 0, {
|
||||
'property_id': property_rec.id if property_rec else None,
|
||||
'contract_id': contract.id if contract else None,
|
||||
'rent_month': 0,
|
||||
'due_date': fields.Date.to_string(first_day),
|
||||
'rent': penalty_amount,
|
||||
'amount': 0,
|
||||
'collection_type': 'penalty',
|
||||
'remake': f'违约金({fields.Date.to_string(first_day)}至{fields.Date.to_string(self.actual_date)},共{penalty_days.days + 1}天)',
|
||||
}))
|
||||
|
||||
|
||||
if missing_penalty_lines:
|
||||
self.write({ 'reconciliation_line_ids': missing_penalty_lines})
|
||||
self.create_reconciliation_vals()
|
||||
@@ -369,7 +396,7 @@ class PropertyReconciliationWizard(models.Model):
|
||||
receivable.write({
|
||||
'is_reconciliation': is_reconciliation,
|
||||
'delivered1': line.amount,
|
||||
'payout_date': rec.actual_date if line.rent == line.amount else None,
|
||||
'payout_date': rec.actual_date,
|
||||
'remark': line.remake,
|
||||
'reconciliation_time': fields.Datetime.now(),
|
||||
'receivable_log': f'当前登录人{rec.env.user.name}于{fields.Datetime.now()}对户名为{rec.bank_id.name_account}进行对账操作,对账应收金额为{rec.receivable_total},实际金额为{rec.actual_total}'
|
||||
@@ -415,13 +442,7 @@ class PropertyReconciliationWizard(models.Model):
|
||||
'remark': line.remake,
|
||||
'reconciliation_time': fields.Datetime.now(),
|
||||
})
|
||||
rec.bank_id.write({
|
||||
'create_receivable_ids': [(4, receivable_id.id)]
|
||||
})
|
||||
# if receivable_id:
|
||||
# rec.bank_id.write({
|
||||
# 'create_receivable_ids': [(4, receivable_id.id)]
|
||||
# })
|
||||
|
||||
else:
|
||||
existing_record.write({
|
||||
'delivered1': existing_record.delivered1 + line.amount,
|
||||
@@ -433,9 +454,6 @@ class PropertyReconciliationWizard(models.Model):
|
||||
'is_write': True if line.amount != 0 else None,
|
||||
'reconciliation_time': fields.Datetime.now(),
|
||||
})
|
||||
# rec.bank_id.write({
|
||||
# 'write_receivable_ids': [(4, existing_record.id)]
|
||||
# })
|
||||
|
||||
# 计算已对账和未对账金额
|
||||
rec.amount_been_reconciled += line.amount
|
||||
|
||||
@@ -167,8 +167,8 @@ class InheritHrPayslip(models.Model):
|
||||
total_payable = fields.Float(string='应缴金额合计')
|
||||
|
||||
performance_deduction = fields.Float(string='扣发绩效奖金')
|
||||
commuting_deduction = fields.Float(string='扣发通信补贴', compute='_compute_deduction', store=True)
|
||||
base_salary_deduction = fields.Float(string='扣发基本工资', compute='_compute_deduction', store=True)
|
||||
commuting_deduction = fields.Float(string='扣发通信补贴', store=True)
|
||||
base_salary_deduction = fields.Float(string='扣发基本工资', store=True)
|
||||
specialized_deduction = fields.Float(string='累计专项扣除')
|
||||
|
||||
@api.onchange('minus_att', 'individual_income_tax', 'minus_annuity_difference')
|
||||
@@ -564,14 +564,6 @@ class InheritHrPayslip(models.Model):
|
||||
}
|
||||
|
||||
|
||||
@api.depends('employee_id')
|
||||
def _compute_deduction(self):
|
||||
for rec in self:
|
||||
employee_id = self.env['hr.employee'].search([('id', '=', rec.employee_id.id)])
|
||||
rec.performance_deduction = employee_id.last_month_performance_deduction
|
||||
rec.commuting_deduction = employee_id.last_month_commuting_deduction
|
||||
rec.base_salary_deduction = employee_id.last_month_base_salary_deduction
|
||||
|
||||
def put_payslip(self):
|
||||
menu_id = self.env['ir.ui.menu'].search([('name', '=', '工资条'), ('parent_id', '!=', False)])
|
||||
url = f'https://oa.thtzjt.com/web#id={self.id}&cids=2&action={menu_id.action.id}&model=hr.payslip&view_type=list&menu_id={menu_id.id}'
|
||||
|
||||
@@ -56,11 +56,11 @@ class YuthonPayrollCommon(models.Model):
|
||||
rule_list = []
|
||||
formula_salary = ''
|
||||
if ins.name == '扣发绩效奖金':
|
||||
formula_salary = "result = employee.last_month_performance_deduction"
|
||||
formula_salary = "result = (employee.last_month_performance_deduction) * -1"
|
||||
if ins.name == '扣发通信补贴':
|
||||
formula_salary = "result = employee.last_month_commuting_deduction"
|
||||
formula_salary = "result = (employee.last_month_commuting_deduction) * -1"
|
||||
if ins.name == '扣发基本工资':
|
||||
formula_salary = "result = employee.last_month_base_salary_deduction"
|
||||
formula_salary = "result = (employee.last_month_base_salary_deduction) * -1"
|
||||
if ins.name == '工龄工资' and ins.company_id.name == '天河物管':
|
||||
formula_salary = "result = employee.company_old_year * 10 if employee.company_old_year >= 1 and employee.department_id.name != '领导班子' else 0"
|
||||
if ins.name == '工龄工资' and ins.company_id.name == '集团本部':
|
||||
@@ -74,7 +74,7 @@ class YuthonPayrollCommon(models.Model):
|
||||
if ins.name == '全勤奖' and ins.company_id.name == '天河物管':
|
||||
formula_salary = "result = 100 if employee.last_attendance else 0"
|
||||
if ins.name == '加班费':
|
||||
formula_salary = "result = c if (employee.is_annual_salary or employee.contract_id.structure_type_id.name == '工勤返聘') else (round(((employee.all_overtime_hours - 40) * (payslip.base_salary / 21.75 / 8) * 1.5), 0) if employee.all_overtime_hours > 40 else 0)"
|
||||
formula_salary = "result = c if (employee.is_annual_salary or employee.contract_id.structure_type_id.name == '工勤返聘') else (round(((employee.last_month_overtime - 40) * (payslip.base_salary / 21.75 / 8) * 1.5), 0) if employee.last_month_overtime > 40 else 0)"
|
||||
if ins.name == '岗位工资':
|
||||
formula_salary = "result = 0"
|
||||
if ins.name == '安全生产管理补贴':
|
||||
|
||||
@@ -55,10 +55,10 @@ class SalaryComputeWizard(models.Model):
|
||||
('contract_id.termination_date', '=', False),
|
||||
('contract_id.date_end', '=', False)
|
||||
])
|
||||
self.employee_ids = [(6, 0, employees.ids)]
|
||||
self.employee_number = len(employees)
|
||||
for employee in employees:
|
||||
print(f"员工姓名: {employee.name}")
|
||||
# self.employee_ids = [(6, 0, employees.ids)]
|
||||
# self.employee_number = len(employees)
|
||||
# for employee in employees:
|
||||
# print(f"员工姓名: {employee.name}")
|
||||
|
||||
@api.onchange('employee_ids')
|
||||
def onchange_employee_ids(self):
|
||||
@@ -97,8 +97,7 @@ class SalaryComputeWizard(models.Model):
|
||||
'state': 'draft',
|
||||
'payslip_count': 0
|
||||
})
|
||||
query_date = datetime(year, month, 1).date()
|
||||
|
||||
query_date = datetime(year, month, 1).date()
|
||||
vacation_report = self.env['yuthon.vacation.reports'].search([
|
||||
('employee_id', '=', employee.id),
|
||||
('vacation_date', '=', query_date)
|
||||
@@ -144,6 +143,11 @@ class SalaryComputeWizard(models.Model):
|
||||
}
|
||||
# 更新员工花名册记录
|
||||
employee.write(update_vals)
|
||||
|
||||
# 加班时长
|
||||
employee.last_month_overtime = vacation_report.done_working_overtime
|
||||
employee.last_attendance = vacation_report.should_attendance == vacation_report.actual_attendance
|
||||
|
||||
employee.salary_date = start_date
|
||||
employee.salary_month = self.select_time
|
||||
employee.salary_year_jin_ids = [(6, 0, self.employee_ids.ids)]
|
||||
@@ -185,11 +189,6 @@ class SalaryComputeWizard(models.Model):
|
||||
contract = employee.contract_id
|
||||
year = int(self.select_year)
|
||||
month = int(self.select_time)
|
||||
# 更改扣发绩效奖金
|
||||
performance_deduction = self.salary_performance_deduction(employee, self.select_year, self.select_time, internship_id.performance_bonuses)
|
||||
internship_id.write({
|
||||
'performance_deduction': performance_deduction,
|
||||
})
|
||||
# 获取离职日期
|
||||
turnover_date = contract.date_end
|
||||
start_date = fields.Date.from_string(start_date)
|
||||
@@ -321,12 +320,29 @@ class SalaryComputeWizard(models.Model):
|
||||
setattr(internship_id, field_name, result)
|
||||
line.write({'total': result})
|
||||
|
||||
# 计算扣发绩效奖金
|
||||
performance_deduction = self.salary_performance_deduction(vacation_report, internship_id.performance_bonuses)
|
||||
employee.write({
|
||||
'last_month_performance_deduction': performance_deduction,
|
||||
})
|
||||
# 计算扣发基本薪资
|
||||
basic_salary_deduction = self.salary_basic_salary_deduction(vacation_report, internship_id.base_salary)
|
||||
employee.write({
|
||||
'last_month_base_salary_deduction': basic_salary_deduction,
|
||||
})
|
||||
# 计算扣发通讯
|
||||
commuting_deduction = self.salary_commuting_deduction(vacation_report, internship_id.commuting_allowance)
|
||||
employee.write({
|
||||
'last_month_commuting_deduction': commuting_deduction,
|
||||
})
|
||||
|
||||
year = int(self.select_year)
|
||||
month = int(self.select_time)
|
||||
for rec2 in self.env['hr.payslip'].search([('is_push', '=', False)]):
|
||||
if not self._is_employee_turnover(rec2.employee_id, year, month) and not self._is_employee_in_probation(
|
||||
rec2.employee_id, year, month):
|
||||
rec2.compute_sheet()
|
||||
if not self._is_employee_turnover(existing_payslip.employee_id, year, month) and not self._is_employee_in_probation(
|
||||
existing_payslip.employee_id, year, month):
|
||||
existing_payslip.compute_sheet()
|
||||
|
||||
|
||||
|
||||
def _get_chinese_month(self, month):
|
||||
chinese_months = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
|
||||
@@ -429,19 +445,62 @@ class SalaryComputeWizard(models.Model):
|
||||
selected_date = fields.Date.to_date(f"{year}-{month:02d}-01")
|
||||
return contract.start_date <= selected_date <= contract.end_date
|
||||
|
||||
def salary_performance_deduction(self, employee, selected_year, selected_month, performance_bonuses):
|
||||
attendance_month_obj = self.env["hr.attendance.month.detail"].search([
|
||||
('employee_id', '=', employee.id),
|
||||
('current_year', '=', selected_year),
|
||||
('current_month', '=', selected_month),
|
||||
('state', '=', 'confirmed')
|
||||
], limit=1)
|
||||
if attendance_month_obj:
|
||||
year = int(selected_year)
|
||||
month = int(selected_month)
|
||||
last_day = calendar.monthrange(year, month)[1]
|
||||
total_days = last_day
|
||||
result = (performance_bonuses / total_days) * attendance_month_obj.maternity_leave if total_days != 0 else 0.0
|
||||
return round(result, 2)
|
||||
else:
|
||||
return 0.00
|
||||
def salary_performance_deduction(self, vacation_report, performance_bonuses):
|
||||
if not (vacation_report and performance_bonuses):
|
||||
return 0.00
|
||||
deduction_leave_fields = [
|
||||
'marriage_leave', # 婚假
|
||||
'maternity_leave', # 产假
|
||||
'paternity_leave', # 陪产假
|
||||
'family_planning_leave', # 计生假
|
||||
'bereavement_leave', # 丧假
|
||||
'home_visit_leave', # 探亲假
|
||||
'general_sick_leave', # 病假(普通)
|
||||
'hospital_sick_leave', # 病假(住院期)
|
||||
'recovery_sick_leave', # 病假(出院恢复期)
|
||||
'exam_leave', # 考试假
|
||||
'parents_meeting_leave', # 家长会假
|
||||
'leave_of_absence' # 事假
|
||||
]
|
||||
total_leave_days = 0.0
|
||||
for field in deduction_leave_fields:
|
||||
leave_days = getattr(vacation_report, field, 0.0)
|
||||
total_leave_days += leave_days if leave_days > 0 else 0.0
|
||||
if total_leave_days <= 0:
|
||||
return 0.00
|
||||
return round((performance_bonuses / 21.75) * total_leave_days, 2)
|
||||
|
||||
def salary_basic_salary_deduction(self, vacation_report, base_salary):
|
||||
if not (vacation_report and base_salary > 0):
|
||||
return 0.00
|
||||
|
||||
deduction_rules = {
|
||||
'general_sick_leave': 1.0, # 普通病假:1%
|
||||
'recovery_sick_leave': 1.0, # 出院恢复期病假:1%
|
||||
'leave_of_absence': 2.5 # 事假:2.5%
|
||||
}
|
||||
total_deduction = 0.0
|
||||
for leave_field, ratio in deduction_rules.items():
|
||||
leave_days = getattr(vacation_report, leave_field, 0.0)
|
||||
if leave_days > 0:
|
||||
single_deduction = base_salary * leave_days * (ratio / 100)
|
||||
total_deduction += single_deduction
|
||||
|
||||
return round(total_deduction, 2)
|
||||
|
||||
def salary_commuting_deduction(self, vacation_report, communication_subsidy):
|
||||
if not (vacation_report and communication_subsidy > 0):
|
||||
return 0.00
|
||||
maternity_days = vacation_report.maternity_leave # 产假天数
|
||||
paternity_days = vacation_report.paternity_leave # 陪产假天数
|
||||
family_planning_days = vacation_report.family_planning_leave # 计生假天数
|
||||
total_days = sum([
|
||||
maternity_days if maternity_days > 0 else 0,
|
||||
paternity_days if paternity_days > 0 else 0,
|
||||
family_planning_days if family_planning_days > 0 else 0
|
||||
])
|
||||
# 通讯补贴 / 21.75 * 总请假天数
|
||||
if total_days <= 0:
|
||||
return 0.00
|
||||
deduction_amount = (communication_subsidy / 21.75) * total_days
|
||||
return round(deduction_amount, 2)
|
||||
@@ -7,7 +7,7 @@ class StockPicking(models.Model):
|
||||
_inherit = 'stock.picking'
|
||||
|
||||
document_ids = fields.Many2many('ir.attachment', string="附件")
|
||||
employee_id = fields.Many2one('hr.employee', string="领用人")
|
||||
employee_id = fields.Many2one('hr.employee', string="验收人")
|
||||
user_id = fields.Many2one('res.users', string="采购人员", compute="_compute_origin")
|
||||
json_display = fields.Char(
|
||||
string="物品详情",
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</group>
|
||||
<group>
|
||||
<field name="user_id" string="采购人员"/>
|
||||
<field name="employee_id" string="验收人"/>
|
||||
<field name="employee_id" string="验收人" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
</xpath>
|
||||
|
||||
Reference in New Issue
Block a user