Merge branch 'dev' of https://gitee.com/jinan-pengyusen-data/gzth into dev_wang
# Conflicts: # soong_workflow/views/soong_workflow_record.xml
This commit is contained in:
@@ -38,14 +38,15 @@
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div t-attf-class="o_attachment o_attachment_many2many #{ editable ? 'o_attachment_editable' : '' } #{upload ? 'o_attachment_uploading' : ''}" t-att-title="file.name">
|
||||
<div class="o_attachment_wrap">
|
||||
<div class="o_attachment_wrap d-flex">
|
||||
<t t-set="ext" t-value="getExtension(file)"/>
|
||||
<t t-set="url" t-value="getUrl(file.id)"/>
|
||||
<div class="o_image_box float-start" t-att-data-tooltip="'Preview ' + file.name">
|
||||
<span class="o_image o_hover" t-on-click.stop="() => this.preview_Obj(file.id,file.name)" t-att-data-mimetype="file.mimetype" t-att-data-ext="ext" role="img"/>
|
||||
</div>
|
||||
|
||||
<div class="caption">
|
||||
<div class="d-flex flex-column">
|
||||
<div class="caption" style="white-space: unset;">
|
||||
<a class="ml4" t-att-data-tooltip="'Download ' + file.name" t-att-href="getUrl(file.id)"><t t-esc='file.name'/></a>
|
||||
</div>
|
||||
<div class="caption small">
|
||||
@@ -54,6 +55,7 @@
|
||||
<div class="progress-bar progress-bar-striped active" style="width: 100%">Uploading</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="o_attachment_uploaded"><i class="text-success fa fa-check" role="img" aria-label="Uploaded" title="Uploaded"/></div>
|
||||
<div t-if="editable" class="o_attachment_delete" t-on-click.stop="() => this.onFileRemove(file.id)"><span class="text-white" role="img" aria-label="Delete" title="Delete">×</span></div>
|
||||
|
||||
@@ -2931,7 +2931,7 @@ nav.o_main_navbar {
|
||||
}
|
||||
}
|
||||
.modal.o_modal_full {
|
||||
z-index: 1111;
|
||||
z-index: 1070;
|
||||
}
|
||||
html {
|
||||
body {
|
||||
|
||||
@@ -20,3 +20,15 @@
|
||||
.o_comment_combined_input {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.o_kanban_soong_wkf_record {
|
||||
.o_kanban_record_headings {
|
||||
flex: 1;
|
||||
}
|
||||
.o_kanban_record_bottom {
|
||||
flex: 0 0 94px;
|
||||
@include media-breakpoint-down(sm) {
|
||||
flex: 0 0 56px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,21 +175,21 @@
|
||||
<field name="node_btn_name"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="o_kanban_record d-md-none card h-100">
|
||||
<div class="o_kanban_record d-md-none card h-100 border-0">
|
||||
<div class="card-body">
|
||||
<div class="mb-2">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<small>
|
||||
节点:<field name="name" />
|
||||
</small>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<small>
|
||||
状态:<field name="approval_state"/>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<small>
|
||||
经办人:<field name="done_by"/>
|
||||
经办人:<field name="done_by"/> <field name="lase_click_date"/>
|
||||
</small>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
@@ -197,7 +197,7 @@
|
||||
意见:<field name="comment"/>
|
||||
</small>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<div class="mb-2" t-if="record.document_ids.raw_value.length">
|
||||
<small>
|
||||
附件:<field name="document_ids" widget="preview_many2many"/>
|
||||
</small>
|
||||
|
||||
@@ -637,10 +637,11 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
has_archive_btn = any(btn_name.name == '归档' for btn_name in self.node_btn_id.node_id.button_ids)
|
||||
if has_archive_btn:
|
||||
log_id = record_id.log_ids.filtered(lambda l: l.name == '归档')
|
||||
employee_id = self.env['hr.employee'].sudo().search([('user_id', '=', record_id.log_ids[0].done_by.id)], limit=1)
|
||||
if workflow_record:
|
||||
workflow_record.write({
|
||||
'approve_state': 'end',
|
||||
'employee_ids': [(6, 0, [record_id.log_ids[0].done_by.employee_id.id])],
|
||||
'employee_ids': [(6, 0, [employee_id.id])],
|
||||
'soong_state': 'to_active',
|
||||
'node_id': False,
|
||||
})
|
||||
|
||||
@@ -85,12 +85,11 @@ class YuThonPhone(http.Controller):
|
||||
user_id = request.env['res.users'].sudo().browse(kw.get('employee'))
|
||||
employee_id = user_id.with_company(user_id.company_id.id).employee_id
|
||||
applet_security_setting_ids = request.env['applet.security'].sudo().search([('employee_id', '=', employee_id.id)]).applet_security_setting_ids
|
||||
task_ids = request.env['yuthon.will.task'].sudo().search([('users_ids', 'in', [user_id])])
|
||||
data = [{
|
||||
'日程': 5,
|
||||
'抄表': 10,
|
||||
'OA': 0,
|
||||
'工作流': 10,
|
||||
'日程': len(task_ids),
|
||||
}]
|
||||
_logger.info(f'{data}-------------------/phone/base/self------------收到请求')
|
||||
return json.dumps({'data': data, 'code': 200, 'message': ''})
|
||||
|
||||
@http.route('/phone/base/test', type='http', auth="none", csrf=False, cors='*')
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
import { DateTimePicker } from "@web/core/datetime/datetime_picker";
|
||||
import { isMobileOS } from "@web/core/browser/feature_detection";
|
||||
import { useEffect, useRef, reactive } from "@odoo/owl";
|
||||
import { useEffect, useRef } from "@odoo/owl";
|
||||
|
||||
patch(DateTimePicker.prototype, {
|
||||
setup() {
|
||||
|
||||
@@ -353,7 +353,7 @@ class HolidaysRequestBatch(models.Model):
|
||||
column1='leave_id',
|
||||
column2='attachment_id'
|
||||
)
|
||||
holiday_allowance = fields.Char(string="可用额度", compute='_compute_holiday_allowance', store=True)
|
||||
holiday_allowance = fields.Text(string="可用额度", compute='_compute_holiday_allowance', store=True)
|
||||
active = fields.Boolean('Active', default=True, tracking=True)
|
||||
|
||||
def _get_default_name_title(self):
|
||||
@@ -365,7 +365,7 @@ class HolidaysRequestBatch(models.Model):
|
||||
@api.onchange('is_day')
|
||||
def _onchange_is_day(self):
|
||||
if not self.is_day:
|
||||
self.leave_ids = [(5, 0, 0)] # 清空One2many字段
|
||||
self.leave_ids = [(5, 0, 0)]
|
||||
|
||||
@api.onchange('is_hour')
|
||||
def _onchange_is_hour(self):
|
||||
@@ -411,7 +411,7 @@ class HolidaysRequestBatch(models.Model):
|
||||
other_leave_types = [
|
||||
'产假', '事假', '法定假', '调休', '补休', '值班调休',
|
||||
'婚假', '陪产假', '计生假', '丧假', '探亲假',
|
||||
'家长会假', '病假(普通)', '病假(住院期)',
|
||||
'家长会假', '病假(普通)', '病假(住院期)', '育儿假',
|
||||
'病假(出院恢复期)', '考试假'
|
||||
]
|
||||
for leave_type in other_leave_types:
|
||||
@@ -851,13 +851,33 @@ class HolidaysRequestBatch(models.Model):
|
||||
current_date = fields.Date.today()
|
||||
vacation_date = current_date
|
||||
for record in self:
|
||||
reports_id = self.env['yuthon.vacation.reports'].search([('employee_id', '=', record.users_id.employee_ids.id),
|
||||
result_parts = []
|
||||
reports_id = self.env['yuthon.vacation.reports'].search([
|
||||
('employee_id', '=', record.users_id.employee_ids.id),
|
||||
('vacation_date', '=', vacation_date.replace(day=1))
|
||||
], limit=1)
|
||||
if reports_id:
|
||||
leave_days = reports_id.leave
|
||||
overtime_days = reports_id.working_overtime
|
||||
record.holiday_allowance = f"年假{leave_days:.3f}天, 补休{overtime_days:.3f}天"
|
||||
|
||||
if not reports_id:
|
||||
record.holiday_allowance = ""
|
||||
continue
|
||||
holiday_configs = [
|
||||
("年假", "previous_year", "remainder_year"),
|
||||
("补休", "previous_year1", "remainder_year1"),
|
||||
("育儿假", None, "remaining_parental_leave")
|
||||
]
|
||||
for name, prev_field, curr_field in holiday_configs:
|
||||
parts = []
|
||||
if prev_field:
|
||||
prev_value = getattr(reports_id, prev_field, 0.0)
|
||||
if prev_value > 0: # 大于0才显示
|
||||
parts.append(f"上年结余{prev_value:.0f}天")
|
||||
curr_value = getattr(reports_id, curr_field, 0.0)
|
||||
if curr_value > 0:
|
||||
parts.append(f"本年剩余{curr_value:.0f}天")
|
||||
if parts:
|
||||
result_parts.append(f"{name}:{','.join(parts)}")
|
||||
|
||||
record.holiday_allowance = "\n".join(result_parts)
|
||||
|
||||
def action_print_leave_batch(self):
|
||||
"""按钮触发打印请假单"""
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
'views/card_remind_form.xml',
|
||||
'views/yuthon_customer_planning_views.xml',
|
||||
'views/planning_slot_template_views.xml',
|
||||
'views/yuthon_overtime_line_views.xml',
|
||||
'views/vacation_overtime_active_views.xml',
|
||||
'views/hr_attendance_month_views.xml',
|
||||
'views/wifi_message_view.xml',
|
||||
'views/back_approval.xml',
|
||||
@@ -65,6 +67,7 @@
|
||||
'views/meal_approval.xml',
|
||||
'views/applet_address_views.xml',
|
||||
'views/yuthon_holiday_statement.xml',
|
||||
'views/yuthon_parenting_allocate_views.xml',
|
||||
'views/all_attendance_menu.xml',
|
||||
'views/overtime_approval_inherit_header.xml',
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from odoo import fields, http, SUPERUSER_ID, _
|
||||
from odoo.exceptions import AccessError, MissingError, ValidationError
|
||||
from odoo.http import request
|
||||
from ....addons.portal.controllers import portal
|
||||
from datetime import datetime, date, time, timedelta
|
||||
|
||||
|
||||
class CustomerPortal(portal.CustomerPortal):
|
||||
@@ -69,13 +70,46 @@ class CustomerPortal(portal.CustomerPortal):
|
||||
|
||||
@http.route('/phone/vacation/self/detail', type='http', auth="none", csrf=False, cors='*')
|
||||
def phone_vacation_self_detail(self, **kw):
|
||||
records = request.env['yuthon.vacation.reports'].sudo().search([('id', '=', kw.get('id'))])
|
||||
record = request.env['yuthon.vacation.reports'].sudo().search([('id', '=', kw.get('id'))])
|
||||
current_date = record.vacation_date
|
||||
if current_date.month == 1:
|
||||
last_month_year = current_date.year - 1
|
||||
last_month = 12
|
||||
else:
|
||||
last_month_year = current_date.year
|
||||
last_month = current_date.month - 1
|
||||
records = request.env['yuthon.vacation.reports'].sudo().search([
|
||||
('employee_id', '=', record.employee_id.id),
|
||||
('vacation_date', '>=', f'{last_month_year}-{last_month:02d}-01'),
|
||||
('vacation_date', '<', f'{last_month_year}-{last_month + 1:02d}-01' if last_month < 12 else f'{last_month_year + 1}-01-01')
|
||||
], limit=1)
|
||||
data = {
|
||||
'日期': records.display_date,
|
||||
'剩余年假': records.leave,
|
||||
'剩余补休': records.working_overtime,
|
||||
'剩余误餐费': records.meal_fee,
|
||||
'剩余体检费': records.medical_fee,
|
||||
'日期': record.display_date,
|
||||
'应到': records.should_attendance,
|
||||
'实到': records.actual_attendance,
|
||||
'迟到': records.is_late_card,
|
||||
'早退': records.is_early_card,
|
||||
'缺卡': records.is_no_card,
|
||||
'旷工': records.is_work,
|
||||
'异常': records.is_abnormal,
|
||||
'年假': records.done_leave,
|
||||
'加班时': records.done_working_overtime,
|
||||
'调休': records.compensatory_leave,
|
||||
'事假': records.leave_of_absence,
|
||||
'加班时(法定假)': records.statutory_leave,
|
||||
'育儿假': records.parental_leave,
|
||||
'值班调休': records.duty_off_leave,
|
||||
'婚假': records.marriage_leave,
|
||||
'产假': records.maternity_leave,
|
||||
'陪产假': records.paternity_leave,
|
||||
'计生假': records.family_planning_leave,
|
||||
'丧假': records.bereavement_leave,
|
||||
'探亲假': records.home_visit_leave,
|
||||
'家长会假': records.parents_meeting_leave,
|
||||
'病假(普通)': records.general_sick_leave,
|
||||
'病假(住院期)': records.hospital_sick_leave,
|
||||
'病假(出院恢复期)': records.recovery_sick_leave,
|
||||
'考试假': records.exam_leave,
|
||||
}
|
||||
return json.dumps({'data': data, 'code': 200, 'message': ''})
|
||||
|
||||
|
||||
@@ -14,19 +14,6 @@
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall"/>
|
||||
</record>
|
||||
<record forcecreate="True" id="yuthon_vacation_start_end_time" model="ir.cron">
|
||||
<field name="name">定时任务:更新我的考勤确认单实到数据</field>
|
||||
<field name="model_id" ref="model_yuthon_vacation_reports"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model.monthly_day_report()</field>
|
||||
<field eval="False" name="active"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">days</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>
|
||||
<record forcecreate="True" id="yuthon_vacation_attendance_confirmation" model="ir.cron">
|
||||
<field name="name">定时任务:批量发送考勤确认</field>
|
||||
<field name="model_id" ref="model_yuthon_vacation_reports"/>
|
||||
|
||||
@@ -34,7 +34,9 @@ from . import staff_dining_report
|
||||
from . import message_reminder_tasks
|
||||
from . import yuthon_holiday_statement
|
||||
from . import yuthon_meal_case
|
||||
|
||||
from . import yuthon_parenting_allocate
|
||||
from . import vacation_overtime_active
|
||||
from . import yuthon_overtime_line
|
||||
# from odoo.tools import SQL
|
||||
# import odoo
|
||||
# odoo.models.READ_GROUP_AGGREGATE.update({
|
||||
|
||||
@@ -23,6 +23,7 @@ class CardApprovals(models.Model):
|
||||
reason_application = fields.Text(string="申请事由")
|
||||
documents_ids = fields.Many2many('ir.attachment', string="附件")
|
||||
attendance_id = fields.Many2one('hr.attendance', string="补卡日期")
|
||||
number_cards_replaced = fields.Integer(string="已补卡次数")
|
||||
attendance = fields.Char(string="补卡日期")
|
||||
is_attendance = fields.Boolean(string="字段隐藏")
|
||||
replacement_time = fields.Selection([('work', '上班卡'), ('quitting', '下班卡'), ('all', '全天卡')], string="补卡", store=True)
|
||||
|
||||
@@ -14,6 +14,7 @@ class OvertimeApprovals(models.Model):
|
||||
_rec_name = 'name'
|
||||
|
||||
name = fields.Char(string="标题", compute='_compute_name')
|
||||
number_card = fields.Char(string="补卡次数")
|
||||
code = fields.Char(string="编号", default=lambda self: self.env['ir.sequence'].next_by_code('overtime_approval'))
|
||||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
company_id = fields.Many2one(related='users_id.employee_ids.company_id', string="公司")
|
||||
@@ -58,6 +59,23 @@ class OvertimeApprovals(models.Model):
|
||||
name_title = fields.Char(default=_get_default_name_title)
|
||||
self_users_ids = fields.Many2many('res.users', string="当前经办人", default=lambda self: [(6, 0, [self.env.user.id])])
|
||||
|
||||
@api.constrains('start_time')
|
||||
def _check_start_time(self):
|
||||
for rec in self:
|
||||
workflow_records = self.env['soong.workflow.record'].search([
|
||||
('workflow_id.name', '=', '加班'),
|
||||
('create_uid', '=', self.env.user.id),
|
||||
])
|
||||
if not workflow_records:
|
||||
continue
|
||||
for wf_rec in workflow_records:
|
||||
target_model = self.env[wf_rec.res_model]
|
||||
target_record = target_model.browse(wf_rec.res_id)
|
||||
if not target_record.exists() or not target_record.start_time:
|
||||
continue
|
||||
if target_record.start_time.date() == rec.start_time.date():
|
||||
raise UserError('当天已有加班审批,请重新选择开始时间')
|
||||
|
||||
def open_record(self):
|
||||
if self.start_time and self.end_time and self.employee_ids:
|
||||
start_date = fields.Date.to_date(self.start_time)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
from datetime import datetime, timedelta, time
|
||||
from email.policy import default
|
||||
from operator import index
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
import calendar
|
||||
from datetime import date
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
class VacationOvertimeActive(models.Model):
|
||||
_name = 'vacation.overtime.active'
|
||||
_description = '加班情况归档'
|
||||
|
||||
employee_id = fields.Many2one('hr.employee', string='员工')
|
||||
department_id = fields.Many2one('hr.department', related='employee_id.department_id', string="部门")
|
||||
company_id = fields.Many2one('res.company', related='employee_id.company_id', string="公司")
|
||||
workflow_record_id = fields.Many2one('soong.workflow.record', string='流程')
|
||||
overtime_name = fields.Char(string="标题")
|
||||
carry_forward_date = fields.Date(string="结转日期")
|
||||
carry_forward_quantity = fields.Float(string="结转时长")
|
||||
carry_result = fields.Selection([('success', '成功'), ('failed', '失败')], string="结转结果")
|
||||
remaining_quantity = fields.Float(string="剩余数")
|
||||
@@ -5,6 +5,7 @@ from datetime import date, timedelta
|
||||
class YuthonOvertimeReport(models.Model):
|
||||
_name = 'yuthon.holiday.statement'
|
||||
|
||||
|
||||
class InheritHrLeave(models.Model):
|
||||
_inherit = 'hr.leave'
|
||||
_description = '请假情况'
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
from odoo import api, fields, models, tools, _
|
||||
from datetime import datetime, time, timedelta
|
||||
from odoo.exceptions import UserError
|
||||
from datetime import date, timedelta
|
||||
|
||||
|
||||
|
||||
class YuthonOvertimeLine(models.Model):
|
||||
_name = 'yuthon.overtime.line'
|
||||
_description = '加班明细'
|
||||
|
||||
employee_id = fields.Many2one('hr.employee', string="员工")
|
||||
last_balance = fields.Float(string="上年结余")
|
||||
valid_date = fields.Date(string="有效至")
|
||||
workday = fields.Float(string='工作日')
|
||||
public_holidays = fields.Float(string='公休日')
|
||||
vacation_sum = fields.Float(string='合计数')
|
||||
carry_forward_quantity = fields.Float(string="结转时长")
|
||||
carry_forward_date = fields.Date(string="结转日期")
|
||||
remaining_quantity = fields.Float(string="剩余数")
|
||||
|
||||
def open_record(self):
|
||||
pass
|
||||
@@ -0,0 +1,31 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import api, fields, models, tools, _
|
||||
from datetime import datetime, time, timedelta
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class YuthonParentingAllocate(models.Model):
|
||||
_name = 'yuthon.parenting.allocate'
|
||||
_description = '育儿额度分配规则'
|
||||
|
||||
company_id = fields.Many2one("res.company", string="公司", default=lambda self: self.env.company)
|
||||
cycle_years = fields.Integer(string='周期年数', default=1, help='按出生日计算的周期年数,如1表示1年')
|
||||
cycle_unit = fields.Integer(string='周期单位', default=1, help='周期的描述单位,如“1”周期')
|
||||
valid_limit = fields.Integer(string='有效期限(岁)', default=1, help='规则生效的截止条件')
|
||||
distribute = fields.Integer(string='年/发放额度')
|
||||
start_date = fields.Date(string="生效日期", copy=False, default=fields.Date.today())
|
||||
end_date = fields.Date(string="失效日期", copy=False, default=fields.Date.from_string('2099-01-01'))
|
||||
is_enable = fields.Boolean(string="是否启用", compute="compute_is_enable", store=True)
|
||||
birth_certificate = fields.Text(string='备注', default='需要在花名册配置紧急联系人才能生效')
|
||||
|
||||
@api.depends('start_date', 'end_date')
|
||||
def compute_is_enable(self):
|
||||
for rec in self:
|
||||
if not rec.end_date:
|
||||
rec.is_enable = True
|
||||
else:
|
||||
if rec.start_date and rec.end_date:
|
||||
if rec.start_date <= fields.Date.today() < rec.end_date:
|
||||
rec.is_enable = True
|
||||
else:
|
||||
rec.is_enable = False
|
||||
@@ -31,6 +31,7 @@ class YuthonVacationReports(models.Model):
|
||||
year_holiday = fields.Float(string="本年公休日", digits=(16, 3))
|
||||
year_workday = fields.Float(string="本年工作日", digits=(16, 3))
|
||||
year_sum = fields.Float(string="本年调休合计", digits=(16, 3), compute="_compute_year_sum")
|
||||
previous_year1 = fields.Float(string="上年剩余(补休)", digits=(16, 3))
|
||||
used_this_year1 = fields.Float(string="本年已休", digits=(16, 3))
|
||||
remainder_year1 = fields.Float(string="剩余(补休)", digits=(16, 3), compute="_compute_year_sum")
|
||||
|
||||
@@ -40,6 +41,7 @@ class YuthonVacationReports(models.Model):
|
||||
overtime_ids = fields.One2many('vacation.over.line', 'vacation_id', string='加班明细')
|
||||
meal_fee_ids = fields.One2many('vacation.meal.line', 'vacation_id', string='误餐明细')
|
||||
medical_fee_ids = fields.One2many('vacation.medical.line', 'vacation_id', string='体检费明细')
|
||||
parenting_line_ids = fields.One2many('vacation.parenting.line', 'vacation_id', string='育儿假明细')
|
||||
other_fee_ids = fields.One2many('vacation.other.line', 'vacation_id', string='其他明细')
|
||||
vacation_date = fields.Date(string='日期', default=lambda self: fields.Date.today().replace(day=1))
|
||||
display_date = fields.Char(string='日期', compute='_compute_display_date')
|
||||
@@ -68,6 +70,8 @@ class YuthonVacationReports(models.Model):
|
||||
general_sick_leave = fields.Float(string='病假(普通)', digits=(16, 3), compute='_compute_other_leave', store=True, group_operator=None)
|
||||
hospital_sick_leave = fields.Float(string='病假(住院期)', digits=(16, 3), compute='_compute_other_leave', store=True, group_operator=None)
|
||||
recovery_sick_leave = fields.Float(string='病假(出院恢复期)', digits=(16, 3), compute='_compute_other_leave', store=True, group_operator=None)
|
||||
parental_leave = fields.Float(string='育儿假', digits=(16, 3), compute='_compute_parental_leave', store=True, group_operator=None)
|
||||
remaining_parental_leave = fields.Float(string='剩余育儿假', digits=(16, 3), compute='_compute_parental_leave', store=True, group_operator=None)
|
||||
exam_leave = fields.Integer(string='考试假', compute='_compute_other_leave', store=True, group_operator=None)
|
||||
right_days = fields.Float(string='转正天数', group_operator=None, compute='compute_attendance_fields')
|
||||
internship_days = fields.Float(string='实习天数', group_operator=None)
|
||||
@@ -97,6 +101,122 @@ class YuthonVacationReports(models.Model):
|
||||
tracking=3,
|
||||
default='not_sent')
|
||||
|
||||
def update_overtime(self):
|
||||
today = date.today()
|
||||
over_line_domain = [
|
||||
('vacation_id', '!=', False),
|
||||
('update_type', '=', 'add'),
|
||||
('is_void', '=', False)
|
||||
]
|
||||
over_lines = self.env['vacation.over.line'].search(over_line_domain)
|
||||
|
||||
void_lines = self.env['vacation.over.line']
|
||||
for line in over_lines:
|
||||
# 确定判断超期的基准日期:有adjust_date则用adjust_date,否则用valid_date
|
||||
check_date = line.adjust_date if line.adjust_date else line.valid_date
|
||||
if check_date and today > check_date:
|
||||
void_lines |= line
|
||||
|
||||
# 批量标记作废
|
||||
if void_lines:
|
||||
void_lines.write({'is_void': True})
|
||||
|
||||
for void_line in void_lines:
|
||||
# 跳过vacation_id为空的情况
|
||||
if not void_line.vacation_id:
|
||||
continue
|
||||
|
||||
main_vacation = void_line.vacation_id
|
||||
vacation_date = main_vacation.vacation_date
|
||||
|
||||
# 查找vacation_date之后的加班记录中,text='上月继承额度'的行
|
||||
inherit_domain = [
|
||||
('vacation_id', '=', main_vacation.id),
|
||||
('create_date', '>=', fields.Datetime.to_datetime(vacation_date)),
|
||||
('text', '=', '上月额度继承'),
|
||||
]
|
||||
inherit_lines = self.env['vacation.over.line'].search(inherit_domain)
|
||||
if not inherit_lines:
|
||||
continue
|
||||
|
||||
deduct_value = void_line.update_lines or 0.0
|
||||
for inherit_line in inherit_lines:
|
||||
new_lines = inherit_line.update_lines - deduct_value
|
||||
inherit_line.write({'update_lines': new_lines})
|
||||
|
||||
def update_leave(self):
|
||||
today = date.today()
|
||||
leave_line_domain = [
|
||||
('vacation_id', '!=', False),
|
||||
('update_type', '=', 'add'),
|
||||
('is_void', '=', False)
|
||||
]
|
||||
leave_lines = self.env['vacation.leave.line'].search(leave_line_domain)
|
||||
|
||||
void_lines = self.env['vacation.leave.line']
|
||||
for line in leave_lines:
|
||||
check_date = line.adjust_date if line.adjust_date else line.valid_date
|
||||
if check_date and today > check_date:
|
||||
void_lines |= line
|
||||
|
||||
if void_lines:
|
||||
void_lines.write({'is_void': True})
|
||||
|
||||
# 3. 扣减update_lines中「上月继承额度」的workday
|
||||
for void_line in void_lines:
|
||||
if not void_line.vacation_id:
|
||||
continue
|
||||
|
||||
main_vacation = void_line.vacation_id
|
||||
vacation_date = main_vacation.vacation_date
|
||||
if not vacation_date:
|
||||
continue
|
||||
|
||||
# 查找vacation_date之后的年假继承记录(关联update_lines)
|
||||
inherit_domain = [
|
||||
('vacation_id', '=', main_vacation.id),
|
||||
('create_date', '>=', fields.Datetime.to_datetime(vacation_date)),
|
||||
('text', '=', '上月额度继承'),
|
||||
('is_void', '=', False)
|
||||
]
|
||||
inherit_lines = self.env['vacation.leave.line'].search(inherit_domain)
|
||||
|
||||
if not inherit_lines:
|
||||
continue
|
||||
|
||||
# 扣减年假workday
|
||||
deduct_value = void_line.workday or 0.0
|
||||
for inherit_line in inherit_lines:
|
||||
new_workday = inherit_line.workday - deduct_value
|
||||
inherit_line.write({'workday': new_workday})
|
||||
|
||||
@api.depends('other_fee_ids', 'other_fee_ids.holiday_type', 'other_fee_ids.lines',
|
||||
'other_fee_ids.is_void', 'other_fee_ids.update_type', 'parenting_line_ids',
|
||||
'parenting_line_ids.update_date', 'parenting_line_ids.end_date', 'parenting_line_ids.lines')
|
||||
def _compute_parental_leave(self):
|
||||
today = date.today()
|
||||
for rec in self:
|
||||
used_amount = 0.0
|
||||
deduct_fee_lines = rec.other_fee_ids.filtered(
|
||||
lambda l:
|
||||
l.holiday_type.name == '育儿假'
|
||||
and l.update_type == 'reduce'
|
||||
and not l.is_void
|
||||
and l.lines > 0
|
||||
)
|
||||
if deduct_fee_lines:
|
||||
used_amount = sum(line.lines for line in deduct_fee_lines)
|
||||
rec.parental_leave = used_amount
|
||||
total_amount = 0.0
|
||||
valid_parenting_lines = rec.parenting_line_ids.filtered(
|
||||
lambda l:
|
||||
l.update_date <= today
|
||||
and (l.end_date >= today if l.end_date else True)
|
||||
)
|
||||
if valid_parenting_lines:
|
||||
total_amount = sum(line.lines for line in valid_parenting_lines)
|
||||
rec.remaining_parental_leave = max(total_amount - used_amount, 0.0)
|
||||
|
||||
def update_vacation_state(self):
|
||||
records = self.env["yuthon.vacation.reports"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id', self.ids))
|
||||
@@ -132,16 +252,17 @@ class YuthonVacationReports(models.Model):
|
||||
record.other_fee_ids.write({'is_confirm': True})
|
||||
return result
|
||||
|
||||
@api.depends('previous_year', 'year_distribution', 'used_this_year')
|
||||
@api.depends('year_distribution', 'used_this_year')
|
||||
def _compute_remainder_year(self):
|
||||
for record in self:
|
||||
record.remainder_year = record.previous_year + record.year_distribution - record.used_this_year
|
||||
record.remainder_year = record.year_distribution - record.used_this_year
|
||||
|
||||
@api.depends('last_holiday', 'last_workday', 'year_holiday', 'year_workday', 'used_this_year1')
|
||||
def _compute_year_sum(self):
|
||||
for record in self:
|
||||
record.year_sum = record.last_holiday + record.last_workday + record.year_holiday + record.year_workday
|
||||
record.remainder_year1 = record.year_sum - record.used_this_year1
|
||||
record.previous_year1 = record.last_holiday + record.last_workday
|
||||
|
||||
@api.constrains('employee_id', 'vacation_date')
|
||||
def _check_duplicate_monthly_record(self):
|
||||
@@ -217,8 +338,6 @@ class YuthonVacationReports(models.Model):
|
||||
if invalid_overtimes:
|
||||
raise UserError('有加班单未结束,请先结束加班批次')
|
||||
|
||||
rec.manage_reject()
|
||||
|
||||
@api.depends('vacation_date')
|
||||
def _compute_display_date(self):
|
||||
for rec in self:
|
||||
@@ -493,11 +612,19 @@ class YuthonVacationReports(models.Model):
|
||||
return f'{month}月{day}日'
|
||||
|
||||
def button_put(self):
|
||||
url = f'https://oa.thtzjt.com/webh5/#/vacation?id={self.id}'
|
||||
we_id = self.env['hr.employee'].search([('id', '=', self.employee_id.id)]).wecom_userid
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='default', user_id=we_id, title="考勤确认",
|
||||
description=self.employee_id.name + '请确认你的考勤:',
|
||||
url=url, btntxt="详细信息")
|
||||
we_id = self.employee_id.wecom_userid
|
||||
if we_id:
|
||||
url = f'https://phone.thtzjt.com/phone/Notarize/{self.id}/{self.employee_id.id}'
|
||||
year = self.vacation_date.year
|
||||
month = self.vacation_date.month
|
||||
data = f"你{year}年{month}月的考勤确认单已经生成,请确认"
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='att_ok', user_id=we_id,
|
||||
title="考勤确认单", description=data, url=url,
|
||||
btntxt="详细信息")
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='att_ok', user_id="18562027762",
|
||||
title="考勤确认单", description=data, url=url,
|
||||
btntxt="详细信息")
|
||||
self.write({'vacation_state': 'pending'})
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
@@ -509,27 +636,32 @@ class YuthonVacationReports(models.Model):
|
||||
}
|
||||
|
||||
def all_put(self):
|
||||
vacation_ids = self.env["yuthon.vacation.reports"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id')))
|
||||
vacation_list = []
|
||||
vacation_ids = self.env["yuthon.vacation.reports"].browse(self._context.get('active_ids', self._context.get('active_id')))
|
||||
for rec in vacation_ids:
|
||||
vacation_list.append(rec.id)
|
||||
we_id = rec.employee_id.wecom_userid
|
||||
year = rec.vacation_date.year
|
||||
month = rec.vacation_date.month
|
||||
if we_id:
|
||||
url = f'https://phone.thtzjt.com/phone/Notarize/{rec.id}/{rec.employee_id.id}'
|
||||
data = f"你{year}年{month}月的考勤确认单已经生成,请确认"
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='att_ok', user_id=we_id, title="考勤确认单", description=data, url=url, btntxt="详细信息")
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='att_ok', user_id="18562027762", title="考勤确认单", description=data, url=url, btntxt="详细信息")
|
||||
rec.write({'vacation_state': 'pending'})
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': '批量发送确认弹窗',
|
||||
'res_model': 'vacation.put.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {'default_vacation_ids': [(6, 0, [vacation_list])]
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'type': 'success',
|
||||
'message': '已发送提醒消息',
|
||||
'sticky': False,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def manage_confirmation(self):
|
||||
vacation_ids = self.env["yuthon.vacation.reports"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id')))
|
||||
for rec in vacation_ids:
|
||||
rec.manage_reject()
|
||||
rec.vacation_state = 'confirmed'
|
||||
|
||||
def manage_reject(self):
|
||||
'''
|
||||
@@ -543,10 +675,7 @@ class YuthonVacationReports(models.Model):
|
||||
('employee_id', '=', rec.employee_id.id),
|
||||
('vacation_date', '>=', fields.Date.to_string(last_month_first)),
|
||||
('vacation_date', '<=', fields.Date.to_string(last_month_last)),
|
||||
('vacation_state', '=', 'confirmed')
|
||||
], limit=1)
|
||||
|
||||
rec.vacation_state = 'confirmed'
|
||||
current_year = rec.vacation_date.year
|
||||
last_month_year = last_month_last.year
|
||||
is_cross_year = current_year != last_month_year
|
||||
@@ -565,6 +694,18 @@ class YuthonVacationReports(models.Model):
|
||||
'leave': last_month_record.leave,
|
||||
'working_overtime': last_month_record.working_overtime,
|
||||
'medical_fee': last_month_record.medical_fee,
|
||||
'previous_year': last_month_record.previous_year,
|
||||
'valid_date': last_month_record.valid_date,
|
||||
'year_distribution': last_month_record.year_distribution,
|
||||
'used_this_year': last_month_record.used_this_year,
|
||||
'last_holiday': last_month_record.last_holiday,
|
||||
'last_workday': last_month_record.last_workday,
|
||||
'valid_date1': last_month_record.valid_date1,
|
||||
'year_holiday': last_month_record.year_holiday,
|
||||
'year_workday': last_month_record.year_workday,
|
||||
'previous_year1': last_month_record.previous_year1,
|
||||
'used_this_year1': last_month_record.used_this_year1,
|
||||
'remainder_year1': last_month_record.remainder_year1,
|
||||
}
|
||||
rec.write(inherit_vals)
|
||||
if rec.leave:
|
||||
@@ -585,7 +726,6 @@ class YuthonVacationReports(models.Model):
|
||||
total += line.lines
|
||||
elif line.update_type == 'reduce':
|
||||
total -= line.lines
|
||||
|
||||
record.medical_fee = max(total, 0.0)
|
||||
|
||||
def disposable_report(self):
|
||||
@@ -701,9 +841,9 @@ class YuthonVacationReports(models.Model):
|
||||
)
|
||||
def _compute_working_overtime(self):
|
||||
for record in self:
|
||||
total_add1 = 0.0
|
||||
total_add2 = 0.0
|
||||
total_add = 0.0
|
||||
total_add1 = 0.0 # 加班时
|
||||
total_add2 = 0.0 # (已用补休)
|
||||
total_add = 0.0 # (剩余补休)
|
||||
legal_total = 0.0
|
||||
for line in record.overtime_ids:
|
||||
if line.is_void:
|
||||
@@ -718,8 +858,10 @@ class YuthonVacationReports(models.Model):
|
||||
|
||||
if line.workflow_record_id and line.update_type == 'add' and line.overtime_methods == 'leave':
|
||||
total_add1 += line_total
|
||||
|
||||
if line.workflow_record_id and line.update_type == 'reduce':
|
||||
total_add2 += line_total
|
||||
|
||||
adjust_holiday_days = 0.0
|
||||
for other_line in record.other_fee_ids:
|
||||
if other_line.holiday_type and other_line.holiday_type.name == '调休':
|
||||
@@ -790,7 +932,7 @@ class YuthonVacationReports(models.Model):
|
||||
], limit=1)
|
||||
# 如果考勤异常,则不自动确认
|
||||
if not attendance_exception:
|
||||
rec.manage_reject()
|
||||
rec.vacation_state = 'confirmed'
|
||||
|
||||
def monthly_report(self):
|
||||
today = fields.Date.today()
|
||||
@@ -952,6 +1094,7 @@ class VacationLeaveLine(models.Model):
|
||||
self._sync_to_employee(reverse=True)
|
||||
return super(VacationLeaveLine, self).unlink()
|
||||
|
||||
|
||||
class VacationOverline(models.Model):
|
||||
_name = 'vacation.over.line'
|
||||
_description = '加班明细'
|
||||
@@ -967,6 +1110,7 @@ class VacationOverline(models.Model):
|
||||
last_balance = fields.Float(string='上年结余', compute='_compute_last_balance', store=True)
|
||||
legal_day = fields.Float(string='法定节假日')
|
||||
public_holidays = fields.Float(string='公休日')
|
||||
vacation_sum = fields.Float(string='合计数', compute='_compute_last_balance')
|
||||
meal_number = fields.Integer(string='误餐次数')
|
||||
update_date = fields.Date(string='更新时间')
|
||||
is_void = fields.Boolean(string='是否作废')
|
||||
@@ -991,10 +1135,24 @@ class VacationOverline(models.Model):
|
||||
],string='结转状态',
|
||||
default='pending',
|
||||
)
|
||||
remaining_quantity = fields.Float(string='剩余数', compute="_compute_remaining_quantity", store=True)
|
||||
remaining_quantity = fields.Float(string='剩余数', compute="_compute_last_balance", store=True)
|
||||
|
||||
def open_record1(self):
|
||||
tree_id = self.env.ref("yuthon_hr_attendance.view_yuthon_vacation_overtime_tree").id
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Overtime Record',
|
||||
'res_model': 'vacation.meal.line',
|
||||
'view_mode': 'tree',
|
||||
'views': [[tree_id, 'tree']],
|
||||
'domain': [('employee_id', '=', self.employee_id.id),
|
||||
('carry_forward_state', '=', 'pending')
|
||||
],
|
||||
}
|
||||
|
||||
@api.model
|
||||
def confirm(self):
|
||||
# 1. 构建筛选域
|
||||
domain = [
|
||||
'|',
|
||||
['is_initial_number', '=', True],
|
||||
@@ -1012,11 +1170,39 @@ class VacationOverline(models.Model):
|
||||
filtered_records = self.search(domain)
|
||||
if not filtered_records:
|
||||
return
|
||||
records_to_update = filtered_records.filtered(
|
||||
lambda r: fields.float_compare(r.duration, r.carry_forward_quantity) == 0
|
||||
|
||||
valid_records = filtered_records.filtered(
|
||||
lambda r: r.carry_forward_quantity and r.carry_forward_quantity != 0.0
|
||||
)
|
||||
if records_to_update:
|
||||
records_to_update.write({'is_filing': True})
|
||||
if not valid_records:
|
||||
return
|
||||
|
||||
active_model = self.env['vacation.overtime.active']
|
||||
for rec in valid_records:
|
||||
if rec.remaining_quantity == 0:
|
||||
rec.is_filing = True
|
||||
|
||||
match_domain = [
|
||||
('employee_id', '=', rec.employee_id.id if rec.employee_id else False),
|
||||
('workflow_record_id', '=', rec.workflow_record_id.id if rec.workflow_record_id else False),
|
||||
('carry_forward_date', '=', rec.carry_forward_date or fields.Date.today()),
|
||||
('overtime_name', '=', rec.overtime_name or '')
|
||||
]
|
||||
existing_active = active_model.search(match_domain, limit=1)
|
||||
active_vals = {
|
||||
'employee_id': rec.employee_id.id if rec.employee_id else False,
|
||||
'workflow_record_id': rec.workflow_record_id.id if rec.workflow_record_id else False,
|
||||
'overtime_name': rec.overtime_name or '',
|
||||
'remaining_quantity': rec.remaining_quantity,
|
||||
'carry_forward_date': rec.carry_forward_date or fields.Date.today(),
|
||||
'carry_forward_quantity': rec.carry_forward_quantity,
|
||||
'carry_result': 'success'
|
||||
}
|
||||
|
||||
if existing_active:
|
||||
existing_active.write(active_vals)
|
||||
else:
|
||||
active_model.create(active_vals)
|
||||
|
||||
def update_is_visible(self):
|
||||
over_ids = self.env["vacation.over.line"].browse(
|
||||
@@ -1028,21 +1214,17 @@ class VacationOverline(models.Model):
|
||||
over_ids = self.env["vacation.over.line"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id')))
|
||||
for rec in over_ids:
|
||||
rec._compute_remaining_quantity()
|
||||
rec._compute_overtime()
|
||||
rec._compute_employee_id()
|
||||
rec._compute_last_balance()
|
||||
|
||||
@api.depends('duration', 'carry_forward_quantity')
|
||||
def _compute_remaining_quantity(self):
|
||||
for rec in self:
|
||||
rec.remaining_quantity = rec.duration - rec.carry_forward_quantity
|
||||
|
||||
@api.depends('vacation_id')
|
||||
def _compute_last_balance(self):
|
||||
for rec in self:
|
||||
if rec.vacation_id:
|
||||
rec.last_balance = rec.vacation_id.last_holiday + rec.vacation_id.last_workday
|
||||
rec.vacation_sum = rec.last_balance + rec.public_holidays + rec.workday
|
||||
rec.remaining_quantity = rec.vacation_sum - rec.carry_forward_quantity
|
||||
else:
|
||||
rec.last_balance = 0
|
||||
|
||||
@@ -1320,6 +1502,19 @@ class VacationMealLine(models.Model):
|
||||
return super(VacationMealLine, self).unlink()
|
||||
|
||||
|
||||
class VacationParentingLine(models.Model):
|
||||
_name = 'vacation.parenting.line'
|
||||
_description = '育儿明细'
|
||||
|
||||
vacation_id = fields.Many2one('yuthon.vacation.reports', string='关联假期额度记录')
|
||||
employee_id = fields.Many2one('hr.employee', string='员工')
|
||||
update_date = fields.Date(string='发放日期')
|
||||
end_date = fields.Date(string='失效日期')
|
||||
lines = fields.Float(string='额度')
|
||||
text = fields.Text(string='备注')
|
||||
is_confirm = fields.Boolean(string="是否确认")
|
||||
|
||||
|
||||
class VacationMedicalLine(models.Model):
|
||||
_name = 'vacation.medical.line'
|
||||
_description = '体检费明细'
|
||||
|
||||
@@ -86,3 +86,8 @@ access_vacation_reports_wizard,vacation.reports.wizard,model_vacation_reports_wi
|
||||
access_yuthon_holiday_statement,access_yuthon_holiday_statement,model_yuthon_holiday_statement,base.group_user,1,1,1,1
|
||||
access_yuthon_meal_case,access_yuthon_meal_case,model_yuthon_meal_case,base.group_user,1,1,1,1
|
||||
access_pay_carryover_wizard,pay.carryover.wizard,model_pay_carryover_wizard,base.group_user,1,1,1,1
|
||||
access_vacation_parenting_line,vacation.parenting.line,model_vacation_parenting_line,base.group_user,1,1,1,1
|
||||
access_yuthon_parenting_allocate,yuthon.parenting.allocate,model_yuthon_parenting_allocate,base.group_user,1,1,1,1
|
||||
access_vacation_overtime_active,vacation.overtime.active,model_vacation_overtime_active,base.group_user,1,1,1,1
|
||||
|
||||
access_yuthon_overtime_line,yuthon.overtime.line,model_yuthon_overtime_line,base.group_user,1,1,1,1
|
||||
|
@@ -7,17 +7,10 @@ export class CustomAttendanceMealConfirmController extends ListController {
|
||||
setup() {
|
||||
super.setup();
|
||||
}
|
||||
|
||||
async getAction(lock_type) {
|
||||
const action = await this.orm.call('vacation.meal.line', 'confirm', [lock_type], {context: this.props.context});
|
||||
action["context"] = {
|
||||
...action.context,
|
||||
...this.model.root.context,
|
||||
}
|
||||
return action
|
||||
await this.orm.call('vacation.meal.line', 'confirm', []);
|
||||
}
|
||||
}
|
||||
|
||||
registry.category("views").add("custom_vacation_meal_button", {
|
||||
...listView,
|
||||
Controller: CustomAttendanceMealConfirmController,
|
||||
|
||||
@@ -8,13 +8,9 @@ export class CustomAttendanceStatementConfirmController extends ListController {
|
||||
super.setup();
|
||||
}
|
||||
|
||||
|
||||
async getAction(lock_type) {
|
||||
const action = await this.orm.call('hr.leave', 'confirm', [lock_type], {context: this.props.context});
|
||||
action["context"] = {
|
||||
...action.context,
|
||||
...this.model.root.context,
|
||||
}
|
||||
return action
|
||||
await this.orm.call('hr.leave', 'confirm', []);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,13 @@ export class CustomAttendanceVacationConfirmController extends ListController {
|
||||
}
|
||||
|
||||
async getAction(lock_type) {
|
||||
const action = await this.orm.call('vacation.over.line', 'confirm', [lock_type], {context: this.props.context});
|
||||
action["context"] = {
|
||||
...action.context,
|
||||
...this.model.root.context,
|
||||
await this.orm.call('vacation.over.line', 'confirm', []);
|
||||
}
|
||||
return action
|
||||
async getNextAction(lock_type) {
|
||||
await this.orm.call('vacation.meal.line', 'confirm', []);
|
||||
}
|
||||
async getLastAction(lock_type) {
|
||||
await this.orm.call('vacation.meal.line', 'confirm', []);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,27 +42,13 @@ export class CustomAttendanceVacationPutController extends ListController {
|
||||
openVacationOverWizard() {
|
||||
this.actionService.doAction({
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'vacation.over.line',
|
||||
name: '加班情况',
|
||||
res_model: 'yuthon.overtime.line',
|
||||
name: '加班合计数报表',
|
||||
view_mode: 'tree',
|
||||
view_type: 'form',
|
||||
views: [[false, 'tree']],
|
||||
target: 'current',
|
||||
context: {'tree_view_ref': "yuthon_hr_attendance.view_yuthon_vacation_overtime_briefly_tree"},
|
||||
domain: [
|
||||
'|',
|
||||
['is_initial_number', '=', true],
|
||||
'&',
|
||||
['is_initial_number', '=', false],
|
||||
'&',
|
||||
['update_type', '=', 'add'],
|
||||
'&',
|
||||
['workflow_record_id', '!=', false],
|
||||
'!',
|
||||
'&',
|
||||
['start_time', '>=', '2025-12-01 00:00:00'],
|
||||
['start_time', '<', '2026-01-01 00:00:00']
|
||||
],
|
||||
context: {'tree_view_ref': "yuthon_hr_attendance.view_yuthon_overtime_line_tree"},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,12 @@
|
||||
<button type="button" class="btn btn-primary" style="margin-left: 10px;" t-on-click="getAction">
|
||||
确认
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" style="margin-left: 10px;" t-on-click="getLastAction">
|
||||
上月
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" style="margin-left: 10px;" t-on-click="getNextAction">
|
||||
下月
|
||||
</button>
|
||||
</xpath>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -8,7 +8,7 @@
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('o_list_buttons')]" position="after">
|
||||
<button type="button" class="btn btn-primary" style="margin-left: 10px;" t-on-click="openVacationOverWizard">
|
||||
加班情况
|
||||
加班合计数报表
|
||||
</button>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('o_list_buttons')]" position="after">
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
<field name="shift_id" invisible="shift_name" readonly="1"/>
|
||||
<field name="shift_name" invisible="shift_id" readonly="1"/>
|
||||
<field name="replacement_time"/>
|
||||
<field name="number_cards_replaced"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="attendance_id" domain="[('employee_id', '=', employee_id), '|', '|', '|', '|', ('is_abnormal', '=', True), ('is_early_card', '=', True), ('is_late_card', '=', True), ('absenteeism_card', '=', True), ('is_no_card', '=', True)]" invisible="is_attendance"/>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="view_vacation_overtime_active_tree" model="ir.ui.view">
|
||||
<field name="name">vacation.overtime.active.tree</field>
|
||||
<field name="model">vacation.overtime.active</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="加班情况(归档)" editable="bottom">
|
||||
<field name="overtime_name"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="department_id"/>
|
||||
<field name="carry_forward_quantity"/>
|
||||
<field name="remaining_quantity"/>
|
||||
<field name="carry_forward_date"/>
|
||||
<field name="carry_result"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_vacation_overtime_active_action" model="ir.actions.act_window">
|
||||
<field name="name">加班情况(归档)</field>
|
||||
<field name="res_model">vacation.overtime.active</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="view_vacation_overtime_active_tree"/>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="view_yuthon_overtime_line_tree" model="ir.ui.view">
|
||||
<field name="name">yuthon.overtime.line.tree</field>
|
||||
<field name="model">yuthon.overtime.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="加班合计数报表" editable="bottom" js_class="custom_vacation_confirm_button" create="0">
|
||||
<field name="employee_id"/>
|
||||
<field name="last_balance"/>
|
||||
<field name="valid_date"/>
|
||||
<field name="workday"/>
|
||||
<field name="public_holidays"/>
|
||||
<field name="vacation_sum"/>
|
||||
<field name="carry_forward_quantity"/>
|
||||
<field name="carry_forward_date"/>
|
||||
<field name="remaining_quantity"/>
|
||||
<button name="open_record" type="object" string="结束" dclass="oe_highlight"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_yuthon_overtime_line_action" model="ir.actions.act_window">
|
||||
<field name="name">加班合计数报表</field>
|
||||
<field name="res_model">yuthon.overtime.line</field>
|
||||
<field name="view_mode">tree</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id ="yuthon_parenting_allocate_tree" model="ir.ui.view">
|
||||
<field name="name">yuthon.parenting.allocate.tree</field>
|
||||
<field name="model">yuthon.parenting.allocate</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom">
|
||||
<field name="cycle_years"/>
|
||||
<field name="cycle_unit"/>
|
||||
<field name="valid_limit"/>
|
||||
<field name="distribute"/>
|
||||
<field name="birth_certificate"/>
|
||||
<field name="company_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id ="yuthon_parenting_allocate_action" model="ir.actions.act_window">
|
||||
<field name="name">育儿假规则</field>
|
||||
<field name="res_model">yuthon.parenting.allocate</field>
|
||||
<field name="view_mode">tree</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -35,7 +35,11 @@
|
||||
<field name="name">yuthon.vacation.reports.tree</field>
|
||||
<field name="model">yuthon.vacation.reports</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="假期额度记录" editable="bottom" edit="0" default_order="vacation_date desc" js_class="custom_vacation_put_button" limit="10">
|
||||
<tree string="考勤确认单台账" editable="bottom" edit="0" default_order="vacation_date desc"
|
||||
js_class="custom_vacation_put_button" limit="10">
|
||||
<header>
|
||||
<button name="manage_confirmation" type="object" string="批量确认" dclass="oe_highlight"/>
|
||||
</header>
|
||||
<field name="vacation_state" widget="badge" decoration-info="vacation_state == 'not_sent'"
|
||||
decoration-success="vacation_state == 'confirmed'"/>
|
||||
<field name="employee_id" options="{'no_open': True}"/>
|
||||
@@ -73,8 +77,10 @@
|
||||
<field name="medical_fee" options='{ "fg_color": "white: medical_fee == False"}'/>
|
||||
<field name="compensatory_leave" options='{ "fg_color": "white: compensatory_leave == False"}'/>
|
||||
<field name="leave_of_absence" options='{ "fg_color": "white: leave_of_absence == False"}'/>
|
||||
<field name="statutory_leave" string="加班时(法定假)" options='{ "fg_color": "white: statutory_leave == False"}'/>
|
||||
<field name="statutory_leave" string="加班时(法定假)"
|
||||
options='{ "fg_color": "white: statutory_leave == False"}'/>
|
||||
<field name="cop_leave" options='{ "fg_color": "white: cop_leave == False"}'/>
|
||||
<field name="parental_leave" options='{ "fg_color": "white: parental_leave == False"}'/>
|
||||
<field name="duty_off_leave" options='{ "fg_color": "white: duty_off_leave == False"}'/>
|
||||
<field name="marriage_leave" options='{ "fg_color": "white: marriage_leave == False"}'/>
|
||||
<field name="maternity_leave" options='{ "fg_color": "white: maternity_leave == False"}'/>
|
||||
@@ -88,7 +94,8 @@
|
||||
<field name="recovery_sick_leave" options='{ "fg_color": "white: recovery_sick_leave == False"}'/>
|
||||
<field name="exam_leave" options='{ "fg_color": "white: exam_leave == False"}'/>
|
||||
<button name="log" type="object" string="详情" class="oe_highlight"/>
|
||||
<button name="button_put" string="发送" type="object" class="oe_highlight"/>
|
||||
<button name="button_put" string="发送" invisible="vacation_state == 'confirmed'" type="object"
|
||||
class="oe_highlight"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -96,7 +103,8 @@
|
||||
<field name="name">yuthon.vacation.my.reports.tree</field>
|
||||
<field name="model">yuthon.vacation.reports</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="我的假期额度记录" editable="bottom" edit="0" delete="0" default_order="vacation_date desc" create="0">
|
||||
<tree string="我的假期额度记录" editable="bottom" edit="0" delete="0" default_order="vacation_date desc"
|
||||
create="0">
|
||||
<field name="vacation_state" widget="badge" decoration-info="vacation_state == 'unconfirmed'"
|
||||
decoration-success="vacation_state == 'confirmed'"/>
|
||||
<field name="employee_id" options="{'no_open': True}"/>
|
||||
@@ -122,8 +130,10 @@
|
||||
<field name="medical_fee" options='{ "fg_color": "white: medical_fee == False"}'/>
|
||||
<field name="compensatory_leave" options='{ "fg_color": "white: compensatory_leave == False"}'/>
|
||||
<field name="leave_of_absence" options='{ "fg_color": "white: leave_of_absence == False"}'/>
|
||||
<field name="statutory_leave" string="加班时(法定假)" options='{ "fg_color": "white: statutory_leave == False"}'/>
|
||||
<field name="statutory_leave" string="加班时(法定假)"
|
||||
options='{ "fg_color": "white: statutory_leave == False"}'/>
|
||||
<field name="cop_leave" options='{ "fg_color": "white: cop_leave == False"}'/>
|
||||
<field name="parental_leave" options='{ "fg_color": "white: parental_leave == False"}'/>
|
||||
<field name="duty_off_leave" options='{ "fg_color": "white: duty_off_leave == False"}'/>
|
||||
<field name="marriage_leave" options='{ "fg_color": "white: marriage_leave == False"}'/>
|
||||
<field name="maternity_leave" options='{ "fg_color": "white: maternity_leave == False"}'/>
|
||||
@@ -137,7 +147,8 @@
|
||||
<field name="recovery_sick_leave" options='{ "fg_color": "white: recovery_sick_leave == False"}'/>
|
||||
<field name="exam_leave" options='{ "fg_color": "white: exam_leave == False"}'/>
|
||||
<button name="log" type="object" string="详情" class="oe_highlight"/>
|
||||
<button name="confirm_state" type="object" string="确认" class="oe_highlight" invisible="vacation_state == 'confirmed'"/>
|
||||
<button name="confirm_state" type="object" string="确认" class="oe_highlight"
|
||||
invisible="vacation_state == 'confirmed'"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -183,16 +194,20 @@
|
||||
<group>
|
||||
<field name="test_days"/>
|
||||
</group>
|
||||
<group/>
|
||||
<group>
|
||||
<field name="remaining_parental_leave"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="年假">
|
||||
<field name="leave_ids" context="{'default_employee_id': employee_id}">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void">
|
||||
<button name="open_record" type="object" string="详情" class="btn-primary" invisible="not workflow_record_id"/>
|
||||
<button name="open_record" type="object" string="详情" class="btn-primary"
|
||||
invisible="not workflow_record_id"/>
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="vacation_id" column_invisible="1"/>
|
||||
<field name="workflow_record_id" domain="[('workflow_id.name', '=', '请假'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="workflow_record_id"
|
||||
domain="[('workflow_id.name', '=', '请假'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="update_type" readonly="0"/>
|
||||
<field name="update_date" readonly="0"/>
|
||||
<field name="update_lines"/>
|
||||
@@ -202,9 +217,12 @@
|
||||
<field name="is_void"/>
|
||||
<field name="text"/>
|
||||
<field name="is_confirm" column_invisible="1"/>
|
||||
<button name="unlink" string="删除" type="object" class="btn-primary" groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="撤销" invisible="is_confirm == True" type="object" class="btn-primary"/>
|
||||
<button name="action_void" string="作废" class="btn-primary" invisible="is_confirm != True" type="object"/>
|
||||
<button name="unlink" string="删除" type="object" class="btn-primary"
|
||||
groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="撤销" invisible="is_confirm == True" type="object"
|
||||
class="btn-primary"/>
|
||||
<button name="action_void" string="作废" class="btn-primary"
|
||||
invisible="is_confirm != True" type="object"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
@@ -212,10 +230,12 @@
|
||||
<button name="overtime_allocation" string="分配" type="object" class="btn btn-primary"/>
|
||||
<field name="overtime_ids" context="{'default_employee_id': employee_id}">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void">
|
||||
<button name="open_record" type="object" string="详情" class="btn-primary" invisible="not workflow_record_id"/>
|
||||
<button name="open_record" type="object" string="详情" class="btn-primary"
|
||||
invisible="not workflow_record_id"/>
|
||||
<field name="vacation_id" column_invisible="1"/>
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="workflow_record_id" domain="[('workflow_id.name', '=', '加班'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="workflow_record_id"
|
||||
domain="[('workflow_id.name', '=', '加班'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="update_type" readonly="0"/>
|
||||
<field name="update_date" readonly="0"/>
|
||||
<field name="workday"/>
|
||||
@@ -227,9 +247,12 @@
|
||||
<field name="overtime_methods"/>
|
||||
<field name="is_void"/>
|
||||
<field name="text"/>
|
||||
<button name="unlink" string="删除" type="object" class="btn-primary" groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="撤销" invisible="is_confirm == True" type="object" class="btn-primary"/>
|
||||
<button name="action_void" string="作废" class="btn-primary" invisible="is_confirm != True" type="object"/>
|
||||
<button name="unlink" string="删除" type="object" class="btn-primary"
|
||||
groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="撤销" invisible="is_confirm == True" type="object"
|
||||
class="btn-primary"/>
|
||||
<button name="action_void" string="作废" class="btn-primary"
|
||||
invisible="is_confirm != True" type="object"/>
|
||||
<field name="is_confirm" column_invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -237,10 +260,12 @@
|
||||
<page string="误餐">
|
||||
<field name="meal_fee_ids" context="{'default_employee_id': employee_id}">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void">
|
||||
<button name="open_record" type="object" string="详情" class="btn-primary" invisible="not workflow_record_id"/>
|
||||
<button name="open_record" type="object" string="详情" class="btn-primary"
|
||||
invisible="not workflow_record_id"/>
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="vacation_id" column_invisible="1"/>
|
||||
<field name="workflow_record_id" domain="[('workflow_id.name', '=', '外出'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="workflow_record_id"
|
||||
domain="[('workflow_id.name', '=', '外出'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="update_type" readonly="0"/>
|
||||
<field name="update_date" readonly="0"/>
|
||||
<field name="update_lines"/>
|
||||
@@ -248,9 +273,12 @@
|
||||
<field name="adjust_date"/>
|
||||
<field name="is_void"/>
|
||||
<field name="text"/>
|
||||
<button name="unlink" string="删除" type="object" class="btn-primary" groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="撤销" invisible="is_confirm == True" type="object" class="btn-primary"/>
|
||||
<button name="action_void" string="作废" class="btn-primary" invisible="is_confirm != True" type="object"/>
|
||||
<button name="unlink" string="删除" type="object" class="btn-primary"
|
||||
groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="撤销" invisible="is_confirm == True" type="object"
|
||||
class="btn-primary"/>
|
||||
<button name="action_void" string="作废" class="btn-primary"
|
||||
invisible="is_confirm != True" type="object"/>
|
||||
<field name="is_confirm" column_invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -258,19 +286,24 @@
|
||||
<page string="其他请假">
|
||||
<field name="other_fee_ids" context="{'default_employee_id': employee_id}">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void">
|
||||
<button name="open_record" type="object" string="详情" class="btn-primary" invisible="not workflow_record_id"/>
|
||||
<button name="open_record" type="object" string="详情" class="btn-primary"
|
||||
invisible="not workflow_record_id"/>
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="vacation_id" column_invisible="1"/>
|
||||
<field name="workflow_record_id" domain="[('workflow_id.name', '=', '请假'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="workflow_record_id"
|
||||
domain="[('workflow_id.name', '=', '请假'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="holiday_type"/>
|
||||
<field name="update_type" readonly="0"/>
|
||||
<field name="update_date" readonly="0"/>
|
||||
<field name="lines"/>
|
||||
<field name="is_void"/>
|
||||
<field name="text"/>
|
||||
<button name="unlink" string="删除" type="object" class="btn-primary" groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="撤销" invisible="is_confirm == True" type="object" class="btn-primary"/>
|
||||
<button name="action_void" string="作废" class="btn-primary" invisible="is_confirm != True" type="object"/>
|
||||
<button name="unlink" string="删除" type="object" class="btn-primary"
|
||||
groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="撤销" invisible="is_confirm == True" type="object"
|
||||
class="btn-primary"/>
|
||||
<button name="action_void" string="作废" class="btn-primary"
|
||||
invisible="is_confirm != True" type="object"/>
|
||||
<field name="is_confirm" column_invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -280,7 +313,8 @@
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void">
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="vacation_id" column_invisible="1"/>
|
||||
<field name="workflow_record_id" domain="[('workflow_id.name', '=', '外出'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="workflow_record_id"
|
||||
domain="[('workflow_id.name', '=', '外出'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="update_type" readonly="0"/>
|
||||
<field name="update_date" readonly="0"/>
|
||||
<field name="lines"/>
|
||||
@@ -288,9 +322,12 @@
|
||||
<field name="adjust_date"/>
|
||||
<field name="is_void"/>
|
||||
<field name="text"/>
|
||||
<button name="unlink" string="删除" type="object" class="btn-primary" groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="撤销" invisible="is_confirm == True" type="object" class="btn-primary"/>
|
||||
<button name="action_void" string="作废" class="btn-primary" invisible="is_confirm != True" type="object"/>
|
||||
<button name="unlink" string="删除" type="object" class="btn-primary"
|
||||
groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="撤销" invisible="is_confirm == True" type="object"
|
||||
class="btn-primary"/>
|
||||
<button name="action_void" string="作废" class="btn-primary"
|
||||
invisible="is_confirm != True" type="object"/>
|
||||
<field name="is_confirm" column_invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -323,6 +360,19 @@
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<page string="育儿假">
|
||||
<field name="parenting_line_ids" context="{'default_employee_id': employee_id}">
|
||||
<tree editable="bottom" delete="false" edit="false" create="false">
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="vacation_id" column_invisible="1"/>
|
||||
<field name="update_date"/>
|
||||
<field name="end_date"/>
|
||||
<field name="lines"/>
|
||||
<field name="text"/>
|
||||
<field name="is_confirm" column_invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="汇总">
|
||||
<group>
|
||||
<field name="is_late_card"/>
|
||||
@@ -367,11 +417,16 @@
|
||||
<field name="employee_id"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="公司" name="group_by_company_id" domain="[]" context="{'group_by': 'company_id'}"/>
|
||||
<filter string="部门" name="group_by_department_id" domain="[]" context="{'group_by': 'department_id'}"/>
|
||||
<filter string="工资组" name="group_by_salary_group_id" domain="[]" context="{'group_by': 'salary_group_id'}"/>
|
||||
<filter string="员工" name="group_by_employee_id" domain="[]" context="{'group_by': 'employee_id'}"/>
|
||||
<filter string="按年" name="group_by_vacation_year" domain="[]" context="{'group_by': 'vacation_date:year'}"/>
|
||||
<filter string="按月" name="group_by_vacation_month" domain="[]" context="{'group_by': 'vacation_date:month'}"/>
|
||||
<filter string="部门" name="group_by_department_id" domain="[]"
|
||||
context="{'group_by': 'department_id'}"/>
|
||||
<filter string="工资组" name="group_by_salary_group_id" domain="[]"
|
||||
context="{'group_by': 'salary_group_id'}"/>
|
||||
<filter string="员工" name="group_by_employee_id" domain="[]"
|
||||
context="{'group_by': 'employee_id'}"/>
|
||||
<filter string="按年" name="group_by_vacation_year" domain="[]"
|
||||
context="{'group_by': 'vacation_date:year'}"/>
|
||||
<filter string="按月" name="group_by_vacation_month" domain="[]"
|
||||
context="{'group_by': 'vacation_date:month'}"/>
|
||||
</group>
|
||||
<header_search class="header-search-inline">
|
||||
<field name="vacation_date"/>
|
||||
@@ -407,26 +462,31 @@
|
||||
<notebook>
|
||||
<page string="年假">
|
||||
<field name="leave_ids" context="{'default_employee_id': employee_id}">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void" edit="false" create="false">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void" edit="false"
|
||||
create="false">
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="vacation_id" column_invisible="1"/>
|
||||
<field name="workflow_record_id" domain="[('workflow_id.name', '=', '请假'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="workflow_record_id"
|
||||
domain="[('workflow_id.name', '=', '请假'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="update_type" readonly="1"/>
|
||||
<field name="update_date" readonly="1"/>
|
||||
<field name="update_lines"/>
|
||||
<field name="allocation_type" optional="hide"/>
|
||||
<field name="is_void"/>
|
||||
<field name="text"/>
|
||||
<button name="unlink" string="删除" invisible="workflow_record_id" type="object" class="btn-primary" groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="删除" invisible="workflow_record_id" type="object"
|
||||
class="btn-primary" groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="加班">
|
||||
<field name="overtime_ids" context="{'default_employee_id': employee_id}">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void" edit="false" create="false">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void" edit="false"
|
||||
create="false">
|
||||
<field name="vacation_id" column_invisible="1"/>
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="workflow_record_id" domain="[('workflow_id.name', '=', '加班'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="workflow_record_id"
|
||||
domain="[('workflow_id.name', '=', '加班'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="update_type" readonly="1"/>
|
||||
<field name="update_date" readonly="1"/>
|
||||
<field name="workday"/>
|
||||
@@ -436,31 +496,37 @@
|
||||
<field name="overtime_methods"/>
|
||||
<field name="is_void"/>
|
||||
<field name="text"/>
|
||||
<button name="unlink" string="删除" invisible="workflow_record_id" type="object" class="btn-primary" groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="删除" invisible="workflow_record_id" type="object"
|
||||
class="btn-primary" groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="误餐">
|
||||
<field name="meal_fee_ids" context="{'default_employee_id': employee_id}">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void" edit="false" create="false">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void" edit="false"
|
||||
create="false">
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="vacation_id" column_invisible="1"/>
|
||||
<field name="workflow_record_id" domain="[('workflow_id.name', '=', '外出'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="workflow_record_id"
|
||||
domain="[('workflow_id.name', '=', '外出'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="update_type" readonly="1"/>
|
||||
<field name="update_date" readonly="1"/>
|
||||
<field name="update_lines"/>
|
||||
<field name="is_void"/>
|
||||
<field name="text"/>
|
||||
<button name="unlink" string="删除" invisible="workflow_record_id" type="object" class="btn-primary" groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
<button name="unlink" string="删除" invisible="workflow_record_id" type="object"
|
||||
class="btn-primary" groups="yuthon_holiday.group_yuthon_holiday_admin"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="其他请假">
|
||||
<field name="other_fee_ids" context="{'default_employee_id': employee_id}">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void" edit="false" create="false">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void" edit="false"
|
||||
create="false">
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="vacation_id" column_invisible="1"/>
|
||||
<field name="workflow_record_id" domain="[('workflow_id.name', '=', '请假'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="workflow_record_id"
|
||||
domain="[('workflow_id.name', '=', '请假'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="holiday_type"/>
|
||||
<field name="update_type" readonly="1"/>
|
||||
<field name="update_date" readonly="1"/>
|
||||
@@ -472,10 +538,12 @@
|
||||
</page>
|
||||
<page string="体检费">
|
||||
<field name="medical_fee_ids" context="{'default_employee_id': employee_id}">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void" edit="false" create="false">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void" edit="false"
|
||||
create="false">
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="vacation_id" column_invisible="1"/>
|
||||
<field name="workflow_record_id" domain="[('workflow_id.name', '=', '外出'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="workflow_record_id"
|
||||
domain="[('workflow_id.name', '=', '外出'), ('create_uid.employee_id', '=', employee_id)]"/>
|
||||
<field name="update_type" readonly="1"/>
|
||||
<field name="update_date" readonly="1"/>
|
||||
<field name="lines"/>
|
||||
@@ -486,6 +554,19 @@
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="育儿假">
|
||||
<field name="parenting_line_ids" context="{'default_employee_id': employee_id}">
|
||||
<tree editable="bottom" delete="false" edit="false" create="false">
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="vacation_id" column_invisible="1"/>
|
||||
<field name="update_date"/>
|
||||
<field name="end_date"/>
|
||||
<field name="lines"/>
|
||||
<field name="text"/>
|
||||
<field name="is_confirm" column_invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<!-- <page string="出勤消息日志" invisible="1">-->
|
||||
<!-- <field name="attendance_message_log_ids">-->
|
||||
<!-- <tree>-->
|
||||
@@ -539,31 +620,17 @@
|
||||
<field name="name">vacation.over.line.overtime.briefly.tree</field>
|
||||
<field name="model">vacation.over.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="加班情况弹窗" editable="bottom" js_class="custom_vacation_confirm_button" create="0">
|
||||
<tree string="加班合计数报表" editable="bottom" create="0">
|
||||
<field name="employee_id"/>
|
||||
<field name="last_balance" groups="yuthon_salary.group_lc_user,yuthon_salary.group_wg_user"/>
|
||||
<field name="valid_date" groups="yuthon_salary.group_lc_user,yuthon_salary.group_wg_user"/>
|
||||
<field name="workday"/>
|
||||
<field name="public_holidays"/>
|
||||
<field name="vacation_sum"/>
|
||||
<field name="carry_forward_quantity"/>
|
||||
<field name="carry_forward_date"/>
|
||||
<field name="remaining_quantity"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_yuthon_vacation_overtime_active_tree" model="ir.ui.view">
|
||||
<field name="name">vacation.over.line.overtime.tree</field>
|
||||
<field name="model">vacation.over.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="加班情况(归档)" editable="bottom">
|
||||
<field name="overtime_name"/>
|
||||
<field name="employee_id" invisible="1"/>
|
||||
<field name="department_id"/>
|
||||
<field name="carry_forward_quantity"/>
|
||||
<field name="carry_forward_date"/>
|
||||
<field name="is_filing" column_invisible="1"/>
|
||||
<field name="is_visible" column_invisible="1"/>
|
||||
<field name="carry_result"/>
|
||||
<button name="open_record" type="object" string="详情" class="btn-primary"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -578,6 +645,7 @@
|
||||
<field name="start_time"/>
|
||||
<field name="end_time"/>
|
||||
<field name="duration"/>
|
||||
<field name="vacation_sum"/>
|
||||
<field name="carry_forward_quantity"/>
|
||||
<field name="carry_forward_date"/>
|
||||
<field name="carry_forward_state"/>
|
||||
@@ -611,19 +679,12 @@
|
||||
<field name="name">加班情况</field>
|
||||
<field name="res_model">vacation.over.line</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">['|', ('workflow_record_id','!=', False), ('is_initial_number', '=', True), ('update_type', '=', 'add'), ('is_filing','=', False), ('is_visible', '=', False)]</field>
|
||||
<field name="domain">['|', ('workflow_record_id','!=', False), ('is_initial_number', '=', True), ('update_type',
|
||||
'=', 'add'), ('is_filing','=', False), ('is_visible', '=', False)]
|
||||
</field>
|
||||
<field name="context">{'search_default_now_month': 1, 'search_default_group_by_employee_id':1}</field>
|
||||
<field name="view_id" ref="view_yuthon_vacation_overtime_tree"/>
|
||||
<field name="search_view_id" ref="view_yuthon_vacation_overtime_search"/>
|
||||
</record>
|
||||
<record id="action_overtime_approval_active_report" model="ir.actions.act_window">
|
||||
<field name="name">加班情况(归档)</field>
|
||||
<field name="res_model">vacation.over.line</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">['|', ('workflow_record_id','!=', False), ('is_initial_number', '=', True), ('update_type', '=', 'add'), ('is_filing','=', True), ('is_visible', '=', False)]</field>
|
||||
<field name="context">{'search_default_group_by_employee_id':1}</field>
|
||||
<field name="view_id" ref="view_yuthon_vacation_overtime_active_tree"/>
|
||||
<field name="search_view_id" ref="view_yuthon_vacation_overtime_search"/>
|
||||
</record>
|
||||
<record id="update_vacation_over_line" model="ir.actions.server">
|
||||
<field name="name">触发计算逻辑</field>
|
||||
@@ -644,7 +705,7 @@
|
||||
<field name="res_model">vacation.meal.line</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">[('is_filing','=', False)]</field>
|
||||
<field name="context">{'search_default_now_month': 1, 'search_default_group_by_employee_id':1}</field>
|
||||
<field name="context">{'search_default_now_month': 1,}</field>
|
||||
<field name="search_view_id" ref="view_yuthon_vacation_meal_search"/>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_hr_attendance.view_vacation_meal_line_tree')}),]"/>
|
||||
@@ -691,7 +752,9 @@
|
||||
<field name="res_model">yuthon.vacation.reports</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('employee_id.user_id', '=', uid)]</field>
|
||||
<field name="context">{'search_default_group_by_vacation_year': True, 'search_default_group_by_vacation_month': True}</field>
|
||||
<field name="context">{'search_default_group_by_vacation_year': True, 'search_default_group_by_vacation_month':
|
||||
True}
|
||||
</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_hr_attendance.view_yuthon_vacation_my_reports_tree')}),
|
||||
(0, 0, {'view_mode': 'form', 'view_id': ref('yuthon_hr_attendance.view_yuthon_vacation_reports_form1')})]"/>
|
||||
|
||||
@@ -10,4 +10,4 @@ class AppletSecurityQuickPermWizard(models.TransientModel):
|
||||
|
||||
def confirm(self):
|
||||
for applet in self.applet_security_ids:
|
||||
applet.write({'applet_security_setting_ids': [(6, 0, self.applet_security_setting_ids.ids)]})
|
||||
applet.write({'applet_security_setting_ids': [(4, setting_id) for setting_id in self.applet_security_setting_ids.ids]})
|
||||
|
||||
@@ -22,7 +22,7 @@ class PayCarryoverWizard(models.TransientModel):
|
||||
is_2025_december = rec.vacation_date.year == 2026 and rec.vacation_date.month == 1
|
||||
if rec.overtime_ids:
|
||||
for overtime in rec.overtime_ids:
|
||||
if overtime.text == '上月额度继承' and overtime.total > 40:
|
||||
if overtime.text == '上月额度继承' and overtime.duration > 40:
|
||||
reduce_workday = overtime.workday - 40
|
||||
new_overtime = self.env['vacation.over.line'].create([{
|
||||
'vacation_id': rec.id,
|
||||
|
||||
@@ -26,15 +26,10 @@ class VacationPutWizard(models.TransientModel):
|
||||
elif report.vacation_date > employee_reports_map[emp].vacation_date:
|
||||
employee_reports_map[emp] = report
|
||||
|
||||
for employee, report in employee_reports_map.items():
|
||||
url = f'https://oa.thtzjt.com/webh5/#/vacation?id={report.id}'
|
||||
we_id = employee.wecom_userid
|
||||
if we_id:
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(
|
||||
category='default',
|
||||
user_id=we_id,
|
||||
title="考勤确认",
|
||||
description=f'{employee.name} 请确认你的考勤:',
|
||||
url=url,
|
||||
btntxt="详细信息"
|
||||
)
|
||||
# for employee, report in employee_reports_map.items():
|
||||
# we_id = employee.wecom_userid
|
||||
# message = f"你{self.select_year}年{self.select_time}月的考勤确认单已经生成,请到手机端确认",
|
||||
# if we_id:
|
||||
# self.sudo().env["wecom.apps"].sync_send_message(category='att', user_id=we_id, message=message,)
|
||||
# self.sudo().env["wecom.apps"].sync_send_message(category='att', user_id="18562027762", message=message,)
|
||||
# self.write({'confirm_status': 'un_confirm'})
|
||||
@@ -876,10 +876,15 @@ class YuthonHrEmployee(models.Model):
|
||||
def update_parental_leave(self):
|
||||
today = datetime.now().date()
|
||||
active_contracts = self.env['hr.contract'].search([
|
||||
('employee_id.name','=', '和博延'),
|
||||
('state', '=', 'open'),
|
||||
('contract_type_id.name', 'ilike', '正式合同'),
|
||||
('employee_id', '!=', False)
|
||||
])
|
||||
allocate_config = self.env['yuthon.parenting.allocate'].search([], limit=1)
|
||||
valid_limit = allocate_config.valid_limit # 截至年龄(如3)
|
||||
cycle_years = allocate_config.cycle_years # 周期年数(如1)
|
||||
distribute = allocate_config.distribute #
|
||||
if not active_contracts:
|
||||
return
|
||||
employees = active_contracts.mapped('employee_id')
|
||||
@@ -905,50 +910,60 @@ class YuthonHrEmployee(models.Model):
|
||||
except (ValueError, IndexError):
|
||||
continue
|
||||
|
||||
age_delta = today - birth_date
|
||||
if age_delta > timedelta(days=3 * 365):
|
||||
valid_end_date = birth_date + relativedelta(years=valid_limit)
|
||||
if today > valid_end_date:
|
||||
continue
|
||||
cycle1_end = birth_date + relativedelta(years=1) # 第1年到期日
|
||||
cycle2_end = birth_date + relativedelta(years=2) # 第2年到期日
|
||||
cycle3_end = birth_date + relativedelta(years=3) # 第3年到期日(3岁生日)
|
||||
cycle_list = []
|
||||
current_cycle_start = birth_date
|
||||
total_cycles = int(valid_limit / cycle_years)
|
||||
|
||||
for i in range(1, total_cycles + 1):
|
||||
current_cycle_end = current_cycle_start + relativedelta(years=cycle_years)
|
||||
cycle_list.append({
|
||||
'cycle_num': i,
|
||||
'start': current_cycle_start,
|
||||
'end': current_cycle_end
|
||||
})
|
||||
current_cycle_start = current_cycle_end
|
||||
|
||||
if today <= cycle1_end:
|
||||
date_from = birth_date
|
||||
date_to = cycle1_end - timedelta(days=1)
|
||||
elif today <= cycle2_end:
|
||||
date_from = cycle1_end
|
||||
date_to = cycle2_end - timedelta(days=1)
|
||||
else:
|
||||
date_from = cycle2_end
|
||||
date_to = cycle3_end - timedelta(days=1)
|
||||
date_to = valid_end_date - timedelta(days=1)
|
||||
for cycle in cycle_list:
|
||||
if today <= cycle['end']:
|
||||
date_from = cycle['start']
|
||||
date_to = cycle['end'] - timedelta(days=1)
|
||||
break
|
||||
|
||||
total_days = distribute
|
||||
if total_days <= 0:
|
||||
continue
|
||||
|
||||
total_days = (date_to - date_from).days + 1
|
||||
holiday_status_id = self.env['hr.leave.type'].search([('name', '=', '育儿假')], limit=1)
|
||||
# 更新报表
|
||||
other_list = []
|
||||
parenting_line_ids = []
|
||||
reports_id = self.env['yuthon.vacation.reports'].search([
|
||||
('employee_id', '=', employee.id),
|
||||
('vacation_date', '=', fields.Date.today().replace(day=1))
|
||||
], limit=1) #
|
||||
if reports_id:
|
||||
existing_line = reports_id.other_fee_ids.search([
|
||||
('holiday_type', '=', holiday_status_id.id),
|
||||
existing_line = reports_id.parenting_line_ids.search([
|
||||
('vacation_id', '=', reports_id.id),
|
||||
('employee_id', '=', employee.id),
|
||||
('update_date', '=', date_from),
|
||||
('update_type', '=', 'add')
|
||||
('end_date', '=', date_to),
|
||||
('text','=', '育儿假分配')
|
||||
], limit=1)
|
||||
if not existing_line:
|
||||
other_list.append([0, 0, {
|
||||
parenting_line_ids.append([0, 0, {
|
||||
'vacation_id': reports_id.id,
|
||||
'holiday_type': holiday_status_id.id,
|
||||
'employee_id': employee.id,
|
||||
'update_date': date_from,
|
||||
'update_type': 'add',
|
||||
'end_date': date_to,
|
||||
'lines': total_days,
|
||||
'text': '育儿假'
|
||||
'text': '育儿假分配'
|
||||
}])
|
||||
if other_list:
|
||||
reports_id.write({'other_fee_ids': other_list})
|
||||
if parenting_line_ids :
|
||||
reports_id.write({'parenting_line_ids': parenting_line_ids})
|
||||
|
||||
# 6. 检查是否已存在相同分配记录,避免重复
|
||||
existing_allocation = self.env['hr.leave.allocation'].search([
|
||||
|
||||
@@ -71,8 +71,8 @@ class YuthonOnboardApproval(models.Model):
|
||||
representatives = fields.Char(related='party_id.representatives', string='法定代表人或委托代理人')
|
||||
economy_type = fields.Char(related='party_id.economy_type', string='经济类型')
|
||||
address = fields.Text(related='party_id.address', string='通讯地址')
|
||||
phone = fields.Char(related='information_form_id.phone', string='联系电话')
|
||||
card = fields.Char(related='information_form_id.id_card', string='身份证号码')
|
||||
phone = fields.Char(string='联系电话', required=True)
|
||||
card = fields.Char(string='身份证号码', required=True)
|
||||
salary_group_id = fields.Many2one(
|
||||
"yuthon.salary.group", string="工资单分组", store=True, index=True
|
||||
)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from email.policy import default
|
||||
|
||||
from odoo import models, fields, api
|
||||
from odoo.exceptions import UserError
|
||||
from datetime import datetime, time, timedelta, date
|
||||
@@ -10,7 +12,7 @@ class YuthonReassignmentApproval(models.Model):
|
||||
|
||||
name = fields.Char(string="标题")
|
||||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
employee_id = fields.Many2one('hr.employee', string="员工姓名")
|
||||
employee_id = fields.Many2one('hr.employee', string="员工姓名", default=lambda self: self.env.user.employee_id.id)
|
||||
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门")
|
||||
company_id = fields.Many2one(related='users_id.employee_id.company_id', string="公司")
|
||||
code = fields.Char(string="编号",
|
||||
@@ -55,6 +57,18 @@ class YuthonReassignmentApproval(models.Model):
|
||||
change_place_of_work = fields.Char(string="工作地点")
|
||||
handing_information_ids = fields.One2many('yuthon.over.infor.detail.lines','infor_id')
|
||||
|
||||
@api.onchange('employee_id')
|
||||
def _onchange_employee_id(self):
|
||||
if self.employee_id:
|
||||
self.phone = self.employee_id.mobile_phone
|
||||
self.job_id = self.employee_id.job_id.id
|
||||
self.structure_id = self.employee_id.contract_id.structure_type_id.id
|
||||
self.onboarding_date = self.employee_id.entry_date
|
||||
self.end_of_contract = self.employee_id.entry_date
|
||||
self.parent_id = self.employee_id.parent_id.id
|
||||
self.version = self.employee_id.contract_id.version
|
||||
|
||||
|
||||
@api.onchange('is_issues')
|
||||
def _onchange_is_issues(self):
|
||||
if self.is_issues:
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
<field name="is_office"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="department_id1" domain = "[('company_id', '=', company_id)] if is_this_company else []" options="{'no_create': True}"/>
|
||||
<field name="department_id1" domain = "[('company_id', '=', company_id)] if is_company else []" options="{'no_create': True}"/>
|
||||
<field name="contract_type" invisible="employment_form == 'formal' or not employment_form"/>
|
||||
<field name="contract_type1" invisible="1"/>
|
||||
<field name="salary_group_id"/>
|
||||
|
||||
@@ -35,7 +35,6 @@ class YuthonFileProcessing(models.Model):
|
||||
string="抄送单位"
|
||||
)
|
||||
department_ids = fields.Many2many('hr.department', string='部门范围')
|
||||
employee_ids = fields.Many2many('hr.employee', string='人员范围')
|
||||
users_role_ids = fields.Many2many('soong.user.role', string='角色范围')
|
||||
servings_number = fields.Integer(string="份数")
|
||||
|
||||
@@ -65,7 +64,7 @@ class YuthonFileProcessing(models.Model):
|
||||
|
||||
red_suit = fields.Char(string="套红")
|
||||
official_documents_ids = fields.Many2many('ir.attachment', string="附件")
|
||||
|
||||
completion_time = fields.Datetime(string="办结时间")
|
||||
is_supervising = fields.Boolean(string="是否督办")
|
||||
deadline = fields.Datetime(string="办理期限")
|
||||
done_date = fields.Date(string="完成时间")
|
||||
@@ -74,6 +73,18 @@ class YuthonFileProcessing(models.Model):
|
||||
issue_library_ids = fields.One2many('issue.library', 'yuthon_official_id', string="议题关联")
|
||||
work_end = fields.Boolean(string="结束")
|
||||
official_state = fields.Selection([('to_do', '待转'), ('done', '已转')], string="状态")
|
||||
employee_ids1 = fields.Many2many(
|
||||
'hr.employee',
|
||||
'yuthon_file_processing_employee1_rel',
|
||||
'file_id', 'employee_id',
|
||||
string="经办人"
|
||||
)
|
||||
employee_ids = fields.Many2many(
|
||||
'hr.employee',
|
||||
'yuthon_file_processing_employee_rel',
|
||||
'file_id', 'employee_id',
|
||||
string='人员范围'
|
||||
)
|
||||
|
||||
def _get_default_name_title(self):
|
||||
return self._description if self._description else self._name
|
||||
@@ -88,7 +99,7 @@ class YuthonFileProcessing(models.Model):
|
||||
default=lambda self: [(6, 0, [self.env.user.id])]
|
||||
)
|
||||
users_ids = fields.Many2many('res.users',
|
||||
string="当前经办人",
|
||||
string="用户",
|
||||
relation='yuthon_file_processing_users_rel',
|
||||
column1='processing_id',
|
||||
column2='compute_user_id',
|
||||
@@ -138,21 +149,34 @@ class YuthonFileProcessing(models.Model):
|
||||
else:
|
||||
return [("users_ids", "in", [current_user_id])]
|
||||
|
||||
def get_no_read_count(self):
|
||||
domain = [
|
||||
('employee_ids1', 'in', self.env.user.employee_id.id),
|
||||
]
|
||||
return self.search_count(domain)
|
||||
|
||||
@api.depends('code')
|
||||
def _compute_workflow(self):
|
||||
for record in self:
|
||||
record.users_ids = False
|
||||
record.approve_state = False
|
||||
record.soong_state = False
|
||||
record.employee_ids1 = False
|
||||
workflow = self.env['soong.workflow.record'].sudo().search(
|
||||
[('code', '=', record.code)],
|
||||
limit=1
|
||||
)
|
||||
if workflow:
|
||||
record.users_ids = workflow.employee_ids.mapped('user_id')
|
||||
record.employee_ids1 = workflow.employee_ids.ids
|
||||
record.users_ids = workflow.users_ids.ids
|
||||
record.approve_state = workflow.approve_state
|
||||
record.soong_state = workflow.soong_state
|
||||
|
||||
if record.log_ids:
|
||||
record.completion_time = record.log_ids[-1].lase_click_date
|
||||
else:
|
||||
record.completion_time = False
|
||||
|
||||
@api.onchange('is_cold')
|
||||
def onchange_is_cold(self):
|
||||
if self.is_cold:
|
||||
|
||||
@@ -28,6 +28,9 @@ class YuthonSubEnterprises(models.Model):
|
||||
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度',
|
||||
default='normal')
|
||||
work_end = fields.Boolean(string="结束")
|
||||
employee_ids = fields.Many2many('hr.employee', string="经办人")
|
||||
completion_time = fields.Datetime(string="办结时间")
|
||||
|
||||
def _get_default_name_title(self):
|
||||
return self._description if self._description else self._name
|
||||
|
||||
@@ -41,7 +44,7 @@ class YuthonSubEnterprises(models.Model):
|
||||
default=lambda self: [(6, 0, [self.env.user.id])]
|
||||
)
|
||||
users_ids = fields.Many2many('res.users',
|
||||
string="当前经办人",
|
||||
string="用户",
|
||||
relation='yuthon_sub_enterprises_users_rel',
|
||||
column1='enterprise_id',
|
||||
column2='compute_user_id',
|
||||
@@ -84,21 +87,35 @@ class YuthonSubEnterprises(models.Model):
|
||||
else:
|
||||
return [("users_ids", "in", [current_user_id])]
|
||||
|
||||
def get_no_read_count(self):
|
||||
domain = [
|
||||
('employee_ids', 'in', self.env.user.employee_id.id),
|
||||
]
|
||||
return self.search_count(domain)
|
||||
|
||||
|
||||
@api.depends('code')
|
||||
def _compute_workflow(self):
|
||||
for record in self:
|
||||
record.users_ids = False
|
||||
record.approve_state = False
|
||||
record.soong_state = False
|
||||
record.employee_ids = False
|
||||
workflow = self.env['soong.workflow.record'].sudo().search(
|
||||
[('code', '=', record.code)],
|
||||
limit=1
|
||||
)
|
||||
if workflow:
|
||||
record.users_ids = workflow.employee_ids.mapped('user_id')
|
||||
record.employee_ids = workflow.employee_ids.ids
|
||||
record.users_ids = workflow.users_ids.ids
|
||||
record.approve_state = workflow.approve_state
|
||||
record.soong_state = workflow.soong_state
|
||||
|
||||
if record.log_ids:
|
||||
record.completion_time = record.log_ids[-1].lase_click_date
|
||||
else:
|
||||
record.completion_time = False
|
||||
|
||||
def compute_workflow(self):
|
||||
enterprises_ids = self.env["yuthon.sub.enterprises"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id')))
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="approve_state" widget="badge" decoration-danger="approve_state == 'end'" decoration-success="approve_state == 'pending'"/>
|
||||
<field name="users_ids" widget="many2many_tags"/>
|
||||
<field name="employee_ids1" widget="many2many_tags"/>
|
||||
<field name="users_ids" widget="many2many_tags" column_invisible="1"/>
|
||||
<field name="completion_time"/>
|
||||
<field name="soong_state"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
||||
@@ -7,8 +7,11 @@
|
||||
<tree string="文件处理(子企业)">
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="approve_state" widget="badge" decoration-danger="approve_state == 'end'" decoration-success="approve_state == 'pending'"/>
|
||||
<field name="users_ids" widget="many2many_tags"/>
|
||||
<field name="approve_state" widget="badge" decoration-danger="approve_state == 'end'"
|
||||
decoration-success="approve_state == 'pending'"/>
|
||||
<field name="employee_ids" widget="many2many_tags"/>
|
||||
<field name="users_ids" widget="many2many_tags" column_invisible="1"/>
|
||||
<field name="completion_time"/>
|
||||
<field name="soong_state"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
'wizard/temporary_payslip_wizard_views.xml',
|
||||
'wizard/salary_import_wizard_views.xml',
|
||||
'wizard/yuthon_payroll_wizard_views.xml',
|
||||
'wizard/salary_active_wizard_views.xml',
|
||||
'wizard/basic_pension_wizard_views.xml',
|
||||
'wizard/payroll_labor_wizard_views.xml',
|
||||
'wizard/payroll_retired_wizard_views.xml',
|
||||
|
||||
@@ -71,59 +71,39 @@ class YuthonWillTask(http.Controller):
|
||||
for record in records:
|
||||
year = int(record.select_year)
|
||||
month = int(record.select_time)
|
||||
status = 'yes' if record.confirm_status == 'confirm' else 'no'
|
||||
if year not in data.keys():
|
||||
data[year] = {'total': 0}
|
||||
if month not in data[year].keys():
|
||||
data[year][month] = {'total': record.actual_paid_salary}
|
||||
data[year][month] = {'total': record.actual_paid_salary, 'id': record.id, 'state': status}
|
||||
data[year]['total'] += record.actual_paid_salary
|
||||
return json.dumps({'data': data, 'code': 200, 'message': ''})
|
||||
|
||||
@http.route('/phone/salary/self/detail', type='http', auth="none", csrf=False, cors='*')
|
||||
def phone_salary_self_detail(self, **kw):
|
||||
users_id = int(kw.get('users_id'))
|
||||
user = request.env['res.users'].sudo().browse(int(users_id))
|
||||
employee_id = user.with_company(user.company_id.id).employee_id.id
|
||||
year = int(kw.get('year'))
|
||||
month = int(kw.get('month'))
|
||||
records = request.env['hr.payslip'].sudo().search(
|
||||
[('employee_id', '=', employee_id)])
|
||||
detail = {}
|
||||
total = 0
|
||||
id = 0
|
||||
for record in records:
|
||||
tar_year = record.date_from.year
|
||||
tar_month = record.date_from.month
|
||||
status = record.state
|
||||
id = record.id
|
||||
if tar_year == year and tar_month == month:
|
||||
for line in record.line_ids:
|
||||
name = line.name
|
||||
contract = line.category_id.name
|
||||
amount = line.amount
|
||||
if contract not in detail.keys():
|
||||
detail[contract] = {'total': 0}
|
||||
detail[contract][name] = amount
|
||||
detail[contract]['total'] += amount
|
||||
total += amount
|
||||
data = {
|
||||
'status': status,
|
||||
'year': year,
|
||||
'month': month,
|
||||
'tatal': total,
|
||||
'detail': detail,
|
||||
'id': id
|
||||
}
|
||||
record = request.env['yuthon.salary.active'].sudo().search([('id', '=', int(kw.get('id')))])
|
||||
data = {}
|
||||
other_fields_list = ['ID', '员工', '公司', '部门', '司龄', '入职日期', '状态', 'Display Name', 'Created by', 'Created on', 'Last Updated by', 'Last Updated on']
|
||||
if record:
|
||||
# 找出所有字段的string和value
|
||||
fields_info = record.fields_get()
|
||||
record_data = record.read()[0]
|
||||
for field_name, field_value in record_data.items():
|
||||
if field_value in [0, 0.0, False] or field_value is None:
|
||||
continue
|
||||
if field_name in fields_info:
|
||||
field_string = fields_info[field_name].get('string', field_name)
|
||||
if field_string in other_fields_list:
|
||||
continue
|
||||
if isinstance(field_value, float):
|
||||
# 使用格式化字符串保留两位小数
|
||||
field_value = f"{field_value:.2f}"
|
||||
data[field_string] = field_value
|
||||
return json.dumps({'data': data, 'code': 200, 'message': ''})
|
||||
|
||||
@http.route('/phone/salary/self/status', type='http', auth="none", csrf=False, cors='*')
|
||||
def phone_salary_self_status(self, **kw):
|
||||
record_id = int(kw.get('record_id'))
|
||||
state = kw.get('state')
|
||||
record = request.env['hr.payslip'].sudo().browse(record_id)
|
||||
if state == 'done':
|
||||
record.state = 'done'
|
||||
data = 'success'
|
||||
else:
|
||||
data = ''
|
||||
return json.dumps({'data': data, 'code': 200, 'message': ''})
|
||||
record = request.env['yuthon.salary.active'].sudo().search([('id', '=', int(kw.get('id')))])
|
||||
record.write({'confirm_status': 'confirm'})
|
||||
return json.dumps({'code': 200, 'message': 'OK'})
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ class YuthonSalaryActive(models.Model):
|
||||
balance_salary = fields.Float(string='2025年结余工资')
|
||||
liquidation_salary_staff = fields.Float(string='2024年清算工资(职工)')
|
||||
business_special_bonus = fields.Float(string='2025经营特别奖')
|
||||
business_base = fields.Float(string='2025年基础年终奖')
|
||||
|
||||
# 扣发类字段
|
||||
deduct_performance_bonus = fields.Float(string='扣发绩效奖金')
|
||||
@@ -88,25 +89,49 @@ class YuthonSalaryActive(models.Model):
|
||||
self.write({'confirm_status': 'confirm'})
|
||||
|
||||
def payslip_transmit(self):
|
||||
self.sudo().env["wecom.apps"].sync_send_message(
|
||||
category='att', user_id=self.employee_id.wecom_userid,
|
||||
message=f"你{self.select_year}年{self.select_time}月的薪资条已经发放,请到手机端查看",
|
||||
url="https://phone.thtzjt.com/phone/Salary/153/23"
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(
|
||||
category='salary', user_id=self.employee_id.wecom_userid,
|
||||
url=url,title='工资条', description=f"{self.select_year}年{self.select_time}月的薪资条已经发放", btntxt = "查看详情"
|
||||
)
|
||||
self.sudo().env["wecom.apps"].sync_send_message(
|
||||
category='att', user_id="18562027762",
|
||||
message=f"你{self.select_year}年{self.select_time}月的薪资条已经发放,请到手机端查看",
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(
|
||||
category='salary', user_id='18562027762',
|
||||
url=url, title='工资条', description=f"{self.select_year}年{self.select_time}月的薪资条已经发放",
|
||||
btntxt="查看详情"
|
||||
)
|
||||
self.write({'confirm_status': 'un_confirm'})
|
||||
|
||||
def all_payslip_transmit(self):
|
||||
salary_ids = self.env["yuthon.salary.active"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id')))
|
||||
for rec in salary_ids:
|
||||
rec.payslip_transmit()
|
||||
|
||||
def open_archive_record(self):
|
||||
tree_id = self.env.ref("yuthon_salary.view_yuthon_salary_active_tree").id
|
||||
self.ensure_one()
|
||||
float_fields_with_value = []
|
||||
for field_name, field in self._fields.items():
|
||||
if field.type == 'float' and self[field_name] != 0 and self[field_name] is not False:
|
||||
float_fields_with_value.append({
|
||||
'field_name': field_name,
|
||||
'field_string': field.string,
|
||||
'field_value': self[field_name]
|
||||
})
|
||||
return {
|
||||
'name': '工资条',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'yuthon.salary.active',
|
||||
'views': [[tree_id, 'tree']],
|
||||
'view_mode': 'tree',
|
||||
'domain': [('employee_id', '=', self.employee_id.id)],
|
||||
'res_model': 'salary.active.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
'default_actual_wages': self.actual_paid_salary,
|
||||
'default_select_year': self.select_year,
|
||||
'default_select_time': self.select_time,
|
||||
'default_active_line': [(0, 0, {
|
||||
'name': item['field_string'],
|
||||
'amount': item['field_value']
|
||||
}) for item in float_fields_with_value]
|
||||
}
|
||||
}
|
||||
|
||||
def _get_default_month(self):
|
||||
|
||||
@@ -46,3 +46,6 @@ access_yuthon_meal_expenses,access_yuthon_meal_expenses,model_yuthon_meal_expens
|
||||
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
|
||||
access_yuthon_salary_active,access_yuthon_salary_active,model_yuthon_salary_active,base.group_user,1,1,1,1
|
||||
|
||||
access_salary_active_wizard,access__salary_active_wizard,model_salary_active_wizard,base.group_user,1,1,1,1
|
||||
access_salary_active_line,access_salary_active_line,model_salary_active_line,base.group_user,1,1,1,1
|
||||
|
@@ -4,9 +4,13 @@
|
||||
<field name="name">yuthon.salary.active.tree</field>
|
||||
<field name="model">yuthon.salary.active</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="工资单归档" create="0" edit="0" delete="0">
|
||||
<tree string="工资单归档" create="1" edit="0" delete="1">
|
||||
<header>
|
||||
<button name="all_payslip_transmit" type="object" string="批量发送" dclass="oe_highlight"/>
|
||||
</header>
|
||||
<!-- 核心关联字段:员工 -->
|
||||
<button type="object" name="payslip_transmit" string="发送" class="oe_highlight"/>
|
||||
<field name="confirm_status"/>
|
||||
<field name="employee_id" string="员工"/>
|
||||
<field name="department_id" column_invisible="1"/>
|
||||
<field name="company_id" column_invisible="1"/>
|
||||
@@ -18,7 +22,7 @@
|
||||
<!-- 基础薪资字段 -->
|
||||
<field name="basic_salary" string="基本工资"/>
|
||||
<field name="rank_salary" string="职级工资"/>
|
||||
<field name="pre_performance_bonus" string="预发绩效奖金"/>
|
||||
<field name="pre_performance_bonus" string="月绩效"/>
|
||||
<field name="post_salary" string="岗位工资"/>
|
||||
<field name="communication_subsidy" string="通讯补贴"/>
|
||||
<field name="seniority_wage" string="工龄工资"/>
|
||||
@@ -31,6 +35,7 @@
|
||||
<field name="balance_salary" string="2025年结余工资"/>
|
||||
<field name="liquidation_salary_staff" string="2024年清算工资(职工)"/>
|
||||
<field name="business_special_bonus" string="2025经营特别奖"/>
|
||||
<field name="business_base" string="2025年基础年终奖"/>
|
||||
|
||||
<!-- 扣发类字段 -->
|
||||
<field name="deduct_performance_bonus" string="扣发绩效奖金"/>
|
||||
@@ -65,7 +70,7 @@
|
||||
<field name="meal_allowance" string="误餐费"/>
|
||||
<field name="reimbursed_medical_exam_fee" string="已报销体检费"/>
|
||||
<field name="remaining_medical_exam_fee" string="剩余体检费"/>
|
||||
<field name="confirm_status"/>
|
||||
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -87,7 +92,7 @@
|
||||
<field name="model">yuthon.salary.active</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="我的薪资" create="false" delete="false" edit="false">
|
||||
<button name="salary_confirm" string="确认" type="object" class="oe_highlight"/>
|
||||
<button name="salary_confirm" string="确认" type="object" class="oe_highlight" invisible="confirm_status == 'confirm'"/>
|
||||
<button name="open_archive_record" string="详情" type="object" class="oe_highlight"/>
|
||||
<field name="select_year"/>
|
||||
<field name="select_time"/>
|
||||
@@ -98,6 +103,7 @@
|
||||
<field name="enterprise_annuity" string="年金"/>
|
||||
<field name="trade_union_dues" string="工会费"/>
|
||||
<field name="meal_allowance"/>
|
||||
<field name="confirm_status" column_invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -18,3 +18,4 @@ from . import salary_import_wizard
|
||||
from . import party_send_wizard
|
||||
from . import party_meal_wizard
|
||||
from . import salary_meal_wizard
|
||||
from . import salary_active_wizard
|
||||
@@ -0,0 +1,43 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import models, fields, api, _, SUPERUSER_ID
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
from odoo.exceptions import ValidationError
|
||||
import calendar
|
||||
from pypinyin import pinyin, Style
|
||||
import math
|
||||
import xlrd
|
||||
import base64
|
||||
import datetime
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
class SalaryActiveWizard(models.TransientModel):
|
||||
_name = 'salary.active.wizard'
|
||||
_description = '工资条查询'
|
||||
|
||||
active_line = fields.One2many('salary.active.line', 'active_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='年份')
|
||||
select_name = fields.Char(compute='_get_default_name')
|
||||
actual_wages = fields.Float(string='实发工资')
|
||||
|
||||
@api.depends('select_year', 'select_time')
|
||||
def _get_default_name(self):
|
||||
for rec in self:
|
||||
rec.select_name = rec.select_year + '年' + rec.select_time + '月'
|
||||
|
||||
|
||||
class SalaryActiveLine(models.TransientModel):
|
||||
_name = 'salary.active.line'
|
||||
_description = '明细'
|
||||
|
||||
sequence = fields.Char(string='序号', store=True)
|
||||
active_id = fields.Many2one('salary.active.wizard', string='工资条')
|
||||
name = fields.Char(string='工资条')
|
||||
amount = fields.Float(string='金额')
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="salary_active_wizard_form" model="ir.ui.view">
|
||||
<field name="name">工资条查询</field>
|
||||
<field name="model">salary.active.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<field name="select_year" invisible="1"/>
|
||||
<field name="select_time" invisible="1"/>
|
||||
<field name="select_name" invisible="1"/>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
||||
<field name="select_name" readonly="1" style="font-weight: bold; font-size: 18px;"/>
|
||||
<div style="text-align: right;">
|
||||
<span style="font-size: 14px; color: #666; margin-right: 8px;"/>
|
||||
<h1 style="display: inline; font-weight: bold; font-size: 20px; margin: 0;">
|
||||
<field name="actual_wages" readonly="1"/>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<field name="active_line" string=" ">
|
||||
<tree editable="bottom" create="0" edit="0" delete="0">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="active_id" column_invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="amount" readonly="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -26,8 +26,7 @@
|
||||
'views/auth_oauth_template.xml',
|
||||
'views/left_login_template.xml',
|
||||
'views/right_login_template.xml',
|
||||
'views/right_login_template.xml',
|
||||
# 'views/inherit_board_views.xml',
|
||||
'views/inherit_board_views.xml',
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
@@ -67,9 +67,9 @@
|
||||
<a t-if="signup_enabled" t-attf-href="/web/signup?{{ keep_query() }}">还没有账户?</a>
|
||||
<a t-if="reset_password_enabled" t-attf-href="/web/reset_password?{{ keep_query() }}">重置密码</a>
|
||||
</div>
|
||||
<!-- <div class="o_login_auth">-->
|
||||
<!-- <t t-call="yuthon_tianhe.yuthon_providers"/>-->
|
||||
<!-- </div>-->
|
||||
<div class="o_login_auth">
|
||||
<t t-call="yuthon_tianhe.yuthon_providers"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="redirect" t-att-value="redirect"/>
|
||||
|
||||
@@ -68,9 +68,9 @@
|
||||
<a t-if="signup_enabled" t-attf-href="/web/signup?{{ keep_query() }}">还没有账户?</a>
|
||||
<a t-if="reset_password_enabled" t-attf-href="/web/reset_password?{{ keep_query() }}">重置密码</a>
|
||||
</div>
|
||||
<!-- <div class="o_login_auth">-->
|
||||
<!-- <t t-call="yuthon_tianhe.yuthon_providers"/>-->
|
||||
<!-- </div>-->
|
||||
<div class="o_login_auth">
|
||||
<t t-call="yuthon_tianhe.yuthon_providers"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="redirect" t-att-value="redirect"/>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<field name="name">Wechat Corp</field>
|
||||
<field name="body">企业微信扫码登录</field>
|
||||
<field name="client_id">corpid agentid corpsecret</field>
|
||||
<field name="css_class">fa fa-fw fa-sign-in text-primary wecom_qr_login</field>
|
||||
<field name="css_class">fa fa-fw fa-sign-in text-primary</field>
|
||||
<field name="auth_endpoint">https://open.work.weixin.qq.com/wwopen/sso/qrConnect</field>
|
||||
<field name="validation_endpoint">https://qyapi.weixin.qq.com/cgi-bin/gettoken</field>
|
||||
<field name="data_endpoint">https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo</field>
|
||||
@@ -15,7 +15,7 @@
|
||||
<field name="name">Wechat Corp2</field>
|
||||
<field name="body">企业微信直接登录</field>
|
||||
<field name="client_id">corpid agentid corpsecret</field>
|
||||
<field name="css_class">fa fa-fw fa-sign-in text-primary wecom_quick_login</field>
|
||||
<field name="css_class">fa fa-fw fa-sign-in text-primary</field>
|
||||
<field name="auth_endpoint">https://open.weixin.qq.com/connect/oauth2/authorize</field>
|
||||
<field name="validation_endpoint">https://qyapi.weixin.qq.com/cgi-bin/gettoken</field>
|
||||
<field name="data_endpoint">https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo</field>
|
||||
|
||||
@@ -160,7 +160,7 @@ class WeComApps(models.Model):
|
||||
"btntxt": btntxt
|
||||
},
|
||||
}
|
||||
elif category == 'task':
|
||||
elif category in ['task', 'att_ok', 'salary']:
|
||||
data = {
|
||||
'touser': user_id,
|
||||
'msgtype': 'textcard',
|
||||
|
||||
@@ -29,6 +29,7 @@ class WecomAppsConfig(models.Model):
|
||||
('att', '出勤类型'),
|
||||
('task', '日程类型'),
|
||||
('att_ok', '考勤确认类型'),
|
||||
('salary', '薪资消息通知'),
|
||||
], default="default")
|
||||
wecom_apps_id = fields.Many2one("wecom.apps", string="企业微信的应用")
|
||||
|
||||
|
||||
@@ -73,12 +73,10 @@ class YuthonWillTask(http.Controller):
|
||||
|
||||
@http.route('/will/task/list', methods=['POST'], type='http', auth='public', csrf=False)
|
||||
def will_task_list(self, **kwargs):
|
||||
employee_id = request.env['hr.employee'].search([('user_id', '=', int(kwargs.get('users_id')))])
|
||||
start = kwargs.get('start')
|
||||
request_hour_selection = request.env['yuthon.will.task'].sudo().fields_get(allfields=['request_hour_from'])['request_hour_from']['selection']
|
||||
result_list = []
|
||||
# task_ids = request.env['yuthon.will.task'].sudo().search([], offset=start, limit=20)
|
||||
task_ids = request.env['yuthon.will.task'].sudo().search(['|', ('employee_ids', 'in', employee_id.id), ('employee_id.id', '=', employee_id.id)], offset=start, limit=20)
|
||||
task_ids = request.env['yuthon.will.task'].sudo().search([('users_ids', 'in', [int(kwargs.get('users_id'))])], offset=start, limit=20)
|
||||
for task in task_ids:
|
||||
weekday_str = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"][task.start_date.weekday()]
|
||||
result = {
|
||||
|
||||
@@ -166,17 +166,17 @@
|
||||
sequence="14"/>
|
||||
|
||||
<menuitem id="menu_yuthon_overtime_report_board_work_brand"
|
||||
name="加班情况"
|
||||
name="加班明细"
|
||||
parent="hr_attendance_root_board_menu"
|
||||
action="yuthon_hr_attendance.action_overtime_approval_report"
|
||||
sequence="15"/>
|
||||
<menuitem id="menu_yuthon_holiday_statement_board"
|
||||
name="请假情况"
|
||||
name="请假明细"
|
||||
parent="hr_attendance_root_board_menu"
|
||||
action="yuthon_hr_attendance.view_yuthon_holiday_statement_action"
|
||||
sequence="16"/>
|
||||
<menuitem id="menu_yuthon_meal_case_board"
|
||||
name="误餐情况"
|
||||
name="误餐明细"
|
||||
parent="hr_attendance_root_board_menu"
|
||||
action="yuthon_hr_attendance.view_yuthon_vacation_meal_action"
|
||||
sequence="17"/>
|
||||
@@ -311,6 +311,11 @@
|
||||
parent="attendance_resources_setting_root_board"
|
||||
action="hr_holidays.hr_leave_allocation_action_approve_department"
|
||||
sequence="20"/>
|
||||
<menuitem id="yuthon_parenting_allocate_board"
|
||||
name="育儿假规则"
|
||||
parent="attendance_resources_setting_root_board"
|
||||
action="yuthon_hr_attendance.yuthon_parenting_allocate_action"
|
||||
sequence="21"/>
|
||||
<menuitem id="holiday_set_vacation_board"
|
||||
name="公共假期"
|
||||
parent="attendance_resources_setting_root_board"
|
||||
@@ -735,7 +740,7 @@
|
||||
<menuitem id="yuthon_overtime_active_menu"
|
||||
parent="yuthon_vacation_active_menu"
|
||||
name="加班归档"
|
||||
action="yuthon_hr_attendance.action_overtime_approval_active_report"
|
||||
action="yuthon_hr_attendance.view_vacation_overtime_active_action"
|
||||
sequence="20"
|
||||
/>
|
||||
<menuitem id="yuthon_menu_active_menu"
|
||||
|
||||
Reference in New Issue
Block a user