添加功能

This commit is contained in:
李鹏宇
2026-02-07 17:31:19 +08:00
parent b7e74e6831
commit 0f3c86fca3
17 changed files with 210 additions and 22 deletions
+13 -4
View File
@@ -564,10 +564,19 @@ class SoongWorkflowMixin(models.AbstractModel):
is_supervising = False
if self.name_title in ['行政发文']:
is_supervising = self.is_supervising
if btn_rec.node_id.comment_id:
comment_note_id = btn_rec.node_id.comment_id.id
else:
comment_note_id = False
comment_field_map = {
'转交': 'transfer_comment_id',
'退回': 'return_comment_id',
'确认': 'confirm_comment_id',
'结束': 'end_comment_id'
}
comment_note_id = False
if btn_rec.name in comment_field_map:
target_field = comment_field_map[btn_rec.name]
if hasattr(btn_rec.node_id, target_field) and btn_rec.node_id[target_field]:
comment_note_id = btn_rec.node_id[target_field].id
# 加签人员过滤
if self.log_ids:
log_node_ids = self.log_ids.mapped('node_id.id')
+5 -1
View File
@@ -112,7 +112,11 @@ class SoongWorkflowNode(models.Model):
column1="node_id",
column2="transfer_department_id"
)
comment_id = fields.Many2one('soong.note', string="固定意见")
transfer_comment_id = fields.Many2one('soong.note', string="转交固定意见")
return_comment_id = fields.Many2one('soong.note', string="退回固定意见")
confirm_comment_id = fields.Many2one('soong.note', string="确认固定意见")
end_comment_id = fields.Many2one('soong.note', string="结束固定意见")
approval_concatenation = fields.Selection([('chuan', '串申'), ('bing', '并申')], string="审批形式", default="bing",
help='并:任何人均给意见,最后一个完成的人转交到下一节点.'
'串:都会收到消息,但任意一个人转交后,即到下一节点,其他人将不再显示,相当于收回.')
@@ -13,7 +13,10 @@
<field name="name" placeholder="ex. 'Draft' or 'Direct Manager'" required="1"/>
<field name="node_name" placeholder="ex. 'draft' or 'direct_manager'" required="1"/>
<field name="department_id" widget="many2many_tags"/>
<field name="comment_id"/>
<field name="transfer_comment_id"/>
<field name="return_comment_id"/>
<field name="confirm_comment_id"/>
<field name="end_comment_id"/>
<field name="illustrate"/>
</group>
<group>
@@ -97,7 +97,7 @@ class HrAttendanceDetail(models.Model):
@api.model
def create(self, vals):
record = super(HrAttendanceDetail, self).create(vals)
if record.employee_id.name != '龙春球':
if record.employee_id.name not in ['龙春球', 'Administrator']:
resource_user_ids = record.employee_id.resource_calendar_id.resource_user_ids.ids
is_resource_user = True if record.employee_id.id in resource_user_ids else False
if record.employee_id and record.checkin_time and record.source == 'iot' and not is_resource_user:
@@ -196,4 +196,24 @@ class YuthonMedicalLine(models.Model):
medical_date = fields.Date(string="报销日期")
medical_fee = fields.Float(string="金额")
enable = fields.Boolean(string="启用", default=True)
remake = fields.Text(string="备注")
@api.constrains('employee_id', 'medical_date')
def _check_duplicate_medical_line(self):
for rec in self:
domain = [
('employee_id', '=', rec.employee_id.id),
('medical_date', '=', rec.medical_date),
('id', '!=', rec.id)
]
duplicate_rec = self.search(domain, limit=1)
if duplicate_rec:
if not self.env.context.get('confirm_update_medical_line'):
raise UserError(_(
f"检测到员工【{rec.employee_id.name}】在【{rec.medical_date}】已有体检费记录,请重新选择日期"
))
@@ -6,11 +6,12 @@
<field name="arch" type="xml">
<tree string="体检费管理" editable="bottom">
<header>
<button name="property_reimbursement_form" string="提交体检费报销审批" type="object" class="oe_highlight"/>
<button name="property_reimbursement_form" string="提交体检费报销审批" type="object"
class="oe_highlight"/>
</header>
<field name="employee_id" options="{'no_create': True}"/>
<field name="year" column_invisible="1"/>
<!-- <field name="company_id" required="1" optional="show"/>-->
<!-- <field name="company_id" required="1" optional="show"/>-->
<field name="current_year_remaining" options='{ "fg_color": "blue"}'/>
<field name="this_year_quota"/>
<field name="last_year_balance"/>
@@ -28,14 +29,32 @@
<field name="name">体检报销费</field>
<field name="model">yuthon.medical.line</field>
<field name="arch" type="xml">
<tree editable="bottom" default_order="medical_date desc">
<tree default_order="medical_date desc">
<field name="medical_date"/>
<field name="medical_fee"/>
<field name="employee_id"/>
<field name="remake"/>
<field name="enable"/>
</tree>
</field>
</record>
<record id="yuthon_medical_line_form" model="ir.ui.view">
<field name="name">体检报销费</field>
<field name="model">yuthon.medical.line</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="employee_id" required="1"/>
<field name="medical_date"/>
<field name="medical_fee" required="1"/>
<field name="remake" required="1"/>
<field name="enable" required="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="yuthon_medical_line_search" model="ir.ui.view">
<field name="name">体检报销费搜索</field>
<field name="model">yuthon.medical.line</field>
@@ -45,7 +64,8 @@
<field name="medical_date"/>
<group expand="0" string="分组方式">
<filter string="报销日期" name="group_medical_date" context="{'group_by':'medical_date'}"/>
<filter string="按年" name="group_by_medical_year" domain="[]" context="{'group_by':'medical_date:year'}"/>
<filter string="按年" name="group_by_medical_year" domain="[]"
context="{'group_by':'medical_date:year'}"/>
</group>
</search>
</field>
@@ -56,12 +76,12 @@
<field name="arch" type="xml">
<search>
<field name="employee_id"/>
<header_search class="header-search-inline">
<header_search class="header-search-inline">
<field name="year"/>
</header_search>
<group expand="0" string="审批分组">
<filter string="年" name='group_year' context="{'group_by':'year'}"/>
</group>
<group expand="0" string="审批分组">
<filter string="年" name='group_year' context="{'group_by':'year'}"/>
</group>
</search>
</field>
</record>
@@ -79,10 +99,10 @@
<field name="code">action = model.medical_manage_wizard()</field>
</record>
<record id="yuthon_medical_line_action" model="ir.actions.act_window">
<field name="name">体检报销费</field>
<field name="res_model">yuthon.medical.line</field>
<field name="view_mode">tree</field>
<field name="context">{'search_default_group_by_medical_year': 1}</field>
<field name="name">体检报销费</field>
<field name="res_model">yuthon.medical.line</field>
<field name="view_mode">tree,form</field>
<field name="context">{'search_default_group_by_medical_year': 1}</field>
</record>
</odoo>
@@ -52,6 +52,13 @@ class PropertyAccountsReceivable(models.Model):
bank_id = fields.Many2one('property.bank.statements', string='流水记录')
receivable_log = fields.Text(string='应收日志')
def update_is_invalid(self):
record_ids = self.env["property.accounts.receivable"].browse(
self._context.get("active_ids", self._context.get("active_id"))
)
for record in record_ids:
record.void_date = fields.Date.today()
record.is_invalid = True
def update_due_date_end(self):
record_ids = self.env["property.accounts.receivable"].browse(
@@ -3,7 +3,8 @@
<field name="name">property.accounts.receivable.tree</field>
<field name="model">property.accounts.receivable</field>
<field name="arch" type="xml">
<tree editable="bottom" string="应收账单" decoration-success="is_reconciliation == True" limit="15" delete="false">
<tree editable="bottom" string="应收账单" decoration-success="is_reconciliation == True" limit="15" delete="false"
decoration-muted="is_invalid">
<field name="acc_type" string=" "/>
<field name="management_type_id" readonly="0"/>
<field name="due_date" readonly="0" width="300px" required="1"/>
@@ -75,6 +76,13 @@
</tree>
</field>
</record>
<record id="all_update_is_invalid" model="ir.actions.server">
<field name="name">批量作废</field>
<field name="model_id" ref="yuthon_property.model_property_accounts_receivable"/>
<field name="binding_model_id" ref="yuthon_property.model_property_accounts_receivable"/>
<field name="state">code</field>
<field name="code">action = model.update_is_invalid()</field>
</record>
<record id="all_property_accounts_receivable_contract" model="ir.actions.server">
<field name="name">导入应收初始化数据</field>
<field name="model_id" ref="yuthon_property.model_property_accounts_receivable"/>
+1
View File
@@ -95,6 +95,7 @@
'wizard/contract_signature_wizard_viwes.xml',
'wizard/penalty_line_wizard_viwes.xml',
'wizard/build_pop_wizard_viwes.xml',
'wizard/build_fee_wizard_views.xml',
'wizard/action_refuse_wizard_views.xml',
'wizard/property_bills_wizard_views.xml',
'wizard/property_meeting_wizard_views.xml',
@@ -15,6 +15,9 @@ class PropertyFeeSpending(models.Model):
property_address = fields.Text(string="物业地址")
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门")
approve_state = fields.Selection([("start", "草稿"), ("pending", "审批中"), ("end", "结束")], default="start",
string="状态", compute="_compute_approve_state")
company_id = fields.Many2one(related='users_id.employee_id.company_id',string="公司")
code = fields.Char(string="编号",
default=lambda self: self.env['ir.sequence'].next_by_code('property_fee_spending_code'))
@@ -32,6 +35,7 @@ class PropertyFeeSpending(models.Model):
pay_date = fields.Date(string="支付日期")
expenses_type = fields.Many2one('yuthon.expenses.type', string="支出类型")
creart_datetime = fields.Datetime(string="创建日期", default=fields.Datetime.now)
spending_ids = fields.One2many('property.fee.spending.line', 'fee_id', string="物业明细")
remake = fields.Text(string="备注")
def _get_default_name_title(self):
@@ -41,6 +45,37 @@ class PropertyFeeSpending(models.Model):
self_users_ids = fields.Many2many('res.users', string="当前经办人", default=lambda self: [(6, 0, [self.env.user.id])])
def build_pop(self):
return {
'name': '添加物业',
'type': 'ir.actions.act_window',
'res_model': 'build.fee.wizard',
'view_mode': 'form',
'target': 'new',
'context': {
'default_fee_id': self.id,
}
}
@api.depends('code')
def _compute_approve_state(self):
for rec in self:
workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', rec.code)])
if workflow_record_id:
rec.approve_state = workflow_record_id.approve_state
else:
rec.approve_state = False
class PropertyFeeSpendingLine(models.Model):
_name = 'property.fee.spending.line'
_description = '物业列表明细行'
fee_id = fields.Many2one('property.fee.spending', string="关联费用支出")
address_id = fields.Many2one('yuthon.property', string="物业地址")
tax = fields.Float(related='address_id.tax',string="税率")
admin_line_id = fields.Many2one(related='address_id.admin_id', string="管理员", store=True)
property_area = fields.Float(related='address_id.rent_area', string="可租面积", store=True)
class YuthonExpensesType(models.Model):
_name = 'yuthon.expenses.type'
@@ -129,4 +129,6 @@ access_property_management_line2,property_management_line2,model_property_manage
access_yuthon_expenses_type,yuthon.expenses.type,model_yuthon_expenses_type,base.group_user,1,1,1,1
access_property_fee_spending,property_fee_spending,model_property_fee_spending,base.group_user,1,1,1,1
access_property_fee_spending,property_fee_spending,model_property_fee_spending,base.group_user,1,1,1,1
access_property_fee_spending_line,property_fee_spending_line,model_property_fee_spending_line,base.group_user,1,1,1,1
access_build_fee_wizard,build_fee_wizard,model_build_fee_wizard,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
129
130
131
132
133
134
@@ -495,6 +495,14 @@
<field name="context">{'search_default_group_by_contract_id': True}</field>
<field name="search_view_id" ref="view_property_accounts_receivable_search"/>
<field name="view_id" ref="yuthon_property.view_property_accounts_receivable_tree"/>
</record>
<record id="property_accounts_penalty_action" model="ir.actions.act_window">
<field name="name">违约金列表</field>
<field name="res_model">property.accounts.receivable</field>
<field name="view_mode">tree</field>
<field name="domain">[('management_type_id.name','=', '违约金')]</field>
<field name="search_view_id" ref="view_property_accounts_receivable_search"/>
<field name="view_id" ref="yuthon_property.view_property_accounts_receivable_tree"/>
</record>
<record id="accounts_receivable_deposit_action" model="ir.actions.act_window">
<field name="name">押金列表</field>
@@ -5,11 +5,15 @@
<field name="model">property.fee.spending</field>
<field name="arch" type="xml">
<tree string="费用支出">
<field name="code" string="流水号"/>
<field name="name"/>
<field name="company_id1"/>
<field name="spending_fee"/>
<field name="expenses_type"/>
<field name="users_id"/>
<field name="approve_state" widget="badge"
decoration-danger="approve_state == 'end'"
decoration-success="approve_state == 'pending'"/>
<field name="creart_datetime"/>
</tree>
</field>
@@ -70,6 +74,21 @@
<field name="expenses_type"/>
<field name="spending_fee"/>
</group>
<notebook>
<page string="物业信息">
<button name="build_pop" string="添加物业" type="object"
class="btn-primary"/>
<field name="spending_ids">
<tree editable="bottom" create="false">
<field name="fee_id" column_invisible="1"/>
<field name="address_id"/>
<field name="admin_line_id"/>
<field name="property_area"/>
<field name="tax"/>
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
+2 -1
View File
@@ -15,4 +15,5 @@ from . import penalty_line_wizard
from . import print_payment_wizard
from . import property_bills_wizard
from . import action_refuse_wizard
from . import property_deposit_wizard
from . import property_deposit_wizard
from . import build_fee_wizard
@@ -0,0 +1,24 @@
from odoo import models, fields, api, _, SUPERUSER_ID
from odoo.exceptions import UserError, ValidationError
class BuildFeeWizard(models.TransientModel):
_name = 'build.fee.wizard'
_description = '添加物业弹窗'
property_ids = fields.Many2many('yuthon.property', string='物业')
fee_id = fields.Many2one('property.fee.spending', string='费用')
def confirm(self):
property_addresses = [
prop.name
for prop in self.property_ids
if prop.name
]
concatenated_address = ', '.join(property_addresses)
self.fee_id.property_address = concatenated_address
for prop in self.property_ids:
self.env['property.fee.spending.line'].create({
'fee_id': self.fee_id.id,
'address_id': prop.id,
})
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="build_fee_wizard_form" model="ir.ui.view">
<field name="name">build.fee.wizard.form</field>
<field name="model">build.fee.wizard</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="property_ids" widget="many2many_tags"/>
<field name="fee_id" invisible="1"/>
</group>
</sheet>
<footer>
<button name="confirm" string="确认" type="object" class="oe_highlight"/>
<button string="返回" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>
+6
View File
@@ -905,6 +905,12 @@
name="应付账单"
action="yuthon_property_approval.view_property_bills_list_action"
sequence="4"/>
<menuitem
id="accounts_receivable_penalty_menu"
parent="yuthon_financial_management_menu"
name="违约金列表"
action="yuthon_property_approval.property_accounts_penalty_action"
sequence="5"/>
<menuitem
id="accounts_receivable_deposit_menu"
parent="yuthon_financial_management_menu"