Compare commits
36 Commits
12.0
...
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 | ||
|
139e451d0c | ||
|
11d99ae6e0 | ||
|
2bd9234fa1 | ||
|
892a526df8 | ||
|
87bdd51043 | ||
|
309f8d4510 | ||
|
56f757505b | ||
|
1f8baa73d1 | ||
|
c4ef88d3d4 |
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "project_assignees",
|
||||
"version": "12.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",
|
||||
@@ -78,7 +79,6 @@ This module is maintained by Elabore.
|
||||
},
|
||||
# always loaded
|
||||
"data": [
|
||||
"data/project_assignees_data.xml",
|
||||
"views/project_task.xml",
|
||||
"views/portal_template.xml",
|
||||
],
|
||||
|
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="mt_task_assignees" model="mail.message.subtype">
|
||||
<field name="name">Assignees change</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="default" eval="False"/>
|
||||
<field name="description">Assignees changed</field>
|
||||
</record>
|
||||
|
||||
<record id="mt_project_task_assignees" model="mail.message.subtype">
|
||||
<field name="name">Task Assignees Changed</field>
|
||||
<field name="sequence">13</field>
|
||||
<field name="res_model">project.project</field>
|
||||
<field name="default" eval="False"/>
|
||||
<field name="parent_id" eval="ref('mt_task_assignees')"/>
|
||||
<field name="relation_field">project_id</field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<!-- Template email user assigned to a task -->
|
||||
<data>
|
||||
<template id="message_user_assigned">
|
||||
<p style="margin: 0px;">
|
||||
<span>Dear <t t-esc="partner_name"/>,</span><br />
|
||||
<span style="margin-top: 8px;">You have been assigned to the <t t-esc="model_description or 'document'"/> <t t-esc="object.name_get()[0][1]"/>.</span>
|
||||
</p>
|
||||
<p style="margin-top: 24px; margin-bottom: 16px;">
|
||||
<a t-att-href="'/mail/view?model=%s&res_id=%s' % (object._name, object.id)" style="background-color:#875A7B; padding: 10px; text-decoration: none; color: #fff; border-radius: 5px;">
|
||||
View <t t-esc="model_description or 'document'"/>
|
||||
</a>
|
||||
</p>
|
||||
</template>
|
||||
</data>
|
||||
</odoo>
|
@@ -1,14 +1,14 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * project_assignees
|
||||
# * project_assignees
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.0\n"
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-04-12 11:37+0000\n"
|
||||
"PO-Revision-Date: 2023-04-12 11:37+0000\n"
|
||||
"Last-Translator: <>\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"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -18,66 +18,19 @@ msgstr ""
|
||||
#. module: project_assignees
|
||||
#: model_terms:ir.ui.view,arch_db:project_assignees.portal_my_task_assignees
|
||||
msgid "<strong>Other assignees</strong>"
|
||||
msgstr "<strong>Assigné à</strong>"
|
||||
msgstr "<strong>Autres intervenants</strong>"
|
||||
|
||||
#. module: project_assignees
|
||||
#: model:mail.message.subtype,name:project_assignees.mt_task_assignees
|
||||
msgid "Assignees change"
|
||||
msgstr "Changement d'assignation"
|
||||
|
||||
#. module: project_assignees
|
||||
#: model:mail.message.subtype,description:project_assignees.mt_task_assignees
|
||||
msgid "Assignees changed"
|
||||
msgstr "Changement d'assignation"
|
||||
#: 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_terms:ir.ui.view,arch_db:project_assignees.message_user_assigned
|
||||
msgid "Dear"
|
||||
msgstr "Cher"
|
||||
|
||||
#. module: project_assignees
|
||||
#: model:ir.model,name:project_assignees.model_mail_thread
|
||||
msgid "Email Thread"
|
||||
msgstr "Discussion par courriel"
|
||||
|
||||
#. module: project_assignees
|
||||
#: model:ir.model,name:project_assignees.model_mail_tracking_value
|
||||
msgid "Mail Tracking Value"
|
||||
msgstr "Valeur de suivi des courriers"
|
||||
|
||||
#. module: project_assignees
|
||||
#: model:ir.model.fields,field_description:project_assignees.field_project_task__assignee_ids
|
||||
msgid "Other Assignees"
|
||||
msgstr "Assigné à"
|
||||
|
||||
#. module: project_assignees
|
||||
#: model:ir.model,name:project_assignees.model_project_task
|
||||
msgid "Task"
|
||||
msgstr "Tâche"
|
||||
|
||||
#. module: project_assignees
|
||||
#: model:mail.message.subtype,name:project_assignees.mt_project_task_assignees
|
||||
msgid "Task Assignees Changed"
|
||||
msgstr "Changement d'assignation pour la tâche"
|
||||
|
||||
#. module: project_assignees
|
||||
#: model_terms:ir.ui.view,arch_db:project_assignees.message_user_assigned
|
||||
msgid "View"
|
||||
msgstr "Vue"
|
||||
|
||||
#. module: project_assignees
|
||||
#: code:addons/project_assignees/models/project_task.py:57
|
||||
#, python-format
|
||||
msgid "You have been assigned to %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: project_assignees
|
||||
#: model_terms:ir.ui.view,arch_db:project_assignees.message_user_assigned
|
||||
msgid "You have been assigned to the"
|
||||
msgstr "Vous avez été assigné à "
|
||||
|
||||
msgstr "Tâche"
|
@@ -1,106 +1,9 @@
|
||||
|
||||
from odoo import models, fields, _, api
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
|
||||
|
||||
class MailTracking(models.Model):
|
||||
_inherit = 'mail.tracking.value'
|
||||
|
||||
@api.model
|
||||
def create_tracking_values(self, initial_value, new_value, col_name, col_info, track_sequence):
|
||||
"""
|
||||
Track values of assignees changes in chatter
|
||||
"""
|
||||
if col_name == 'assignee_ids':
|
||||
values = {'field': col_name, 'field_desc': col_info['string'], 'field_type': col_info['type'], 'track_sequence': track_sequence}
|
||||
if initial_value:
|
||||
values.update({
|
||||
'old_value_char': ', '.join([i.name for i in initial_value]),
|
||||
})
|
||||
else:
|
||||
values.update({
|
||||
'old_value_char': '',
|
||||
})
|
||||
values.update({
|
||||
'new_value_char': ', '.join([i.name for i in new_value])
|
||||
})
|
||||
return values
|
||||
return super(MailTracking, self).create_tracking_values(initial_value, new_value, col_name, col_info, track_sequence)
|
||||
|
||||
class Task(models.Model):
|
||||
_inherit = "project.task"
|
||||
|
||||
assignee_ids = fields.Many2many('res.users', 'assignee_ids_rel', string='Other Assignees', track_visibility='change')
|
||||
assignee_ids = fields.Many2many('res.users', 'assignee_ids_rel', string='Assignees')
|
||||
|
||||
@api.multi
|
||||
def subscribe_and_notify_assignees(self, new_assignee_ids=None):
|
||||
for task in self:
|
||||
# Use assignees on parameter if exists
|
||||
if new_assignee_ids:
|
||||
assignees = self.env['res.users'].browse(new_assignee_ids)
|
||||
else:
|
||||
assignees = task.assignee_ids
|
||||
|
||||
# Subscribe partners
|
||||
partner_ids = [a.partner_id.id for a in assignees]
|
||||
task.message_subscribe(partner_ids)
|
||||
|
||||
# Send notification to assignees
|
||||
view = self.env['ir.ui.view'].browse(self.env['ir.model.data'].xmlid_to_res_id('project_assignees.message_user_assigned'))
|
||||
model_description = self.env['ir.model']._get(task._name).display_name
|
||||
|
||||
for assignee in assignees:
|
||||
values = {
|
||||
'object': task,
|
||||
'model_description': model_description,
|
||||
'partner_name':assignee.name_get()[0][1]
|
||||
}
|
||||
assignation_msg = view.render(values, engine='ir.qweb', minimal_qcontext=True)
|
||||
assignation_msg = self.env['mail.thread']._replace_local_links(assignation_msg)
|
||||
|
||||
|
||||
task.message_notify(
|
||||
subject=_('You have been assigned to %s') % task.display_name,
|
||||
body=assignation_msg,
|
||||
partner_ids=[(4, assignee.partner_id.id)],
|
||||
record_name=task.display_name,
|
||||
notif_layout='mail.mail_notification_light',
|
||||
model_description=model_description,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@api.multi
|
||||
def write(self, vals):
|
||||
# Notify only new assignees
|
||||
if 'assignee_ids' in vals:
|
||||
new_assignee_ids = vals['assignee_ids'][0][2].copy()
|
||||
for a in self.assignee_ids:
|
||||
if a.id in new_assignee_ids:
|
||||
new_assignee_ids.remove(a.id)
|
||||
self.subscribe_and_notify_assignees(new_assignee_ids)
|
||||
|
||||
result = super(Task, self).write(vals)
|
||||
|
||||
return result
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
task = super(Task, self).create(vals)
|
||||
task.subscribe_and_notify_assignees()
|
||||
return task
|
||||
|
||||
|
||||
@api.multi
|
||||
def _track_subtype(self, init_values):
|
||||
self.ensure_one()
|
||||
# keep notification of new task when creating a new task
|
||||
res = super(Task, self)._track_subtype(init_values)
|
||||
if res == 'project.mt_task_new':
|
||||
return res
|
||||
# if assignees change, notify it
|
||||
if len(init_values) == 1 and 'assignee_ids' in init_values:
|
||||
return 'project_assignees.mt_task_assignees'
|
||||
|
||||
return super(Task, self)._track_subtype(init_values)
|
@@ -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>
|
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "project_average_acceptable_time",
|
||||
"version": "12.0.1.0.0",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://github.com/elabore-coop/project-tools",
|
||||
"maintainer": "Clément Thomas",
|
||||
|
@@ -7,7 +7,7 @@ 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")
|
||||
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)
|
||||
|
||||
|
@@ -1,2 +1,3 @@
|
||||
|
||||
from . import project_project
|
||||
from . import project_project
|
||||
from . import res_partner
|
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
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<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">
|
||||
<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"/>
|
||||
@@ -23,9 +23,14 @@
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.edit_project"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="subtask_project_id" position="after">
|
||||
<field name="average_acceptable_time" widget="float_time"/>
|
||||
</field>
|
||||
<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": "12.0.0.1.0",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Alusage",
|
||||
"website": "https://alusage.fr",
|
||||
"data": [
|
||||
|
@@ -1,14 +1,16 @@
|
||||
==============================
|
||||
project_timesheet_funding_wish
|
||||
==============================
|
||||
=================
|
||||
project_link_from_invoice
|
||||
=================
|
||||
|
||||
Add a funding wish select field to timesheet line.
|
||||
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_timesheet_funding_wish``.
|
||||
``project_link_from_invoice``.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
@@ -16,8 +18,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.
|
||||
|
||||
@@ -30,9 +33,7 @@ Images
|
||||
|
||||
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
|
||||
-------
|
||||
@@ -42,6 +43,5 @@ The development of this module has been financially supported by:
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
This module is maintained by Elabore.
|
||||
|
||||
|
||||
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
|
@@ -2,38 +2,40 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "project_timesheet_funding_wish",
|
||||
"version": "12.0.1.0.0",
|
||||
"name": "project_link_from_invoice",
|
||||
"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": "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_timesheet_funding_wish
|
||||
==============================
|
||||
=================
|
||||
project_link_from_invoice
|
||||
=================
|
||||
|
||||
Add a funding wish select field to timesheet line.
|
||||
Users can access to related project from invoices
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Use Odoo normal procedure to install add-ons to install
|
||||
``project_timesheet_funding_wish``.
|
||||
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
|
||||
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 <https://github.com/stephansainleger>
|
||||
|
||||
Funders
|
||||
-------
|
||||
|
||||
The development of this module has been financially supported by:
|
||||
* Elabore (https://elabore.coop)
|
||||
|
||||
@@ -64,7 +67,9 @@ This module is maintained by Elabore.
|
||||
# any module necessary for this one to work correctly
|
||||
"depends": [
|
||||
"base",
|
||||
"hr_timesheet",
|
||||
"project",
|
||||
"account",
|
||||
"sale"
|
||||
],
|
||||
"qweb": [
|
||||
# "static/src/xml/*.xml",
|
||||
@@ -74,7 +79,7 @@ This module is maintained by Elabore.
|
||||
},
|
||||
# always loaded
|
||||
"data": [
|
||||
"views/hr_timesheet.xml",
|
||||
"views/account_move_view.xml",
|
||||
],
|
||||
# only loaded in demonstration mode
|
||||
"demo": [],
|
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
|
2
project_name_from_quote/.gitignore
vendored
Normal file
2
project_name_from_quote/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.*~
|
||||
*pyc
|
57
project_name_from_quote/README.rst
Normal file
57
project_name_from_quote/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.
|
2
project_name_from_quote/__init__.py
Normal file
2
project_name_from_quote/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
from . import models
|
36
project_name_from_quote/__manifest__.py
Normal file
36
project_name_from_quote/__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_quote",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Stéphan Sainléger",
|
||||
"license": "AGPL-3",
|
||||
"category": "Tools",
|
||||
"summary": "Use quote name as project name",
|
||||
# any module necessary for this one to work correctly
|
||||
"depends": [
|
||||
"base",
|
||||
"sale_project",
|
||||
"account_quotation_sale_order_invoice_title",
|
||||
],
|
||||
"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_quote/models/__init__.py
Normal file
1
project_name_from_quote/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import sale_order
|
11
project_name_from_quote/models/sale_order.py
Normal file
11
project_name_from_quote/models/sale_order.py
Normal file
@@ -0,0 +1,11 @@
|
||||
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()
|
||||
values["name"] = self.order_id.so_title
|
||||
return values
|
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": "12.0.1.0.0",
|
||||
"version": "16.0.1.2.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Stéphan Sainléger",
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.0\n"
|
||||
"Project-Id-Version: Odoo Server 14.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-08-26 12:51+0000\n"
|
||||
"PO-Revision-Date: 2022-08-26 12:51+0000\n"
|
||||
|
@@ -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>
|
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "project_task_portal_form",
|
||||
"version": "12.0.1.1.0",
|
||||
"version": "16.0.1.1.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Stéphan Sainléger",
|
||||
|
@@ -11,9 +11,9 @@ class PortalTaskCreation(CustomerPortal):
|
||||
"name",
|
||||
"service_id",
|
||||
"request_type_id",
|
||||
"small_description",
|
||||
"access",
|
||||
"bug_report",
|
||||
"small_description", #not in v14
|
||||
"access", #not in v14
|
||||
"bug_report", #not in v14
|
||||
"priority",
|
||||
]
|
||||
|
||||
@@ -51,7 +51,7 @@ class PortalTaskCreation(CustomerPortal):
|
||||
website=True,
|
||||
)
|
||||
def portal_task_creation(self, access_token=None, redirect=None, **kw):
|
||||
values = self._task_get_page_view_values(request.env.user.partner_id, access_token, **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()
|
||||
@@ -79,12 +79,17 @@ class PortalTaskCreation(CustomerPortal):
|
||||
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(
|
||||
@@ -100,17 +105,21 @@ class PortalTaskCreation(CustomerPortal):
|
||||
values = self._compute_form_data(kwargs)
|
||||
values["project_id"] = user.default_project_id.id
|
||||
values["partner_id"] = user.partner_id.id
|
||||
values["user_id"] = user.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 values.get("attachments", False):
|
||||
for file in files:
|
||||
attachment_value = {
|
||||
'name': file.filename,
|
||||
'datas': base64.encodestring(file.read()),
|
||||
'datas_fname': file.filename,
|
||||
'datas': base64.encodestring(file.read()),
|
||||
'res_model': "project.task",
|
||||
'res_id': task_id,
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "project_timebox",
|
||||
"version": "12.0.1.0.0",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Stéphan Sainléger",
|
||||
|
@@ -15,16 +15,6 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: project_timebox
|
||||
#: model_terms:ir.ui.view,arch_db:project_timebox.portal_my_task_timebox
|
||||
msgid "<strong>Timebox Max:</strong>"
|
||||
msgstr "<strong>Temps estimé maxi :</strong>"
|
||||
|
||||
#. module: project_timebox
|
||||
#: model_terms:ir.ui.view,arch_db:project_timebox.portal_my_task_timebox
|
||||
msgid "<strong>Timebox Min:</strong>"
|
||||
msgstr "<strong>Temps estimé mini :</strong>"
|
||||
|
||||
#. module: project_timebox
|
||||
#: model:ir.model.fields,field_description:project_timebox.field_timebox__create_uid
|
||||
msgid "Created by"
|
||||
|
@@ -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="after">
|
||||
<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 +0,0 @@
|
||||
This directory should contain the *.po for Odoo translation.
|
@@ -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": "12.0.1.0.0",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Stéphan Sainléger",
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.0\n"
|
||||
"Project-Id-Version: Odoo Server 14.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-08-25 15:58+0000\n"
|
||||
"PO-Revision-Date: 2022-08-25 15:58+0000\n"
|
||||
|
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