From 4de3dd6e739ff39d7679b84a70791ba5cc5ec8c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20-=20Le=20Filament?= <30716308+remi-filament@users.noreply.github.com> Date: Sat, 12 Apr 2025 20:37:26 +0200 Subject: [PATCH 01/18] [ADD] hr_work_entry_timesheet --- hr_work_entry_timesheet/README.rst | 136 ++++++++++++++++++ hr_work_entry_timesheet/__init__.py | 1 + hr_work_entry_timesheet/__manifest__.py | 20 +++ .../i18n/hr_work_entry_timesheet.pot | 37 +++++ hr_work_entry_timesheet/models/__init__.py | 2 + .../models/hr_timesheet.py | 41 ++++++ .../models/hr_work_entry.py | 46 ++++++ hr_work_entry_timesheet/readme/CONTEXT.md | 7 + .../readme/CONTRIBUTORS.md | 1 + hr_work_entry_timesheet/readme/DESCRIPTION.md | 5 + hr_work_entry_timesheet/readme/ROADMAP.md | 1 + hr_work_entry_timesheet/readme/USAGE.md | 9 ++ .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/icon.svg | 79 ++++++++++ .../static/description/index.html | 124 ++++++++++++++++ .../views/hr_work_entry_view.xml | 52 +++++++ .../odoo/addons/hr_work_entry_timesheet | 1 + setup/hr_work_entry_timesheet/setup.py | 6 + 18 files changed, 568 insertions(+) create mode 100644 hr_work_entry_timesheet/README.rst create mode 100644 hr_work_entry_timesheet/__init__.py create mode 100644 hr_work_entry_timesheet/__manifest__.py create mode 100644 hr_work_entry_timesheet/i18n/hr_work_entry_timesheet.pot create mode 100644 hr_work_entry_timesheet/models/__init__.py create mode 100644 hr_work_entry_timesheet/models/hr_timesheet.py create mode 100644 hr_work_entry_timesheet/models/hr_work_entry.py create mode 100644 hr_work_entry_timesheet/readme/CONTEXT.md create mode 100644 hr_work_entry_timesheet/readme/CONTRIBUTORS.md create mode 100644 hr_work_entry_timesheet/readme/DESCRIPTION.md create mode 100644 hr_work_entry_timesheet/readme/ROADMAP.md create mode 100644 hr_work_entry_timesheet/readme/USAGE.md create mode 100644 hr_work_entry_timesheet/static/description/icon.png create mode 100644 hr_work_entry_timesheet/static/description/icon.svg create mode 100644 hr_work_entry_timesheet/static/description/index.html create mode 100644 hr_work_entry_timesheet/views/hr_work_entry_view.xml create mode 120000 setup/hr_work_entry_timesheet/odoo/addons/hr_work_entry_timesheet create mode 100644 setup/hr_work_entry_timesheet/setup.py diff --git a/hr_work_entry_timesheet/README.rst b/hr_work_entry_timesheet/README.rst new file mode 100644 index 00000000000..789fc9e1c70 --- /dev/null +++ b/hr_work_entry_timesheet/README.rst @@ -0,0 +1,136 @@ +========================== +Work Entry with timesheets +========================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:96eb505415cddcb1b2c8c641f493ff97424f3420d941266623c9a92dddda19c1 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :alt: Alpha +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr-lightgray.png?logo=github + :target: https://github.com/OCA/hr/tree/16.0/hr_work_entry_timesheet + :alt: OCA/hr +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/hr-16-0/hr-16-0-hr_work_entry_timesheet + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends the functionality of hr_work_entry_contract in order +to display corresponding timesheet duration on work entries. + +Also a check is made for discrepancy and the work entries are displayed +hatched on calendar view in case : + +1. no timesheet has been recorded on some day (assuming that leaves also + create timesheets with native Odoo module project_timesheet_holidays) +2. more hours have been recorded than duration of the work entry + +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + +**Table of contents** + +.. contents:: + :local: + +Use Cases / Context +=================== + +In France, when your employes have a contract with a specific number of +days worked per year, you need to have every month the count of days +worked per employee. hr_work_entry_contract module from Odoo can be used +to cover this need. + +However, the above native Odoo module shows you the work entry per type, +depending on contract and leaves. + +From time to time, leaves are not up to date (somebody worked a few +hours one day on which he should be on leave for instance). Based on +timesheets, this module proposes to retrieve existing timesheets and +display those on work entries. + +Usage +===== + +- Go to *Employees* + +- On an "Employee" form view, click on smart-button "Work entries" + +- In the calendar view for work entries, you get : + + - hatched entries when discrepancy are found + - timesheet duration on card view (when clicking on an entry) + +- Timesheet duration has also been added on Work entries form, tree and + pivot views. + +Known issues / Roadmap +====================== + +- In case resource calendar is using half-day attendances you get 2 + work entries per day, when timesheets are per day, so we do not know + on which work entry the timesheets should be attributed. So far they + are attributed to both work entries for the day. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Le Filament + +Contributors +------------ + +- Rémi remi-filament (https://le-filament.com) + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-remi-filament| image:: https://github.com/remi-filament.png?size=40px + :target: https://github.com/remi-filament + :alt: remi-filament + +Current `maintainer `__: + +|maintainer-remi-filament| + +This module is part of the `OCA/hr `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_work_entry_timesheet/__init__.py b/hr_work_entry_timesheet/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/hr_work_entry_timesheet/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/hr_work_entry_timesheet/__manifest__.py b/hr_work_entry_timesheet/__manifest__.py new file mode 100644 index 00000000000..08e2d989996 --- /dev/null +++ b/hr_work_entry_timesheet/__manifest__.py @@ -0,0 +1,20 @@ +{ + "name": "Work Entry with timesheets", + "version": "16.0.1.0.0", + "development_status": "Alpha", + "category": "Human Resources/Employees", + "website": "https://github.com/OCA/hr", + "author": "Le Filament, Odoo Community Association (OCA)", + "maintainers": ["remi-filament"], + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": [ + "hr_timesheet", + "hr_work_entry_contract", + "project_timesheet_holidays", + ], + "data": [ + "views/hr_work_entry_view.xml", + ], +} diff --git a/hr_work_entry_timesheet/i18n/hr_work_entry_timesheet.pot b/hr_work_entry_timesheet/i18n/hr_work_entry_timesheet.pot new file mode 100644 index 00000000000..3df9c4accd8 --- /dev/null +++ b/hr_work_entry_timesheet/i18n/hr_work_entry_timesheet.pot @@ -0,0 +1,37 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_work_entry_timesheet +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-04-12 18:13+0000\n" +"PO-Revision-Date: 2025-04-12 18:13+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: hr_work_entry_timesheet +#: model:ir.model,name:hr_work_entry_timesheet.model_account_analytic_line +msgid "Analytic Line" +msgstr "" + +#. module: hr_work_entry_timesheet +#: model:ir.model,name:hr_work_entry_timesheet.model_hr_work_entry +msgid "HR Work Entry" +msgstr "" + +#. module: hr_work_entry_timesheet +#: model:ir.model.fields,field_description:hr_work_entry_timesheet.field_hr_work_entry__is_hatched +#: model:ir.model.fields,field_description:hr_work_entry_timesheet.field_hr_work_entry__timesheet_conflict +msgid "Timesheet Conflict" +msgstr "" + +#. module: hr_work_entry_timesheet +#: model:ir.model.fields,field_description:hr_work_entry_timesheet.field_hr_work_entry__timesheet_duration +msgid "Timesheet Duration" +msgstr "" diff --git a/hr_work_entry_timesheet/models/__init__.py b/hr_work_entry_timesheet/models/__init__.py new file mode 100644 index 00000000000..8d40a264f6c --- /dev/null +++ b/hr_work_entry_timesheet/models/__init__.py @@ -0,0 +1,2 @@ +from . import hr_work_entry +from . import hr_timesheet diff --git a/hr_work_entry_timesheet/models/hr_timesheet.py b/hr_work_entry_timesheet/models/hr_timesheet.py new file mode 100644 index 00000000000..6a5a594b83e --- /dev/null +++ b/hr_work_entry_timesheet/models/hr_timesheet.py @@ -0,0 +1,41 @@ +# Copyright 2025- Le Filament (https://le-filament.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from dateutil.relativedelta import relativedelta + +from odoo import api, models + + +class AccountAnalyticLine(models.Model): + _inherit = "account.analytic.line" + + def _get_work_entry(self): + work_entries = self.env["hr.work.entry"] + for timesheet in self.filtered(lambda l: not l.project_id and l.employee_id): + work_entries += work_entries.search( + [ + ("employee_id", "=", timesheet.employee_id.id), + ("date_start", ">=", timesheet.date), + ("date_start", "<", timesheet.date + relativedelta(days=1)), + ] + ) + return work_entries + + @api.model_create_multi + def create(self, vals_list): + res = super().create(vals_list) + work_entries = res._get_work_entry() + if work_entries: + work_entries._compute_timesheet_count() + return res + + def write(self, vals): + res = super().write(vals) + if "unit_amount" in vals or "employee_id" in vals or "date" in vals: + self._get_work_entry()._compute_timesheet_count() + return res + + def unlink(self): + work_entries = self._get_work_entry() + res = super().unlink() + work_entries._compute_timesheet_count() + return res diff --git a/hr_work_entry_timesheet/models/hr_work_entry.py b/hr_work_entry_timesheet/models/hr_work_entry.py new file mode 100644 index 00000000000..0838b78f585 --- /dev/null +++ b/hr_work_entry_timesheet/models/hr_work_entry.py @@ -0,0 +1,46 @@ +# Copyright 2025- Le Filament (https://le-filament.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class HrWorkEntry(models.Model): + _inherit = "hr.work.entry" + + timesheet_duration = fields.Float(compute="_compute_timesheet_duration", store=True) + timesheet_conflict = fields.Boolean( + compute="_compute_timesheet_conflict", store=True, readonly=False + ) + is_hatched = fields.Boolean(related="timesheet_conflict") + + @api.depends("date_start", "employee_id") + def _compute_timesheet_duration(self): + if not self: + return + timesheets = self.env["account.analytic.line"].read_group( + domain=[ + ("project_id", "!=", False), + ("employee_id", "in", self.mapped("employee_id").ids), + ("date", ">=", min(self.mapped("date_start")).date()), + ("date", "<=", max(self.mapped("date_start")).date()), + ], + fields=["unit_amount"], + groupby=["employee_id", "date:day"], + lazy=False, + ) + result = {eid: {} for eid in self.mapped("employee_id").ids} + for line in timesheets: + date = fields.Date().from_string(line["__range"]["date:day"]["from"]) + result[line["employee_id"][0]][date] = line["unit_amount"] + for work_entry in self: + work_entry.timesheet_duration = result[work_entry.employee_id.id].get( + work_entry.date_start.date(), 0.0 + ) + + @api.depends("duration", "timesheet_duration") + def _compute_timesheet_conflict(self): + for entry in self: + entry.timesheet_conflict = entry.duration > 0.0 and ( + entry.timesheet_duration == 0.0 + or entry.timesheet_duration > entry.duration * 2 + ) diff --git a/hr_work_entry_timesheet/readme/CONTEXT.md b/hr_work_entry_timesheet/readme/CONTEXT.md new file mode 100644 index 00000000000..7e169a04b41 --- /dev/null +++ b/hr_work_entry_timesheet/readme/CONTEXT.md @@ -0,0 +1,7 @@ +In France, when your employes have a contract with a specific number of days worked per year, you need to have every month the count of days worked per employee. +hr_work_entry_contract module from Odoo can be used to cover this need. + +However, the above native Odoo module shows you the work entry per type, depending on contract and leaves. + +From time to time, leaves are not up to date (somebody worked a few hours one day on which he should be on leave for instance). +Based on timesheets, this module proposes to retrieve existing timesheets and display those on work entries. diff --git a/hr_work_entry_timesheet/readme/CONTRIBUTORS.md b/hr_work_entry_timesheet/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..53f884c65b5 --- /dev/null +++ b/hr_work_entry_timesheet/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Rémi remi-filament (https://le-filament.com) diff --git a/hr_work_entry_timesheet/readme/DESCRIPTION.md b/hr_work_entry_timesheet/readme/DESCRIPTION.md new file mode 100644 index 00000000000..65673060597 --- /dev/null +++ b/hr_work_entry_timesheet/readme/DESCRIPTION.md @@ -0,0 +1,5 @@ +This module extends the functionality of hr_work_entry_contract in order to display corresponding timesheet duration on work entries. + +Also a check is made for discrepancy and the work entries are displayed hatched on calendar view in case : +1. no timesheet has been recorded on some day (assuming that leaves also create timesheets with native Odoo module project_timesheet_holidays) +1. more hours have been recorded than duration of the work entry diff --git a/hr_work_entry_timesheet/readme/ROADMAP.md b/hr_work_entry_timesheet/readme/ROADMAP.md new file mode 100644 index 00000000000..4a3d2930ba9 --- /dev/null +++ b/hr_work_entry_timesheet/readme/ROADMAP.md @@ -0,0 +1 @@ +- In case resource calendar is using half-day attendances you get 2 work entries per day, when timesheets are per day, so we do not know on which work entry the timesheets should be attributed. So far they are attributed to both work entries for the day. diff --git a/hr_work_entry_timesheet/readme/USAGE.md b/hr_work_entry_timesheet/readme/USAGE.md new file mode 100644 index 00000000000..7c4d5385ed3 --- /dev/null +++ b/hr_work_entry_timesheet/readme/USAGE.md @@ -0,0 +1,9 @@ +- Go to *Employees* + +- On an "Employee" form view, click on smart-button "Work entries" + +- In the calendar view for work entries, you get : + - hatched entries when discrepancy are found + - timesheet duration on card view (when clicking on an entry) + +- Timesheet duration has also been added on Work entries form, tree and pivot views. diff --git a/hr_work_entry_timesheet/static/description/icon.png b/hr_work_entry_timesheet/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~! zVpnB`o+K7|Al`Q_U;eD$B zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__ zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_ zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)( z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9 zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz# z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K= z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C zuVl&0duN<;uOsB3%T9Fp8t{ED108<+W(nOZd?gDnfNBC3>M8WE61$So|P zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1 zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_ zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8 zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ> zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD z#z-)AXwSRY?OPefw^iI+ z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$ z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6 zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+ z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC) zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x! zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8 z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n= z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@ zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y< zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6 zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6% z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(| z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6 z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d} z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/hr_work_entry_timesheet/static/description/icon.svg b/hr_work_entry_timesheet/static/description/icon.svg new file mode 100644 index 00000000000..a7a26d0932a --- /dev/null +++ b/hr_work_entry_timesheet/static/description/icon.svg @@ -0,0 +1,79 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/hr_work_entry_timesheet/static/description/index.html b/hr_work_entry_timesheet/static/description/index.html new file mode 100644 index 00000000000..f92d18ab8d6 --- /dev/null +++ b/hr_work_entry_timesheet/static/description/index.html @@ -0,0 +1,124 @@ +
+
+
+

