Compare commits
27 Commits
14.0-proje
...
16.0-proje
Author | SHA1 | Date | |
---|---|---|---|
|
5d74a26247 | ||
|
93a6768716 | ||
|
16c1da3c42 | ||
|
792c3d602a | ||
|
a06cd29014 | ||
|
e9ec522405 | ||
|
6dc94c02fa | ||
|
0e36b3d9e3 | ||
|
a240b6cf71 | ||
|
2cd17ce8ef | ||
|
eb85069ff8 | ||
|
38e12ee2ed | ||
|
15b21771dd | ||
|
e6595ec6f7 | ||
45e38de4ff | |||
1a342d3b8b | |||
0bff01ad76 | |||
cd884b967e | |||
22a703d9bd | |||
|
250ef5b5ec | ||
|
77b26fd755 | ||
|
5a30d61fee | ||
|
da60ebb310 | ||
|
c3cc59cec7 | ||
|
cd663ec6e5 | ||
|
34dfc13936 | ||
|
355e77fc70 |
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "project_assignees",
|
||||
"version": "14.0.1.0.0",
|
||||
"version": "16.0.1.1.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://github.com/elabore-coop/project-tools",
|
||||
"maintainer": "Stéphan Sainléger",
|
||||
@@ -69,6 +69,7 @@ This module is maintained by Elabore.
|
||||
"depends": [
|
||||
"base",
|
||||
"project",
|
||||
"project_task_portal_form",
|
||||
],
|
||||
"qweb": [
|
||||
# "static/src/xml/*.xml",
|
||||
|
@@ -4,10 +4,10 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 14.0\n"
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-07-26 07:38+0000\n"
|
||||
"PO-Revision-Date: 2022-07-26 07:38+0000\n"
|
||||
"POT-Creation-Date: 2023-11-02 07:56+0000\n"
|
||||
"PO-Revision-Date: 2023-11-02 07:56+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,17 +16,21 @@ msgstr ""
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: project_assignees
|
||||
#: model_terms:ir.ui.view,arch_db:project_assignees.portal_my_task_timebox
|
||||
msgid "<strong>Other assignements</strong>"
|
||||
#: model_terms:ir.ui.view,arch_db:project_assignees.portal_my_task_assignees
|
||||
msgid "<strong>Other assignees</strong>"
|
||||
msgstr "<strong>Autres intervenants</strong>"
|
||||
|
||||
#. module: project_assignees
|
||||
#: model:ir.model.fields,field_description:project_assignees.field_project_task__assignee_ids |
|
||||
msgid "Assignees" |
|
||||
#: model:ir.model.fields,field_description:project_assignees.field_project_task__assignee_ids
|
||||
msgid "Assignees"
|
||||
msgstr "Autres assignations"
|
||||
|
||||
#. module: project_assignees
|
||||
#: model_terms:ir.ui.view,arch_db:project_assignees.portal_my_task_assignees
|
||||
msgid "Contact"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_assignees
|
||||
#: model:ir.model,name:project_assignees.model_project_task
|
||||
msgid "Task"
|
||||
msgstr "Tâche"
|
||||
|
||||
msgstr "Tâche"
|
@@ -1,21 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_my_task_assignees" name="My Task: Assignees" inherit_id="project.portal_my_task" priority="40">
|
||||
<xpath expr="//div[hasclass('flex-grow-0')]/../../.." position="inside">
|
||||
<div class="col-12 col-md-6 pb-2" t-if="task.assignee_ids">
|
||||
<xpath expr="//t[@t-foreach='task.user_ids']" position="after">
|
||||
<div class="col-12 col-md-12 pb-2" t-if="task.assignee_ids">
|
||||
<strong>Other assignees</strong>
|
||||
<div class="row">
|
||||
<t t-foreach="task.assignee_ids" t-as="assignee">
|
||||
<div class="col flex-grow-0 pr-3">
|
||||
<img t-if="assignee.image" class="rounded-circle mt-1 o_portal_contact_img" t-att-src="image_data_uri(assignee.image)" alt="Contact" />
|
||||
<img t-else="" class="rounded-circle mt-1 o_portal_contact_img" src="/web/static/src/img/user_menu_avatar.png" alt="Contact" />
|
||||
</div>
|
||||
<div class="col pl-md-0">
|
||||
<strong>
|
||||
<span t-field="assignee.name" />
|
||||
</strong>
|
||||
<span t-field="assignee.email" />
|
||||
<span t-field="assignee.phone" />
|
||||
<t t-foreach="task.assignee_ids" t-as="user">
|
||||
<div class="d-flex mb-3 flex-nowrap">
|
||||
<img class="rounded-circle mt-1 o_portal_contact_img" t-att-src="image_data_uri(user.avatar_1024)" alt="Contact"/>
|
||||
<div class="ms-2">
|
||||
<div t-esc="user" t-options='{"widget": "contact", "fields": ["name"]}'/>
|
||||
<a t-attf-href="tel:{{user.phone}}" t-if="user.phone"><div t-esc="user" t-options='{"widget": "contact", "fields": ["phone"]}'/></a>
|
||||
<a t-if="user.email" class="text-break" t-attf-href="mailto:{{user.email}}">
|
||||
<div t-out="user" t-options='{"widget": "contact", "fields": ["email"]}'/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<field name="inherit_id" ref="project.view_task_form2" />
|
||||
<field name="priority" eval="99" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='user_id']" position="after">
|
||||
<xpath expr="//field[@name='user_ids']" position="after">
|
||||
<field name="assignee_ids" widget="many2many_tags" />
|
||||
</xpath>
|
||||
</field>
|
||||
@@ -19,8 +19,11 @@
|
||||
<field name="priority" eval="99" />
|
||||
<field name="arch" type="xml">
|
||||
<filter name="my_tasks" position="attributes">
|
||||
<attribute name="domain">['|', ('user_id', '=', uid), ('assignee_ids', 'in', uid)]</attribute>
|
||||
<attribute name="domain">['|', ('user_ids', 'in', uid), ('assignee_ids', 'in', uid)]</attribute>
|
||||
</filter>
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="assignee_ids" filter_domain="[('assignee_ids.user_ids.name', 'ilike', self)]"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
@@ -1,14 +1,14 @@
|
||||
==============================
|
||||
project_timesheet_funding_wish
|
||||
==============================
|
||||
=================
|
||||
project_assignees
|
||||
=================
|
||||
|
||||
Add a funding wish select field to timesheet line.
|
||||
Add multiple assignees field to project task
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Use Odoo normal procedure to install add-ons to install
|
||||
``project_timesheet_funding_wish``.
|
||||
``project_assignees``.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
@@ -16,8 +16,9 @@ Known issues / Roadmap
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `our issues website <https://github.com/elabore-coop/project-tools/issues>`_. In
|
||||
case of trouble, please check there if your issue has already been
|
||||
Bugs are tracked on `our issues website
|
||||
<https://github.com/elabore-coop/project-tools/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.
|
||||
|
||||
@@ -31,8 +32,6 @@ Images
|
||||
Contributors
|
||||
------------
|
||||
* Stéphan Sainléger <https://github.com/stephansainleger>
|
||||
* Valentin Lab <valentin.lab@kalysto.org>
|
||||
* Nicolas Jeudy <https://github.com/njeudy>
|
||||
|
||||
Funders
|
||||
-------
|
||||
@@ -42,6 +41,5 @@ The development of this module has been financially supported by:
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
This module is maintained by Elabore.
|
||||
|
||||
|
||||
This module is maintained by Elabore.
|
3
project_average_acceptable_time/__init__.py
Normal file
3
project_average_acceptable_time/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import models, controllers
|
@@ -2,38 +2,40 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "project_timesheet_funding_wish",
|
||||
"version": "14.0.1.0.0",
|
||||
"name": "project_average_acceptable_time",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://github.com/elabore-coop/project-tools",
|
||||
"maintainer": "Stéphan Sainléger",
|
||||
"maintainer": "Clément Thomas",
|
||||
"license": "AGPL-3",
|
||||
"category": "Tools",
|
||||
"summary": "Add a funding wish select field to timesheet line.",
|
||||
"summary": "Task validation without customer agreement",
|
||||
"description": """
|
||||
:image: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
==============================
|
||||
project_timesheet_funding_wish
|
||||
==============================
|
||||
=================
|
||||
project_average_acceptable_time
|
||||
=================
|
||||
|
||||
|
||||
Add a funding wish select field to timesheet line.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Use Odoo normal procedure to install add-ons to install
|
||||
``project_timesheet_funding_wish``.
|
||||
Install ``project_average_acceptable_time``, all dependencies will be installed by default.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
None yet.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `our issues website <https://github.com/elabore-coop/project-tools/issues>`_. In
|
||||
case of trouble, please check there if your issue has already been
|
||||
Bugs are tracked on `our issues website
|
||||
<https://github.com/elabore-coop/project-tools/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.
|
||||
|
||||
@@ -42,16 +44,17 @@ Credits
|
||||
|
||||
Images
|
||||
------
|
||||
|
||||
* Elabore: `Icon <https://elabore.coop/web/image/res.company/1/logo?unique=f3db262>`_.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
* Stéphan Sainléger <https://github.com/stephansainleger>
|
||||
* Valentin Lab <valentin.lab@kalysto.org>
|
||||
* Nicolas Jeudy <https://github.com/njeudy>
|
||||
|
||||
* Clément Thomas
|
||||
|
||||
Funders
|
||||
-------
|
||||
|
||||
The development of this module has been financially supported by:
|
||||
* Elabore (https://elabore.coop)
|
||||
|
||||
@@ -64,7 +67,8 @@ This module is maintained by Elabore.
|
||||
# any module necessary for this one to work correctly
|
||||
"depends": [
|
||||
"base",
|
||||
"hr_timesheet",
|
||||
"project",
|
||||
"project_user_default_project"
|
||||
],
|
||||
"qweb": [
|
||||
# "static/src/xml/*.xml",
|
||||
@@ -74,7 +78,8 @@ This module is maintained by Elabore.
|
||||
},
|
||||
# always loaded
|
||||
"data": [
|
||||
"views/hr_timesheet.xml",
|
||||
"views/project_project.xml",
|
||||
"views/portal_home_template.xml"
|
||||
],
|
||||
# only loaded in demonstration mode
|
||||
"demo": [],
|
2
project_average_acceptable_time/controllers/__init__.py
Normal file
2
project_average_acceptable_time/controllers/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
from . import custom_portal
|
21
project_average_acceptable_time/controllers/custom_portal.py
Normal file
21
project_average_acceptable_time/controllers/custom_portal.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# Copyright 2020 Lokavaluto ()
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo.http import request, route
|
||||
from odoo.addons.portal.controllers.portal import CustomerPortal
|
||||
|
||||
|
||||
class CustomCustomerPortal(CustomerPortal):
|
||||
@route(["/my/account"], type="http", auth="user", website=True)
|
||||
def account(self, redirect=None, **post):
|
||||
self.OPTIONAL_BILLING_FIELDS.append("average_acceptable_time") #unecessary save in res partner, but necessary to avoid error on form post
|
||||
|
||||
response = super(CustomCustomerPortal, self).account(redirect, **post)
|
||||
|
||||
if post and request.httprequest.method == "POST":
|
||||
error, error_message = self.details_form_validate(post)
|
||||
if not error:
|
||||
user = request.env.user
|
||||
if user.default_project_id and post["average_acceptable_time"]:
|
||||
user.default_project_id.average_acceptable_time = post["average_acceptable_time"]
|
||||
|
||||
return response
|
46
project_average_acceptable_time/i18n/fr.po
Normal file
46
project_average_acceptable_time/i18n/fr.po
Normal file
@@ -0,0 +1,46 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * project_average_acceptable_time
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-03-31 09:33+0000\n"
|
||||
"PO-Revision-Date: 2023-03-31 09:33+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: project_average_acceptable_time
|
||||
#: model_terms:ir.ui.view,arch_db:project_average_acceptable_time.portal_my_home_average_acceptable_time
|
||||
msgid "<b>Average acceptable time</b>:"
|
||||
msgstr "<b>Temps moyen acceptable</b>:"
|
||||
|
||||
#. module: project_average_acceptable_time
|
||||
#: model_terms:ir.ui.view,arch_db:project_average_acceptable_time.portal_my_home_average_acceptable_time
|
||||
msgid "Average acceptable time"
|
||||
msgstr "Temps moyen acceptable"
|
||||
|
||||
#. module: project_average_acceptable_time
|
||||
#: model_terms:ir.ui.view,arch_db:project_average_acceptable_time.project_project_view_kanban_inherit_average_acceptable_time
|
||||
msgid "<span>Average acceptable time:&nbsp;</span>"
|
||||
msgstr "<span>Temps moyen acceptable&nbsp;:&nbsp;</span>"
|
||||
|
||||
#. module: project_average_acceptable_time
|
||||
#: model:ir.model.fields,field_description:project_average_acceptable_time.field_project_project__average_acceptable_time
|
||||
msgid "Average acceptable time"
|
||||
msgstr "Temps moyen acceptable"
|
||||
|
||||
#. module: project_average_acceptable_time
|
||||
#: model_terms:ir.ui.view,arch_db:project_average_acceptable_time.portal_my_details_average_acceptable_time
|
||||
msgid "Average acceptable time (h)"
|
||||
msgstr "Temps moyen acceptable (h)"
|
||||
|
||||
#. module: project_average_acceptable_time
|
||||
#: model:ir.model,name:project_average_acceptable_time.model_project_project
|
||||
msgid "Project"
|
||||
msgstr "Projet"
|
3
project_average_acceptable_time/models/__init__.py
Normal file
3
project_average_acceptable_time/models/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
from . import project_project
|
||||
from . import res_partner
|
10
project_average_acceptable_time/models/project_project.py
Normal file
10
project_average_acceptable_time/models/project_project.py
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
from odoo import models, fields, _, api
|
||||
|
||||
|
||||
class Project(models.Model):
|
||||
_inherit = "project.project"
|
||||
|
||||
average_acceptable_time = fields.Float('Average acceptable time')
|
||||
|
||||
|
10
project_average_acceptable_time/models/res_partner.py
Normal file
10
project_average_acceptable_time/models/res_partner.py
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
from odoo import models, fields, _, api
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_inherit = "res.partner"
|
||||
|
||||
average_acceptable_time = fields.Float('Average acceptable time') # not used, but necessary to post custom field from /my/account
|
||||
|
||||
|
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Template /my/home -->
|
||||
<template id="portal_my_home_average_acceptable_time" name="Portal My Home: Average acceptable time" inherit_id="portal.portal_layout" priority="40">
|
||||
<xpath expr="//div[hasclass('o_portal_my_details')]" position="inside">
|
||||
<hr class="mt-1 mb-0"/>
|
||||
<b>Average acceptable time</b>: <t t-esc="user_id.default_project_id.average_acceptable_time" t-options="{'widget': 'float_time'}"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Template /my/account -->
|
||||
<template id="portal_my_details_average_acceptable_time" name="Portal My details: Average acceptable time" inherit_id="portal.portal_my_details">
|
||||
<xpath expr="//input[@name='redirect']" position="before">
|
||||
<div t-attf-class="form-group #{error.get('average_acceptable_time') and 'o_has_error' or ''} col-xl-6">
|
||||
<label class="col-form-label" for="average_acceptable_time">Average acceptable time (h)</label>
|
||||
<input
|
||||
type="text"
|
||||
name="average_acceptable_time"
|
||||
t-attf-class="form-control #{error.get('average_acceptable_time') and 'is-invalid' or ''}"
|
||||
t-att-value="average_acceptable_time or user_id.default_project_id.average_acceptable_time"
|
||||
t-options="{'widget': 'float_time'}"
|
||||
/>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
36
project_average_acceptable_time/views/project_project.xml
Normal file
36
project_average_acceptable_time/views/project_project.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
|
||||
<!--Project KANBAN -->
|
||||
<record id="project_project_view_kanban_inherit_average_acceptable_time" model="ir.ui.view">
|
||||
<field name="name">project.project.kanban.inherit.average.acceptable.time</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.view_project_kanban"/>
|
||||
<field name="priority">999</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@class='o_project_kanban_main ']" position="inside">
|
||||
<div class="o_project_kanban_boxes">
|
||||
<span>Average acceptable time:<![CDATA[ ]]></span>
|
||||
<field name="average_acceptable_time" widget="float_time"/>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Project FORM -->
|
||||
<record id="project_project_form_inherit_average_acceptable_time" model="ir.ui.view">
|
||||
<field name="name">project.project.form.inherit.average.acceptable.time</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.edit_project"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@id='subtask_settings']/div[@class='o_setting_right_pane']" position="inside">
|
||||
<div class="o_settings_average_acceptable_time" style="margin-top:10px;">
|
||||
<!-- <span>Average acceptable time:<![CDATA[ ]]></span> -->
|
||||
<label for="average_acceptable_time"/>
|
||||
<field name="average_acceptable_time" widget="float_time"/>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
43
project_disable_last_sol_as_sol_by_default/README.rst
Normal file
43
project_disable_last_sol_as_sol_by_default/README.rst
Normal file
@@ -0,0 +1,43 @@
|
||||
==========================================
|
||||
project_disable_last_sol_as_sol_by_default
|
||||
==========================================
|
||||
|
||||
If there is no sale order line in a task, do not add automaticly the last sol of customer as the sale order line by default
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Use Odoo normal module installation procedure to install ``project_disable_last_sol_as_sol_by_default``.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
None yet.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `our issues website <https://github.com/elabore-coop/project-tools/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.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Laetitia Da Costa (https://github.com/LaetitiaElabore)
|
||||
|
||||
Funders
|
||||
-------
|
||||
|
||||
The development of this module has been financially supported by:
|
||||
* Elabore (https://elabore.coop)
|
||||
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
This module is maintained by Elabore.
|
1
project_disable_last_sol_as_sol_by_default/__init__.py
Normal file
1
project_disable_last_sol_as_sol_by_default/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import models
|
37
project_disable_last_sol_as_sol_by_default/__manifest__.py
Normal file
37
project_disable_last_sol_as_sol_by_default/__manifest__.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# Copyright 2022 Stéphan Sainléger (Elabore)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "project_disable_last_sol_as_sol_by_default",
|
||||
"version": "14.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Laetitia Da Costa",
|
||||
"license": "AGPL-3",
|
||||
"category": "Project",
|
||||
"summary": "Do not add last sale order line automaticly as the sale order line by default in a task",
|
||||
# any module necessary for this one to work correctly
|
||||
"depends": [
|
||||
"base",
|
||||
"project",
|
||||
"sale_timesheet"
|
||||
],
|
||||
"qweb": [
|
||||
# "static/src/xml/*.xml",
|
||||
],
|
||||
"external_dependencies": {
|
||||
"python": [],
|
||||
},
|
||||
# always loaded
|
||||
"data": [
|
||||
],
|
||||
# only loaded in demonstration mode
|
||||
"demo": [],
|
||||
"js": [],
|
||||
"css": [],
|
||||
"installable": True,
|
||||
# Install this module automatically if all dependency have been previously
|
||||
# and independently installed. Used for synergetic or glue modules.
|
||||
"auto_install": False,
|
||||
"application": False,
|
||||
}
|
@@ -0,0 +1 @@
|
||||
from . import project_task
|
@@ -0,0 +1,7 @@
|
||||
from odoo import models
|
||||
|
||||
class Task(models.Model):
|
||||
_inherit = "project.task"
|
||||
|
||||
def _get_last_sol_of_customer(self):
|
||||
return False
|
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "project_funders",
|
||||
"version": "14.0.1.0.0",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Alusage",
|
||||
"website": "https://alusage.fr",
|
||||
"data": [
|
||||
|
47
project_link_from_invoice/README.rst
Normal file
47
project_link_from_invoice/README.rst
Normal file
@@ -0,0 +1,47 @@
|
||||
=================
|
||||
project_link_from_invoice
|
||||
=================
|
||||
|
||||
Easily access to your projects from invoices
|
||||
View project(s) in invoices tree view
|
||||
Access to related projects of an invoice from a button
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Use Odoo normal procedure to install add-ons to install
|
||||
``project_link_from_invoice``.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `our issues website
|
||||
<https://github.com/elabore-coop/project-tools/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.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Images
|
||||
------
|
||||
* Elabore: `Icon <https://elabore.coop/web/image/res.company/1/logo?unique=f3db262>`_.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
* Clément Thomas
|
||||
|
||||
Funders
|
||||
-------
|
||||
The development of this module has been financially supported by:
|
||||
* Elabore (https://elabore.coop)
|
||||
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
This module is maintained by Elabore.
|
2
project_link_from_invoice/__init__.py
Normal file
2
project_link_from_invoice/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
from . import models
|
93
project_link_from_invoice/__manifest__.py
Normal file
93
project_link_from_invoice/__manifest__.py
Normal file
@@ -0,0 +1,93 @@
|
||||
# Copyright 2022 Stéphan Sainléger (Elabore)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "project_link_from_invoice",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://github.com/elabore-coop/project-tools",
|
||||
"maintainer": "Clément Thomas",
|
||||
"license": "AGPL-3",
|
||||
"category": "Tools",
|
||||
"summary": "Add link from invoice to project",
|
||||
"description": """
|
||||
:image: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
=================
|
||||
project_link_from_invoice
|
||||
=================
|
||||
|
||||
Users can access to related project from invoices
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Install ``project_link_from_invoice``, all dependencies will be installed by default.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
None yet.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `our issues website
|
||||
<https://github.com/elabore-coop/project-tools/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.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Images
|
||||
------
|
||||
|
||||
* Elabore: `Icon <https://elabore.coop/web/image/res.company/1/logo?unique=f3db262>`_.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Clément Thomas <https://github.com/stephansainleger>
|
||||
|
||||
Funders
|
||||
-------
|
||||
|
||||
The development of this module has been financially supported by:
|
||||
* Elabore (https://elabore.coop)
|
||||
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
This module is maintained by Elabore.
|
||||
|
||||
""",
|
||||
# any module necessary for this one to work correctly
|
||||
"depends": [
|
||||
"base",
|
||||
"project",
|
||||
"account",
|
||||
"sale"
|
||||
],
|
||||
"qweb": [
|
||||
# "static/src/xml/*.xml",
|
||||
],
|
||||
"external_dependencies": {
|
||||
"python": [],
|
||||
},
|
||||
# always loaded
|
||||
"data": [
|
||||
"views/account_move_view.xml",
|
||||
],
|
||||
# only loaded in demonstration mode
|
||||
"demo": [],
|
||||
"js": [],
|
||||
"css": [],
|
||||
"installable": True,
|
||||
# Install this module automatically if all dependency have been previously
|
||||
# and independently installed. Used for synergetic or glue modules.
|
||||
"auto_install": False,
|
||||
"application": False,
|
||||
}
|
58
project_link_from_invoice/i18n/fr.po
Normal file
58
project_link_from_invoice/i18n/fr.po
Normal file
@@ -0,0 +1,58 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * project_link_from_invoice
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 14.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-04-27 12:47+0000\n"
|
||||
"PO-Revision-Date: 2023-04-27 12:47+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: project_link_from_invoice
|
||||
#: model:ir.model.fields,field_description:project_link_from_invoice.field_account_move__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nom affiché"
|
||||
|
||||
#. module: project_link_from_invoice
|
||||
#: model:ir.model.fields,field_description:project_link_from_invoice.field_account_move__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_link_from_invoice
|
||||
#: model:ir.model,name:project_link_from_invoice.model_account_move
|
||||
msgid "Journal Entry"
|
||||
msgstr "Pièce comptable"
|
||||
|
||||
#. module: project_link_from_invoice
|
||||
#: model:ir.model.fields,field_description:project_link_from_invoice.field_account_move____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Dernière modification le"
|
||||
|
||||
#. module: project_link_from_invoice
|
||||
#: model:ir.model.fields,field_description:project_link_from_invoice.field_account_bank_statement_line__project_ids
|
||||
#: model:ir.model.fields,field_description:project_link_from_invoice.field_account_move__project_ids
|
||||
#: model:ir.model.fields,field_description:project_link_from_invoice.field_account_payment__project_ids
|
||||
msgid "Project"
|
||||
msgstr "Projet"
|
||||
|
||||
#. module: project_link_from_invoice
|
||||
#: model:ir.model.fields,field_description:project_link_from_invoice.field_account_bank_statement_line__project_count
|
||||
#: model:ir.model.fields,field_description:project_link_from_invoice.field_account_move__project_count
|
||||
#: model:ir.model.fields,field_description:project_link_from_invoice.field_account_payment__project_count
|
||||
msgid "Project Count"
|
||||
msgstr "Numbre de projets"
|
||||
|
||||
#. module: project_link_from_invoice
|
||||
#: model_terms:ir.ui.view,arch_db:project_link_from_invoice.view_move_form_project_link_from_invoice_inherit
|
||||
#: model:ir.model.fields,field_description:project_link_from_invoice.field_account_bank_statement_line__projects_name
|
||||
#: model:ir.model.fields,field_description:project_link_from_invoice.field_account_move__projects_name
|
||||
#: model:ir.model.fields,field_description:project_link_from_invoice.field_account_payment__projects_name
|
||||
msgid "Project(s)"
|
||||
msgstr "Projet(s)"
|
2
project_link_from_invoice/models/__init__.py
Normal file
2
project_link_from_invoice/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
from . import account_move
|
38
project_link_from_invoice/models/account_move.py
Normal file
38
project_link_from_invoice/models/account_move.py
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class AccountMove(models.Model):
|
||||
_inherit = "account.move"
|
||||
|
||||
project_ids = fields.Many2many('project.project', name="Projects", compute='get_related_project_ids')
|
||||
project_count = fields.Integer("Project Count", compute='get_related_project_ids')
|
||||
projects_name = fields.Char('Project(s)', compute='get_related_project_ids')
|
||||
|
||||
def action_open_projects(self):
|
||||
'''
|
||||
Open related projects, in form or tree view depending on project numbers
|
||||
'''
|
||||
project_ids = self.project_ids.ids
|
||||
action = self.env["ir.actions.actions"]._for_xml_id("project.open_view_project_all")
|
||||
|
||||
if self.project_count == 1:
|
||||
action['res_id'] = project_ids[0]
|
||||
action['views'] = [[False, "form"]]
|
||||
else:
|
||||
action['views'] = [[False, "tree"], [False, "form"]]
|
||||
|
||||
action['domain'] = [('id', 'in', project_ids)]
|
||||
|
||||
del action['target'] #to display breadcrumbs
|
||||
|
||||
return action
|
||||
|
||||
|
||||
@api.depends('line_ids.sale_line_ids')
|
||||
def get_related_project_ids(self):
|
||||
for move in self:
|
||||
projects = self.env['project.task'].search([('sale_order_id','in',move.line_ids.sale_line_ids.order_id.ids)]).project_id
|
||||
move.project_ids = projects.ids
|
||||
move.projects_name = ' ; '.join([p.name for p in projects])
|
||||
move.project_count = len(projects)
|
32
project_link_from_invoice/views/account_move_view.xml
Normal file
32
project_link_from_invoice/views/account_move_view.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<record id="view_move_form_project_link_from_invoice_inherit" model="ir.ui.view">
|
||||
<field name="name">account.move.form.project.link</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="account.view_move_form" />
|
||||
<field name="priority" eval="99" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//header" position="inside">
|
||||
<button name="action_open_projects"
|
||||
string="Project(s)" class="oe_highlight" type="object" icon="fa-puzzle-piece"
|
||||
invisible="[]" attrs="{'invisible': [('project_count', '=', 0)]}" />
|
||||
</xpath>
|
||||
<xpath expr="//header" position="after">
|
||||
<field name="project_count" invisible="1" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_invoice_tree_project_link_from_invoice_inherit" model="ir.ui.view">
|
||||
<field name="name">account.invoice.tree.project.link</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="account.view_invoice_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree/field[@name='invoice_date']" position="before">
|
||||
<field name="projects_name" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
2
project_name_from_lead/.gitignore
vendored
Normal file
2
project_name_from_lead/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.*~
|
||||
*pyc
|
57
project_name_from_lead/README.rst
Normal file
57
project_name_from_lead/README.rst
Normal file
@@ -0,0 +1,57 @@
|
||||
=======================
|
||||
project_name_from_quote
|
||||
=======================
|
||||
|
||||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
|
||||
:target: https://odoo-community.org/page/development-status
|
||||
:alt: Beta
|
||||
.. |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%2Faccount--analytic-lightgray.png?logo=github
|
||||
:target: https://github.com/elabore-coop/project-tools
|
||||
:alt: elabore/hr-tools
|
||||
|
||||
|badge1| |badge2| |badge3|
|
||||
|
||||
|
||||
This module tranfers the Quote / Sale order title to the project name.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Use Odoo normal module installation procedure to install ``project_name_from_quote``.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
None yet.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `our issues website <https://github.com/elabore-coop/project-tools/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.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Stéphan Sainléger
|
||||
|
||||
Funders
|
||||
-------
|
||||
|
||||
The development of this module has been financially supported by:
|
||||
* Elabore (https://elabore.coop)
|
||||
* Datactivist (https://datactivist.coop)
|
||||
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
This module is maintained by Elabore.
|
@@ -1 +1,2 @@
|
||||
|
||||
from . import models
|
36
project_name_from_lead/__manifest__.py
Normal file
36
project_name_from_lead/__manifest__.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# Copyright 2022 Stéphan Sainléger (Elabore)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "project_name_from_lead",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Clément Thomas",
|
||||
"license": "AGPL-3",
|
||||
"category": "Tools",
|
||||
"summary": "Use lead name as project name",
|
||||
# any module necessary for this one to work correctly
|
||||
"depends": [
|
||||
"base",
|
||||
"crm",
|
||||
"sale_project",
|
||||
],
|
||||
"qweb": [
|
||||
# "static/src/xml/*.xml",
|
||||
],
|
||||
"external_dependencies": {
|
||||
"python": [],
|
||||
},
|
||||
# always loaded
|
||||
"data": [],
|
||||
# only loaded in demonstration mode
|
||||
"demo": [],
|
||||
"js": [],
|
||||
"css": [],
|
||||
"installable": True,
|
||||
# Install this module automatically if all dependency have been previously
|
||||
# and independently installed. Used for synergetic or glue modules.
|
||||
"auto_install": False,
|
||||
"application": False,
|
||||
}
|
1
project_name_from_lead/models/__init__.py
Normal file
1
project_name_from_lead/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import sale_order, crm_lead
|
17
project_name_from_lead/models/crm_lead.py
Normal file
17
project_name_from_lead/models/crm_lead.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from odoo import models
|
||||
|
||||
class Lead(models.Model):
|
||||
_inherit = 'crm.lead'
|
||||
|
||||
def write(self, vals):
|
||||
"""update project name if project created from lead
|
||||
"""
|
||||
for lead in self:
|
||||
if 'name' in vals:
|
||||
sale = self.env['sale.order'].search([('opportunity_id','=',lead.id)])
|
||||
if sale:
|
||||
project = self.env['project.project'].search([('sale_order_id','=',sale.id)])
|
||||
if project:
|
||||
project.name = vals['name']
|
||||
|
||||
return super(Lead, self).write(vals)
|
12
project_name_from_lead/models/sale_order.py
Normal file
12
project_name_from_lead/models/sale_order.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from typing import ValuesView
|
||||
from odoo import models
|
||||
|
||||
|
||||
class SaleOrderLine(models.Model):
|
||||
_inherit = "sale.order.line"
|
||||
|
||||
def _timesheet_create_project_prepare_values(self):
|
||||
values = super(SaleOrderLine, self)._timesheet_create_project_prepare_values()
|
||||
if self.order_id and self.order_id.opportunity_id:
|
||||
values['name'] = self.order_id.opportunity_id.name
|
||||
return values
|
@@ -1,3 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import models
|
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "project_name_from_quote",
|
||||
"version": "14.0.1.0.0",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Stéphan Sainléger",
|
||||
|
0
project_parent_task/__init__.py
Normal file
0
project_parent_task/__init__.py
Normal file
86
project_parent_task/__manifest__.py
Normal file
86
project_parent_task/__manifest__.py
Normal file
@@ -0,0 +1,86 @@
|
||||
# Copyright 2022 Laetitia Da Costa (Elabore)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "project_parent_tasks",
|
||||
"version": "14.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Laetitia Da Costa",
|
||||
"license": "AGPL-3",
|
||||
"category": "Project",
|
||||
"summary": "in parent's tasks dropdown field, show only tasks from the current projet",
|
||||
"description": """
|
||||
:image: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
====================
|
||||
project_parent_tasks
|
||||
====================
|
||||
|
||||
when selecting a parent task in a task, display only tasks from the current project
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Use Odoo normal module installation procedure to install ``project_parent_tasks``.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
None yet.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `our issues website <https://github.com/elabore-coop/project-tools/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.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Laetitia Da Costa (https://github.com/LaetitiaElabore)
|
||||
|
||||
Funders
|
||||
-------
|
||||
|
||||
The development of this module has been financially supported by:
|
||||
* Elabore (https://elabore.coop)
|
||||
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
This module is maintained by Elabore.
|
||||
|
||||
""",
|
||||
# any module necessary for this one to work correctly
|
||||
"depends": [
|
||||
"base",
|
||||
"project",
|
||||
],
|
||||
"qweb": [
|
||||
# "static/src/xml/*.xml",
|
||||
],
|
||||
"external_dependencies": {
|
||||
"python": [],
|
||||
},
|
||||
# always loaded
|
||||
"data": [
|
||||
"views/project_task.xml",
|
||||
],
|
||||
# only loaded in demonstration mode
|
||||
"demo": [],
|
||||
"js": [],
|
||||
"css": [],
|
||||
"installable": True,
|
||||
# Install this module automatically if all dependency have been previously
|
||||
# and independently installed. Used for synergetic or glue modules.
|
||||
"auto_install": False,
|
||||
"application": False,
|
||||
}
|
13
project_parent_task/views/project_task.xml
Normal file
13
project_parent_task/views/project_task.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<record model="ir.ui.view" id="view_tasks_form2_parent_project_inherited">
|
||||
<field name="name">view.tasks.form2.parent.project.inherited</field>
|
||||
<field name="model">project.task</field>
|
||||
<field name="inherit_id" ref="project.view_task_form2" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//page[@name='extra_info']//field[@name='parent_id']" position="attributes">
|
||||
<attribute name="domain">[('project_id','=', project_id)]</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "project_request_data",
|
||||
"version": "14.0.1.0.0",
|
||||
"version": "16.0.1.2.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Stéphan Sainléger",
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_my_task_request_data" name="My Task: Request Data" inherit_id="project.portal_my_task" priority="40">
|
||||
<xpath expr="//t[@t-set='card_body']/div[hasclass('row','mb-4')]" position="after">
|
||||
<xpath expr="//div[@id='card_body']/div[hasclass('row','mb-4','container')]" position="after">
|
||||
<div id="request_data" class="row mb-4">
|
||||
<div class="col-12 col-md-6" t-if="task.service_id">
|
||||
<strong>Service:</strong>
|
||||
|
@@ -12,4 +12,18 @@
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_task_kanban_request_data" model="ir.ui.view">
|
||||
<field name="name">project.task.kanban.request.data</field>
|
||||
<field name="inherit_id" ref="project.view_task_kanban" />
|
||||
<field name="model">project.task</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='name']" position="before">
|
||||
<div style="font-size:11px; margin-bottom: 8px;"><field name="create_date" widget="date"/></div>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='tag_ids']" position="before">
|
||||
<span style="background:lightblue; font-size:11px"><field name="service_id"/></span>
|
||||
<span style="background:lightsteelblue; font-size:11px"><field name="request_type_id"/></span>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
2
project_task_portal_form/.gitignore
vendored
Normal file
2
project_task_portal_form/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.*~
|
||||
*pyc
|
7
project_task_portal_form/README.rst
Normal file
7
project_task_portal_form/README.rst
Normal file
@@ -0,0 +1,7 @@
|
||||
=====================
|
||||
project_task_portal_form
|
||||
=====================
|
||||
|
||||
Add a portal form to create project tasks
|
||||
|
||||
This is an Odoo addon.
|
3
project_task_portal_form/__init__.py
Normal file
3
project_task_portal_form/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import controllers
|
86
project_task_portal_form/__manifest__.py
Normal file
86
project_task_portal_form/__manifest__.py
Normal file
@@ -0,0 +1,86 @@
|
||||
# Copyright 2022 Stéphan Sainléger (Elabore)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "project_task_portal_form",
|
||||
"version": "16.0.1.1.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Stéphan Sainléger",
|
||||
"license": "AGPL-3",
|
||||
"category": "Tools",
|
||||
"summary": "Add a portal form to create project tasks",
|
||||
"description": """
|
||||
:image: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
========================
|
||||
project_task_portal_form
|
||||
========================
|
||||
|
||||
Add a portal form to create project tasks
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Use Odoo normal module installation procedure to install
|
||||
``project_task_portal_form``.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
None yet.
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `our issues website <https://github.com/elabore-coop/project-tools/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.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Stéphan Sainléger
|
||||
|
||||
Funders
|
||||
-------
|
||||
|
||||
The development of this module has been financially supported by:
|
||||
* Elabore (https://elabore.coop)
|
||||
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
This module is maintained by Elabore.
|
||||
|
||||
""",
|
||||
# any module necessary for this one to work correctly
|
||||
"depends": [
|
||||
"base",
|
||||
"project",
|
||||
"project_request_data",
|
||||
"project_user_default_project",
|
||||
],
|
||||
"qweb": [],
|
||||
"external_dependencies": {
|
||||
"python": [],
|
||||
},
|
||||
# always loaded
|
||||
"data": [
|
||||
"views/portal_task_creation_form.xml",
|
||||
],
|
||||
# only loaded in demonstration mode
|
||||
"demo": [],
|
||||
"js": [],
|
||||
"css": [],
|
||||
"installable": True,
|
||||
# Install this module automatically if all dependency have been previously
|
||||
# and independently installed. Used for synergetic or glue modules.
|
||||
"auto_install": False,
|
||||
"application": False,
|
||||
}
|
3
project_task_portal_form/controllers/__init__.py
Normal file
3
project_task_portal_form/controllers/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import portal_task_creation
|
127
project_task_portal_form/controllers/portal_task_creation.py
Normal file
127
project_task_portal_form/controllers/portal_task_creation.py
Normal file
@@ -0,0 +1,127 @@
|
||||
# Copyright 2020 Lokavaluto ()
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import base64
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo.addons.portal.controllers.portal import CustomerPortal
|
||||
|
||||
|
||||
class PortalTaskCreation(CustomerPortal):
|
||||
_TASK_CREATION_FIELDS = [
|
||||
"name",
|
||||
"service_id",
|
||||
"request_type_id",
|
||||
"small_description", #not in v14
|
||||
"access", #not in v14
|
||||
"bug_report", #not in v14
|
||||
"priority",
|
||||
]
|
||||
|
||||
# Variable to update to add other fields in child classes
|
||||
_EXTRA_FIELDS = []
|
||||
|
||||
def _taskform_get_page_view_values(self, partner, access_token, **kwargs):
|
||||
values = {
|
||||
"page_name": "portal_task_form",
|
||||
"partner": partner,
|
||||
}
|
||||
return self._get_page_view_values(
|
||||
partner,
|
||||
access_token,
|
||||
values,
|
||||
"my_task_creation_history",
|
||||
False,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def _get_task_priorities(self):
|
||||
priorities = []
|
||||
for id, name in request.env['project.task']._fields['priority'].selection:
|
||||
value = {
|
||||
"id": id,
|
||||
"name": name
|
||||
}
|
||||
priorities.append(value)
|
||||
return priorities
|
||||
|
||||
@http.route(
|
||||
["/task/form"],
|
||||
type="http",
|
||||
auth="user",
|
||||
website=True,
|
||||
)
|
||||
def portal_task_creation(self, access_token=None, redirect=None, **kw):
|
||||
values = self._taskform_get_page_view_values(request.env.user.partner_id, access_token, **kw)
|
||||
request_types = request.env["request.type"].sudo().search([])
|
||||
task_services = request.env["task.service"].sudo().search([])
|
||||
priorities = self._get_task_priorities()
|
||||
error = dict()
|
||||
error_message = []
|
||||
values.update(
|
||||
{
|
||||
"request_types": request_types,
|
||||
"task_services": task_services,
|
||||
"priorities": priorities,
|
||||
"error": error,
|
||||
"error_message": error_message,
|
||||
}
|
||||
)
|
||||
return request.render("project_task_portal_form.portal_task_creation_form", values)
|
||||
|
||||
def _compute_form_data(self, data):
|
||||
values = {}
|
||||
for field in self._TASK_CREATION_FIELDS:
|
||||
if data.get(field):
|
||||
values[field] = data.pop(field)
|
||||
for field in self._EXTRA_FIELDS:
|
||||
if data.get(field):
|
||||
values[field] = data.pop(field)
|
||||
description = ""
|
||||
if values.get("small_description", False):
|
||||
description = description + "<b>DESCRIPTION:</b><br/>" + values["small_description"]
|
||||
del values['small_description']
|
||||
if values.get("access", False):
|
||||
description = description + "<br/><br/><b>ACCESS:</b><br/>" + values["access"]
|
||||
del values['access']
|
||||
if values.get("bug_report", False):
|
||||
description = description + "<br/><br/><b>BUG REPORT:</b><br/>" + values["bug_report"]
|
||||
del values['bug_report']
|
||||
|
||||
values["description"] = description
|
||||
values["attachments"] = request.httprequest.files.getlist("attachment")
|
||||
|
||||
return values
|
||||
|
||||
@http.route(
|
||||
["/task/create"],
|
||||
type="http",
|
||||
auth="public",
|
||||
methods=['POST'],
|
||||
website=True,
|
||||
)
|
||||
def create_task(self, **kwargs):
|
||||
# Get form values
|
||||
user = request.env.user
|
||||
values = self._compute_form_data(kwargs)
|
||||
values["project_id"] = user.default_project_id.id
|
||||
values["partner_id"] = user.partner_id.id
|
||||
values["user_ids"] = [(6, 0, [user.id])]
|
||||
|
||||
|
||||
|
||||
files = values.get("attachments", False)
|
||||
del values['attachments']
|
||||
|
||||
# Create task
|
||||
task_id = request.env["project.task"].sudo().create(values) #use sudo to avoid access error on resource calendar when user_id is set
|
||||
|
||||
# Add attachments
|
||||
for file in files:
|
||||
attachment_value = {
|
||||
'name': file.filename,
|
||||
'datas': base64.encodestring(file.read()),
|
||||
'res_model': "project.task",
|
||||
'res_id': task_id,
|
||||
}
|
||||
request.env['ir.attachment'].sudo().create(attachment_value)
|
||||
return request.render("project_task_portal_form.portal_task_created", {})
|
1
project_task_portal_form/i18n/README
Normal file
1
project_task_portal_form/i18n/README
Normal file
@@ -0,0 +1 @@
|
||||
This directory should contain the *.po for Odoo translation.
|
124
project_task_portal_form/i18n/fr.po
Normal file
124
project_task_portal_form/i18n/fr.po
Normal file
@@ -0,0 +1,124 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * project_task_portal_form
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-09-22 09:34+0000\n"
|
||||
"PO-Revision-Date: 2022-09-22 09:34+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: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_created
|
||||
msgid "<br/>\n"
|
||||
" Task created"
|
||||
msgstr "<br/>\n"
|
||||
" Tâche créée"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "<span>Be precise. If there is a bug/error, please describe how to reproduce it</span>"
|
||||
msgstr "<span>Soyez précis. Si vous avez une erreur, veuillez décrire le scénario pour la reproduire</span>"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "<span>Link toward error or additional information</span>"
|
||||
msgstr "<span>Lien vers l'erreur ou des informations supplémentaires</span>"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "<span>Paste here the complete error message (ex: error code Odoo)</span>"
|
||||
msgstr "<span>COpier ici le message d'erreur complet (ex: error code Odoo)</span>"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Access"
|
||||
msgstr "Accès"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_created
|
||||
msgid "Back to my Home\n"
|
||||
" <span class=\"fa fa-long-arrow-right\"/>"
|
||||
msgstr "Retour sur mon espace\n"
|
||||
" <span class=\"fa fa-long-arrow-right\"/>"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Bug report"
|
||||
msgstr "Rapport de bug"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Choose a priority..."
|
||||
msgstr "Choisir la priorité..."
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Choose a service..."
|
||||
msgstr "Choisir le logiciel"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Choose a type..."
|
||||
msgstr "Choisir un type de demande"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Priority"
|
||||
msgstr "Priorité"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Request type"
|
||||
msgstr "Type de demande"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Service"
|
||||
msgstr "Logiciel"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Submit\n"
|
||||
" <span class=\"fa fa-long-arrow-right\"/>"
|
||||
msgstr "Soumettre\n"
|
||||
" <span class=\"fa fa-long-arrow-right\"/>"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_created
|
||||
msgid "Task created"
|
||||
msgstr "Tâche créée"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Task creation form"
|
||||
msgstr "Formulaire de création de tâche"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_created
|
||||
msgid "Thanks for request!\n"
|
||||
" <br/>\n"
|
||||
" A new task has been saved and you can keep track on your request handling from your portal account!\n"
|
||||
" <br/>"
|
||||
msgstr "Merci pour votre demande !\n"
|
||||
" <br/>\n"
|
||||
" Une nouvelle tâche a été créée et vous pouvez suivre votre demande depuis votre compte portail !\n"
|
||||
" <br/>"
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Title"
|
||||
msgstr "Titre"
|
||||
|
118
project_task_portal_form/i18n/project_task_portal_form.pot
Normal file
118
project_task_portal_form/i18n/project_task_portal_form.pot
Normal file
@@ -0,0 +1,118 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * project_task_portal_form
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-09-22 09:35+0000\n"
|
||||
"PO-Revision-Date: 2022-09-22 09:35+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: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_created
|
||||
msgid "<br/>\n"
|
||||
" Task created"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "<span>Be precise. If there is a bug/error, please describe how to reproduce it</span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "<span>Link toward error or additional information</span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "<span>Paste here the complete error message (ex: error code Odoo)</span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Access"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_created
|
||||
msgid "Back to my Home\n"
|
||||
" <span class=\"fa fa-long-arrow-right\"/>"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Bug report"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Choose a priority..."
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Choose a service..."
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Choose a type..."
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Request type"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Submit\n"
|
||||
" <span class=\"fa fa-long-arrow-right\"/>"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_created
|
||||
msgid "Task created"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Task creation form"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_created
|
||||
msgid "Thanks for request!\n"
|
||||
" <br/>\n"
|
||||
" A new task has been saved and you can keep track on your request handling from your portal account!\n"
|
||||
" <br/>"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_task_portal_form
|
||||
#: model_terms:ir.ui.view,arch_db:project_task_portal_form.portal_task_creation_form
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
141
project_task_portal_form/views/portal_task_creation_form.xml
Normal file
141
project_task_portal_form/views/portal_task_creation_form.xml
Normal file
@@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_task_creation_form" name="Portal: Task creation form">
|
||||
<t t-call="portal.portal_layout">
|
||||
<!-- <div id="wrap" class="col-lg-6 container"></div> -->
|
||||
<t t-set="additional_title">Task creation form</t>
|
||||
<form
|
||||
action="/task/create"
|
||||
method="post"
|
||||
accept-charset="UTF-8"
|
||||
class="s_website_form col-md-12 mt32"
|
||||
data-model_name="project.task"
|
||||
data-force_action=""
|
||||
data-success_page=""
|
||||
enctype="multipart/form-data">
|
||||
|
||||
<div class="oe_structure" id="oe_structure_portal_task_creation_form_1" />
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()" />
|
||||
<div class="row">
|
||||
<div t-attf-class="form-group #{error.get('name') and 'o_has_error' or ''} col-xl-12">
|
||||
<label class="col-form-label" for="name">Title</label>
|
||||
<label class="text-danger"> *</label>
|
||||
<input type="text" name="name" t-attf-class="form-control #{error.get('name') and 'is-invalid' or ''}" t-att-value="name" required="True" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div t-attf-class="form-group #{error.get('request_type_id') and 'o_has_error' or ''} col-xl-6">
|
||||
<label class="col-form-label" for="request_type_id">Request type</label>
|
||||
<label class="text-danger"> *</label>
|
||||
<select name="request_type_id" t-attf-class="form-control" required="True">
|
||||
<option value="">Choose a type...</option>
|
||||
<t t-foreach="request_types or []" t-as="request_type">
|
||||
<option t-att-value="request_type.id">
|
||||
<t t-esc="request_type.name" />
|
||||
</option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('service_id') and 'o_has_error' or ''} col-xl-6">
|
||||
<label class="col-form-label" for="service_id">Service</label>
|
||||
<label class="text-danger"> *</label>
|
||||
<select name="service_id" t-attf-class="form-control" required="True">
|
||||
<option value="">Choose a service...</option>
|
||||
<t t-foreach="task_services or []" t-as="task_service">
|
||||
<option t-att-value="task_service.id">
|
||||
<t t-esc="task_service.name" />
|
||||
</option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div t-attf-class="form-group #{error.get('small_description') and 'o_has_error' or ''} col-xl-12">
|
||||
<label class="col-form-label" for="small_description">Description</label>
|
||||
<label class="text-danger"> *</label>
|
||||
<textarea rows="4" name="small_description" t-attf-class="form-control #{error.get('small_description') and 'is-invalid' or ''}" t-att-value="small_description" required="True" />
|
||||
<span>Be precise. If there is a bug/error, please describe how to reproduce it</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div t-attf-class="form-group #{error.get('access') and 'o_has_error' or ''} col-xl-12">
|
||||
<label class="col-form-label" for="access">Access</label>
|
||||
<input type="text" name="access" t-attf-class="form-control #{error.get('access') and 'is-invalid' or ''}" t-att-value="access" />
|
||||
<span>Link toward error or additional information</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div t-attf-class="form-group #{error.get('bug_report') and 'o_has_error' or ''} col-xl-12">
|
||||
<label class="col-form-label" for="bug_report">Bug report</label>
|
||||
<textarea rows="4" name="bug_report" t-attf-class="form-control #{error.get('bug_report') and 'is-invalid' or ''}" t-att-value="bug_report" />
|
||||
<span>Paste here the complete error message (ex: error code Odoo)</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ## IMPORT FILE -->
|
||||
<div class="form-group form-field form-field-binary" data-model-field="false" data-optional="true">
|
||||
<label class="col-form-label" for="attachment">
|
||||
<span>Join document</span>
|
||||
</label>
|
||||
<i>
|
||||
<input type="file" name="attachment" multiple="true" data-show-upload="true" data-show-caption="true" data-show-preview="true" />
|
||||
</i>
|
||||
<p class="form-text text-muted">
|
||||
<i>Join a screenshot to your request or any other helpfull document.</i>
|
||||
<br />
|
||||
</p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div t-attf-class="form-group #{error.get('priority') and 'o_has_error' or ''} col-xl-6">
|
||||
<label class="col-form-label" for="priority">Priority</label>
|
||||
<label class="text-danger"> *</label>
|
||||
<select name="priority" t-attf-class="form-control" required="True">
|
||||
<option value="">Choose a priority...</option>
|
||||
<t t-foreach="priorities or []" t-as="priority">
|
||||
<option t-att-value="priority['id']">
|
||||
<t t-esc="priority['name']" />
|
||||
</option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix">
|
||||
<br />
|
||||
<button type="submit" class="btn btn-primary float-right mb32 ">
|
||||
Submit
|
||||
<span class="fa fa-long-arrow-right" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_structure" id="oe_structure_portal_task_creation_form_2" />
|
||||
</form>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
|
||||
<template id="portal_task_created" name="Portal: Task created">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="additional_title">Task created</t>
|
||||
<form action="/my/tasks" method="post">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()" />
|
||||
<h3>
|
||||
<br />
|
||||
Task created
|
||||
</h3>
|
||||
<div>
|
||||
<p>
|
||||
Thanks for request!
|
||||
<br />
|
||||
A new task has been saved and you can keep track on your request handling from your portal account!
|
||||
<br />
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearfix">
|
||||
<br />
|
||||
<button type="submit" class="btn btn-primary float-right mb32 ">
|
||||
Back to my Tasks
|
||||
<span class="fa fa-long-arrow-right" />
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "project_timebox",
|
||||
"version": "14.0.1.0.0",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Stéphan Sainléger",
|
||||
|
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_my_task_timebox" name="My Task: Timebox" inherit_id="project.portal_my_task" priority="40">
|
||||
<xpath expr="//t[@t-set='card_body']/div[hasclass('row','mb-4')]" position="before">
|
||||
<xpath expr="//div[@t-if='task.date_deadline']" position="after">
|
||||
<div id="timebox" class="row mb-2">
|
||||
<div class="col-12 col-md-6" t-if="task.timebox_min_id">
|
||||
<div t-if="task.timebox_min_id">
|
||||
<strong>Timebox Min:</strong>
|
||||
<span t-field="task.timebox_min_id" />
|
||||
</div>
|
||||
<div class="col-12 col-md-6" t-if="task.timebox_max_id">
|
||||
<div t-if="task.timebox_max_id">
|
||||
<strong>Timebox Max:</strong>
|
||||
<span t-field="task.timebox_max_id" />
|
||||
</div>
|
||||
|
@@ -1,65 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * project_timesheet_funding_wish
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 14.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-07-25 17:02+0000\n"
|
||||
"PO-Revision-Date: 2022-07-25 17:02+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: project_timesheet_funding_wish
|
||||
#: model:ir.model,name:project_timesheet_funding_wish.model_account_analytic_line
|
||||
msgid "Analytic Line"
|
||||
msgstr "Ligne analytique"
|
||||
|
||||
#. module: project_timesheet_funding_wish
|
||||
#: model:ir.model.fields,field_description:project_timesheet_funding_wish.field_account_analytic_line__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nom affiché"
|
||||
|
||||
#. module: project_timesheet_funding_wish
|
||||
#: model:ir.model.fields.selection,name:project_timesheet_funding_wish.selection__account_analytic_line__funding_wish__free
|
||||
msgid "Free"
|
||||
msgstr "Offert"
|
||||
|
||||
#. module: project_timesheet_funding_wish
|
||||
#: code:addons/project_timesheet_funding_wish/models/hr_timesheet.py:0
|
||||
#: model:ir.model.fields,field_description:project_timesheet_funding_wish.field_account_analytic_line__funding_wish
|
||||
#, python-format
|
||||
msgid "Funding wish"
|
||||
msgstr "Type de financement"
|
||||
|
||||
#. module: project_timesheet_funding_wish
|
||||
#: model:ir.model.fields,field_description:project_timesheet_funding_wish.field_account_analytic_line__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_timesheet_funding_wish
|
||||
#: model:ir.model.fields,field_description:project_timesheet_funding_wish.field_account_analytic_line____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Dernière modification le"
|
||||
|
||||
#. module: project_timesheet_funding_wish
|
||||
#: model:ir.model.fields.selection,name:project_timesheet_funding_wish.selection__account_analytic_line__funding_wish__accepted
|
||||
msgid "Payment accepted"
|
||||
msgstr "Paiement accepté"
|
||||
|
||||
#. module: project_timesheet_funding_wish
|
||||
#: model:ir.model.fields.selection,name:project_timesheet_funding_wish.selection__account_analytic_line__funding_wish__expected
|
||||
msgid "Payment expected"
|
||||
msgstr "Paiement attendu"
|
||||
|
||||
#. module: project_timesheet_funding_wish
|
||||
#: code:addons/project_timesheet_funding_wish/models/hr_timesheet.py:0
|
||||
#: model:ir.model.fields,field_description:project_timesheet_funding_wish.field_account_analytic_line__treated
|
||||
#, python-format
|
||||
msgid "Treated"
|
||||
msgstr "Traité"
|
@@ -1 +0,0 @@
|
||||
from . import hr_timesheet
|
@@ -1,16 +0,0 @@
|
||||
from odoo import _, fields, models
|
||||
|
||||
|
||||
class AccountAnalyticLine(models.Model):
|
||||
_inherit = "account.analytic.line"
|
||||
|
||||
funding_wish = fields.Selection(
|
||||
[
|
||||
("free", "Free"),
|
||||
("accepted", "Payment accepted"),
|
||||
("expected", "Payment expected"),
|
||||
],
|
||||
string=_("Funding wish"),
|
||||
copy=False,
|
||||
)
|
||||
treated = fields.Boolean(string=_("Treated"), copy=False)
|
@@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="hr_timesheet_line_tree_funding_view" model="ir.ui.view">
|
||||
<field name="name">hr.timesheet.line.tree.funding.view</field>
|
||||
<field name="model">account.analytic.line</field>
|
||||
<field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='date']" position="after">
|
||||
<field name="treated" />
|
||||
<field name="funding_wish" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_task_form2_inherited_funding" model="ir.ui.view">
|
||||
<field name="name">view.task.form2.inherited.funding</field>
|
||||
<field name="model">project.task</field>
|
||||
<field name="inherit_id" ref="hr_timesheet.view_task_form2_inherited" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='timesheet_ids']/tree/field[@name='date']" position="after">
|
||||
<field name="treated" />
|
||||
<field name="funding_wish" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "project_user_default_project",
|
||||
"version": "14.0.1.0.0",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Stéphan Sainléger",
|
||||
|
45
project_visibility_followers_portal/README.rst
Normal file
45
project_visibility_followers_portal/README.rst
Normal file
@@ -0,0 +1,45 @@
|
||||
=================
|
||||
project_visibility_followers_portal
|
||||
=================
|
||||
|
||||
Add project visibility : some employees and some portal users
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Use Odoo normal procedure to install add-ons to install
|
||||
``project_visibility_followers_portal``.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `our issues website
|
||||
<https://github.com/elabore-coop/project-tools/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.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Images
|
||||
------
|
||||
* Elabore: `Icon <https://elabore.coop/web/image/res.company/1/logo?unique=f3db262>`_.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
* Clément Thomas
|
||||
|
||||
Funders
|
||||
-------
|
||||
The development of this module has been financially supported by:
|
||||
* Elabore (https://elabore.coop)
|
||||
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
This module is maintained by Elabore.
|
2
project_visibility_followers_portal/__init__.py
Normal file
2
project_visibility_followers_portal/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
from . import models
|
91
project_visibility_followers_portal/__manifest__.py
Normal file
91
project_visibility_followers_portal/__manifest__.py
Normal file
@@ -0,0 +1,91 @@
|
||||
# Copyright 2022 Stéphan Sainléger (Elabore)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "project_visibility_followers_portal",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://github.com/elabore-coop/project-tools",
|
||||
"maintainer": "Clément Thomas",
|
||||
"license": "AGPL-3",
|
||||
"category": "Tools",
|
||||
"summary": "Add project visibility : some employees and some portal users",
|
||||
"description": """
|
||||
:image: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
=================
|
||||
project_visibility_followers_portal
|
||||
=================
|
||||
|
||||
Add project visibility : some employees and some portal users
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Install ``project_visibility_followers_portal``, all dependencies will be installed by default.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
None yet.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `our issues website
|
||||
<https://github.com/elabore-coop/project-tools/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.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Images
|
||||
------
|
||||
|
||||
* Elabore: `Icon <https://elabore.coop/web/image/res.company/1/logo?unique=f3db262>`_.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Clément Thomas
|
||||
|
||||
Funders
|
||||
-------
|
||||
|
||||
The development of this module has been financially supported by:
|
||||
* Elabore (https://elabore.coop)
|
||||
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
This module is maintained by Elabore.
|
||||
|
||||
""",
|
||||
# any module necessary for this one to work correctly
|
||||
"depends": [
|
||||
"base",
|
||||
"project",
|
||||
],
|
||||
"qweb": [
|
||||
# "static/src/xml/*.xml",
|
||||
],
|
||||
"external_dependencies": {
|
||||
"python": [],
|
||||
},
|
||||
# always loaded
|
||||
"data": [
|
||||
"security/project_security.xml"
|
||||
],
|
||||
# only loaded in demonstration mode
|
||||
"demo": [],
|
||||
"js": [],
|
||||
"css": [],
|
||||
"installable": True,
|
||||
# Install this module automatically if all dependency have been previously
|
||||
# and independently installed. Used for synergetic or glue modules.
|
||||
"auto_install": False,
|
||||
"application": False,
|
||||
}
|
100
project_visibility_followers_portal/i18n/fr.po
Normal file
100
project_visibility_followers_portal/i18n/fr.po
Normal file
@@ -0,0 +1,100 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * project_visibility_followers_portal
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 14.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-05-22 13:09+0000\n"
|
||||
"PO-Revision-Date: 2023-05-22 13:09+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: project_visibility_followers_portal
|
||||
#: model:ir.model.fields,field_description:project_visibility_followers_portal.field_project_project__display_name
|
||||
#: model:ir.model.fields,field_description:project_visibility_followers_portal.field_project_task__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nom affiché"
|
||||
|
||||
#. module: project_visibility_followers_portal
|
||||
#: model:ir.model.fields,field_description:project_visibility_followers_portal.field_project_project__id
|
||||
#: model:ir.model.fields,field_description:project_visibility_followers_portal.field_project_task__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_visibility_followers_portal
|
||||
#: model:ir.model.fields.selection,name:project_visibility_followers_portal.selection__project_project__privacy_visibility__followers_portal
|
||||
msgid "Invited portal users and invited internal users"
|
||||
msgstr "Utilisateurs portail invités et utilisateurs internes invités"
|
||||
|
||||
#. module: project_visibility_followers_portal
|
||||
#: model:ir.model.fields,field_description:project_visibility_followers_portal.field_project_project____last_update
|
||||
#: model:ir.model.fields,field_description:project_visibility_followers_portal.field_project_task____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Dernière modification le"
|
||||
|
||||
#. module: project_visibility_followers_portal
|
||||
#: model:ir.model.fields,help:project_visibility_followers_portal.field_project_project__privacy_visibility
|
||||
msgid ""
|
||||
"People to whom this project and its tasks will be visible.\n"
|
||||
"\n"
|
||||
"- Invited internal users: when following a project, internal users will get access to all of its tasks without distinction. Otherwise, they will only get access to the specific tasks they are following.\n"
|
||||
" A user with the project > administrator access right level can still access this project and its tasks, even if they are not explicitly part of the followers.\n"
|
||||
"\n"
|
||||
"- All internal users: all internal users can access the project and all of its tasks without distinction.\n"
|
||||
"\n"
|
||||
"- Invited portal users and all internal users: all internal users can access the project and all of its tasks without distinction.\n"
|
||||
"When following a project, portal users will get access to all of its tasks without distinction. Otherwise, they will only get access to the specific tasks they are following."
|
||||
msgstr ""
|
||||
"Personnes pour lesquelles ce projet et ses tâches seront visibles.\n"
|
||||
"\n"
|
||||
"- Utilisateurs internes invités : lorsqu'ils sont abonnés à un projet, les utilisateurs internes auront accès à toutes ses tâches sans distinction. Autrement, ils auront uniquement accès aux tâches spécifiques auxquelles ils sont abonnés.\n"
|
||||
" Un utilisateur avec le niveau de droits d'accès projet > administrateur peut toujours accéder au projet et à ses tâches, même s'il ne fait pas explicitement partie des abonnés.\n"
|
||||
"\n"
|
||||
"- Tous les utilisateurs internes : tous les utilisateurs internes peuvent accéder au projet et à toutes ses tâches sans distinction.\n"
|
||||
"\n"
|
||||
"- Les utilisateurs portail invités et tous les utilisateurs internes : tous les utilisateurs internes peuvent accéder au projet et à toutes ses tâches sans distinction.\n"
|
||||
"Quand ils suivent un projet, les utilisateurs portail auront accès à toutes ses tâches sans distinction. Autrement, ils auront uniquement accès aux tâches spécifiques auxquelles ils sont abonnés."
|
||||
|
||||
#. module: project_visibility_followers_portal
|
||||
#: model:ir.model,name:project_visibility_followers_portal.model_project_project
|
||||
msgid "Project"
|
||||
msgstr "Projet"
|
||||
|
||||
#. module: project_visibility_followers_portal
|
||||
#: model:ir.model,name:project_visibility_followers_portal.model_project_task
|
||||
msgid "Task"
|
||||
msgstr "Tâche"
|
||||
|
||||
#. module: project_visibility_followers_portal
|
||||
#: code:addons/project_visibility_followers_portal/models/project_task.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The project visibility setting doesn't allow portal users to see the "
|
||||
"project's tasks. (%s)"
|
||||
msgstr ""
|
||||
"Le paramètre de visibilité du projet ne permet pas aux utilisateurs portail "
|
||||
"de voir les tâches du projet. (%s)"
|
||||
|
||||
#. module: project_visibility_followers_portal
|
||||
#: code:addons/project_visibility_followers_portal/models/project_task.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The task cannot be shared with the recipient(s) because the privacy of the "
|
||||
"project is too restricted. Set the privacy of the project to 'Visible by "
|
||||
"following customers' in order to make it accessible by the recipient(s)."
|
||||
msgstr ""
|
||||
"La tâche ne peut pas être partagée avec le(s) destinataire(s) car la "
|
||||
"confidentialité du projet est trop restreinte. Définissez la confidentialité"
|
||||
" sur \"Visible par les clients suiveurs\" afin de la rendre accessible au(x)"
|
||||
" destinataire(s)."
|
||||
|
||||
#. module: project_visibility_followers_portal
|
||||
#: model:ir.model.fields,field_description:project_visibility_followers_portal.field_project_project__privacy_visibility
|
||||
msgid "Visibility"
|
||||
msgstr "Visibilité"
|
2
project_visibility_followers_portal/models/__init__.py
Normal file
2
project_visibility_followers_portal/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
from . import project_project, project_task
|
@@ -0,0 +1,32 @@
|
||||
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class Project(models.Model):
|
||||
_inherit = "project.project"
|
||||
|
||||
# A reprendre pour ajouter l’option de visibilité
|
||||
privacy_visibility = fields.Selection(
|
||||
selection_add=[('followers_portal','Invited portal users and invited internal users')],
|
||||
ondelete={'followers_portal': 'set default'})
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
"""In case of "followers_portal" privacy visibility, add current user to list of allowed users.
|
||||
Same behaviour than "portal" privacy visibility.
|
||||
"""
|
||||
project = super(Project, self).create(vals)
|
||||
if project.privacy_visibility == 'followers_portal' and project.partner_id.user_ids:
|
||||
project.message_partner_ids |= project.partner_id
|
||||
return project
|
||||
|
||||
def write(self, vals):
|
||||
"""In case of "followers_portal" privacy visibility, add current user to list of allowed users.
|
||||
Same behaviour than "portal" privacy visibility.
|
||||
"""
|
||||
res = super(Project, self).write(vals)
|
||||
if vals.get('partner_id') or vals.get('privacy_visibility'):
|
||||
for project in self.filtered(lambda project: project.privacy_visibility == 'followers_portal'):
|
||||
project.message_partner_ids |= project.partner_id
|
||||
return res
|
||||
|
60
project_visibility_followers_portal/models/project_task.py
Normal file
60
project_visibility_followers_portal/models/project_task.py
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class Task(models.Model):
|
||||
_inherit = "project.task"
|
||||
|
||||
@api.constrains('message_partner_ids')
|
||||
def _check_no_portal_allowed(self):
|
||||
for task in self.filtered(lambda t: t.project_id.privacy_visibility not in ('portal','followers_portal')):
|
||||
portal_users = task.message_partner_ids.user_ids.filtered('share')
|
||||
if portal_users:
|
||||
user_names = ', '.join(portal_users[:10].mapped('name'))
|
||||
raise ValidationError(_("The project visibility setting doesn't allow portal users to see the project's tasks. (%s)", user_names))
|
||||
|
||||
def _compute_access_warning(self):
|
||||
for task in self.filtered(lambda x: x.project_id.privacy_visibility not in ('portal','followers_portal')):
|
||||
task.access_warning = _(
|
||||
"The task cannot be shared with the recipient(s) because the privacy of the project is too restricted. Set the privacy of the project to 'Visible by following customers' in order to make it accessible by the recipient(s).")
|
||||
|
||||
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
tasks = super(Task, self).create(vals_list)
|
||||
for task in tasks:
|
||||
if task.project_id.privacy_visibility == 'followers_portal':
|
||||
task._portal_ensure_token()
|
||||
return tasks
|
||||
|
||||
def _notify_get_groups(self, msg_vals=None):
|
||||
groups = super(Task, self)._notify_get_groups(msg_vals=msg_vals)
|
||||
""" Handle project users and managers recipients that can assign
|
||||
tasks and create new one directly from notification emails. Also give
|
||||
access button to portal users and portal customers. If they are notified
|
||||
they should probably have access to the document. """
|
||||
self.ensure_one()
|
||||
|
||||
project_user_group_id = self.env.ref('project.group_project_user').id
|
||||
project_manager_group_id = self.env.ref('project.group_project_manager').id
|
||||
|
||||
group_func = lambda pdata: pdata['type'] == 'user' and project_user_group_id in pdata['groups']
|
||||
if self.project_id.privacy_visibility == 'followers_portal':
|
||||
message_partner_ids = self.project_id.message_partner_ids.partner_id.ids
|
||||
group_func = lambda pdata:\
|
||||
pdata['type'] == 'user'\
|
||||
and (
|
||||
project_manager_group_id in pdata['groups']\
|
||||
or (project_user_group_id in pdata['groups'] and pdata['id'] in message_partner_ids)
|
||||
)
|
||||
groups = [('group_project_user', group_func, {})]+groups
|
||||
message_partner_ids = self.project_id.message_partner_ids
|
||||
groups.insert(0, (
|
||||
'message_partner_ids',
|
||||
lambda pdata: pdata['type'] == 'portal' and pdata['id'] in message_partner_ids,
|
||||
{}
|
||||
))
|
||||
|
||||
return groups
|
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<data noupdate="0">
|
||||
|
||||
<record model="ir.rule" id="project_project_rule_followers_portal">
|
||||
<field name="name">Project: Invited internal users and invited portal users</field>
|
||||
<field name="model_id" ref="model_project_project"/>
|
||||
<field name="domain_force">[
|
||||
('privacy_visibility', '=', 'followers_portal'),
|
||||
('message_partner_ids', 'in', [user.partner_id.id])
|
||||
]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_user')),(4, ref('base.group_portal'))]"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="project_task_rule_followers_portal">
|
||||
<field name="name">Task: Invited internal users and invited portal users</field>
|
||||
<field name="model_id" ref="model_project_task"/>
|
||||
<field name="domain_force">[
|
||||
('project_id.privacy_visibility', '=', 'followers_portal'),
|
||||
'|',
|
||||
('project_id.message_partner_ids', 'child_of', [user.partner_id.commercial_partner_id.id]),
|
||||
('message_partner_ids', 'child_of', [user.partner_id.commercial_partner_id.id]),
|
||||
]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_user')),(4, ref('base.group_portal'))]"/>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- extend existing rule -->
|
||||
<record model="ir.rule" id="project.project_public_members_rule">
|
||||
<field name="domain_force">[
|
||||
'|',
|
||||
('privacy_visibility', '!=', 'followers_portal'),
|
||||
('message_partner_ids', 'in', [user.partner_id.id]),
|
||||
'|',
|
||||
('privacy_visibility', '!=', 'followers'),
|
||||
('message_partner_ids', 'in', [user.partner_id.id])
|
||||
]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="project.task_visibility_rule">
|
||||
<field name="domain_force">[
|
||||
'|',
|
||||
'&',
|
||||
('project_id', '!=', False),
|
||||
(
|
||||
'|',
|
||||
('project_id.privacy_visibility', '!=', 'followers_portal'),
|
||||
('project_id.message_partner_ids', 'in', [user.partner_id.id]),
|
||||
'|',
|
||||
('project_id.privacy_visibility', '!=', 'followers'),
|
||||
('project_id.message_partner_ids', 'in', [user.partner_id.id]),
|
||||
),
|
||||
'|',
|
||||
('message_partner_ids', 'in', [user.partner_id.id]),
|
||||
# to subscribe check access to the record, follower is not enough at creation
|
||||
('user_ids', 'in', user.id)
|
||||
]</field>
|
||||
<field name="groups" eval="[(4,ref('base.group_user'))]"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
Reference in New Issue
Block a user