!6881 添加功能

Merge pull request !6881 from 李鹏宇/dev_zhou
This commit is contained in:
李鹏宇
2025-12-05 10:19:41 +00:00
committed by Gitee
17 changed files with 318 additions and 9 deletions
+1
View File
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from . import controllers
from . import models
from . import wizard
+8 -5
View File
@@ -13,12 +13,15 @@
'views/root_menu.xml',
'views/yuthon_catering.xml',
'views/yuthon_catering_conf.xml',
'views/yuthon_catering_setting_views.xml',
'wizard/catering_reinstated_wizard_views.xml',
'templates/templates.xml',
],
# 'assets': {
# 'web.assets_backend': [
# 'base_dynamic_columns/static/src/**/*',
# ],
# },
'assets': {
'web.assets_backend': [
'yuthon_catering/static/src/js/catering_create_button.js',
'yuthon_catering/static/src/xml/catering_create_button_views.xml',
],
},
}
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data noupdate="1">
<record forcecreate="True" id="yuthon_catering_time" model="ir.cron">
<field name="name">定时任务:餐饮收集任务</field>
<field name="model_id" ref="model_yuthon_catering"/>
<field name="state">code</field>
<field name="code">model.catering_task()</field>
<field eval="True" name="active"/>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">weeks</field>
<field name="nextcall" eval="(DateTime.now()).strftime('%Y-%m-%d 00:00:00')"/>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
</record>
</data>
</odoo>
+1
View File
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from . import yuthon_catering
from . import yuthon_catering_conf
from . import yuthon_catering_setting
+66
View File
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models
from datetime import datetime, timedelta
class YuthonCatering(models.Model):
@@ -9,9 +10,74 @@ class YuthonCatering(models.Model):
employee_id = fields.Many2one(string='员工', comodel_name='hr.employee', required=True)
breakfast = fields.Boolean(string='早餐', default=False)
lunch = fields.Boolean(string='午餐', default=False)
menu_day_id = fields.Many2one('yuthon.menu.setting', string='菜单')
amount = fields.Float(string='结算费用')
note = fields.Text(string='备注')
def catering_task(self):
conf_records = self.env['yuthon.catering.conf'].search([])
employee_ids = conf_records.mapped('employee_ids')
today = fields.Date.today()
date_list = [today + timedelta(days=i) for i in range(7)]
create_vals = []
for employee in employee_ids:
for target_date in date_list:
if not self._process_shift_days(target_date):
continue
existing = self.search([
('employee_id', '=', employee.id),
('date', '=', target_date)
], limit=1)
menu_record = self.env['yuthon.menu.setting'].search([
('menu_date', '=', target_date)
], limit=1)
if not existing:
create_vals.append({
'menu_record': menu_record.id if menu_record else False,
'date': target_date,
'employee_id': employee.id,
})
if create_vals:
self.create(create_vals)
def _process_shift_days(self, current_data):
"""
判断是否是工作日 调休日 双休
"""
calendar_leaves = self.env['resource.calendar.leaves'].search([("calendar_id", "=", "行政考勤工作日")])
holidays_list = []
shift_days_list = []
# 提取节假日和调休日
for leave in calendar_leaves:
if leave.holidays:
holidays_list.extend(leave.holidays.split(','))
if leave.alternate_rest_day:
holidays_list.extend(leave.alternate_rest_day.split(','))
if leave.shift_replacement_day:
shift_days_list.extend(leave.shift_replacement_day.split(','))
holidays_list = [self.remove_leading_zero(date) for date in holidays_list]
shift_days_list = [self.remove_leading_zero(date) for date in shift_days_list]
result = f"{current_data.month}月{current_data.day}日"
if result in shift_days_list:
return True
elif (result in holidays_list) or (current_data.weekday() in [5, 6]):
return False
else:
return True
def remove_leading_zero(self, date_str):
month, day = date_str.split('月')
month = month.lstrip('0')
day = day.rstrip('日')
day = day.lstrip('0')
return f'{month}月{day}日'
def cron_send_message(self):
url = f'/catering/portal/<int:employee_id>'
@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models
class YuthonMenuSetting(models.Model):
_name = 'yuthon.menu.setting'
_description = '菜单配置'
breakfast_ids = fields.Many2many(
'yuthon.dishes.setting',
'yuthon_menu_breakfast_rel',
'menu_id',
'dish_id',
string='早餐'
)
lunch_ids = fields.Many2many(
'yuthon.dishes.setting',
'yuthon_menu_lunch_rel',
'menu_id',
'dish_id',
string='午餐'
)
menu_date = fields.Date(string='日期')
class YuthonDishesSetting(models.Model):
_name = 'yuthon.dishes.setting'
_description = '菜品配置'
name = fields.Char(string='菜品名称')
dishes_type = fields.Selection([('breakfast', '早餐'), ('lunch', '午餐')], string='菜品类型')
+2 -1
View File
@@ -1,6 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_yuthon_catering,yuthon_catering,model_yuthon_catering,,1,1,1,1
access_yuthon_catering_conf,yuthon_catering_conf,model_yuthon_catering_conf,,1,1,1,1
access_yuthon_menu_setting,yuthon_menu_setting,model_yuthon_menu_setting,,1,1,1,1
access_yuthon_dishes_setting,yuthon_dishes_setting,model_yuthon_dishes_setting,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_yuthon_catering yuthon_catering model_yuthon_catering 1 1 1 1
3 access_yuthon_catering_conf yuthon_catering_conf model_yuthon_catering_conf 1 1 1 1
4 access_yuthon_menu_setting yuthon_menu_setting model_yuthon_menu_setting 1 1 1 1
5 access_yuthon_dishes_setting yuthon_dishes_setting model_yuthon_dishes_setting 1 1 1 1
6
7
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