Module name

+

This module was written to extend the functionality of ... to support ... and allow you to ...

+
+
+
+ +
+
+
+

Installation

+
+
+

To install this module, you need to: +

    +
  • ...
  • +
+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Configuration

+
+
+

To configure this module, you need to: +

    +
  • ...
  • +
+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Usage

+
+
+

To use this module, you need to: +

    +
  • ...
  • +
+

+

For further information, please visit: +

+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Known issues / Roadmap

+
+
+

+

    +
  • ...
  • +
+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Credits

+
+
+

Contributors

+ +
+
+

Maintainer

+

+ This module is maintained by the OCA.
+ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.
+ To contribute to this module, please visit http://odoo-community.org.
+ +

+
+
+
diff --git a/hr_work_entry_timesheet/views/hr_work_entry_view.xml b/hr_work_entry_timesheet/views/hr_work_entry_view.xml new file mode 100644 index 00000000000..801bdbdaca0 --- /dev/null +++ b/hr_work_entry_timesheet/views/hr_work_entry_view.xml @@ -0,0 +1,52 @@ + + + + + + hr.work.entry.calendar.with_timesheet + hr.work.entry + + + + + + + + + + + + hr.work.entry.form.with_timesheet + hr.work.entry + + + + + + + + + + hr.work.entry.tree.with_timesheet + hr.work.entry + + + + + + + + + + hr.work.entry.pivot.with_timesheet + hr.work.entry + + + + + + + + + diff --git a/setup/hr_work_entry_timesheet/odoo/addons/hr_work_entry_timesheet b/setup/hr_work_entry_timesheet/odoo/addons/hr_work_entry_timesheet new file mode 120000 index 00000000000..0f08f0632ab --- /dev/null +++ b/setup/hr_work_entry_timesheet/odoo/addons/hr_work_entry_timesheet @@ -0,0 +1 @@ +../../../../hr_work_entry_timesheet \ No newline at end of file diff --git a/setup/hr_work_entry_timesheet/setup.py b/setup/hr_work_entry_timesheet/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/hr_work_entry_timesheet/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 755e3dd39acf69309565b296ee34b601af4fff68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20-=20Le=20Filament?= <30716308+remi-filament@users.noreply.github.com> Date: Sat, 12 Apr 2025 20:48:50 +0200 Subject: [PATCH 02/18] [ADD] hr_work_entry_timesheet_weekend --- hr_work_entry_timesheet_weekend/README.rst | 109 +++++++++++++++ hr_work_entry_timesheet_weekend/__init__.py | 1 + .../__manifest__.py | 18 +++ .../data/hr_work_entry_type_data.xml | 9 ++ .../i18n/hr_work_entry_timesheet_weekend.pot | 54 ++++++++ .../models/__init__.py | 1 + .../models/hr_contract.py | 79 +++++++++++ .../readme/CONTRIBUTORS.md | 1 + .../readme/DESCRIPTION.md | 2 + .../readme/USAGE.md | 9 ++ .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/icon.svg | 79 +++++++++++ .../static/description/index.html | 124 ++++++++++++++++++ .../addons/hr_work_entry_timesheet_weekend | 1 + .../hr_work_entry_timesheet_weekend/setup.py | 6 + 15 files changed, 493 insertions(+) create mode 100644 hr_work_entry_timesheet_weekend/README.rst create mode 100644 hr_work_entry_timesheet_weekend/__init__.py create mode 100644 hr_work_entry_timesheet_weekend/__manifest__.py create mode 100644 hr_work_entry_timesheet_weekend/data/hr_work_entry_type_data.xml create mode 100644 hr_work_entry_timesheet_weekend/i18n/hr_work_entry_timesheet_weekend.pot create mode 100644 hr_work_entry_timesheet_weekend/models/__init__.py create mode 100644 hr_work_entry_timesheet_weekend/models/hr_contract.py create mode 100644 hr_work_entry_timesheet_weekend/readme/CONTRIBUTORS.md create mode 100644 hr_work_entry_timesheet_weekend/readme/DESCRIPTION.md create mode 100644 hr_work_entry_timesheet_weekend/readme/USAGE.md create mode 100644 hr_work_entry_timesheet_weekend/static/description/icon.png create mode 100644 hr_work_entry_timesheet_weekend/static/description/icon.svg create mode 100644 hr_work_entry_timesheet_weekend/static/description/index.html create mode 120000 setup/hr_work_entry_timesheet_weekend/odoo/addons/hr_work_entry_timesheet_weekend create mode 100644 setup/hr_work_entry_timesheet_weekend/setup.py diff --git a/hr_work_entry_timesheet_weekend/README.rst b/hr_work_entry_timesheet_weekend/README.rst new file mode 100644 index 00000000000..58ef517e40d --- /dev/null +++ b/hr_work_entry_timesheet_weekend/README.rst @@ -0,0 +1,109 @@ +======================================= +Work Entry with timesheets for weekends +======================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:52d01e811327de69384ccdf81729cd163c1672e4aaa4294745010610215f61d5 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :alt: Alpha +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr-lightgray.png?logo=github + :target: https://github.com/OCA/hr/tree/16.0/hr_work_entry_timesheet_weekend + :alt: OCA/hr +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/hr-16-0/hr-16-0-hr_work_entry_timesheet_weekend + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Native Odoo module hr_work_entry_contract, by default does not create +work entries on week-ends. This module extends the functionality of +hr_work_entry_timesheet from this same OCA repo to generate work entries +on week-ends in case you have timesheet registered on these days. + +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To use this module, you need to: + +- Go to *Employees* + +- On an "Employee" form view, click on smart-button "Work entries" + +- On "Work entries" calendar view, click on "Regenerate work entries" + and select dates + +- If you have timesheets on week-ends (meaning on days which are not + listed in calendar resource attendance), you will get an + hr_work_entry for that day, using "Not working day" type added by + this module. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Le Filament + +Contributors +------------ + +- Rémi remi-filament (https://le-filament.com) + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-remi-filament| image:: https://github.com/remi-filament.png?size=40px + :target: https://github.com/remi-filament + :alt: remi-filament + +Current `maintainer `__: + +|maintainer-remi-filament| + +This module is part of the `OCA/hr `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_work_entry_timesheet_weekend/__init__.py b/hr_work_entry_timesheet_weekend/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/hr_work_entry_timesheet_weekend/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/hr_work_entry_timesheet_weekend/__manifest__.py b/hr_work_entry_timesheet_weekend/__manifest__.py new file mode 100644 index 00000000000..cd2b2debe9c --- /dev/null +++ b/hr_work_entry_timesheet_weekend/__manifest__.py @@ -0,0 +1,18 @@ +{ + "name": "Work Entry with timesheets for weekends", + "version": "16.0.1.0.0", + "development_status": "Alpha", + "category": "Human Resources/Employees", + "website": "https://github.com/OCA/hr", + "author": "Le Filament, Odoo Community Association (OCA)", + "maintainers": ["remi-filament"], + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": [ + "hr_work_entry_timesheet", + ], + "data": [ + "data/hr_work_entry_type_data.xml", + ], +} diff --git a/hr_work_entry_timesheet_weekend/data/hr_work_entry_type_data.xml b/hr_work_entry_timesheet_weekend/data/hr_work_entry_type_data.xml new file mode 100644 index 00000000000..d022b5ac32e --- /dev/null +++ b/hr_work_entry_timesheet_weekend/data/hr_work_entry_type_data.xml @@ -0,0 +1,9 @@ + + + + Not working day + NOTWORK + 3 + False + + diff --git a/hr_work_entry_timesheet_weekend/i18n/hr_work_entry_timesheet_weekend.pot b/hr_work_entry_timesheet_weekend/i18n/hr_work_entry_timesheet_weekend.pot new file mode 100644 index 00000000000..8eacb48b1eb --- /dev/null +++ b/hr_work_entry_timesheet_weekend/i18n/hr_work_entry_timesheet_weekend.pot @@ -0,0 +1,54 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_work_entry_timesheet_weekend +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-04-12 18:14+0000\n" +"PO-Revision-Date: 2025-04-12 18:14+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: hr_work_entry_timesheet_weekend +#: model:ir.model,name:hr_work_entry_timesheet_weekend.model_hr_contract +msgid "Employee Contract" +msgstr "" + +#. module: hr_work_entry_timesheet_weekend +#. odoo-javascript +#: code:addons/hr_work_entry_timesheet_weekend/static/src/js/web_module_name.tour.js:0 +#, python-format +msgid "Instructions for end user." +msgstr "" + +#. module: hr_work_entry_timesheet_weekend +#: model:hr.work.entry.type,name:hr_work_entry_timesheet_weekend.work_entry_type_leave +msgid "Not working day" +msgstr "" + +#. module: hr_work_entry_timesheet_weekend +#. odoo-javascript +#: code:addons/hr_work_entry_timesheet_weekend/static/src/js/web_module_name.tour.js:0 +#, python-format +msgid "Text for continue button." +msgstr "" + +#. module: hr_work_entry_timesheet_weekend +#. odoo-javascript +#: code:addons/hr_work_entry_timesheet_weekend/static/src/js/web_module_name.tour.js:0 +#, python-format +msgid "The title of this step, appears in logs" +msgstr "" + +#. module: hr_work_entry_timesheet_weekend +#. odoo-javascript +#: code:addons/hr_work_entry_timesheet_weekend/static/src/js/web_module_name.tour.js:0 +#, python-format +msgid "Try to demostrate how to create a tour" +msgstr "" diff --git a/hr_work_entry_timesheet_weekend/models/__init__.py b/hr_work_entry_timesheet_weekend/models/__init__.py new file mode 100644 index 00000000000..b07b7896843 --- /dev/null +++ b/hr_work_entry_timesheet_weekend/models/__init__.py @@ -0,0 +1 @@ +from . import hr_contract diff --git a/hr_work_entry_timesheet_weekend/models/hr_contract.py b/hr_work_entry_timesheet_weekend/models/hr_contract.py new file mode 100644 index 00000000000..59195a41b6f --- /dev/null +++ b/hr_work_entry_timesheet_weekend/models/hr_contract.py @@ -0,0 +1,79 @@ +# Copyright 2025- Le Filament (https://le-filament.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import pytz +from dateutil.relativedelta import relativedelta + +from odoo import fields, models + + +class HrContract(models.Model): + _inherit = "hr.contract" + + def _get_contract_work_entries_values(self, date_start, date_stop): + contract_vals = super()._get_contract_work_entries_values(date_start, date_stop) + + start_dt = ( + pytz.utc.localize(date_start) if not date_start.tzinfo else date_start + ) + end_dt = pytz.utc.localize(date_stop) if not date_stop.tzinfo else date_stop + result = dict() + for calendar in self.mapped("resource_calendar_id"): + result.update(calendar._get_unusual_days(start_dt, end_dt)) + weekends = [] + for we_date in result: + if result[we_date]: + weekends.append(we_date) + + timesheets = self.env["account.analytic.line"].search( + [ + ("date", "in", weekends), + ("project_id", "!=", False), + ("holiday_id", "=", False), + ("global_leave_id", "=", False), + ] + ) + + for contract in self: + new_work_entry_dates = [] + for timesheet in timesheets.filtered( + lambda aal: aal.employee_id == contract.employee_id + ): + if ( + not timesheet._get_work_entry() + and timesheet.date not in new_work_entry_dates + ): + new_work_entry_dates.append(timesheet.date) + leave_entry_type = self.env.ref( + "hr_work_entry_timesheet_weekend.work_entry_type_leave" + ) + date_start = ( + pytz.timezone(contract.resource_calendar_id.tz) + .localize(fields.Datetime().to_datetime(timesheet.date)) + .astimezone(pytz.UTC) + .replace(tzinfo=None) + ) + contract_vals += [ + dict( + [ + ( + "name", + "%s%s" + % ( + leave_entry_type.name + ": " + if leave_entry_type + else "", + contract.employee_id.name, + ), + ), + ("date_start", date_start), + ("date_stop", date_start + relativedelta(minutes=1)), + ("work_entry_type_id", leave_entry_type.id), + ("employee_id", contract.employee_id.id), + ("company_id", contract.company_id.id), + ("state", "draft"), + ("contract_id", contract.id), + ] + ) + ] + return contract_vals diff --git a/hr_work_entry_timesheet_weekend/readme/CONTRIBUTORS.md b/hr_work_entry_timesheet_weekend/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..53f884c65b5 --- /dev/null +++ b/hr_work_entry_timesheet_weekend/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Rémi remi-filament (https://le-filament.com) diff --git a/hr_work_entry_timesheet_weekend/readme/DESCRIPTION.md b/hr_work_entry_timesheet_weekend/readme/DESCRIPTION.md new file mode 100644 index 00000000000..cd9bfd454d6 --- /dev/null +++ b/hr_work_entry_timesheet_weekend/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +Native Odoo module hr_work_entry_contract, by default does not create work entries on week-ends. +This module extends the functionality of hr_work_entry_timesheet from this same OCA repo to generate work entries on week-ends in case you have timesheet registered on these days. diff --git a/hr_work_entry_timesheet_weekend/readme/USAGE.md b/hr_work_entry_timesheet_weekend/readme/USAGE.md new file mode 100644 index 00000000000..1e990aabf08 --- /dev/null +++ b/hr_work_entry_timesheet_weekend/readme/USAGE.md @@ -0,0 +1,9 @@ +To use this module, you need to: + +- Go to *Employees* + +- On an "Employee" form view, click on smart-button "Work entries" + +- On "Work entries" calendar view, click on "Regenerate work entries" and select dates + +- If you have timesheets on week-ends (meaning on days which are not listed in calendar resource attendance), you will get an hr_work_entry for that day, using "Not working day" type added by this module. diff --git a/hr_work_entry_timesheet_weekend/static/description/icon.png b/hr_work_entry_timesheet_weekend/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/hr_work_entry_timesheet_weekend/static/description/icon.svg b/hr_work_entry_timesheet_weekend/static/description/icon.svg new file mode 100644 index 00000000000..a7a26d0932a --- /dev/null +++ b/hr_work_entry_timesheet_weekend/static/description/icon.svg @@ -0,0 +1,79 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/hr_work_entry_timesheet_weekend/static/description/index.html b/hr_work_entry_timesheet_weekend/static/description/index.html new file mode 100644 index 00000000000..f92d18ab8d6 --- /dev/null +++ b/hr_work_entry_timesheet_weekend/static/description/index.html @@ -0,0 +1,124 @@ +
+
+
+

Module name

+

This module was written to extend the functionality of ... to support ... and allow you to ...

+
+
+
+ +
+
+
+

Installation

+
+
+

To install this module, you need to: +

    +
  • ...
  • +
