From 0712b78dc9bd8cff63b44ad2f149d3f4745d374f Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Sun, 21 Feb 2021 07:10:53 +0100 Subject: [PATCH 01/10] [ADD] hr_timesheet_portal --- hr_timesheet_portal/README.rst | 85 +++++++++++ hr_timesheet_portal/__init__.py | 1 + hr_timesheet_portal/__manifest__.py | 26 ++++ .../demo/hr_timesheet_portal.xml | 11 ++ hr_timesheet_portal/readme/CONFIGURE.rst | 3 + hr_timesheet_portal/readme/CONTRIBUTORS.rst | 1 + hr_timesheet_portal/readme/DESCRIPTION.rst | 1 + .../readme/newsfragments/.gitkeep | 0 .../security/hr_timesheet_portal_security.xml | 33 +++++ .../security/ir.model.access.csv | 3 + .../static/src/css/hr_timesheet_portal.css | 43 ++++++ .../static/src/js/hr_timesheet_portal.js | 134 ++++++++++++++++++ hr_timesheet_portal/templates/assets.xml | 16 +++ hr_timesheet_portal/templates/portal.xml | 36 +++++ 14 files changed, 393 insertions(+) create mode 100644 hr_timesheet_portal/README.rst create mode 100644 hr_timesheet_portal/__init__.py create mode 100644 hr_timesheet_portal/__manifest__.py create mode 100644 hr_timesheet_portal/demo/hr_timesheet_portal.xml create mode 100644 hr_timesheet_portal/readme/CONFIGURE.rst create mode 100644 hr_timesheet_portal/readme/CONTRIBUTORS.rst create mode 100644 hr_timesheet_portal/readme/DESCRIPTION.rst create mode 100644 hr_timesheet_portal/readme/newsfragments/.gitkeep create mode 100644 hr_timesheet_portal/security/hr_timesheet_portal_security.xml create mode 100644 hr_timesheet_portal/security/ir.model.access.csv create mode 100644 hr_timesheet_portal/static/src/css/hr_timesheet_portal.css create mode 100644 hr_timesheet_portal/static/src/js/hr_timesheet_portal.js create mode 100644 hr_timesheet_portal/templates/assets.xml create mode 100644 hr_timesheet_portal/templates/portal.xml diff --git a/hr_timesheet_portal/README.rst b/hr_timesheet_portal/README.rst new file mode 100644 index 000000000..bffa4226f --- /dev/null +++ b/hr_timesheet_portal/README.rst @@ -0,0 +1,85 @@ +=========================== +Timesheet portal (editable) +=========================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Ftimesheet-lightgray.png?logo=github + :target: https://github.com/OCA/timesheet/tree/12.0/hr_timesheet_portal + :alt: OCA/timesheet +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/timesheet-12-0/timesheet-12-0-hr_timesheet_portal + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/117/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows portal users to edit their timesheets via the frontend. + +.. 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: + +Configuration +============= + +To configure this module, you need to: + +#. Add users to the group `Editable timesheets`. If you want all portal users be able to edit timesheets, add the group as an implied group of the `Portal` group + +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Hunki Enterprises BV + +Contributors +~~~~~~~~~~~~ + +* Holger Brunn (https://hunki-enterprises.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. + +This module is part of the `OCA/timesheet `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_timesheet_portal/__init__.py b/hr_timesheet_portal/__init__.py new file mode 100644 index 000000000..ef5ae3587 --- /dev/null +++ b/hr_timesheet_portal/__init__.py @@ -0,0 +1 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). diff --git a/hr_timesheet_portal/__manifest__.py b/hr_timesheet_portal/__manifest__.py new file mode 100644 index 000000000..80b5bb132 --- /dev/null +++ b/hr_timesheet_portal/__manifest__.py @@ -0,0 +1,26 @@ +# Copyright 2021 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Timesheet portal (editable)", + "summary": "Fill in timesheets via the portal", + "version": "12.0.1.0.0", + "development_status": "Alpha", + "category": "Website", + "website": "https://github.com/OCA/hr-timesheet", + "author": "Hunki Enterprises BV, Odoo Community Association (OCA)", + "license": "AGPL-3", + "depends": [ + "hr_timesheet", + "portal", + "website", + ], + "data": [ + "templates/assets.xml", + "templates/portal.xml", + "security/hr_timesheet_portal_security.xml", + "security/ir.model.access.csv", + ], + "demo": [ + "demo/hr_timesheet_portal.xml", + ], +} diff --git a/hr_timesheet_portal/demo/hr_timesheet_portal.xml b/hr_timesheet_portal/demo/hr_timesheet_portal.xml new file mode 100644 index 000000000..ee730e337 --- /dev/null +++ b/hr_timesheet_portal/demo/hr_timesheet_portal.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/hr_timesheet_portal/readme/CONFIGURE.rst b/hr_timesheet_portal/readme/CONFIGURE.rst new file mode 100644 index 000000000..8688936ce --- /dev/null +++ b/hr_timesheet_portal/readme/CONFIGURE.rst @@ -0,0 +1,3 @@ +To configure this module, you need to: + +#. Add users to the group `Editable timesheets`. If you want all portal users be able to edit timesheets, add the group as an implied group of the `Portal` group diff --git a/hr_timesheet_portal/readme/CONTRIBUTORS.rst b/hr_timesheet_portal/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..33b6eb2c3 --- /dev/null +++ b/hr_timesheet_portal/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Holger Brunn (https://hunki-enterprises.com) diff --git a/hr_timesheet_portal/readme/DESCRIPTION.rst b/hr_timesheet_portal/readme/DESCRIPTION.rst new file mode 100644 index 000000000..ad249353a --- /dev/null +++ b/hr_timesheet_portal/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module allows portal users to edit their timesheets via the frontend. diff --git a/hr_timesheet_portal/readme/newsfragments/.gitkeep b/hr_timesheet_portal/readme/newsfragments/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/hr_timesheet_portal/security/hr_timesheet_portal_security.xml b/hr_timesheet_portal/security/hr_timesheet_portal_security.xml new file mode 100644 index 000000000..b7492af81 --- /dev/null +++ b/hr_timesheet_portal/security/hr_timesheet_portal_security.xml @@ -0,0 +1,33 @@ + + + + + + + Editable timesheets + + Add portal users who should be allowed to edit their timesheets + + + + + [ + '|', + '&', + ('task_id.project_id.privacy_visibility', '=', 'portal'), + ('task_id.project_id.message_partner_ids', 'child_of', [user.partner_id.commercial_partner_id.id]), + '&', + ('task_id.project_id.privacy_visibility', '=', 'portal'), + ('task_id.message_partner_ids', 'child_of', [user.partner_id.commercial_partner_id.id]), + ] + + + + + + [(0, '=', 1)] + + + + diff --git a/hr_timesheet_portal/security/ir.model.access.csv b/hr_timesheet_portal/security/ir.model.access.csv new file mode 100644 index 000000000..7c63d9949 --- /dev/null +++ b/hr_timesheet_portal/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +crud_account_analytic_line,CRUD analytic lines,analytic.model_account_analytic_line,group_hr_timesheet_portal,1,1,1,1 +read_hr_employee,Read employees,hr.model_hr_employee,group_hr_timesheet_portal,1,0,0,0 diff --git a/hr_timesheet_portal/static/src/css/hr_timesheet_portal.css b/hr_timesheet_portal/static/src/css/hr_timesheet_portal.css new file mode 100644 index 000000000..b2d3541eb --- /dev/null +++ b/hr_timesheet_portal/static/src/css/hr_timesheet_portal.css @@ -0,0 +1,43 @@ +/* Copyright 2021 Hunki Enterprises BV + * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */ + +div.hr_timesheet_portal h5 i,div.hr_timesheet_portal tr i, div.hr_timesheet_portal tr:hover.edit i { + display: none; +} +div.hr_timesheet_portal:hover h5 i { + display: inline-block; + cursor: pointer; +} +div.hr_timesheet_portal tr[data-line-id]:hover { + cursor: pointer; +} +div.hr_timesheet_portal tr[data-line-id]:hover i { + display: block; + cursor: pointer; + position: absolute; + top: .3em; + background: #fff; + padding: .3em; +} +div.hr_timesheet_portal tr[data-line-id]:hover i.fa-remove { + right: .2em; +} +div.hr_timesheet_portal tr[data-line-id]:hover i.fa-edit { + left: .2em; +} +div.hr_timesheet_portal tr[data-line-id] td { + position: relative; +} +div.hr_timesheet_portal tr form { + display: inline-block; +} +div.hr_timesheet_portal tr form button { + margin-left: .2em; +} +div.hr_timesheet_portal tr td { + vertical-align: middle; +} +div.hr_timesheet_portal tr input[name="unit_amount"] { + width: 5em; + display: inline-block; +} diff --git a/hr_timesheet_portal/static/src/js/hr_timesheet_portal.js b/hr_timesheet_portal/static/src/js/hr_timesheet_portal.js new file mode 100644 index 000000000..3db87fc28 --- /dev/null +++ b/hr_timesheet_portal/static/src/js/hr_timesheet_portal.js @@ -0,0 +1,134 @@ +/* Copyright 2021 Hunki Enterprises BV + * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */ + +odoo.define('hr_timesheet_portal', function(require){ + "use strict"; + + var sAnimation = require('website.content.snippets.animation'), + rpc = require('web.rpc'), + core = require('web.core'), + _t = core._t; + + sAnimation.registry.hr_timesheet_portal = sAnimation.Class.extend({ + selector: 'div.hr_timesheet_portal', + events: { + 'click h5': '_onclick_add', + 'click tr[data-line-id]:not(.edit)': '_onclick_edit', + 'click i.fa-remove': '_onclick_delete', + 'click button.submit': '_onclick_submit', + 'submit form': '_onclick_submit', + 'click button.cancel': '_reload_timesheet', + }, + + start: function (editable_mode) { + if (editable_mode) { + this.stop(); + return; + } + }, + + _onclick_delete: function (e) { + e.stopPropagation(); + rpc.query({ + model: 'account.analytic.line', + method: 'unlink', + args: [[jQuery(e.currentTarget).parents('tr').data('line-id')]] + }) + .done(this.proxy('_reload_timesheet')) + .fail(this.proxy('_display_failure')); + }, + + _onclick_add: function (e) { + var self = this; + return rpc.query({ + model: 'account.analytic.line', + method: 'create', + args: [{ + user_id: this.getSession().user_id, + account_id: this.$el.data('account-id'), + project_id: this.$el.data('project-id'), + task_id: this.$el.data('task-id'), + unit_amount: 0, + name: '/', + }], + }) + .done(function (line_id) { + return self._reload_timesheet().then(function () { + setTimeout(self._edit_line.bind(self, line_id), 0); + }); + }) + .fail(this.proxy('_display_failure')); + }, + + _onclick_edit: function (e) { + return this._edit_line(jQuery(e.target).parents('tr').data('line-id')); + }, + + _onclick_submit: function (e) { + e.preventDefault(); + var $tr = jQuery(e.target).parents('tr'), + data = _.object(_.map($tr.find('form').serializeArray(), function(a) { + return [a.name, a.value] + })); + return rpc.query({ + model: 'account.analytic.line', + method: 'write', + args: [$tr.data('line-id'), data], + }) + .done(this.proxy('_reload_timesheet')) + .fail(this.proxy('_display_failure')); + + }, + + _reload_timesheet: function () { + var self = this; + this.$el.children('div.alert').remove(); + return $.ajax({ + dataType: 'html', + }).then(function (data) { + var timesheets = _.filter(jQuery.parseHTML(data), function (element) { + return jQuery(element).find('div.hr_timesheet_portal').length > 0; + }), $tbody = jQuery(timesheets).find('tbody'); + return self.$('tbody').replaceWith($tbody); + }); + }, + + _display_failure: function (error) { + this.$el.prepend(jQuery('
').text(error.data.message)); + this.$el.prepend(jQuery('
').text(error.message)); + }, + + _edit_line (line_id) { + var $line = this.$(_.str.sprintf('tr[data-line-id=%s]', line_id)), + $edit_line = $line.clone(); + this.$('tbody tr.edit').remove(); + this.$('tbody tr').show(); + $line.before($edit_line) + $edit_line.children('[data-field-name]').each(function () { + var $this = jQuery(this), + $input = jQuery('', { + class: 'form-control', + type: $this.data('field-type') || 'text', + value: $this.data('field-value') || $this.text(), + form: 'hr_timesheet_portal_form', + name: $this.data('field-name'), + }); + $this.empty().append($input); + }); + $edit_line.addClass('edit'); + var $form = jQuery('
', { + id: 'hr_timesheet_portal_form', + }), $submit = jQuery('