添加功能

This commit is contained in:
李鹏宇
2025-12-01 20:21:07 +08:00
parent 7dd26b23fb
commit ef5c0a99bf
21 changed files with 439 additions and 20 deletions
+2 -1
View File
@@ -1 +1,2 @@
from . import models
from . import models
from . import wizard
+12
View File
@@ -12,8 +12,20 @@
'data/account_setting_data.xml',
'views/financial_sheet_collection_views.xml',
'views/information_summary_table_views.xml',
'wizard/table_setting_wizard_viwes.xml',
'wizard/collection_create_button_wizard_views.xml',
'wizard/summary_create_button_wizard_views.xml',
'views/table_setting_views.xml',
],
'assets': {
'web.assets_backend': [
'yuthon_account_report/static/src/js/collection_create_button.js',
'yuthon_account_report/static/src/js/summary_create_button.js',
'yuthon_account_report/static/src/xml/collection_create_button.xml',
'yuthon_account_report/static/src/xml/summary_create_button.xml',
]
},
'installable': True,
'application': True,
@@ -1,5 +1,5 @@
from odoo import fields, models, api
import json
from datetime import datetime
from odoo import models, fields, api
class FinancialSheetCollection(models.Model):
@@ -11,6 +11,7 @@ class FinancialSheetCollection(models.Model):
department_id = fields.Many2one(related='employee_id.department_id', string="部门")
user_role_id = fields.Many2one(related='employee_id.user_role_id', string="角色")
create_date = fields.Datetime(string='创建日期', default=fields.Datetime.now)
cycle = fields.Selection(selection=[(str(i), str(i)) for i in range(1, 54)], string='周期')
account_type = fields.Selection([('to', '待确认',), ('ok', '已确认')], string='状态', default='to')
sheet_line_ids = fields.One2many('financial.sheet.line', 'sheet_id', string='财务数据表行')
@@ -35,7 +36,47 @@ class FinancialSheetCollection(models.Model):
record.account_type = 'ok'
def account_task(self):
pass
collection_settings = self.env['sheet.collection.setting'].search([('employee_ids', '!=', False)])
# 计算当前时间对应的本年第几周
today = datetime.now()
first_day_of_year = datetime(today.year, 1, 1)
days_since_year_start = (today - first_day_of_year).days
first_weekday = first_day_of_year.weekday() # 0=周一,6=周日
current_week = (days_since_year_start + first_weekday + 1) // 7
if first_weekday == 6:
current_week = (days_since_year_start + 1) // 7
cycle = str(min(max(current_week, 1), 53))
for setting in collection_settings:
employees = setting.employee_ids
for employee in employees:
sheet_collection = self.env['financial.sheet.collection'].search([
('employee_id', '=', employee.id),
('cycle', '=', cycle)
], limit=1)
if not sheet_collection:
sheet_collection = self.env['financial.sheet.collection'].create({
'employee_id': employee.id,
'cycle': cycle,
'account_type': 'to',
'create_date': fields.Datetime.now()
})
existing_line = self.env['financial.sheet.line'].search([
('sheet_id', '=', sheet_collection.id),
('collection_id', '=', setting.id)
], limit=1)
if not existing_line:
self.env['financial.sheet.line'].create({
'sheet_id': sheet_collection.id,
'collection_id': setting.id,
'employee_ids': [(6, 0, [employee.id])],
'this_issue_number': 0,
'same_last_year': 0,
'remake': ''
})
class FinancialSheetLine(models.Model):
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models
import json
from datetime import datetime
from odoo import models, fields, api
class InformationSummaryTable(models.Model):
@@ -13,6 +12,7 @@ class InformationSummaryTable(models.Model):
user_role_id = fields.Many2one(related='employee_id.user_role_id', string="角色")
account_type = fields.Selection([('to', '待确认', ), ('ok', '已确认')], string='状态', default='to')
summary_line = fields.One2many('information.summary.line', 'summary_id', string='汇总表')
month = fields.Selection(selection=[(str(i), str(i)) for i in range(1, 13)], string='月份')
create_date = fields.Datetime(string='创建日期', default=fields.Datetime.now)
def open_record(self):
@@ -33,7 +33,39 @@ class InformationSummaryTable(models.Model):
record.account_type = 'ok'
def account_task(self):
pass
self.ensure_one()
summary_settings = self.env['summary.table.setting'].search([
('employee_ids', '!=', False)
])
current_month = str(datetime.now().month)
for setting in summary_settings:
employees = setting.employee_ids
for employee in employees:
summary_table = self.env['information.summary.table'].search([
('employee_id', '=', employee.id),
('month', '=', current_month)
], limit=1) #
if not summary_table:
summary_table = self.env['information.summary.table'].create({
'employee_id': employee.id,
'month': current_month,
'account_type': 'to',
'create_date': fields.Datetime.now()
})
existing_line = self.env['information.summary.line'].search([
('summary_id', '=', summary_table.id),
('table_id', '=', setting.id)
], limit=1)
if not existing_line:
self.env['information.summary.line'].create({
'summary_id': summary_table.id,
'table_id': setting.id,
'this_year': 0.0,
'remake': ''
})
class InformationSummaryLine(models.Model):
@@ -36,6 +36,18 @@ class SheetCollectionSetting(models.Model):
all_employees = rec.employee_ids | new_employees
rec.employee_ids = all_employees
def table_setting_wizard(self):
collection_ids = self.env["sheet.collection.setting"].browse(
self._context.get('active_ids', self._context.get('active_id')))
return {
'name': '批量添加弹窗',
'type': 'ir.actions.act_window',
'res_model': 'table.setting.wizard',
'view_mode': 'form',
'target': 'new',
'context': {'default_financial_ids': collection_ids.ids}
}
class SummaryTableSetting(models.Model):
_name = 'summary.table.setting'
_description = '信息汇总表项目配置'
@@ -68,3 +80,15 @@ class SummaryTableSetting(models.Model):
new_employees = self.env['hr.employee'].search(domain)
all_employees = rec.employee_ids | new_employees
rec.employee_ids = all_employees
def table_setting_wizard(self):
table_ids = self.env["summary.table.setting"].browse(
self._context.get('active_ids', self._context.get('active_id')))
return {
'name': 'Table Setting Wizard',
'type': 'ir.actions.act_window',
'res_model': 'table.setting.wizard',
'view_mode': 'form',
'target': 'new',
'context': {'default_information_ids': table_ids.ids}
}
@@ -4,4 +4,7 @@ access_summary_table_setting,summary_table_setting,model_summary_table_setting,b
access_information_summary_table,information_summary_table,model_information_summary_table,base.group_system,1,1,1,1
access_sheet_collection_setting,sheet_collection_setting,model_sheet_collection_setting,base.group_system,1,1,1,1
access_financial_sheet_line,financial_sheet_line,model_financial_sheet_line,base.group_system,1,1,1,1
access_information_summary_line,information_summary_line,model_information_summary_line,base.group_system,1,1,1,1
access_information_summary_line,information_summary_line,model_information_summary_line,base.group_system,1,1,1,1
access_table_setting_wizard,table_setting_wizard,model_table_setting_wizard,base.group_system,1,1,1,
access_collection_create_button_wizard,collection_create_button_wizard,model_collection_create_button_wizard,base.group_system,1,1,1,
access_summary_create_button_wizard,summary_create_button_wizard,model_summary_create_button_wizard,base.group_system,1,1,1,
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
4 access_information_summary_table information_summary_table model_information_summary_table base.group_system 1 1 1 1
5 access_sheet_collection_setting sheet_collection_setting model_sheet_collection_setting base.group_system 1 1 1 1
6 access_financial_sheet_line financial_sheet_line model_financial_sheet_line base.group_system 1 1 1 1
7 access_information_summary_line information_summary_line model_information_summary_line base.group_system 1 1 1 1
8 access_table_setting_wizard table_setting_wizard model_table_setting_wizard base.group_system 1 1 1
9 access_collection_create_button_wizard collection_create_button_wizard model_collection_create_button_wizard base.group_system 1 1 1
10 access_summary_create_button_wizard summary_create_button_wizard model_summary_create_button_wizard base.group_system 1 1 1
@@ -0,0 +1,29 @@
/** @odoo-module */
import { ListController } from "@web/views/list/list_controller";
import { registry } from '@web/core/registry';
import { listView } from '@web/views/list/list_view';
export class CustomCollectionController extends ListController {
setup() {
super.setup();
}
openCollectionWizard() {
this.actionService.doAction({
type: 'ir.actions.act_window',
res_model: 'collection.create.button.wizard',
name: '财务数据表项目配置弹窗',
view_mode: 'form',
view_type: 'form',
views: [[false, 'form']],
target: 'new', // 以弹窗形式打开
context: {},
});
}
}
registry.category("views").add("custom_collection_button", {
...listView,
Controller: CustomCollectionController,
buttonTemplate: "collection_module.ListView.Buttons",
});
@@ -0,0 +1,29 @@
/** @odoo-module */
import { ListController } from "@web/views/list/list_controller";
import { registry } from '@web/core/registry';
import { listView } from '@web/views/list/list_view';
export class CustomSummaryController extends ListController {
setup() {
super.setup();
}
openSummaryWizard() {
this.actionService.doAction({
type: 'ir.actions.act_window',
res_model: 'summary.create.button.wizard',
name: '信息汇总表配置',
view_mode: 'form',
view_type: 'form',
views: [[false, 'form']],
target: 'new',
context: {},
});
}
}
registry.category("views").add("summary_button", {
...listView,
Controller: CustomSummaryController,
buttonTemplate: "summary_module.ListView.Buttons",
});
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<templates>
<t t-name="collection_module.ListView.Buttons" t-inherit="web.ListView.Buttons">
<xpath expr="//div[hasclass('o_list_buttons')]" position="after">
<button type="button" class="btn btn-primary" style="margin-left: 10px;" t-on-click="openCollectionWizard">
初始化周期任务
</button>
</xpath>
</t>
</templates>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<templates>
<t t-name="summary_module.ListView.Buttons" t-inherit="web.ListView.Buttons">
<xpath expr="//div[hasclass('o_list_buttons')]" position="after">
<button type="button" class="btn btn-primary" style="margin-left: 10px;" t-on-click="openSummaryWizard">
初始化周期任务
</button>
</xpath>
</t>
</templates>
@@ -6,9 +6,10 @@
<field name="arch" type="xml">
<tree string="财务数据表收集" editable="bottom" create="False" delete="False"
decoration-danger="account_type == 'to'"
decoration-success="account_type == 'ok'"
decoration-success="account_type == 'ok'">
>
<field name="employee_id" required="1"/>
<field name="cycle"/>
<field name="company_id"/>
<field name="department_id"/>
<field name="user_role_id"/>
@@ -55,6 +56,18 @@
</form>
</field>
</record>
<record id="financial_sheet_collection_search" model="ir.ui.view">
<field name="name">financial.sheet.collection.search</field>
<field name="model">financial.sheet.collection</field>
<field name="arch" type="xml">
<search>
<field name="employee_id"/>
<group expand="0" string="Group By">
<filter string="周期" name="group_by_cycle" context="{'group_by': 'cycle'}"/>
</group>
</search>
</field>
</record>
<record id="financial_sheet_line_kanban" model="ir.ui.view">
<field name="name">financial.sheet.line.kanban</field>
<field name="model">financial.sheet.line</field>
@@ -98,7 +111,8 @@
<record id="financial_sheet_collection_action" model="ir.actions.act_window">
<field name="name">财务数据表收集</field>
<field name="res_model">financial.sheet.collection</field>
<field name="view_mode">tree,form</field>
<field name="view_mode">tree,form,search</field>
<field name="context">{'search_default_group_by_cycle': 1}</field>
</record>
</odoo>
@@ -6,9 +6,10 @@
<field name="arch" type="xml">
<tree string="信息汇总表" editable="bottom" create="False" delete="False"
decoration-danger="account_type == 'to'"
decoration-success="account_type == 'ok'"
decoration-success="account_type == 'ok'">
>
<field name="employee_id" required="1"/>
<field name="month"/>
<field name="company_id"/>
<field name="department_id"/>
<field name="user_role_id"/>
@@ -54,6 +55,18 @@
</form>
</field>
</record>
<record id="information_summary_table_search" model="ir.ui.view">
<field name="name">information.summary.table.search</field>
<field name="model">information.summary.table</field>
<field name="arch" type="xml">
<search>
<field name="employee_id"/>
<group expand="0" string="Group By">
<filter string="月份" name="group_by_month" context="{'group_by': 'month'}"/>
</group>
</search>
</field>
</record>
<record id="information_summary_line_kanban" model="ir.ui.view">
<field name="name">information.summary.line.kanban</field>
<field name="model">information.summary.line</field>
@@ -91,6 +104,7 @@
<record id="information_summary_table_action" model="ir.actions.act_window">
<field name="name">信息汇总表</field>
<field name="res_model">information.summary.table</field>
<field name="view_mode">tree,form</field>
<field name="view_mode">tree,form,search</field>
<field name="context">{'search_default_group_by_month': 1}</field>
</record>
</odoo>
@@ -4,7 +4,10 @@
<field name="name">sheet.collection.setting.tree</field>
<field name="model">sheet.collection.setting</field>
<field name="arch" type="xml">
<tree string="财务数据表项目配置" editable="bottom">
<tree string="财务数据表项目配置" editable="bottom" js_class="custom_collection_button">
<header>
<button name="table_setting_wizard" string="初始化人员" type="object" class='btn btn-primary'/>
</header>
<field name="sequence"/>
<field name="name"/>
<field name="employee_ids" widget="many2many_tags" options="{'no_create': True}"/>
@@ -24,7 +27,10 @@
<field name="name">summary.table.setting.tree</field>
<field name="model">summary.table.setting</field>
<field name="arch" type="xml">
<tree string="信息汇总表项目配置" editable="bottom">
<tree string="信息汇总表项目配置" editable="bottom" js_class="summary_button">
<header>
<button name="table_setting_wizard" string="初始化人员" type="object" class='btn btn-primary'/>
</header>
<field name="sequence"/>
<field name="name"/>
<field name="employee_ids" widget="many2many_tags" options="{'no_create': True}"/>
+3
View File
@@ -0,0 +1,3 @@
from . import table_setting_wizard
from . import summary_create_button_wizard
from . import collection_create_button_wizard
@@ -0,0 +1,54 @@
from datetime import datetime
from odoo import models, fields, api
class CollectionCreateButtonWizard(models.TransientModel):
_name = 'collection.create.button.wizard'
_description = '财务数据表项目配置弹窗'
def action_confirm(self):
self.ensure_one()
collection_settings = self.env['sheet.collection.setting'].search([('employee_ids', '!=', False)])
# 计算当前时间对应的本年第几周
today = datetime.now()
first_day_of_year = datetime(today.year, 1, 1)
days_since_year_start = (today - first_day_of_year).days
first_weekday = first_day_of_year.weekday() # 0=周一,6=周日
current_week = (days_since_year_start + first_weekday + 1) // 7
if first_weekday == 6:
current_week = (days_since_year_start + 1) // 7
cycle = str(min(max(current_week, 1), 53))
for setting in collection_settings:
employees = setting.employee_ids
for employee in employees:
sheet_collection = self.env['financial.sheet.collection'].search([
('employee_id', '=', employee.id),
('cycle', '=', cycle)
], limit=1)
if not sheet_collection:
sheet_collection = self.env['financial.sheet.collection'].create({
'employee_id': employee.id,
'cycle': cycle,
'account_type': 'to',
'create_date': fields.Datetime.now()
})
existing_line = self.env['financial.sheet.line'].search([
('sheet_id', '=', sheet_collection.id),
('collection_id', '=', setting.id)
], limit=1)
if not existing_line:
self.env['financial.sheet.line'].create({
'sheet_id': sheet_collection.id,
'collection_id': setting.id,
'employee_ids': [(6, 0, [employee.id])],
'this_issue_number': 0,
'same_last_year': 0,
'remake': ''
})
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="collection_create_button_wizard_form" model="ir.ui.view">
<field name="name">collection.create.button.wizard.form</field>
<field name="model">collection.create.button.wizard</field>
<field name="arch" type="xml">
<form>
<div>
确定要初始化周期吗?
</div>
<footer>
<button type="object" name="action_confirm" string="确认" class="oe_highlight"/>
<button special="cancel" string="取消" class="btn-secondary"/>
</footer>
</form>
</field>
</record>
</odoo>
@@ -0,0 +1,46 @@
from datetime import datetime
from odoo import models, fields, api
class SummaryCreateButtonWizard(models.TransientModel):
_name = 'summary.create.button.wizard'
_description = '初始化周期任务'
def action_confirm(self):
self.ensure_one()
summary_settings = self.env['summary.table.setting'].search([
('employee_ids', '!=', False)
])
if not summary_settings:
return self._show_notification('无有效项目配置(需关联人员)', 'warning')
current_month = str(datetime.now().month)
for setting in summary_settings:
employees = setting.employee_ids
for employee in employees:
summary_table = self.env['information.summary.table'].search([
('employee_id', '=', employee.id),
('month', '=', current_month)
], limit=1) #
if not summary_table:
summary_table = self.env['information.summary.table'].create({
'employee_id': employee.id,
'month': current_month,
'account_type': 'to',
'create_date': fields.Datetime.now()
})
existing_line = self.env['information.summary.line'].search([
('summary_id', '=', summary_table.id),
('table_id', '=', setting.id)
], limit=1)
if not existing_line:
self.env['information.summary.line'].create({
'summary_id': summary_table.id,
'table_id': setting.id,
'this_year': 0.0,
'remake': ''
})
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="summary_create_button_wizard_form" model="ir.ui.view">
<field name="name">summary.create.button.wizard.form</field>
<field name="model">summary.create.button.wizard</field>
<field name="arch" type="xml">
<form>
<div>
确定要初始化周期吗?
</div>
<footer>
<button type="object" name="action_confirm" string="确认" class="oe_highlight"/>
<button special="cancel" string="取消" class="btn-secondary"/>
</footer>
</form>
</field>
</record>
</odoo>
@@ -0,0 +1,31 @@
from odoo import models, fields, api, _, SUPERUSER_ID
from odoo.exceptions import UserError, ValidationError
class TableSettingWizard(models.TransientModel):
_name = 'table.setting.wizard'
_description = ''
financial_ids = fields.Many2many('sheet.collection.setting', string='财务数据表行')
information_ids = fields.Many2many('summary.table.setting', string='信息汇总表行')
employee_ids = fields.Many2many('hr.employee', string='员工')
user_role_ids = fields.Many2many('soong.user.role', string="角色")
@api.onchange('user_role_ids')
def _onchange_user_role_ids(self):
for rec in self:
domain = ['|', ('user_role_id', 'in', rec.user_role_ids.ids),
('user_role_ids', 'in', rec.user_role_ids.ids)]
new_employees = self.env['hr.employee'].search(domain)
all_employees = rec.employee_ids | new_employees
rec.employee_ids = all_employees
def action_confirm(self):
if self.financial_ids:
for rec in self.financial_ids:
rec.write({'employee_ids': [(6, 0, self.employee_ids.ids)]})
if self.information_ids:
for rec in self.information_ids:
rec.write({'employee_ids': [(6, 0, self.employee_ids.ids)]})
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="view_table_setting_wizard" model="ir.ui.view">
<field name="name">table_setting_wizard</field>
<field name="model">table.setting.wizard</field>
<field name="arch" type="xml">
<form>
<group>
<field name="financial_ids" invisible="not financial_ids" widget="many2many_tags"/>
<field name="information_ids" invisible="not information_ids" widget="many2many_tags"/>
<field name="employee_ids" widget="many2many_tags"/>
<field name="user_role_ids" widget="many2many_tags"/>
</group>
<footer>
<button type="object" name="action_confirm" string="确认" class="oe_highlight"/>
<button special="cancel" string="取消" class="btn-secondary"/>
</footer>
</form>
</field>
</record>
</odoo>
+5 -5
View File
@@ -164,11 +164,11 @@
parent="hr_attendance_root_board_menu"
action="yuthon_hr_attendance.view_yuthon_vacation_reports_action"
sequence="14"/>
<menuitem id="staff_dining_report_board"
name="员工就餐收集表"
parent="hr_attendance_root_board_menu"
action="yuthon_hr_attendance.view_staff_dining_report_action"
sequence="15"/>
<!-- <menuitem id="staff_dining_report_board"-->
<!-- name="员工就餐收集表"-->
<!-- parent="hr_attendance_root_board_menu"-->
<!-- action="yuthon_hr_attendance.view_staff_dining_report_action"-->
<!-- sequence="15"/>-->
<menuitem id="menu_hr_attendance_detail_view_attendances"
name="打卡详情"
parent="hr_attendance_root_board_menu"