+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Configuration

+
+
+

To configure this module, you need to: +

    +
  • ...
  • +
+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Usage

+
+
+

To use this module, you need to: +

    +
  • ...
  • +
+

+

For further information, please visit: +

+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Known issues / Roadmap

+
+
+

+

    +
  • ...
  • +
+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Credits

+
+
+

Contributors

+ +
+
+

Maintainer

+

+ This module is maintained by the OCA.
+ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.
+ To contribute to this module, please visit http://odoo-community.org.
+ +

+
+
+
diff --git a/setup/hr_work_entry_timesheet_weekend/odoo/addons/hr_work_entry_timesheet_weekend b/setup/hr_work_entry_timesheet_weekend/odoo/addons/hr_work_entry_timesheet_weekend new file mode 120000 index 00000000000..f07558b5463 --- /dev/null +++ b/setup/hr_work_entry_timesheet_weekend/odoo/addons/hr_work_entry_timesheet_weekend @@ -0,0 +1 @@ +../../../../hr_work_entry_timesheet_weekend \ No newline at end of file diff --git a/setup/hr_work_entry_timesheet_weekend/setup.py b/setup/hr_work_entry_timesheet_weekend/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/hr_work_entry_timesheet_weekend/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From d3bc584454d6b33460d3d185955031ade2e6962d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20-=20Le=20Filament?= <30716308+remi-filament@users.noreply.github.com> Date: Sat, 12 Apr 2025 22:54:04 +0200 Subject: [PATCH 03/18] [ADD] hr_work_entry_validate --- hr_work_entry_validate/README.rst | 120 +++++++++++++++++ hr_work_entry_validate/__init__.py | 1 + hr_work_entry_validate/__manifest__.py | 18 +++ .../data/ir_actions_server_data.xml | 16 +++ hr_work_entry_validate/i18n/.empty | 0 hr_work_entry_validate/models/__init__.py | 1 + .../models/hr_work_entry.py | 36 +++++ hr_work_entry_validate/readme/CONTEXT.md | 3 + hr_work_entry_validate/readme/CONTRIBUTORS.md | 1 + hr_work_entry_validate/readme/DESCRIPTION.md | 1 + hr_work_entry_validate/readme/ROADMAP.md | 1 + hr_work_entry_validate/readme/USAGE.md | 9 ++ .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/icon.svg | 79 +++++++++++ .../static/description/index.html | 124 ++++++++++++++++++ .../odoo/addons/hr_work_entry_validate | 1 + setup/hr_work_entry_validate/setup.py | 6 + 17 files changed, 417 insertions(+) create mode 100644 hr_work_entry_validate/README.rst create mode 100644 hr_work_entry_validate/__init__.py create mode 100644 hr_work_entry_validate/__manifest__.py create mode 100644 hr_work_entry_validate/data/ir_actions_server_data.xml create mode 100644 hr_work_entry_validate/i18n/.empty create mode 100644 hr_work_entry_validate/models/__init__.py create mode 100644 hr_work_entry_validate/models/hr_work_entry.py create mode 100644 hr_work_entry_validate/readme/CONTEXT.md create mode 100644 hr_work_entry_validate/readme/CONTRIBUTORS.md create mode 100644 hr_work_entry_validate/readme/DESCRIPTION.md create mode 100644 hr_work_entry_validate/readme/ROADMAP.md create mode 100644 hr_work_entry_validate/readme/USAGE.md create mode 100644 hr_work_entry_validate/static/description/icon.png create mode 100644 hr_work_entry_validate/static/description/icon.svg create mode 100644 hr_work_entry_validate/static/description/index.html create mode 120000 setup/hr_work_entry_validate/odoo/addons/hr_work_entry_validate create mode 100644 setup/hr_work_entry_validate/setup.py diff --git a/hr_work_entry_validate/README.rst b/hr_work_entry_validate/README.rst new file mode 100644 index 00000000000..b1254f557b5 --- /dev/null +++ b/hr_work_entry_validate/README.rst @@ -0,0 +1,120 @@ +=================== +Validate Work Entry +=================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:96eb505415cddcb1b2c8c641f493ff97424f3420d941266623c9a92dddda19c1 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :alt: Alpha +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr-lightgray.png?logo=github + :target: https://github.com/OCA/hr/tree/16.0/hr_work_entry_validate + :alt: OCA/hr +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/hr-16-0/hr-16-0-hr_work_entry_validate + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends the functionality of hr_work_entry_contract in order +to allow users to validate their work entries. + +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + +**Table of contents** + +.. contents:: + :local: + +Use Cases / Context +=================== + +In France, when your employees have a contract with a specific number of +days worked per year, they need to validate every month the count of +days worked for the past month. + +Function to validate already exists in native hr_work_entry module but +is not accessible on the interface. + +Usage +===== + +To use this module, you need to: + +- Go to *Employees* + +- On an "Employee" form view, click on smart-button "Work entries" + +- Switch to list view, select a number of entries and click on "Action" + > "Validate work entries" + +- On form view, you can also click on "Action" > "Validate work + entries" + +Known issues / Roadmap +====================== + +- Add an action on calendar view to validate displayed work entries. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Le Filament + +Contributors +------------ + +- Rémi remi-filament (https://le-filament.com) + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-remi-filament| image:: https://github.com/remi-filament.png?size=40px + :target: https://github.com/remi-filament + :alt: remi-filament + +Current `maintainer `__: + +|maintainer-remi-filament| + +This module is part of the `OCA/hr `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_work_entry_validate/__init__.py b/hr_work_entry_validate/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/hr_work_entry_validate/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/hr_work_entry_validate/__manifest__.py b/hr_work_entry_validate/__manifest__.py new file mode 100644 index 00000000000..b68be11a514 --- /dev/null +++ b/hr_work_entry_validate/__manifest__.py @@ -0,0 +1,18 @@ +{ + "name": "Validate Work Entry", + "version": "16.0.1.0.0", + "development_status": "Alpha", + "category": "Human Resources/Employees", + "website": "https://github.com/OCA/hr", + "author": "Le Filament, Odoo Community Association (OCA)", + "maintainers": ["remi-filament"], + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": [ + "hr_work_entry_contract", + ], + "data": [ + "data/ir_actions_server_data.xml", + ], +} diff --git a/hr_work_entry_validate/data/ir_actions_server_data.xml b/hr_work_entry_validate/data/ir_actions_server_data.xml new file mode 100644 index 00000000000..6e9bde870d0 --- /dev/null +++ b/hr_work_entry_validate/data/ir_actions_server_data.xml @@ -0,0 +1,16 @@ + + + + + Validate work entries + + + + code + records.action_validate_with_error() + + diff --git a/hr_work_entry_validate/i18n/.empty b/hr_work_entry_validate/i18n/.empty new file mode 100644 index 00000000000..e69de29bb2d diff --git a/hr_work_entry_validate/models/__init__.py b/hr_work_entry_validate/models/__init__.py new file mode 100644 index 00000000000..32b8578582d --- /dev/null +++ b/hr_work_entry_validate/models/__init__.py @@ -0,0 +1 @@ +from . import hr_work_entry diff --git a/hr_work_entry_validate/models/hr_work_entry.py b/hr_work_entry_validate/models/hr_work_entry.py new file mode 100644 index 00000000000..7fd4bfb48ae --- /dev/null +++ b/hr_work_entry_validate/models/hr_work_entry.py @@ -0,0 +1,36 @@ +# Copyright 2025- Le Filament (https://le-filament.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from datetime import datetime, time + +from odoo import _, fields, models +from odoo.exceptions import ValidationError + + +class HrWorkEntry(models.Model): + _inherit = "hr.work.entry" + + def action_validate_with_error(self): + res = self.action_validate() + if not res: + raise ValidationError( + _( + "Some entries are in conflict and cannot be validated, " + "please solve conflicts first." + ) + ) + return res + + def validate_work_entries(self, employee_id, date_start, date_stop): + date_start = datetime.combine(fields.Date().from_string(date_start), time.min) + date_stop = date_start = datetime.combine( + fields.Date().from_string(date_stop), time.max + ) + work_entries = self.search( + [ + ("employee_id", "=", int(employee_id)), + ("date_start", ">=", date_start), + ("date_stop", "<=", date_stop), + ] + ) + return work_entries.action_validate() diff --git a/hr_work_entry_validate/readme/CONTEXT.md b/hr_work_entry_validate/readme/CONTEXT.md new file mode 100644 index 00000000000..b66e63c0774 --- /dev/null +++ b/hr_work_entry_validate/readme/CONTEXT.md @@ -0,0 +1,3 @@ +In France, when your employees have a contract with a specific number of days worked per year, they need to validate every month the count of days worked for the past month. + +Function to validate already exists in native hr_work_entry module but is not accessible on the interface. diff --git a/hr_work_entry_validate/readme/CONTRIBUTORS.md b/hr_work_entry_validate/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..53f884c65b5 --- /dev/null +++ b/hr_work_entry_validate/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Rémi remi-filament (https://le-filament.com) diff --git a/hr_work_entry_validate/readme/DESCRIPTION.md b/hr_work_entry_validate/readme/DESCRIPTION.md new file mode 100644 index 00000000000..24b2a53bea3 --- /dev/null +++ b/hr_work_entry_validate/readme/DESCRIPTION.md @@ -0,0 +1 @@ +This module extends the functionality of hr_work_entry_contract in order to allow users to validate their work entries. diff --git a/hr_work_entry_validate/readme/ROADMAP.md b/hr_work_entry_validate/readme/ROADMAP.md new file mode 100644 index 00000000000..7be93d7a938 --- /dev/null +++ b/hr_work_entry_validate/readme/ROADMAP.md @@ -0,0 +1 @@ +- Add an action on calendar view to validate displayed work entries. diff --git a/hr_work_entry_validate/readme/USAGE.md b/hr_work_entry_validate/readme/USAGE.md new file mode 100644 index 00000000000..078b37e917a --- /dev/null +++ b/hr_work_entry_validate/readme/USAGE.md @@ -0,0 +1,9 @@ +To use this module, you need to: + +- Go to *Employees* + +- On an "Employee" form view, click on smart-button "Work entries" + +- Switch to list view, select a number of entries and click on "Action" > "Validate work entries" + +- On form view, you can also click on "Action" > "Validate work entries" diff --git a/hr_work_entry_validate/static/description/icon.png b/hr_work_entry_validate/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/hr_work_entry_validate/static/description/icon.svg b/hr_work_entry_validate/static/description/icon.svg new file mode 100644 index 00000000000..a7a26d0932a --- /dev/null +++ b/hr_work_entry_validate/static/description/icon.svg @@ -0,0 +1,79 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/hr_work_entry_validate/static/description/index.html b/hr_work_entry_validate/static/description/index.html new file mode 100644 index 00000000000..f92d18ab8d6 --- /dev/null +++ b/hr_work_entry_validate/static/description/index.html @@ -0,0 +1,124 @@ +
+
+
+

Module name

+

This module was written to extend the functionality of ... to support ... and allow you to ...

+
+
+
+ +
+
+
+

Installation

+
+
+

To install this module, you need to: +

    +
  • ...
  • +
+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Configuration

+
+
+

To configure this module, you need to: +

    +
  • ...
  • +
+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Usage

+
+
+

To use this module, you need to: +

    +
  • ...
  • +
+

+

For further information, please visit: +

+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Known issues / Roadmap

+
+
+

+

    +
  • ...
  • +
+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Credits

+
+
+

Contributors

+ +
+
+

Maintainer

+

+ This module is maintained by the OCA.
+ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.
+ To contribute to this module, please visit http://odoo-community.org.
+ +

