From 1d20a7bf0b3a156b0256cb51f2bc3728543b83c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Mon, 1 Sep 2025 19:50:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- funenc_json_widget/__init__.py | 1 + funenc_json_widget/__manifest__.py | 37 +++++++++ funenc_json_widget/static/src/json_widget.js | 76 +++++++++++++++++++ .../models/overtime_approval.py | 39 ++++++---- .../views/overtime_approval.xml | 1 - yuthon_stock/__manifest__.py | 7 +- yuthon_stock/models/inherit_stock_picking.py | 30 +++++++- yuthon_stock/static/xml/misc.xml | 39 ++++++++++ yuthon_stock/views/inherit_stock_picking.xml | 3 + 9 files changed, 214 insertions(+), 19 deletions(-) create mode 100644 funenc_json_widget/__init__.py create mode 100644 funenc_json_widget/__manifest__.py create mode 100644 funenc_json_widget/static/src/json_widget.js create mode 100644 yuthon_stock/static/xml/misc.xml diff --git a/funenc_json_widget/__init__.py b/funenc_json_widget/__init__.py new file mode 100644 index 000000000..40a96afc6 --- /dev/null +++ b/funenc_json_widget/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/funenc_json_widget/__manifest__.py b/funenc_json_widget/__manifest__.py new file mode 100644 index 000000000..a2996a5a0 --- /dev/null +++ b/funenc_json_widget/__manifest__.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +{ + 'name': "funenc_json_widget", + + 'summary': """ + json widget for odoo + """, + + 'description': """ + json widget for odoo + json + template widget + template + color widget + color + """, + + 'author': "Funenc", + 'website': "http://odoo.funenc.com", + "images": [ + "static/description/description.gif" + ], + + 'category': 'App/json', + 'version': '17.0.0.1', + 'price': 5, + 'license': 'OPL-1', + + 'depends': ['base', 'web'], + 'data': [], + + 'assets': { + 'web.assets_backend': [ + 'funenc_json_widget/static/src/json_widget.js', + ] + } +} diff --git a/funenc_json_widget/static/src/json_widget.js b/funenc_json_widget/static/src/json_widget.js new file mode 100644 index 000000000..d586bac64 --- /dev/null +++ b/funenc_json_widget/static/src/json_widget.js @@ -0,0 +1,76 @@ +/** @odoo-module **/ + +import { registry } from "@web/core/registry"; +import { _t } from "@web/core/l10n/translation"; +import { standardFieldProps } from "@web/views/fields/standard_field_props"; + +import { Component, xml, onWillUpdateProps } from "@odoo/owl"; + +export class JsonTemplateWidget extends Component { + + setup() { + this.parseValue(); + onWillUpdateProps(() => { + this.parseValue(); + }); + } + + parseValue() { + try { + let name = this.props.name; + let data = this.props.record.data; + let value = data[name] || "{}"; + this.jsonData = JSON.parse(value); + console.log('JsonTemplateWidget - 解析的JSON数据:', this.jsonData); + } catch (e) { + console.error('JsonTemplateWidget - JSON解析错误:', e.message); + this.jsonData = { error: e.message }; + } + } + + get templateName() { + if (this.jsonData && this.jsonData.template) { + return this.jsonData.template; + } + return null; + } + + get hasValidTemplate() { + return this.templateName !== null; + } + + static template = xml` +
+ `; + + static props = { + ...standardFieldProps, + }; + + get isReadonly() { + return true; + } +} + +export const JsonTemplateField = { + component: JsonTemplateWidget, + displayName: _t("Json Template"), + supportedTypes: ["char", "text"], + isEmpty: () => false +}; + +registry.category("fields").add("json_template", JsonTemplateField); diff --git a/yuthon_hr_attendance/models/overtime_approval.py b/yuthon_hr_attendance/models/overtime_approval.py index a2596b75f..16cae0dd5 100644 --- a/yuthon_hr_attendance/models/overtime_approval.py +++ b/yuthon_hr_attendance/models/overtime_approval.py @@ -29,15 +29,13 @@ class OvertimeApprovals(models.Model): related_issues_id = fields.Many2one('issue.library', string="关联议题") documents_ids = fields.Many2many('ir.attachment', string="附件") duration = fields.Float(string="时长", compute='_compute_duration', store=True, help="如果时长大于8则按8小时算") - real_duration = fields.Float(string="实际时长", compute='_compute_duration', store=True, - help="如果时长大于8则按实际时长算") overtime_hours = fields.Float(string="本月加班时长") start_time = fields.Datetime(string="开始时间") start_week = fields.Char(string="星期", compute='_compute_weekday') end_time = fields.Datetime(string="结束时间") end_week = fields.Char(string="星期", compute='_compute_weekday') type_overtime = fields.Selection([('work', '工作日加班'), ('weekend', '周末加班'), ('holiday', '节假日加班')], - string="加班类型", compute="_compute_overtime_type") + string="加班类型", compute="_compute_overtime_type", store=True) urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度', default='normal') active = fields.Boolean('Active', default=True, tracking=True) @@ -72,15 +70,24 @@ class OvertimeApprovals(models.Model): @api.depends('start_time', 'end_time') def _compute_duration(self): for rec in self: - if rec.start_time and rec.end_time: - rec.duration = round((rec.end_time - rec.start_time).total_seconds() / 3600, 1) - rec.real_duration = rec.duration - else: + rec.duration = 0.0 + if not (rec.start_time and rec.end_time): + continue + total_seconds = (rec.end_time - rec.start_time).total_seconds() + original_hours = total_seconds / 3600 + # 加班起步一小时 + if original_hours < 1.0: rec.duration = 0.0 - rec.real_duration = 0.0 - - if rec.duration > 8: - rec.real_duration = 8 + continue + excess = original_hours - 1.0 + # 每半小时为一个单位,不足半小时不计 + excess_units = int(excess // 0.5) + calculated_hours = 1.0 + (excess_units * 0.5) + if rec.type_overtime == 'work': + max_hours = 3.0 + else: + max_hours = 8.0 + rec.duration = min(calculated_hours, max_hours) @api.depends('start_time', 'end_time') def _compute_weekday(self): @@ -177,10 +184,10 @@ class OvertimeApprovals(models.Model): allocation = self.env['hr.leave.allocation'].create({ 'employee_id': employee_id.id, 'name': '补休', - 'number_of_days': self.real_duration / 8, + 'number_of_days': self.duration / 8, 'holiday_status_id': holiday_status_id.id, 'allocation_type': 'regular', - "number_of_days_display": self.real_duration / 8, + "number_of_days_display": self.duration / 8, }) if allocation: allocation.sudo().action_validate() @@ -200,11 +207,11 @@ class OvertimeApprovals(models.Model): public_holidays = 0.0 if record.type_overtime == 'work': - workday = record.real_duration + workday = record.duration elif record.type_overtime == 'weekend': - public_holidays = record.real_duration + public_holidays = record.duration elif record.type_overtime == 'holiday': - legal_day = record.real_duration + legal_day = record.duration overtime_data = { 'vacation_id': reports_id.id, diff --git a/yuthon_hr_attendance/views/overtime_approval.xml b/yuthon_hr_attendance/views/overtime_approval.xml index c21b6aab4..9267cfc75 100644 --- a/yuthon_hr_attendance/views/overtime_approval.xml +++ b/yuthon_hr_attendance/views/overtime_approval.xml @@ -55,7 +55,6 @@| 序号 | +物业编号 | +产品 | +数量 | +单位 | +金额 | +
|---|---|---|---|---|---|