@@ -0,0 +1,28 @@
/** @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 CustomCateringController extends ListController {
setup() {
super.setup();
}
openCateringWizard() {
this.actionService.doAction({
type: 'ir.actions.act_window',
res_model: 'catering.reinstated.wizard',
name: '复用弹窗',
view_mode: 'form',
view_type: 'form',
views: [[false, 'form']],
target: 'new', // 以弹窗形式打开
context: {},
});
}
}
registry.category("views").add("custom_catering_button", {
...listView,
Controller: CustomCateringController,
buttonTemplate: "catering_module.ListView.Buttons"
});
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<templates>
<t t-name="catering_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="openCateringWizard">
复用
</button>
</xpath>
</t>
</templates>
+3 -1
View File
@@ -1,7 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data>
<menuitem id="yuthon_catering_root_menu" name="餐饮" sequence="1">
<menuitem id="yuthon_catering_root_menu" name="餐饮" sequence="1"
web_icon="yuthon_catering,static/description/catering.png"
>
<menuitem id="yuthon_catering_conf_root_menu" name="配置" sequence="99"/>
</menuitem>
</data>
+2 -1
View File
@@ -6,12 +6,13 @@
<field name="name">yuthon.catering.tree</field>
<field name="model">yuthon.catering</field>
<field name="arch" type="xml">
<tree string="餐饮" editable="top">
<tree string="餐饮" editable="top" js_class="custom_catering_button">
<field name="date"/>
<field name="employee_id"/>
<field name="breakfast"/>
<field name="lunch"/>
<field name="amount"/>
<field name="menu_day_id"/>
<field name="note"/>
</tree>
</field>
@@ -8,7 +8,7 @@
<field name="arch" type="xml">
<tree string="配置" editable="top">
<field name="company_id"/>
<field name="employee_ids"/>
<field name="employee_ids" widget="many2many_tags" domain="[('company_id', '=', company_id)]"/>
</tree>
</field>
</record>
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="yuthon_menu_setting_tree" model="ir.ui.view">
<field name="name">yuthon_menu_setting_tree</field>
<field name="model">yuthon.menu.setting</field>
<field name="arch" type="xml">
<tree string="菜单配置" editable="bottom">
<field name="breakfast_ids" widget="many2many_tags" domain="[('dishes_type','=','breakfast')]"/>
<field name="lunch_ids" widget="many2many_tags" domain="[('dishes_type','=','lunch')]"/>
<field name="menu_date"/>
</tree>
</field>
</record>
<record id="yuthon_menu_setting_action" model="ir.actions.act_window">
<field name="name">菜单配置</field>
<field name="res_model">yuthon.menu.setting</field>
<field name="view_mode">tree</field>
</record>
<record id="yuthon_dishes_setting_tree" model="ir.ui.view">
<field name="name">yuthon_dishes_setting_tree</field>
<field name="model">yuthon.dishes.setting</field>
<field name="arch" type="xml">
<tree string="菜品配置" editable="bottom">
<field name="name"/>
<field name="dishes_type"/>
</tree>
</field>
</record>
<record id="yuthon_dishes_setting_action" model="ir.actions.act_window">
<field name="name">菜品配置</field>
<field name="res_model">yuthon.dishes.setting</field>
<field name="view_mode">tree</field>
</record>
<menuitem
id="yuthon_menu_setting_menu"
name="菜单配置"
parent="yuthon_catering_conf_root_menu"
sequence="5"
action="yuthon_menu_setting_action"/>
<menuitem
id="yuthon_dishes_setting_menu"
name="菜品配置"
parent="yuthon_catering_conf_root_menu"
sequence="10"
action="yuthon_dishes_setting_action"/>
</odoo>
+1
View File
@@ -0,0 +1 @@
from . import catering_reinstated_wizard
@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models
from datetime import datetime, timedelta, time
class CateringReinstatedWizard(models.TransientModel):
_name = 'catering.reinstated.wizard'
_description = '复用弹窗'
def confirm(self):
today = fields.Date.today()
date_list = []
for i in range(7):
target_date = today + timedelta(days=i)
if self._process_shift_days(target_date):
date_list.append(target_date)
for current_date in date_list:
# 上周对应日期
last_week_date = current_date - timedelta(days=7)
# 查找上周该日期的所有餐饮记录
last_week_records = self.env['yuthon.catering'].search([
('date', '=', last_week_date)
])
if not last_week_records:
continue
for last_record in last_week_records:
existing = self.env['yuthon.catering'].search([
('employee_id', '=', last_record.employee_id.id),
('date', '=', current_date)
], limit=1)
if existing:
continue
self.env['yuthon.catering'].create({
'date': current_date,
'employee_id': last_record.employee_id.id,
'breakfast': last_record.breakfast,
'lunch': last_record.lunch,
'menu_day_id': last_record.menu_day_id.id,
'amount': last_record.amount,
'note': last_record.note,
})
def _process_shift_days(self, current_data):
"""
判断是否是工作日 调休日 双休
"""
calendar_leaves = self.env['resource.calendar.leaves'].search([("calendar_id", "=", "行政考勤工作日")])
holidays_list = []
shift_days_list = []
# 提取节假日和调休日
for leave in calendar_leaves:
if leave.holidays:
holidays_list.extend(leave.holidays.split(','))
if leave.alternate_rest_day:
holidays_list.extend(leave.alternate_rest_day.split(','))
if leave.shift_replacement_day:
shift_days_list.extend(leave.shift_replacement_day.split(','))
holidays_list = [self.remove_leading_zero(date) for date in holidays_list]
shift_days_list = [self.remove_leading_zero(date) for date in shift_days_list]
result = f"{current_data.month}月{current_data.day}日"
if result in shift_days_list:
return True
elif (result in holidays_list) or (current_data.weekday() in [5, 6]):
return False
else:
return True
def remove_leading_zero(self, date_str):
month, day = date_str.split('月')
month = month.lstrip('0')
day = day.rstrip('日')
day = day.lstrip('0')
return f'{month}月{day}日'
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="catering_reinstated_wizard_form" model="ir.ui.view">
<field name="name">catering.reinstated.wizard.form</field>
<field name="model">catering.reinstated.wizard</field>
<field name="arch" type="xml">
<form string="复用弹窗">
<sheet>
<div>
确定要执行复用逻辑吗?
</div>
</sheet>
<footer>
<button name="confirm" type="object" string="确定" class="btn-primary"/>
<button special="cancel" string="取消"/>
</footer>
</form>
</field>
</record>
</odoo>