+
+
+
diff --git a/setup/hr_work_entry_validate/odoo/addons/hr_work_entry_validate b/setup/hr_work_entry_validate/odoo/addons/hr_work_entry_validate new file mode 120000 index 00000000000..b93bf311fa7 --- /dev/null +++ b/setup/hr_work_entry_validate/odoo/addons/hr_work_entry_validate @@ -0,0 +1 @@ +../../../../hr_work_entry_validate \ No newline at end of file diff --git a/setup/hr_work_entry_validate/setup.py b/setup/hr_work_entry_validate/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/hr_work_entry_validate/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From d38f09a08b43ceb52259bfc64d857dffb48d03e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20-=20Le=20Filament?= <30716308+remi-filament@users.noreply.github.com> Date: Sat, 12 Apr 2025 22:58:41 +0200 Subject: [PATCH 04/18] [IMP] keep only is_hatched field --- hr_work_entry_timesheet/models/hr_work_entry.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hr_work_entry_timesheet/models/hr_work_entry.py b/hr_work_entry_timesheet/models/hr_work_entry.py index 0838b78f585..02a45652565 100644 --- a/hr_work_entry_timesheet/models/hr_work_entry.py +++ b/hr_work_entry_timesheet/models/hr_work_entry.py @@ -8,10 +8,12 @@ class HrWorkEntry(models.Model): _inherit = "hr.work.entry" timesheet_duration = fields.Float(compute="_compute_timesheet_duration", store=True) - timesheet_conflict = fields.Boolean( - compute="_compute_timesheet_conflict", store=True, readonly=False + is_hatched = fields.Boolean( + compute="_compute_timesheet_conflict", + string="Timesheet Conflict", + store=True, + readonly=False, ) - is_hatched = fields.Boolean(related="timesheet_conflict") @api.depends("date_start", "employee_id") def _compute_timesheet_duration(self): @@ -40,7 +42,7 @@ def _compute_timesheet_duration(self): @api.depends("duration", "timesheet_duration") def _compute_timesheet_conflict(self): for entry in self: - entry.timesheet_conflict = entry.duration > 0.0 and ( + entry.is_hatched = entry.duration > 0.0 and ( entry.timesheet_duration == 0.0 or entry.timesheet_duration > entry.duration * 2 ) From be6fe6872003445ac4fff5849cbf014343028618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20-=20Le=20Filament?= <30716308+remi-filament@users.noreply.github.com> Date: Mon, 14 Apr 2025 17:04:39 +0200 Subject: [PATCH 05/18] [FIX] rename compute function --- hr_work_entry_timesheet/models/hr_timesheet.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hr_work_entry_timesheet/models/hr_timesheet.py b/hr_work_entry_timesheet/models/hr_timesheet.py index 6a5a594b83e..15c85bddb5f 100644 --- a/hr_work_entry_timesheet/models/hr_timesheet.py +++ b/hr_work_entry_timesheet/models/hr_timesheet.py @@ -25,17 +25,17 @@ def create(self, vals_list): res = super().create(vals_list) work_entries = res._get_work_entry() if work_entries: - work_entries._compute_timesheet_count() + work_entries._compute_timesheet_duration() return res def write(self, vals): res = super().write(vals) if "unit_amount" in vals or "employee_id" in vals or "date" in vals: - self._get_work_entry()._compute_timesheet_count() + self._get_work_entry()._compute_timesheet_duration() return res def unlink(self): work_entries = self._get_work_entry() res = super().unlink() - work_entries._compute_timesheet_count() + work_entries._compute_timesheet_duration() return res From a320c78996834c8a116f294b148bdec68b44b7ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20-=20Le=20Filament?= <30716308+remi-filament@users.noreply.github.com> Date: Tue, 27 May 2025 12:06:38 +0200 Subject: [PATCH 06/18] [MIG] migration to v17 --- hr_work_entry_timesheet/README.rst | 12 +- hr_work_entry_timesheet/__manifest__.py | 2 +- hr_work_entry_timesheet/i18n/fr.po | 36 ++++ .../i18n/hr_work_entry_timesheet.pot | 7 +- .../models/hr_work_entry.py | 86 ++++++-- hr_work_entry_timesheet/pyproject.toml | 3 + hr_work_entry_timesheet/readme/ROADMAP.md | 2 +- hr_work_entry_timesheet_validate/README.rst | 104 +++++++++ .../__init__.py | 0 .../__manifest__.py | 19 ++ .../pyproject.toml | 3 + .../readme/CONTRIBUTORS.md | 1 + .../readme/DESCRIPTION.md | 1 + .../readme/USAGE.md | 7 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/icon.svg | 79 +++++++ .../static/description/index.html | 124 +++++++++++ .../views/hr_work_entry_view.xml | 58 +++++ hr_work_entry_timesheet_weekend/README.rst | 10 +- .../__manifest__.py | 2 +- hr_work_entry_timesheet_weekend/i18n/fr.po | 26 +++ .../i18n/hr_work_entry_timesheet_weekend.pot | 34 +-- .../pyproject.toml | 3 + hr_work_entry_validate/README.rst | 14 +- hr_work_entry_validate/__manifest__.py | 5 +- hr_work_entry_validate/i18n/fr.po | 139 ++++++++++++ .../i18n/hr_work_entry_validate.pot | 135 ++++++++++++ hr_work_entry_validate/pyproject.toml | 3 + hr_work_entry_validate/readme/USAGE.md | 4 +- .../security/hr_work_entry_security.xml | 32 +++ .../security/ir.model.access.csv | 4 + .../views/hr_work_entry_views.xml | 204 ++++++++++++++++++ 32 files changed, 1083 insertions(+), 76 deletions(-) create mode 100644 hr_work_entry_timesheet/i18n/fr.po create mode 100644 hr_work_entry_timesheet/pyproject.toml create mode 100644 hr_work_entry_timesheet_validate/README.rst rename hr_work_entry_validate/i18n/.empty => hr_work_entry_timesheet_validate/__init__.py (100%) create mode 100644 hr_work_entry_timesheet_validate/__manifest__.py create mode 100644 hr_work_entry_timesheet_validate/pyproject.toml create mode 100644 hr_work_entry_timesheet_validate/readme/CONTRIBUTORS.md create mode 100644 hr_work_entry_timesheet_validate/readme/DESCRIPTION.md create mode 100644 hr_work_entry_timesheet_validate/readme/USAGE.md create mode 100644 hr_work_entry_timesheet_validate/static/description/icon.png create mode 100644 hr_work_entry_timesheet_validate/static/description/icon.svg create mode 100644 hr_work_entry_timesheet_validate/static/description/index.html create mode 100644 hr_work_entry_timesheet_validate/views/hr_work_entry_view.xml create mode 100644 hr_work_entry_timesheet_weekend/i18n/fr.po create mode 100644 hr_work_entry_timesheet_weekend/pyproject.toml create mode 100644 hr_work_entry_validate/i18n/fr.po create mode 100644 hr_work_entry_validate/i18n/hr_work_entry_validate.pot create mode 100644 hr_work_entry_validate/pyproject.toml create mode 100644 hr_work_entry_validate/security/hr_work_entry_security.xml create mode 100644 hr_work_entry_validate/security/ir.model.access.csv create mode 100644 hr_work_entry_validate/views/hr_work_entry_views.xml diff --git a/hr_work_entry_timesheet/README.rst b/hr_work_entry_timesheet/README.rst index 789fc9e1c70..57f02628029 100644 --- a/hr_work_entry_timesheet/README.rst +++ b/hr_work_entry_timesheet/README.rst @@ -17,13 +17,13 @@ Work Entry with timesheets :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr-lightgray.png?logo=github - :target: https://github.com/OCA/hr/tree/16.0/hr_work_entry_timesheet + :target: https://github.com/OCA/hr/tree/17.0/hr_work_entry_timesheet :alt: OCA/hr .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/hr-16-0/hr-16-0-hr_work_entry_timesheet + :target: https://translation.odoo-community.org/projects/hr-17-0/hr-17-0-hr_work_entry_timesheet :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=17.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -85,7 +85,7 @@ Known issues / Roadmap - In case resource calendar is using half-day attendances you get 2 work entries per day, when timesheets are per day, so we do not know on which work entry the timesheets should be attributed. So far they - are attributed to both work entries for the day. + are divided by number of work entries for the day. Bug Tracker =========== @@ -93,7 +93,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -131,6 +131,6 @@ Current `maintainer `__: |maintainer-remi-filament| -This module is part of the `OCA/hr `_ project on GitHub. +This module is part of the `OCA/hr `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_work_entry_timesheet/__manifest__.py b/hr_work_entry_timesheet/__manifest__.py index 08e2d989996..67614bb329a 100644 --- a/hr_work_entry_timesheet/__manifest__.py +++ b/hr_work_entry_timesheet/__manifest__.py @@ -1,6 +1,6 @@ { "name": "Work Entry with timesheets", - "version": "16.0.1.0.0", + "version": "17.0.1.0.0", "development_status": "Alpha", "category": "Human Resources/Employees", "website": "https://github.com/OCA/hr", diff --git a/hr_work_entry_timesheet/i18n/fr.po b/hr_work_entry_timesheet/i18n/fr.po new file mode 100644 index 00000000000..e2571f92976 --- /dev/null +++ b/hr_work_entry_timesheet/i18n/fr.po @@ -0,0 +1,36 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_work_entry_timesheet +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-05-27 09:58+0000\n" +"PO-Revision-Date: 2025-05-27 09:58+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: hr_work_entry_timesheet +#: model:ir.model,name:hr_work_entry_timesheet.model_account_analytic_line +msgid "Analytic Line" +msgstr "Ligne analytique" + +#. module: hr_work_entry_timesheet +#: model:ir.model,name:hr_work_entry_timesheet.model_hr_work_entry +msgid "HR Work Entry" +msgstr "Prestation RH" + +#. module: hr_work_entry_timesheet +#: model:ir.model.fields,field_description:hr_work_entry_timesheet.field_hr_work_entry__is_hatched +msgid "Timesheet Conflict" +msgstr "Conflit de feuille de temps" + +#. module: hr_work_entry_timesheet +#: model:ir.model.fields,field_description:hr_work_entry_timesheet.field_hr_work_entry__timesheet_duration +msgid "Timesheet Duration" +msgstr "Durée de feuilles de temps" diff --git a/hr_work_entry_timesheet/i18n/hr_work_entry_timesheet.pot b/hr_work_entry_timesheet/i18n/hr_work_entry_timesheet.pot index 3df9c4accd8..a3ae66b95c8 100644 --- a/hr_work_entry_timesheet/i18n/hr_work_entry_timesheet.pot +++ b/hr_work_entry_timesheet/i18n/hr_work_entry_timesheet.pot @@ -4,10 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 16.0\n" +"Project-Id-Version: Odoo Server 17.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-12 18:13+0000\n" -"PO-Revision-Date: 2025-04-12 18:13+0000\n" +"POT-Creation-Date: 2025-05-27 09:53+0000\n" +"PO-Revision-Date: 2025-05-27 09:53+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -27,7 +27,6 @@ msgstr "" #. module: hr_work_entry_timesheet #: model:ir.model.fields,field_description:hr_work_entry_timesheet.field_hr_work_entry__is_hatched -#: model:ir.model.fields,field_description:hr_work_entry_timesheet.field_hr_work_entry__timesheet_conflict msgid "Timesheet Conflict" msgstr "" diff --git a/hr_work_entry_timesheet/models/hr_work_entry.py b/hr_work_entry_timesheet/models/hr_work_entry.py index 02a45652565..322525953ce 100644 --- a/hr_work_entry_timesheet/models/hr_work_entry.py +++ b/hr_work_entry_timesheet/models/hr_work_entry.py @@ -1,6 +1,8 @@ # Copyright 2025- Le Filament (https://le-filament.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import pytz + from odoo import api, fields, models @@ -19,24 +21,78 @@ class HrWorkEntry(models.Model): def _compute_timesheet_duration(self): if not self: return - timesheets = self.env["account.analytic.line"].read_group( - domain=[ - ("project_id", "!=", False), - ("employee_id", "in", self.mapped("employee_id").ids), - ("date", ">=", min(self.mapped("date_start")).date()), - ("date", "<=", max(self.mapped("date_start")).date()), - ], - fields=["unit_amount"], - groupby=["employee_id", "date:day"], - lazy=False, + min_datetime = min(self.mapped("date_start")) + max_datetime = max(self.mapped("date_stop")) + dates = self.mapped( + lambda work_entry: pytz.UTC.localize(work_entry.date_start) + .astimezone(pytz.timezone(work_entry.employee_id.tz)) + .replace(tzinfo=None) + .date() + ) + min_date = min(dates) + max_date = max(dates) + employee_ids = self.mapped("employee_id").ids + timesheets = ( + self.env["account.analytic.line"] + .with_context(tz="UTC") + .read_group( + domain=[ + ("project_id", "!=", False), + ("employee_id", "in", employee_ids), + ("date", ">=", min_date), + ("date", "<=", max_date), + ], + fields=["unit_amount"], + groupby=["employee_id", "date:day"], + lazy=False, + ) ) - result = {eid: {} for eid in self.mapped("employee_id").ids} + timesheet_dict = {eid: {} for eid in employee_ids} for line in timesheets: date = fields.Date().from_string(line["__range"]["date:day"]["from"]) - result[line["employee_id"][0]][date] = line["unit_amount"] + timesheet_dict[line["employee_id"][0]][date] = line["unit_amount"] + work_entries_dict = {eid: {} for eid in employee_ids} + for employee_id in employee_ids: + employee = self.env["hr.employee"].browse(employee_id) + work_entries = ( + self.env["hr.work.entry"] + .with_context(tz=employee.tz) + .read_group( + domain=[ + ("employee_id", "=", employee_id), + ("date_start", ">=", min_datetime), + ("date_stop", "<=", max_datetime), + ], + fields=[], + groupby=["date_start:day"], + ) + ) + work_entries_dict[employee_id] = { + pytz.UTC.localize( + fields.Datetime().from_string( + line["__range"]["date_start:day"]["from"] + ) + ) + .astimezone(pytz.timezone(employee.tz)) + .replace(tzinfo=None) + .date(): line["date_start_count"] + for line in work_entries + } for work_entry in self: - work_entry.timesheet_duration = result[work_entry.employee_id.id].get( - work_entry.date_start.date(), 0.0 + date_start = ( + pytz.UTC.localize(work_entry.date_start) + .astimezone(pytz.timezone(work_entry.employee_id.tz)) + .replace(tzinfo=None) + .date() + ) + timesheet_duration = timesheet_dict[work_entry.employee_id.id].get( + date_start, 0.0 + ) + work_entry_count = work_entries_dict[work_entry.employee_id.id].get( + date_start, 0 + ) + work_entry.timesheet_duration = ( + timesheet_duration / work_entry_count if work_entry_count else 0.0 ) @api.depends("duration", "timesheet_duration") @@ -44,5 +100,5 @@ def _compute_timesheet_conflict(self): for entry in self: entry.is_hatched = entry.duration > 0.0 and ( entry.timesheet_duration == 0.0 - or entry.timesheet_duration > entry.duration * 2 + or entry.timesheet_duration > entry.duration ) diff --git a/hr_work_entry_timesheet/pyproject.toml b/hr_work_entry_timesheet/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/hr_work_entry_timesheet/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/hr_work_entry_timesheet/readme/ROADMAP.md b/hr_work_entry_timesheet/readme/ROADMAP.md index 4a3d2930ba9..d6669644224 100644 --- a/hr_work_entry_timesheet/readme/ROADMAP.md +++ b/hr_work_entry_timesheet/readme/ROADMAP.md @@ -1 +1 @@ -- In case resource calendar is using half-day attendances you get 2 work entries per day, when timesheets are per day, so we do not know on which work entry the timesheets should be attributed. So far they are attributed to both work entries for the day. +- In case resource calendar is using half-day attendances you get 2 work entries per day, when timesheets are per day, so we do not know on which work entry the timesheets should be attributed. So far they are divided by number of work entries for the day. diff --git a/hr_work_entry_timesheet_validate/README.rst b/hr_work_entry_timesheet_validate/README.rst new file mode 100644 index 00000000000..5c1a3eab9ea --- /dev/null +++ b/hr_work_entry_timesheet_validate/README.rst @@ -0,0 +1,104 @@ +========================================= +Work Entry with timesheets and validation +========================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:96eb505415cddcb1b2c8c641f493ff97424f3420d941266623c9a92dddda19c1 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :alt: Alpha +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr-lightgray.png?logo=github + :target: https://github.com/OCA/hr/tree/17.0/hr_work_entry_timesheet_validate + :alt: OCA/hr +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/hr-17-0/hr-17-0-hr_work_entry_timesheet_validate + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module is a glue module between hr_work_entry_timesheet and +hr_work_entry_validate, allowing to show timesheet on new views created +for simple employees. + +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +- Go to *Employees* / *My Work Entries* + +- In the calendar view for work entries, you get : + + - hatched entries when discrepancy are found + - timesheet duration on card view (when clicking on an entry) + +- Timesheet duration has also been added on Work entries form, tree and + pivot views. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Le Filament + +Contributors +------------ + +- Rémi remi-filament (https://le-filament.com) + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-remi-filament| image:: https://github.com/remi-filament.png?size=40px + :target: https://github.com/remi-filament + :alt: remi-filament + +Current `maintainer `__: + +|maintainer-remi-filament| + +This module is part of the `OCA/hr `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_work_entry_validate/i18n/.empty b/hr_work_entry_timesheet_validate/__init__.py similarity index 100% rename from hr_work_entry_validate/i18n/.empty rename to hr_work_entry_timesheet_validate/__init__.py diff --git a/hr_work_entry_timesheet_validate/__manifest__.py b/hr_work_entry_timesheet_validate/__manifest__.py new file mode 100644 index 00000000000..a2bd1ac3806 --- /dev/null +++ b/hr_work_entry_timesheet_validate/__manifest__.py @@ -0,0 +1,19 @@ +{ + "name": "Work Entry with timesheets and validation", + "version": "17.0.1.0.0", + "development_status": "Alpha", + "category": "Human Resources/Employees", + "website": "https://github.com/OCA/hr", + "author": "Le Filament, Odoo Community Association (OCA)", + "maintainers": ["remi-filament"], + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": [ + "hr_work_entry_timesheet", + "hr_work_entry_validate", + ], + "data": [ + "views/hr_work_entry_view.xml", + ], +} diff --git a/hr_work_entry_timesheet_validate/pyproject.toml b/hr_work_entry_timesheet_validate/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/hr_work_entry_timesheet_validate/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/hr_work_entry_timesheet_validate/readme/CONTRIBUTORS.md b/hr_work_entry_timesheet_validate/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..53f884c65b5 --- /dev/null +++ b/hr_work_entry_timesheet_validate/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Rémi remi-filament (https://le-filament.com) diff --git a/hr_work_entry_timesheet_validate/readme/DESCRIPTION.md b/hr_work_entry_timesheet_validate/readme/DESCRIPTION.md new file mode 100644 index 00000000000..9193ec57c26 --- /dev/null +++ b/hr_work_entry_timesheet_validate/readme/DESCRIPTION.md @@ -0,0 +1 @@ +This module is a glue module between hr_work_entry_timesheet and hr_work_entry_validate, allowing to show timesheet on new views created for simple employees. diff --git a/hr_work_entry_timesheet_validate/readme/USAGE.md b/hr_work_entry_timesheet_validate/readme/USAGE.md new file mode 100644 index 00000000000..291d0d2b492 --- /dev/null +++ b/hr_work_entry_timesheet_validate/readme/USAGE.md @@ -0,0 +1,7 @@ +- Go to *Employees* / *My Work Entries* + +- In the calendar view for work entries, you get : + - hatched entries when discrepancy are found + - timesheet duration on card view (when clicking on an entry) + +- Timesheet duration has also been added on Work entries form, tree and pivot views. diff --git a/hr_work_entry_timesheet_validate/static/description/icon.png b/hr_work_entry_timesheet_validate/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/hr_work_entry_timesheet_validate/static/description/icon.svg b/hr_work_entry_timesheet_validate/static/description/icon.svg new file mode 100644 index 00000000000..a7a26d0932a --- /dev/null +++ b/hr_work_entry_timesheet_validate/static/description/icon.svg @@ -0,0 +1,79 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/hr_work_entry_timesheet_validate/static/description/index.html b/hr_work_entry_timesheet_validate/static/description/index.html new file mode 100644 index 00000000000..f92d18ab8d6 --- /dev/null +++ b/hr_work_entry_timesheet_validate/static/description/index.html @@ -0,0 +1,124 @@ +
+
+
+

Module name

+

This module was written to extend the functionality of ... to support ... and allow you to ...

+
+
+
+ +
+
+
+

Installation

+
+
+

To install this module, you need to: +

    +
  • ...
  • +
+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Configuration

+
+
+

To configure this module, you need to: +

    +
  • ...
  • +
+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Usage

+
+
+

To use this module, you need to: +

    +
  • ...
  • +
+

+

For further information, please visit: +

+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Known issues / Roadmap

+
+
+

+

    +
  • ...
  • +
+

+
+
+
+ + + +
+
+
+
+ +
+
+
+

Credits

+
+
+

Contributors

+ +
+
+

Maintainer

+

+ This module is maintained by the OCA.
+ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.
+ To contribute to this module, please visit http://odoo-community.org.
+ +

+
+
+
diff --git a/hr_work_entry_timesheet_validate/views/hr_work_entry_view.xml b/hr_work_entry_timesheet_validate/views/hr_work_entry_view.xml new file mode 100644 index 00000000000..a7cf60e442e --- /dev/null +++ b/hr_work_entry_timesheet_validate/views/hr_work_entry_view.xml @@ -0,0 +1,58 @@ + + + + + + hr.work.entry.calendar.with_timesheet_validate + hr.work.entry + + + + + + + + + + + + hr.work.entry.form.with_timesheet_validate + hr.work.entry + + + + + + + + + + hr.work.entry.tree.with_timesheet_validate + hr.work.entry + + + + + + + + + + hr.work.entry.pivot.with_timesheet_validate + hr.work.entry + + + + + + + + + diff --git a/hr_work_entry_timesheet_weekend/README.rst b/hr_work_entry_timesheet_weekend/README.rst index 58ef517e40d..08fae9b49ab 100644 --- a/hr_work_entry_timesheet_weekend/README.rst +++ b/hr_work_entry_timesheet_weekend/README.rst @@ -17,13 +17,13 @@ Work Entry with timesheets for weekends :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr-lightgray.png?logo=github - :target: https://github.com/OCA/hr/tree/16.0/hr_work_entry_timesheet_weekend + :target: https://github.com/OCA/hr/tree/17.0/hr_work_entry_timesheet_weekend :alt: OCA/hr .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/hr-16-0/hr-16-0-hr_work_entry_timesheet_weekend + :target: https://translation.odoo-community.org/projects/hr-17-0/hr-17-0-hr_work_entry_timesheet_weekend :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=17.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -66,7 +66,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -104,6 +104,6 @@ Current `maintainer `__: |maintainer-remi-filament| -This module is part of the `OCA/hr `_ project on GitHub. +This module is part of the `OCA/hr `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_work_entry_timesheet_weekend/__manifest__.py b/hr_work_entry_timesheet_weekend/__manifest__.py index cd2b2debe9c..10dd731fa38 100644 --- a/hr_work_entry_timesheet_weekend/__manifest__.py +++ b/hr_work_entry_timesheet_weekend/__manifest__.py @@ -1,6 +1,6 @@ { "name": "Work Entry with timesheets for weekends", - "version": "16.0.1.0.0", + "version": "17.0.1.0.0", "development_status": "Alpha", "category": "Human Resources/Employees", "website": "https://github.com/OCA/hr", diff --git a/hr_work_entry_timesheet_weekend/i18n/fr.po b/hr_work_entry_timesheet_weekend/i18n/fr.po new file mode 100644 index 00000000000..c25839f1549 --- /dev/null +++ b/hr_work_entry_timesheet_weekend/i18n/fr.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_work_entry_timesheet_weekend +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-05-27 09:59+0000\n" +"PO-Revision-Date: 2025-05-27 09:59+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: hr_work_entry_timesheet_weekend +#: model:ir.model,name:hr_work_entry_timesheet_weekend.model_hr_contract +msgid "Employee Contract" +msgstr "Contrat de l'employé" + +#. module: hr_work_entry_timesheet_weekend +#: model:hr.work.entry.type,name:hr_work_entry_timesheet_weekend.work_entry_type_leave +msgid "Not working day" +msgstr "Jour non ouvré" diff --git a/hr_work_entry_timesheet_weekend/i18n/hr_work_entry_timesheet_weekend.pot b/hr_work_entry_timesheet_weekend/i18n/hr_work_entry_timesheet_weekend.pot index 8eacb48b1eb..f15e6f10613 100644 --- a/hr_work_entry_timesheet_weekend/i18n/hr_work_entry_timesheet_weekend.pot +++ b/hr_work_entry_timesheet_weekend/i18n/hr_work_entry_timesheet_weekend.pot @@ -4,10 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 16.0\n" +"Project-Id-Version: Odoo Server 17.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-12 18:14+0000\n" -"PO-Revision-Date: 2025-04-12 18:14+0000\n" +"POT-Creation-Date: 2025-05-27 09:54+0000\n" +"PO-Revision-Date: 2025-05-27 09:54+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -20,35 +20,7 @@ msgstr "" msgid "Employee Contract" msgstr "" -#. module: hr_work_entry_timesheet_weekend -#. odoo-javascript -#: code:addons/hr_work_entry_timesheet_weekend/static/src/js/web_module_name.tour.js:0 -#, python-format -msgid "Instructions for end user." -msgstr "" - #. module: hr_work_entry_timesheet_weekend #: model:hr.work.entry.type,name:hr_work_entry_timesheet_weekend.work_entry_type_leave msgid "Not working day" msgstr "" - -#. module: hr_work_entry_timesheet_weekend -#. odoo-javascript -#: code:addons/hr_work_entry_timesheet_weekend/static/src/js/web_module_name.tour.js:0 -#, python-format -msgid "Text for continue button." -msgstr "" - -#. module: hr_work_entry_timesheet_weekend -#. odoo-javascript -#: code:addons/hr_work_entry_timesheet_weekend/static/src/js/web_module_name.tour.js:0 -#, python-format -msgid "The title of this step, appears in logs" -msgstr "" - -#. module: hr_work_entry_timesheet_weekend -#. odoo-javascript -#: code:addons/hr_work_entry_timesheet_weekend/static/src/js/web_module_name.tour.js:0 -#, python-format -msgid "Try to demostrate how to create a tour" -msgstr "" diff --git a/hr_work_entry_timesheet_weekend/pyproject.toml b/hr_work_entry_timesheet_weekend/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/hr_work_entry_timesheet_weekend/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/hr_work_entry_validate/README.rst b/hr_work_entry_validate/README.rst index b1254f557b5..5c2c57ec288 100644 --- a/hr_work_entry_validate/README.rst +++ b/hr_work_entry_validate/README.rst @@ -17,13 +17,13 @@ Validate Work Entry :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr-lightgray.png?logo=github - :target: https://github.com/OCA/hr/tree/16.0/hr_work_entry_validate + :target: https://github.com/OCA/hr/tree/17.0/hr_work_entry_validate :alt: OCA/hr .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/hr-16-0/hr-16-0-hr_work_entry_validate + :target: https://translation.odoo-community.org/projects/hr-17-0/hr-17-0-hr_work_entry_validate :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=17.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -56,9 +56,7 @@ Usage To use this module, you need to: -- Go to *Employees* - -- On an "Employee" form view, click on smart-button "Work entries" +- Go to *Employees* / *My Work Entries* - Switch to list view, select a number of entries and click on "Action" > "Validate work entries" @@ -77,7 +75,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -115,6 +113,6 @@ Current `maintainer `__: |maintainer-remi-filament| -This module is part of the `OCA/hr `_ project on GitHub. +This module is part of the `OCA/hr `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_work_entry_validate/__manifest__.py b/hr_work_entry_validate/__manifest__.py index b68be11a514..17afe1731e3 100644 --- a/hr_work_entry_validate/__manifest__.py +++ b/hr_work_entry_validate/__manifest__.py @@ -1,6 +1,6 @@ { "name": "Validate Work Entry", - "version": "16.0.1.0.0", + "version": "17.0.1.0.0", "development_status": "Alpha", "category": "Human Resources/Employees", "website": "https://github.com/OCA/hr", @@ -13,6 +13,9 @@ "hr_work_entry_contract", ], "data": [ + "security/ir.model.access.csv", + "security/hr_work_entry_security.xml", "data/ir_actions_server_data.xml", + "views/hr_work_entry_views.xml", ], } diff --git a/hr_work_entry_validate/i18n/fr.po b/hr_work_entry_validate/i18n/fr.po new file mode 100644 index 00000000000..cfc103f6eed --- /dev/null +++ b/hr_work_entry_validate/i18n/fr.po @@ -0,0 +1,139 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_work_entry_validate +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-05-27 10:00+0000\n" +"PO-Revision-Date: 2025-05-27 10:00+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form +msgid "Hours" +msgstr "Heures" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Archived" +msgstr "Archivé" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_tree +msgid "Beginning" +msgstr "Début" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Conflicting" +msgstr "En conflit" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Current Month" +msgstr "Mois courant" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Date" +msgstr "Date" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form +msgid "Description" +msgstr "Description" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_tree +msgid "End" +msgstr "Fin" + +#. module: hr_work_entry_validate +#: model:ir.model,name:hr_work_entry_validate.model_hr_work_entry +msgid "HR Work Entry" +msgstr "Prestation RH" + +#. module: hr_work_entry_validate +#: model:ir.ui.menu,name:hr_work_entry_validate.menu_my_work_entry +msgid "My Work Entries" +msgstr "Mes prestations" + +#. module: hr_work_entry_validate +#: model_terms:ir.actions.act_window,help:hr_work_entry_validate.hr_work_entry_action +msgid "No data to display" +msgstr "Aucune donnée à afficher" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form +msgid "Note: Validated work entries cannot be modified." +msgstr "Note : Les prestations validées ne peuvent être modifiées" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Search Work Entry" +msgstr "Recherche de prestation" + +#. module: hr_work_entry_validate +#. odoo-python +#: code:addons/hr_work_entry_validate/models/hr_work_entry.py:0 +#: code:addons/hr_work_entry_validate/models/hr_work_entry.py:0 +#, python-format +msgid "" +"Some entries are in conflict and cannot be validated, please solve conflicts" +" first." +msgstr "" +"Certaines entrées sont en conflit et ne peuvent être validées, merci de résoudre les" +" confilts avant de valider." + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Start Date" +msgstr "Date de début" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form +msgid "This work entry cannot be validated. The work entry type is undefined." +msgstr "Cette prestation ne peut pas être validée. Son type est inconnu." + +#. module: hr_work_entry_validate +#: model_terms:ir.actions.act_window,help:hr_work_entry_validate.hr_work_entry_action +msgid "" +"Try to add some records, or make sure that there is no active filter in the " +"search bar." +msgstr "" +"Essayez d'ajouter quelques entrées, ou assurez-vous qu'il n'y a pas de filtre actif " +"dans la barre de recherche." + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Type" +msgstr "Type" + +#. module: hr_work_entry_validate +#: model:ir.actions.server,name:hr_work_entry_validate.action_validate_work_entries +msgid "Validate work entries" +msgstr "Valider les prestations" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_pivot +msgid "Work Entries" +msgstr "Prestations" + +#. module: hr_work_entry_validate +#: model:ir.actions.act_window,name:hr_work_entry_validate.hr_work_entry_action +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_calendar +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form +msgid "Work Entry" +msgstr "Prestation" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form +msgid "Work Entry Name" +msgstr "Nom de la prestation" diff --git a/hr_work_entry_validate/i18n/hr_work_entry_validate.pot b/hr_work_entry_validate/i18n/hr_work_entry_validate.pot new file mode 100644 index 00000000000..b99e9e4d207 --- /dev/null +++ b/hr_work_entry_validate/i18n/hr_work_entry_validate.pot @@ -0,0 +1,135 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_work_entry_validate +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-05-27 09:54+0000\n" +"PO-Revision-Date: 2025-05-27 09:54+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form +msgid "Hours" +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Archived" +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_tree +msgid "Beginning" +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Conflicting" +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Current Month" +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Date" +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form +msgid "Description" +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_tree +msgid "End" +msgstr "" + +#. module: hr_work_entry_validate +#: model:ir.model,name:hr_work_entry_validate.model_hr_work_entry +msgid "HR Work Entry" +msgstr "" + +#. module: hr_work_entry_validate +#: model:ir.ui.menu,name:hr_work_entry_validate.menu_my_work_entry +msgid "My Work Entries" +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.actions.act_window,help:hr_work_entry_validate.hr_work_entry_action +msgid "No data to display" +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form +msgid "Note: Validated work entries cannot be modified." +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Search Work Entry" +msgstr "" + +#. module: hr_work_entry_validate +#. odoo-python +#: code:addons/hr_work_entry_validate/models/hr_work_entry.py:0 +#: code:addons/hr_work_entry_validate/models/hr_work_entry.py:0 +#, python-format +msgid "" +"Some entries are in conflict and cannot be validated, please solve conflicts" +" first." +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Start Date" +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form +msgid "This work entry cannot be validated. The work entry type is undefined." +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.actions.act_window,help:hr_work_entry_validate.hr_work_entry_action +msgid "" +"Try to add some records, or make sure that there is no active filter in the " +"search bar." +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Type" +msgstr "" + +#. module: hr_work_entry_validate +#: model:ir.actions.server,name:hr_work_entry_validate.action_validate_work_entries +msgid "Validate work entries" +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_pivot +msgid "Work Entries" +msgstr "" + +#. module: hr_work_entry_validate +#: model:ir.actions.act_window,name:hr_work_entry_validate.hr_work_entry_action +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_calendar +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form +msgid "Work Entry" +msgstr "" + +#. module: hr_work_entry_validate +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form +msgid "Work Entry Name" +msgstr "" diff --git a/hr_work_entry_validate/pyproject.toml b/hr_work_entry_validate/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/hr_work_entry_validate/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/hr_work_entry_validate/readme/USAGE.md b/hr_work_entry_validate/readme/USAGE.md index 078b37e917a..8f93031e10a 100644 --- a/hr_work_entry_validate/readme/USAGE.md +++ b/hr_work_entry_validate/readme/USAGE.md @@ -1,8 +1,6 @@ To use this module, you need to: -- Go to *Employees* - -- On an "Employee" form view, click on smart-button "Work entries" +- Go to *Employees* / *My Work Entries* - Switch to list view, select a number of entries and click on "Action" > "Validate work entries" diff --git a/hr_work_entry_validate/security/hr_work_entry_security.xml b/hr_work_entry_validate/security/hr_work_entry_security.xml new file mode 100644 index 00000000000..cb086ef67d0 --- /dev/null +++ b/hr_work_entry_validate/security/hr_work_entry_security.xml @@ -0,0 +1,32 @@ + + + + + Work entries/Employee : only self + + [('employee_id.user_id', '=', user.id)] + + + + + + + + + Work entries/HR officer : all work entries + + [(1, '=', 1)] + + + + + + + + + HR Contract: Employee + + + [('employee_id.user_id', '=', user.id)] + + diff --git a/hr_work_entry_validate/security/ir.model.access.csv b/hr_work_entry_validate/security/ir.model.access.csv new file mode 100644 index 00000000000..3c9bcb30277 --- /dev/null +++ b/hr_work_entry_validate/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_hr_work_entry_user,access_hr_work_entry_user,hr_work_entry.model_hr_work_entry,base.group_user,1,1,0,0 +access_hr_work_entry_type_user,access_hr_work_entry_type_user,hr_work_entry.model_hr_work_entry_type,base.group_user,1,0,0,0 +access_hr_contract_user,hr.contract.user,hr_contract.model_hr_contract,base.group_user,1,0,0,0 diff --git a/hr_work_entry_validate/views/hr_work_entry_views.xml b/hr_work_entry_validate/views/hr_work_entry_views.xml new file mode 100644 index 00000000000..6f0c6813c8a --- /dev/null +++ b/hr_work_entry_validate/views/hr_work_entry_views.xml @@ -0,0 +1,204 @@ + + + + hr.work.entry.calendar + hr.work.entry + + + + + + + + + hr.work.entry.form + hr.work.entry + +
+
+ +
+ +
+ +
+ + + + + + + + + + + + +
+
+
+ + + hr.work.entry.tree + hr.work.entry + + + + + + + + + + + + + + + + hr.work.entry.pivot + hr.work.entry + + + + + + + + + + hr.work.entry.filter + hr.work.entry + + + + + + + + + + + + + + + + + + + Work Entry + hr.work.entry + calendar,tree,form,pivot + {} + + + + + + calendar + + + + + + tree + + + + + + pivot + + + + + + form + + + + +
From 2f46ece2c3497e616ec59153b2851c75870d8c58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20-=20Le=20Filament?= <30716308+remi-filament@users.noreply.github.com> Date: Tue, 17 Jun 2025 17:21:45 +0200 Subject: [PATCH 07/18] [MIG] hr_work_entry_*: Migration to version 18.0 --- hr_work_entry_timesheet/README.rst | 10 ++-- hr_work_entry_timesheet/__manifest__.py | 2 +- .../models/hr_timesheet.py | 4 +- .../views/hr_work_entry_view.xml | 2 - hr_work_entry_timesheet_validate/README.rst | 10 ++-- .../__manifest__.py | 2 +- .../views/hr_work_entry_view.xml | 2 - hr_work_entry_timesheet_weekend/README.rst | 10 ++-- .../__manifest__.py | 2 +- .../data/hr_work_entry_type_data.xml | 2 +- .../models/hr_contract.py | 14 +++-- hr_work_entry_validate/README.rst | 10 ++-- hr_work_entry_validate/__manifest__.py | 2 +- .../data/ir_actions_server_data.xml | 16 +++--- .../security/hr_work_entry_security.xml | 53 +++++++++---------- .../views/hr_work_entry_views.xml | 10 ++-- 16 files changed, 73 insertions(+), 78 deletions(-) diff --git a/hr_work_entry_timesheet/README.rst b/hr_work_entry_timesheet/README.rst index 57f02628029..35009544c80 100644 --- a/hr_work_entry_timesheet/README.rst +++ b/hr_work_entry_timesheet/README.rst @@ -17,13 +17,13 @@ Work Entry with timesheets :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr-lightgray.png?logo=github - :target: https://github.com/OCA/hr/tree/17.0/hr_work_entry_timesheet + :target: https://github.com/OCA/hr/tree/18.0/hr_work_entry_timesheet :alt: OCA/hr .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/hr-17-0/hr-17-0-hr_work_entry_timesheet + :target: https://translation.odoo-community.org/projects/hr-18-0/hr-18-0-hr_work_entry_timesheet :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=17.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -93,7 +93,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -131,6 +131,6 @@ Current `maintainer `__: |maintainer-remi-filament| -This module is part of the `OCA/hr `_ project on GitHub. +This module is part of the `OCA/hr `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_work_entry_timesheet/__manifest__.py b/hr_work_entry_timesheet/__manifest__.py index 67614bb329a..d06586495b0 100644 --- a/hr_work_entry_timesheet/__manifest__.py +++ b/hr_work_entry_timesheet/__manifest__.py @@ -1,6 +1,6 @@ { "name": "Work Entry with timesheets", - "version": "17.0.1.0.0", + "version": "18.0.1.0.0", "development_status": "Alpha", "category": "Human Resources/Employees", "website": "https://github.com/OCA/hr", diff --git a/hr_work_entry_timesheet/models/hr_timesheet.py b/hr_work_entry_timesheet/models/hr_timesheet.py index 15c85bddb5f..722e69d2e22 100644 --- a/hr_work_entry_timesheet/models/hr_timesheet.py +++ b/hr_work_entry_timesheet/models/hr_timesheet.py @@ -10,7 +10,9 @@ class AccountAnalyticLine(models.Model): def _get_work_entry(self): work_entries = self.env["hr.work.entry"] - for timesheet in self.filtered(lambda l: not l.project_id and l.employee_id): + for timesheet in self.filtered( + lambda line: not line.project_id and line.employee_id + ): work_entries += work_entries.search( [ ("employee_id", "=", timesheet.employee_id.id), diff --git a/hr_work_entry_timesheet/views/hr_work_entry_view.xml b/hr_work_entry_timesheet/views/hr_work_entry_view.xml index 801bdbdaca0..f70b9ff0e9f 100644 --- a/hr_work_entry_timesheet/views/hr_work_entry_view.xml +++ b/hr_work_entry_timesheet/views/hr_work_entry_view.xml @@ -2,7 +2,6 @@ - hr.work.entry.calendar.with_timesheet hr.work.entry @@ -48,5 +47,4 @@ - diff --git a/hr_work_entry_timesheet_validate/README.rst b/hr_work_entry_timesheet_validate/README.rst index 5c1a3eab9ea..ad38f4c5f5e 100644 --- a/hr_work_entry_timesheet_validate/README.rst +++ b/hr_work_entry_timesheet_validate/README.rst @@ -17,13 +17,13 @@ Work Entry with timesheets and validation :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr-lightgray.png?logo=github - :target: https://github.com/OCA/hr/tree/17.0/hr_work_entry_timesheet_validate + :target: https://github.com/OCA/hr/tree/18.0/hr_work_entry_timesheet_validate :alt: OCA/hr .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/hr-17-0/hr-17-0-hr_work_entry_timesheet_validate + :target: https://translation.odoo-community.org/projects/hr-18-0/hr-18-0-hr_work_entry_timesheet_validate :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=17.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -61,7 +61,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -99,6 +99,6 @@ Current `maintainer `__: |maintainer-remi-filament| -This module is part of the `OCA/hr `_ project on GitHub. +This module is part of the `OCA/hr `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_work_entry_timesheet_validate/__manifest__.py b/hr_work_entry_timesheet_validate/__manifest__.py index a2bd1ac3806..7eb138a2987 100644 --- a/hr_work_entry_timesheet_validate/__manifest__.py +++ b/hr_work_entry_timesheet_validate/__manifest__.py @@ -1,6 +1,6 @@ { "name": "Work Entry with timesheets and validation", - "version": "17.0.1.0.0", + "version": "18.0.1.0.0", "development_status": "Alpha", "category": "Human Resources/Employees", "website": "https://github.com/OCA/hr", diff --git a/hr_work_entry_timesheet_validate/views/hr_work_entry_view.xml b/hr_work_entry_timesheet_validate/views/hr_work_entry_view.xml index a7cf60e442e..1314dc350fa 100644 --- a/hr_work_entry_timesheet_validate/views/hr_work_entry_view.xml +++ b/hr_work_entry_timesheet_validate/views/hr_work_entry_view.xml @@ -2,7 +2,6 @@ - hr.work.entry.calendar.with_timesheet_validate hr.work.entry @@ -54,5 +53,4 @@ - diff --git a/hr_work_entry_timesheet_weekend/README.rst b/hr_work_entry_timesheet_weekend/README.rst index 08fae9b49ab..2bad8ccd06f 100644 --- a/hr_work_entry_timesheet_weekend/README.rst +++ b/hr_work_entry_timesheet_weekend/README.rst @@ -17,13 +17,13 @@ Work Entry with timesheets for weekends :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr-lightgray.png?logo=github - :target: https://github.com/OCA/hr/tree/17.0/hr_work_entry_timesheet_weekend + :target: https://github.com/OCA/hr/tree/18.0/hr_work_entry_timesheet_weekend :alt: OCA/hr .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/hr-17-0/hr-17-0-hr_work_entry_timesheet_weekend + :target: https://translation.odoo-community.org/projects/hr-18-0/hr-18-0-hr_work_entry_timesheet_weekend :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=17.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -66,7 +66,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -104,6 +104,6 @@ Current `maintainer `__: |maintainer-remi-filament| -This module is part of the `OCA/hr `_ project on GitHub. +This module is part of the `OCA/hr `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_work_entry_timesheet_weekend/__manifest__.py b/hr_work_entry_timesheet_weekend/__manifest__.py index 10dd731fa38..104d89fc43a 100644 --- a/hr_work_entry_timesheet_weekend/__manifest__.py +++ b/hr_work_entry_timesheet_weekend/__manifest__.py @@ -1,6 +1,6 @@ { "name": "Work Entry with timesheets for weekends", - "version": "17.0.1.0.0", + "version": "18.0.1.0.0", "development_status": "Alpha", "category": "Human Resources/Employees", "website": "https://github.com/OCA/hr", diff --git a/hr_work_entry_timesheet_weekend/data/hr_work_entry_type_data.xml b/hr_work_entry_timesheet_weekend/data/hr_work_entry_type_data.xml index d022b5ac32e..f8b59a2ffbd 100644 --- a/hr_work_entry_timesheet_weekend/data/hr_work_entry_type_data.xml +++ b/hr_work_entry_timesheet_weekend/data/hr_work_entry_type_data.xml @@ -1,6 +1,6 @@ - + Not working day NOTWORK 3 diff --git a/hr_work_entry_timesheet_weekend/models/hr_contract.py b/hr_work_entry_timesheet_weekend/models/hr_contract.py index 59195a41b6f..050c8b95210 100644 --- a/hr_work_entry_timesheet_weekend/models/hr_contract.py +++ b/hr_work_entry_timesheet_weekend/models/hr_contract.py @@ -37,7 +37,7 @@ def _get_contract_work_entries_values(self, date_start, date_stop): for contract in self: new_work_entry_dates = [] for timesheet in timesheets.filtered( - lambda aal: aal.employee_id == contract.employee_id + lambda aal: aal.employee_id == contract.employee_id # noqa: B023 ): if ( not timesheet._get_work_entry() @@ -53,18 +53,16 @@ def _get_contract_work_entries_values(self, date_start, date_stop): .astimezone(pytz.UTC) .replace(tzinfo=None) ) + if leave_entry_type: + contract_name = f"{leave_entry_type.name}: " + else: + contract_name = "" contract_vals += [ dict( [ ( "name", - "%s%s" - % ( - leave_entry_type.name + ": " - if leave_entry_type - else "", - contract.employee_id.name, - ), + f"{contract_name}{contract.employee_id.name}", ), ("date_start", date_start), ("date_stop", date_start + relativedelta(minutes=1)), diff --git a/hr_work_entry_validate/README.rst b/hr_work_entry_validate/README.rst index 5c2c57ec288..9a88e03dd25 100644 --- a/hr_work_entry_validate/README.rst +++ b/hr_work_entry_validate/README.rst @@ -17,13 +17,13 @@ Validate Work Entry :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr-lightgray.png?logo=github - :target: https://github.com/OCA/hr/tree/17.0/hr_work_entry_validate + :target: https://github.com/OCA/hr/tree/18.0/hr_work_entry_validate :alt: OCA/hr .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/hr-17-0/hr-17-0-hr_work_entry_validate + :target: https://translation.odoo-community.org/projects/hr-18-0/hr-18-0-hr_work_entry_validate :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=17.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -75,7 +75,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -113,6 +113,6 @@ Current `maintainer `__: |maintainer-remi-filament| -This module is part of the `OCA/hr `_ project on GitHub. +This module is part of the `OCA/hr `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_work_entry_validate/__manifest__.py b/hr_work_entry_validate/__manifest__.py index 17afe1731e3..0a2240cfff8 100644 --- a/hr_work_entry_validate/__manifest__.py +++ b/hr_work_entry_validate/__manifest__.py @@ -1,6 +1,6 @@ { "name": "Validate Work Entry", - "version": "17.0.1.0.0", + "version": "18.0.1.0.0", "development_status": "Alpha", "category": "Human Resources/Employees", "website": "https://github.com/OCA/hr", diff --git a/hr_work_entry_validate/data/ir_actions_server_data.xml b/hr_work_entry_validate/data/ir_actions_server_data.xml index 6e9bde870d0..c023b2528de 100644 --- a/hr_work_entry_validate/data/ir_actions_server_data.xml +++ b/hr_work_entry_validate/data/ir_actions_server_data.xml @@ -5,12 +5,12 @@ --> - - Validate work entries - - - - code - records.action_validate_with_error() - + + Validate work entries + + + + code + records.action_validate_with_error() + diff --git a/hr_work_entry_validate/security/hr_work_entry_security.xml b/hr_work_entry_validate/security/hr_work_entry_security.xml index cb086ef67d0..51fdb96781b 100644 --- a/hr_work_entry_validate/security/hr_work_entry_security.xml +++ b/hr_work_entry_validate/security/hr_work_entry_security.xml @@ -1,32 +1,31 @@ + + Work entries/Employee : only self + + [('employee_id.user_id', '=', user.id)] + + + + + + - - Work entries/Employee : only self - - [('employee_id.user_id', '=', user.id)] - - - - - - + + Work entries/HR officer : all work entries + + [(1, '=', 1)] + + + + + + - - Work entries/HR officer : all work entries - - [(1, '=', 1)] - - - - - - - - - HR Contract: Employee - - - [('employee_id.user_id', '=', user.id)] - + + HR Contract: Employee + + + [('employee_id.user_id', '=', user.id)] + diff --git a/hr_work_entry_validate/views/hr_work_entry_views.xml b/hr_work_entry_validate/views/hr_work_entry_views.xml index 6f0c6813c8a..e675e590e84 100644 --- a/hr_work_entry_validate/views/hr_work_entry_views.xml +++ b/hr_work_entry_validate/views/hr_work_entry_views.xml @@ -90,10 +90,10 @@ - hr.work.entry.tree + hr.work.entry.list hr.work.entry - + - + @@ -165,7 +165,7 @@ Work Entry hr.work.entry - calendar,tree,form,pivot + calendar,list,form,pivot {} @@ -178,7 +178,7 @@ - tree + list From 63372ccfb31415fa3e390f94bcb7a5e5058eb6a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20-=20Le=20Filament?= <30716308+remi-filament@users.noreply.github.com> Date: Mon, 3 Nov 2025 14:32:19 +0100 Subject: [PATCH 08/18] [FIX] link timesheet work entries --- .../models/hr_timesheet.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/hr_work_entry_timesheet/models/hr_timesheet.py b/hr_work_entry_timesheet/models/hr_timesheet.py index 722e69d2e22..4f7d113d3a3 100644 --- a/hr_work_entry_timesheet/models/hr_timesheet.py +++ b/hr_work_entry_timesheet/models/hr_timesheet.py @@ -11,7 +11,7 @@ class AccountAnalyticLine(models.Model): def _get_work_entry(self): work_entries = self.env["hr.work.entry"] for timesheet in self.filtered( - lambda line: not line.project_id and line.employee_id + lambda line: line.project_id and line.employee_id ): work_entries += work_entries.search( [ @@ -25,19 +25,28 @@ def _get_work_entry(self): @api.model_create_multi def create(self, vals_list): res = super().create(vals_list) - work_entries = res._get_work_entry() + timesheets = res.filtered("project_id") + if not timesheets: + return res + work_entries = timesheets._get_work_entry() if work_entries: work_entries._compute_timesheet_duration() return res def write(self, vals): res = super().write(vals) - if "unit_amount" in vals or "employee_id" in vals or "date" in vals: + if ("unit_amount" in vals or "employee_id" in vals or "date" in vals) and ( + self.filtered("project_id") or "project_id" in vals + ): self._get_work_entry()._compute_timesheet_duration() return res def unlink(self): - work_entries = self._get_work_entry() + work_entries = self.env["hr.work.entry"] + timesheets = self.filtered("project_id") + if timesheets: + work_entries = timesheets._get_work_entry() res = super().unlink() - work_entries._compute_timesheet_duration() + if timesheets: + work_entries._compute_timesheet_duration() return res From 34f4585d8d791df2f7f6feda960de40063ec8ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20-=20Le=20Filament?= <30716308+remi-filament@users.noreply.github.com> Date: Mon, 3 Nov 2025 14:32:32 +0100 Subject: [PATCH 09/18] [FIX] add missing domain on action --- hr_work_entry_validate/views/hr_work_entry_views.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/hr_work_entry_validate/views/hr_work_entry_views.xml b/hr_work_entry_validate/views/hr_work_entry_views.xml index e675e590e84..4caf4147d10 100644 --- a/hr_work_entry_validate/views/hr_work_entry_views.xml +++ b/hr_work_entry_validate/views/hr_work_entry_views.xml @@ -166,6 +166,7 @@ Work Entry hr.work.entry calendar,list,form,pivot + [('employee_id.user_id', '=', uid)] {} From 53b100a8502f2a0a57f063b530c0ca76e1f695ee Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux Date: Mon, 3 Nov 2025 18:00:33 +0100 Subject: [PATCH 10/18] wip --- hr_work_entry_validate/__manifest__.py | 6 +++ .../views/calendar/calendar_controller.esm.js | 37 +++++++++++++++++++ .../views/calendar/calendar_controller.xml | 13 +++++++ 3 files changed, 56 insertions(+) create mode 100644 hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js create mode 100644 hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml diff --git a/hr_work_entry_validate/__manifest__.py b/hr_work_entry_validate/__manifest__.py index 0a2240cfff8..8fbf543a36e 100644 --- a/hr_work_entry_validate/__manifest__.py +++ b/hr_work_entry_validate/__manifest__.py @@ -18,4 +18,10 @@ "data/ir_actions_server_data.xml", "views/hr_work_entry_views.xml", ], + "assets": { + "web.assets_backend": [ + "hr_work_entry_validate/static/src/views/**/*.js", + "hr_work_entry_validate/static/src/views/**/*.xml", + ], + }, } diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js new file mode 100644 index 00000000000..4219b1b6a23 --- /dev/null +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js @@ -0,0 +1,37 @@ +import { patch } from "@web/core/utils/patch"; +import { CalendarController } from "@web/views/calendar/calendar_controller"; + +patch(CalendarController.prototype, { + async validateWorkentries() { + console.log("validate"); + console.log(this); + + const records = this.model.data.records; + + console.log(records); + + const employeeId = ""; // TODO employé actuel + const start = ""; // TODO début période + const stop = ""; // TODO fin période + + const record_ids = []; + + for (const record of Object.items(records)) { + if (record) { + // TODO filter date and maybe employee id? + record_ids.push(record.id); + } + } + + console.log(record_ids); + + const result = await this.orm.call( + "hr.work.entry", + "action_validate", + [record_ids], + {} + ); + + console.log(result); + }, +}); diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml new file mode 100644 index 00000000000..d788f5f1e9b --- /dev/null +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + From 38d08466042017edad1204a6b0367ffecb9c0c1e Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux Date: Tue, 4 Nov 2025 15:02:23 +0100 Subject: [PATCH 11/18] refac --- .../views/calendar/calendar_controller.esm.js | 80 +++++++++++++------ .../views/calendar/calendar_controller.xml | 9 +-- 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js index 4219b1b6a23..fcbad3d8234 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js @@ -1,37 +1,69 @@ import { patch } from "@web/core/utils/patch"; import { CalendarController } from "@web/views/calendar/calendar_controller"; +import { useService } from "@web/core/utils/hooks"; patch(CalendarController.prototype, { - async validateWorkentries() { - console.log("validate"); + // just log this + setup() { + super.setup(...arguments); + this.notification = useService("notification"); console.log(this); + }, - const records = this.model.data.records; - - console.log(records); - - const employeeId = ""; // TODO employé actuel - const start = ""; // TODO début période - const stop = ""; // TODO fin période - - const record_ids = []; + // only display button if month or week + get displayButton() { + return this.model.meta.scale == "week" || this.model.meta.scale == "month"; + }, - for (const record of Object.items(records)) { - if (record) { - // TODO filter date and maybe employee id? - record_ids.push(record.id); - } - } + // tell if any record is still draft + get anyDraftWorkentry() { + return this.filteredRecords.length != 0; + }, - console.log(record_ids); + // get current draft records + get filteredRecords() { + return this.filterRecords( + this.model.data.records, + this.model.meta.scale, + this.model.meta.date, + "draft" + ); + }, - const result = await this.orm.call( - "hr.work.entry", - "action_validate", - [record_ids], - {} + // filter records based on current month / week and state + filterRecords(records, scale, date, state) { + const start = date.startOf(scale); + const stop = date.endOf(scale); + // filter records + return Object.values(records).filter( + (record) => + record.start > start && + record.end < stop && + record.rawRecord.state == state ); + }, - console.log(result); + // call action_validate on current records + async validateWorkentries() { + const record_ids = this.filteredRecords.map((r) => r.id); + console.log("Validating records", record_ids); + const success = await this.orm.call("hr.work.entry", "action_validate", [ + record_ids, + ]); + if (success) { + // refresh + this.model.env.searchModel.search(); + // notify success + this.notification.add(`${record_ids.length} entrées validées`, { + title: "Ok", + type: "success", + }); + } else { + // notify failure + this.notification.add("Les entrées n'ont pas pu être validées.", { + title: "Erreur", + type: "danger", + }); + } }, }); diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml index d788f5f1e9b..7f780418416 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml @@ -1,12 +1,9 @@ - - - - - - + + + From a555b70f8c4d2537eeb2f829097c1c355dac458c Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux Date: Tue, 4 Nov 2025 15:12:05 +0100 Subject: [PATCH 12/18] ajoute traductions --- hr_work_entry_validate/i18n/fr.po | 52 ++++++++++++------- .../views/calendar/calendar_controller.esm.js | 7 +-- .../views/calendar/calendar_controller.xml | 2 +- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/hr_work_entry_validate/i18n/fr.po b/hr_work_entry_validate/i18n/fr.po index cfc103f6eed..835d290ec72 100644 --- a/hr_work_entry_validate/i18n/fr.po +++ b/hr_work_entry_validate/i18n/fr.po @@ -4,10 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 17.0\n" +"Project-Id-Version: Odoo Server 18.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-05-27 10:00+0000\n" -"PO-Revision-Date: 2025-05-27 10:00+0000\n" +"POT-Creation-Date: 2025-11-04 14:09+0000\n" +"PO-Revision-Date: 2025-11-04 14:09+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -15,6 +15,12 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: hr_work_entry_validate +#. odoo-javascript +#: code:addons/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js:0 +msgid "%s work entries validated" +msgstr "%s entrées validées" + #. module: hr_work_entry_validate #: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form msgid "Hours" @@ -55,6 +61,12 @@ msgstr "Description" msgid "End" msgstr "Fin" +#. module: hr_work_entry_validate +#. odoo-javascript +#: code:addons/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js:0 +msgid "Error" +msgstr "Erreur" + #. module: hr_work_entry_validate #: model:ir.model,name:hr_work_entry_validate.model_hr_work_entry msgid "HR Work Entry" @@ -65,11 +77,6 @@ msgstr "Prestation RH" msgid "My Work Entries" msgstr "Mes prestations" -#. module: hr_work_entry_validate -#: model_terms:ir.actions.act_window,help:hr_work_entry_validate.hr_work_entry_action -msgid "No data to display" -msgstr "Aucune donnée à afficher" - #. module: hr_work_entry_validate #: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form msgid "Note: Validated work entries cannot be modified." @@ -83,8 +90,6 @@ msgstr "Recherche de prestation" #. module: hr_work_entry_validate #. odoo-python #: code:addons/hr_work_entry_validate/models/hr_work_entry.py:0 -#: code:addons/hr_work_entry_validate/models/hr_work_entry.py:0 -#, python-format msgid "" "Some entries are in conflict and cannot be validated, please solve conflicts" " first." @@ -103,18 +108,21 @@ msgid "This work entry cannot be validated. The work entry type is undefined." msgstr "Cette prestation ne peut pas être validée. Son type est inconnu." #. module: hr_work_entry_validate -#: model_terms:ir.actions.act_window,help:hr_work_entry_validate.hr_work_entry_action -msgid "" -"Try to add some records, or make sure that there is no active filter in the " -"search bar." +#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search +msgid "Type" msgstr "" -"Essayez d'ajouter quelques entrées, ou assurez-vous qu'il n'y a pas de filtre actif " -"dans la barre de recherche." #. module: hr_work_entry_validate -#: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_search -msgid "Type" -msgstr "Type" +#. odoo-javascript +#: code:addons/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml:0 +msgid "Validate period" +msgstr "Valider la période" + +#. module: hr_work_entry_validate +#. odoo-javascript +#: code:addons/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml:0 +msgid "Validate period work entries" +msgstr "Valider les entrées de la période en cours" #. module: hr_work_entry_validate #: model:ir.actions.server,name:hr_work_entry_validate.action_validate_work_entries @@ -137,3 +145,9 @@ msgstr "Prestation" #: model_terms:ir.ui.view,arch_db:hr_work_entry_validate.hr_work_entry_view_form msgid "Work Entry Name" msgstr "Nom de la prestation" + +#. module: hr_work_entry_validate +#. odoo-javascript +#: code:addons/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js:0 +msgid "Work entries could not be validated." +msgstr "Les entrées n'ont pas pu être validées." diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js index fcbad3d8234..bd684b71423 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js @@ -1,6 +1,7 @@ import { patch } from "@web/core/utils/patch"; import { CalendarController } from "@web/views/calendar/calendar_controller"; import { useService } from "@web/core/utils/hooks"; +import { _t } from "@web/core/l10n/translation"; patch(CalendarController.prototype, { // just log this @@ -54,14 +55,14 @@ patch(CalendarController.prototype, { // refresh this.model.env.searchModel.search(); // notify success - this.notification.add(`${record_ids.length} entrées validées`, { + this.notification.add(_t("%s work entries validated", record_ids.length), { title: "Ok", type: "success", }); } else { // notify failure - this.notification.add("Les entrées n'ont pas pu être validées.", { - title: "Erreur", + this.notification.add(_t("Work entries could not be validated."), { + title: _t("Error"), type: "danger", }); } diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml index 7f780418416..1396b7451ce 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml @@ -3,7 +3,7 @@ - + From de18fe7cedef0170820d645955aee5b40acf1af1 Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux Date: Tue, 4 Nov 2025 15:41:45 +0100 Subject: [PATCH 13/18] prefix with workEntry to avoid any collision --- .../views/calendar/calendar_controller.esm.js | 19 +++++++++---------- .../views/calendar/calendar_controller.xml | 4 ++-- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js index bd684b71423..c7b10c94136 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js @@ -4,26 +4,25 @@ import { useService } from "@web/core/utils/hooks"; import { _t } from "@web/core/l10n/translation"; patch(CalendarController.prototype, { - // just log this setup() { super.setup(...arguments); this.notification = useService("notification"); - console.log(this); + // console.log(this); }, // only display button if month or week - get displayButton() { + get workEntryDisplayButton() { return this.model.meta.scale == "week" || this.model.meta.scale == "month"; }, // tell if any record is still draft - get anyDraftWorkentry() { - return this.filteredRecords.length != 0; + get workEntryAnyDraft() { + return this.workEntryFilteredRecords.length != 0; }, // get current draft records - get filteredRecords() { - return this.filterRecords( + get workEntryFilteredRecords() { + return this.workEntryFilterRecords( this.model.data.records, this.model.meta.scale, this.model.meta.date, @@ -32,7 +31,7 @@ patch(CalendarController.prototype, { }, // filter records based on current month / week and state - filterRecords(records, scale, date, state) { + workEntryFilterRecords(records, scale, date, state) { const start = date.startOf(scale); const stop = date.endOf(scale); // filter records @@ -45,8 +44,8 @@ patch(CalendarController.prototype, { }, // call action_validate on current records - async validateWorkentries() { - const record_ids = this.filteredRecords.map((r) => r.id); + async workEntryValidate() { + const record_ids = this.workEntryFilteredRecords.map((r) => r.id); console.log("Validating records", record_ids); const success = await this.orm.call("hr.work.entry", "action_validate", [ record_ids, diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml index 1396b7451ce..d55a8ddd5e8 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml @@ -2,8 +2,8 @@ - - + + From 488ff1f9afffc538cba820589de42e202c5060ae Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux Date: Wed, 5 Nov 2025 11:45:18 +0100 Subject: [PATCH 14/18] refac to create new view rather than patch existing --- .../views/calendar/calendar_controller.esm.js | 62 +++++++++++-------- .../views/calendar/calendar_controller.xml | 8 +-- .../views/hr_work_entry_views.xml | 1 + 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js index c7b10c94136..c3667e56205 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js @@ -1,51 +1,48 @@ -import { patch } from "@web/core/utils/patch"; -import { CalendarController } from "@web/views/calendar/calendar_controller"; +import { registry } from "@web/core/registry"; import { useService } from "@web/core/utils/hooks"; import { _t } from "@web/core/l10n/translation"; +import { WorkEntryCalendarView, WorkEntryCalendarController } from "@hr_work_entry_contract/views/work_entry_calendar/work_entry_calendar_controller"; -patch(CalendarController.prototype, { +export class ValidateWorkEntryCalendarController extends WorkEntryCalendarController { setup() { super.setup(...arguments); this.notification = useService("notification"); // console.log(this); - }, + } // only display button if month or week - get workEntryDisplayButton() { + get displayValidateButton() { return this.model.meta.scale == "week" || this.model.meta.scale == "month"; - }, + } // tell if any record is still draft - get workEntryAnyDraft() { - return this.workEntryFilteredRecords.length != 0; - }, + get anyDraft() { + return this.filteredRecords.length != 0; + } // get current draft records - get workEntryFilteredRecords() { - return this.workEntryFilterRecords( + get filteredRecords() { + return this.filterRecords( this.model.data.records, - this.model.meta.scale, - this.model.meta.date, "draft" ); - }, + } // filter records based on current month / week and state - workEntryFilterRecords(records, scale, date, state) { - const start = date.startOf(scale); - const stop = date.endOf(scale); + filterRecords(records, state) { + const {start, end} = this.model.computeRange() // filter records return Object.values(records).filter( (record) => record.start > start && - record.end < stop && + record.end < end && record.rawRecord.state == state ); - }, + } // call action_validate on current records - async workEntryValidate() { - const record_ids = this.workEntryFilteredRecords.map((r) => r.id); + async validate() { + const record_ids = this.filteredRecords.map((r) => r.id); console.log("Validating records", record_ids); const success = await this.orm.call("hr.work.entry", "action_validate", [ record_ids, @@ -54,10 +51,13 @@ patch(CalendarController.prototype, { // refresh this.model.env.searchModel.search(); // notify success - this.notification.add(_t("%s work entries validated", record_ids.length), { - title: "Ok", - type: "success", - }); + this.notification.add( + _t("%s work entries validated", record_ids.length), + { + title: "Ok", + type: "success", + } + ); } else { // notify failure this.notification.add(_t("Work entries could not be validated."), { @@ -65,5 +65,13 @@ patch(CalendarController.prototype, { type: "danger", }); } - }, -}); + } +} + +export const ValidateWorkEntryCalendarView = { + ...WorkEntryCalendarView, + Controller: ValidateWorkEntryCalendarController, + buttonTemplate: "hr_work_entry_validate.calendar.controlButtons", +}; + +registry.category("views").add("validate_work_entries_calendar", ValidateWorkEntryCalendarView); diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml index d55a8ddd5e8..89084d51db4 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml @@ -1,10 +1,8 @@ - - - - - + + + diff --git a/hr_work_entry_validate/views/hr_work_entry_views.xml b/hr_work_entry_validate/views/hr_work_entry_views.xml index 4caf4147d10..204e35293c8 100644 --- a/hr_work_entry_validate/views/hr_work_entry_views.xml +++ b/hr_work_entry_validate/views/hr_work_entry_views.xml @@ -12,6 +12,7 @@ quick_create="0" color="color" event_limit="5" + js_class="validate_work_entries_calendar" > From 4f8ffa8234eed7ee41b838a469c3464002916ef3 Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux Date: Wed, 5 Nov 2025 11:49:12 +0100 Subject: [PATCH 15/18] pre-commit --- .../views/calendar/calendar_controller.esm.js | 125 +++++++++--------- .../views/calendar/calendar_controller.xml | 16 ++- 2 files changed, 75 insertions(+), 66 deletions(-) diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js index c3667e56205..58edc1feb23 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js @@ -1,77 +1,76 @@ -import { registry } from "@web/core/registry"; -import { useService } from "@web/core/utils/hooks"; -import { _t } from "@web/core/l10n/translation"; -import { WorkEntryCalendarView, WorkEntryCalendarController } from "@hr_work_entry_contract/views/work_entry_calendar/work_entry_calendar_controller"; +import {registry} from "@web/core/registry"; +import {useService} from "@web/core/utils/hooks"; +import {_t} from "@web/core/l10n/translation"; +import { + WorkEntryCalendarController, + WorkEntryCalendarView, +} from "@hr_work_entry_contract/views/work_entry_calendar/work_entry_calendar_controller"; export class ValidateWorkEntryCalendarController extends WorkEntryCalendarController { - setup() { - super.setup(...arguments); - this.notification = useService("notification"); - // console.log(this); - } + setup() { + super.setup(...arguments); + this.notification = useService("notification"); + // Console.log(this); + } - // only display button if month or week - get displayValidateButton() { - return this.model.meta.scale == "week" || this.model.meta.scale == "month"; - } + // Only display button if month or week + get displayValidateButton() { + return this.model.meta.scale == "week" || this.model.meta.scale == "month"; + } - // tell if any record is still draft - get anyDraft() { - return this.filteredRecords.length != 0; - } + // Tell if any record is still draft + get anyDraft() { + return this.filteredRecords.length != 0; + } - // get current draft records - get filteredRecords() { - return this.filterRecords( - this.model.data.records, - "draft" - ); - } + // Get current draft records + get filteredRecords() { + return this.filterRecords(this.model.data.records, "draft"); + } - // filter records based on current month / week and state - filterRecords(records, state) { - const {start, end} = this.model.computeRange() - // filter records - return Object.values(records).filter( - (record) => - record.start > start && - record.end < end && - record.rawRecord.state == state - ); - } + // Filter records based on current month / week and state + filterRecords(records, state) { + const {start, end} = this.model.computeRange(); + // Filter records + return Object.values(records).filter( + (record) => + record.start > start && + record.end < end && + record.rawRecord.state == state + ); + } - // call action_validate on current records - async validate() { - const record_ids = this.filteredRecords.map((r) => r.id); - console.log("Validating records", record_ids); - const success = await this.orm.call("hr.work.entry", "action_validate", [ - record_ids, - ]); - if (success) { - // refresh - this.model.env.searchModel.search(); - // notify success - this.notification.add( - _t("%s work entries validated", record_ids.length), - { - title: "Ok", - type: "success", + // Call action_validate on current records + async validate() { + const record_ids = this.filteredRecords.map((r) => r.id); + console.log("Validating records", record_ids); + const success = await this.orm.call("hr.work.entry", "action_validate", [ + record_ids, + ]); + if (success) { + // Refresh + this.model.env.searchModel.search(); + // Notify success + this.notification.add(_t("%s work entries validated", record_ids.length), { + title: "Ok", + type: "success", + }); + } else { + // Notify failure + this.notification.add(_t("Work entries could not be validated."), { + title: _t("Error"), + type: "danger", + }); } - ); - } else { - // notify failure - this.notification.add(_t("Work entries could not be validated."), { - title: _t("Error"), - type: "danger", - }); } - } } export const ValidateWorkEntryCalendarView = { - ...WorkEntryCalendarView, - Controller: ValidateWorkEntryCalendarController, - buttonTemplate: "hr_work_entry_validate.calendar.controlButtons", + ...WorkEntryCalendarView, + Controller: ValidateWorkEntryCalendarController, + buttonTemplate: "hr_work_entry_validate.calendar.controlButtons", }; -registry.category("views").add("validate_work_entries_calendar", ValidateWorkEntryCalendarView); +registry + .category("views") + .add("validate_work_entries_calendar", ValidateWorkEntryCalendarView); diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml index 89084d51db4..6cb1a661a7a 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml @@ -1,8 +1,18 @@ - + - + - + From 601b081514ec2d9e135f10ee1b4ea5e20adde7b6 Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux Date: Wed, 5 Nov 2025 11:53:21 +0100 Subject: [PATCH 16/18] pre-commit --- .../src/views/calendar/calendar_controller.esm.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js index 58edc1feb23..e49de61b964 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js @@ -1,10 +1,10 @@ -import {registry} from "@web/core/registry"; -import {useService} from "@web/core/utils/hooks"; -import {_t} from "@web/core/l10n/translation"; import { WorkEntryCalendarController, WorkEntryCalendarView, } from "@hr_work_entry_contract/views/work_entry_calendar/work_entry_calendar_controller"; +import {_t} from "@web/core/l10n/translation"; +import {registry} from "@web/core/registry"; +import {useService} from "@web/core/utils/hooks"; export class ValidateWorkEntryCalendarController extends WorkEntryCalendarController { setup() { @@ -15,12 +15,12 @@ export class ValidateWorkEntryCalendarController extends WorkEntryCalendarContro // Only display button if month or week get displayValidateButton() { - return this.model.meta.scale == "week" || this.model.meta.scale == "month"; + return this.model.meta.scale === "week" || this.model.meta.scale === "month"; } // Tell if any record is still draft get anyDraft() { - return this.filteredRecords.length != 0; + return this.filteredRecords.length !== 0; } // Get current draft records @@ -36,14 +36,14 @@ export class ValidateWorkEntryCalendarController extends WorkEntryCalendarContro (record) => record.start > start && record.end < end && - record.rawRecord.state == state + record.rawRecord.state === state ); } // Call action_validate on current records async validate() { const record_ids = this.filteredRecords.map((r) => r.id); - console.log("Validating records", record_ids); + // Console.log("Validating records", record_ids); const success = await this.orm.call("hr.work.entry", "action_validate", [ record_ids, ]); From 7eba2d0e32f4fbeef3a1dac3edcfed89895bf26c Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux Date: Wed, 5 Nov 2025 16:50:09 +0100 Subject: [PATCH 17/18] patch work entry calendar view instead of creating new hides button if user does not have rights eslint sort import fails but I do not understand why --- .../views/calendar/calendar_controller.esm.js | 40 ++++++++----------- .../views/calendar/calendar_controller.xml | 11 +++-- .../views/hr_work_entry_views.xml | 2 +- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js index e49de61b964..cb5cd40f4fe 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.esm.js @@ -1,32 +1,36 @@ -import { - WorkEntryCalendarController, - WorkEntryCalendarView, -} from "@hr_work_entry_contract/views/work_entry_calendar/work_entry_calendar_controller"; import {_t} from "@web/core/l10n/translation"; -import {registry} from "@web/core/registry"; +import {onWillStart} from "@odoo/owl"; +import {patch} from "@web/core/utils/patch"; +import {user} from "@web/core/user"; import {useService} from "@web/core/utils/hooks"; +import {WorkEntryCalendarController} from "@hr_work_entry_contract/views/work_entry_calendar/work_entry_calendar_controller"; -export class ValidateWorkEntryCalendarController extends WorkEntryCalendarController { +patch(WorkEntryCalendarController.prototype, { setup() { super.setup(...arguments); this.notification = useService("notification"); + this.isHrUser = false; // Console.log(this); - } + + onWillStart(async () => { + this.isHrUser = await user.hasGroup("hr.group_hr_user"); + }); + }, // Only display button if month or week get displayValidateButton() { return this.model.meta.scale === "week" || this.model.meta.scale === "month"; - } + }, // Tell if any record is still draft get anyDraft() { return this.filteredRecords.length !== 0; - } + }, // Get current draft records get filteredRecords() { return this.filterRecords(this.model.data.records, "draft"); - } + }, // Filter records based on current month / week and state filterRecords(records, state) { @@ -38,7 +42,7 @@ export class ValidateWorkEntryCalendarController extends WorkEntryCalendarContro record.end < end && record.rawRecord.state === state ); - } + }, // Call action_validate on current records async validate() { @@ -62,15 +66,5 @@ export class ValidateWorkEntryCalendarController extends WorkEntryCalendarContro type: "danger", }); } - } -} - -export const ValidateWorkEntryCalendarView = { - ...WorkEntryCalendarView, - Controller: ValidateWorkEntryCalendarController, - buttonTemplate: "hr_work_entry_validate.calendar.controlButtons", -}; - -registry - .category("views") - .add("validate_work_entries_calendar", ValidateWorkEntryCalendarView); + }, +}); diff --git a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml index 6cb1a661a7a..846667a2abd 100644 --- a/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml +++ b/hr_work_entry_validate/static/src/views/calendar/calendar_controller.xml @@ -1,11 +1,14 @@ - + + isHrUser + + +