diff --git a/yuthon_salary/__manifest__.py b/yuthon_salary/__manifest__.py index 9979fc76a..eca970dfd 100644 --- a/yuthon_salary/__manifest__.py +++ b/yuthon_salary/__manifest__.py @@ -31,10 +31,14 @@ 'views/yuthon_salary_documents_views.xml', 'views/yuthon_welfare_expenses_views.xml', 'views/yuthon_payroll_retired_views.xml', + 'views/yuthon_meal_expenses_views.xml', 'views/yuthon_salary_year_views.xml', 'wizard/rank_log_wizard_views.xml', + 'wizard/salary_meal_wizard_views.xml', 'wizard/yuthon_salary_wizard_views.xml', 'wizard/salary_party_wizard_views.xml', + 'wizard/party_send_wizard_views.xml', + 'wizard/party_meal_wizard_views.xml', 'wizard/temporary_payslip_wizard_views.xml', 'wizard/salary_import_wizard_views.xml', 'wizard/yuthon_payroll_wizard_views.xml', @@ -64,6 +68,8 @@ 'yuthon_salary/static/src/js/salary_validation_button.js', 'yuthon_salary/static/src/js/salary_year_button.js', 'yuthon_salary/static/src/js/salary_import_button.js', + 'yuthon_salary/static/src/js/salary_meal_button.js', + 'yuthon_salary/static/src/xml/salary_meal_button.xml', 'yuthon_salary/static/src/xml/salary_create_button.xml', 'yuthon_salary/static/src/xml/salary_labor_button.xml', 'yuthon_salary/static/src/xml/salary_import_button.xml', diff --git a/yuthon_salary/models/__init__.py b/yuthon_salary/models/__init__.py index 8864f9ba9..345668a87 100644 --- a/yuthon_salary/models/__init__.py +++ b/yuthon_salary/models/__init__.py @@ -15,4 +15,5 @@ from . import yuthon_welfare_expenses from . import inherit_hr_payslip_run from . import inherit_hr_payslip_line from . import yuthon_salary_party -from . import yuthon_individual_tax \ No newline at end of file +from . import yuthon_individual_tax +from . import yuthon_meal_expenses \ No newline at end of file diff --git a/yuthon_salary/models/yuthon_meal_expenses.py b/yuthon_salary/models/yuthon_meal_expenses.py new file mode 100644 index 000000000..e0b571b42 --- /dev/null +++ b/yuthon_salary/models/yuthon_meal_expenses.py @@ -0,0 +1,45 @@ +from odoo import api, fields, models +from datetime import datetime +import calendar + + +class YuthonMealExpenses(models.Model): + _name = 'yuthon.meal.expenses' + _description = '餐费' + + employee_id = fields.Many2one('hr.employee', string='姓名') + card = fields.Char(string='身份证') + number_breakfasts = fields.Integer(string='早餐次数') + number_lunches = fields.Integer(string='午餐次数') + total_payment = fields.Float(string='合计缴费') + company_id = fields.Many2one(related='employee_id.company_id', string="公司") + select_time = fields.Selection([('1', '一月'), ('2', '二月'), ('3', '三月'), ('4', '四月'), + ('5', '五月'), ('6', '六月'), ('7', '七月'), ('8', '八月'), + ('9', '九月'), ('10', '十月'), ('11', '十一月'), + ('12', '十二月')], string='月份', + default=lambda self: self._get_default_month()) + select_year = fields.Selection(selection=[(str(i), str(i)) for i in range(2024, 2040)], string='年份', + default=lambda self: str(datetime.now().year)) + meal_state = fields.Selection([('to_do', '待发送'), ('done', '已发送')], string='状态', default='to_do') + + + def _get_default_month(self): + current_month = datetime.now().month + return str(current_month) + + def send_meal(self): + year = self.select_year or datetime.now().year + month = self.select_time or datetime.now().month + last_day = calendar.monthrange(year, month)[1] + message = f"""致{self.employee_id.name}: + {self.select_year}年{self.select_time}月 早餐{self.number_breakfasts} 次、午餐{self.number_lunches} 次,按餐标核算, + 本月餐费合计{self.total_payment}元。缴费截止{self.select_year}年{self.select_time}月{last_day}日],可汇入账户:[账户信息]。异议请联系行政部 [联系方式]。 + 办公室 + {fields.Date.today()}""" + self.sudo().env["wecom.apps"].sync_send_message( + category='att', + user_id=self.employee_id.wecom_userid, + message=message, + ) + self.write({'party_state': 'done'}) + diff --git a/yuthon_salary/models/yuthon_salary_party.py b/yuthon_salary/models/yuthon_salary_party.py index 0f948e3a8..7ca732b7d 100644 --- a/yuthon_salary/models/yuthon_salary_party.py +++ b/yuthon_salary/models/yuthon_salary_party.py @@ -1,4 +1,5 @@ from odoo import api, fields, models +from datetime import datetime class YuthonSalaryParty(models.Model): @@ -6,12 +7,35 @@ class YuthonSalaryParty(models.Model): _description = '党建' employee_id = fields.Many2one('hr.employee', string='姓名') - phone = fields.Char(string='手机') + card = fields.Char(string='身份找') fee = fields.Float(string='党费') payment = fields.Float(string='补缴党费') total_payment = fields.Float(string='合计缴费') company_id = fields.Many2one(related='employee_id.company_id', string="公司") + select_time = fields.Selection([('1', '一月'), ('2', '二月'), ('3', '三月'), ('4', '四月'), + ('5', '五月'), ('6', '六月'), ('7', '七月'), ('8', '八月'), + ('9', '九月'), ('10', '十月'), ('11', '十一月'), + ('12', '十二月')], string='月份', + default=lambda self: self._get_default_month()) + select_year = fields.Selection(selection=[(str(i), str(i)) for i in range(2024, 2040)], string='年份', + default=lambda self: str(datetime.now().year)) + party_state = fields.Selection([('to_do', '待发送'), ('done', '已发送')], string='状态', default='to_do') + def _get_default_month(self): + current_month = datetime.now().month + return str(current_month) + def send_party(self): + pay_year_month = self.select_year + '年' + self.select_time + '月' + message = f"""【{pay_year_month}缴纳党费通知】: + 请于{fields.Date.today()}(今天)15:00前将党费按时汇入账户:44001580909059000222 广州市天河投资集团有限公司, + 并在群里告知汇款完毕。 + 您当月的缴费金额为{self.total_payment},其中党费{self.fee},补缴党费{self.payment}。""" + self.sudo().env["wecom.apps"].sync_send_message( + category='att', + user_id=self.employee_id.wecom_userid, + message=message, + ) + self.write({'party_state': 'done'}) diff --git a/yuthon_salary/security/ir.model.access.csv b/yuthon_salary/security/ir.model.access.csv index 34e5dc719..bf11fa4f7 100644 --- a/yuthon_salary/security/ir.model.access.csv +++ b/yuthon_salary/security/ir.model.access.csv @@ -39,4 +39,9 @@ access_yuthon_salary_party,access_yuthon_salary_party,model_yuthon_salary_party, access_salary_party_wizard,access_salary_party_wizard,model_salary_party_wizard,base.group_user,1,1,1,1 access_salary_import_wizard,access_salary_import_wizard,model_salary_import_wizard,base.group_user,1,1,1,1 -access_yuthon_individual_tax,access_yuthon_individual_tax,model_yuthon_individual_tax,base.group_user,1,1,1,1 \ No newline at end of file +access_yuthon_individual_tax,access_yuthon_individual_tax,model_yuthon_individual_tax,base.group_user,1,1,1,1 +access_party_send_wizard,access_party_send_wizard,model_party_send_wizard,base.group_user,1,1,1,1 + +access_yuthon_meal_expenses,access_yuthon_meal_expenses,model_yuthon_meal_expenses,base.group_user,1,1,1,1 +access_party_meal_wizard,access_party_meal_wizard,model_party_meal_wizard,base.group_user,1,1,1,1 +access_salary_meal_wizard,access_salary_meal_wizard,model_salary_meal_wizard,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/yuthon_salary/static/others/salary_meal.xlsx b/yuthon_salary/static/others/salary_meal.xlsx new file mode 100644 index 000000000..5296faeeb Binary files /dev/null and b/yuthon_salary/static/others/salary_meal.xlsx differ diff --git a/yuthon_salary/static/others/salary_party.xlsx b/yuthon_salary/static/others/salary_party.xlsx index 61d522f69..991dd8d29 100644 Binary files a/yuthon_salary/static/others/salary_party.xlsx and b/yuthon_salary/static/others/salary_party.xlsx differ diff --git a/yuthon_salary/static/src/js/salary_meal_button.js b/yuthon_salary/static/src/js/salary_meal_button.js new file mode 100644 index 000000000..29f22edff --- /dev/null +++ b/yuthon_salary/static/src/js/salary_meal_button.js @@ -0,0 +1,42 @@ +/** @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 CustomSalaryMealController extends ListController { + setup() { + super.setup(); + } + + openMealWizard() { + this.actionService.doAction({ + type: 'ir.actions.act_window', + res_model: 'salary.meal.wizard', + name: '餐费导入', + view_mode: 'form', + view_type: 'form', + views: [[false, 'form']], + target: 'new', + context: {}, + }); + } + + openMealSendWizard() { + this.actionService.doAction({ + type: 'ir.actions.act_window', + res_model: 'party.meal.wizard', + name: '发送弹窗', + view_mode: 'form', + view_type: 'form', + views: [[false, 'form']], + target: 'new', + context: {}, + }); + } +} + +registry.category("views").add("custom_meal_button", { + ...listView, + Controller: CustomSalaryMealController, + buttonTemplate: "meal_module.ListView.Buttons" +}); \ No newline at end of file diff --git a/yuthon_salary/static/src/js/salary_party_button.js b/yuthon_salary/static/src/js/salary_party_button.js index 229ac576d..d91cd2775 100644 --- a/yuthon_salary/static/src/js/salary_party_button.js +++ b/yuthon_salary/static/src/js/salary_party_button.js @@ -20,6 +20,19 @@ export class CustomSalaryPartyController extends ListController { context: {}, }); } + + openPartySendWizard() { + this.actionService.doAction({ + type: 'ir.actions.act_window', + res_model: 'party.send.wizard', + name: '发送弹窗', + view_mode: 'form', + view_type: 'form', + views: [[false, 'form']], + target: 'new', + context: {}, + }); + } } registry.category("views").add("custom_party_button", { diff --git a/yuthon_salary/static/src/xml/salary_meal_button.xml b/yuthon_salary/static/src/xml/salary_meal_button.xml new file mode 100644 index 000000000..53feb64ad --- /dev/null +++ b/yuthon_salary/static/src/xml/salary_meal_button.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/yuthon_salary/static/src/xml/salary_party_button.xml b/yuthon_salary/static/src/xml/salary_party_button.xml index a909547ba..a1cb363de 100644 --- a/yuthon_salary/static/src/xml/salary_party_button.xml +++ b/yuthon_salary/static/src/xml/salary_party_button.xml @@ -5,6 +5,9 @@ + diff --git a/yuthon_salary/views/yuthon_meal_expenses_views.xml b/yuthon_salary/views/yuthon_meal_expenses_views.xml new file mode 100644 index 000000000..f3f73a9e6 --- /dev/null +++ b/yuthon_salary/views/yuthon_meal_expenses_views.xml @@ -0,0 +1,27 @@ + + + + yuthon.meal.expenses.tree + yuthon.meal.expenses + + + + + + + + + + + +