20 Commits

Author SHA1 Message Date
clementthomas
6b8c423a63 [FIX] project_task_portal_form: fix access right error when portal user send support request 2023-04-17 08:54:06 +02:00
clementthomas
758d448ad1 [FIX] project_average_acceptable_time: view priority 2023-04-13 10:42:56 +02:00
clementthomas
2ca161594a [FIX] project_assignees: track assignees
change chatter message behaviour when change assignees
2023-04-13 10:06:13 +02:00
clementthomas
d49387ed2a [IMP] project_assignees: add notification for new assignees 2023-04-12 13:48:33 +02:00
clementthomas
66c35be70d [ADD] project_average_acceptable_time 2023-03-31 16:11:50 +02:00
clementthomas
86711f2884 [FIX] project_assignees: Fix bug when save task 2023-03-31 16:11:50 +02:00
clementthomas
3c78eb58a7 [IMP] project_task_portal_form: Current user as user_id in portal task request 2023-03-31 16:11:50 +02:00
clementthomas
9b4cef63f0 [IMP] project_assignees: chatter auto subscription to assignees 2023-03-31 16:11:50 +02:00
clementthomas
5e7af745c9 [FIX] project_task_portal_form: allow multiple uploads in portal 2023-03-31 16:11:50 +02:00
Stéphan Sainléger
ed987d03b9 [I18N] Add french translations 2022-10-03 14:56:55 +02:00
Stéphan Sainléger
0dd04c8ec6 [IMP] Add file import field in portal task creation form 2022-10-03 14:56:55 +02:00
Stéphan Sainléger
bab8138f11 [ADD] create `project_task_portal_form` add-on 2022-10-03 14:56:55 +02:00
Stéphan Sainléger
75950af5a6 [ADD] create `project_request_data` add-on 2022-10-03 14:56:55 +02:00
Stéphan Sainléger
3b045229d1 [ADD] create `project_user_default_project` add-on 2022-10-03 14:56:55 +02:00
Stéphan Sainléger
5ad7c22034 [IMP] project_assignees: add assignee_ids field to task portal view 2022-10-03 14:56:55 +02:00
Stéphan Sainléger
1952cd17e8 [IMP] project_timebox: add timebox fields in task portal view 2022-10-03 14:56:55 +02:00
Stéphan Sainléger
fd63ab1709 [ADD] project_timebox: create addon to estimate task effort
Adds fields to estimate the min and max time needed to solve a task.

Task: [JOI-13](https://justodooit.fr/mail/view?model=project.task&res_id=13&access_token=cca0b860-25d1-472d-9da1-76f68b01a932)
2022-08-25 17:19:31 +02:00
Stéphan Sainléger
d6fce31db5 [ADD] create `project_timesheet_funding_wish` add-on
Add timesheet line fields:
- ``funding_wish`` to inform about if the user expects a payment
for the registered time.
- ``treated`` to keep track if the timesheet line funding wish has
been taken into account.

Task: JOI-13
Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>
2022-08-25 17:19:31 +02:00
Nicolas JEUDY
677999bf9f [ADD] create project_funders to track funds on tasks
Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>
2022-08-25 17:19:31 +02:00
Valentin Lab
d4f7f9626d [ADD] add `project_assignees` add-on
Add a field in ``project.task`` to assign users to task. This
completes ``user_id`` field, that is then considered as the owner of
the task. Assignment becomes optional and can now target multiple
users.

Task: JOI-13
Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>
2022-08-25 17:19:31 +02:00
64 changed files with 383 additions and 1080 deletions

View File

@@ -3,7 +3,7 @@
{ {
"name": "project_assignees", "name": "project_assignees",
"version": "16.0.1.1.0", "version": "12.0.1.0.0",
"author": "Elabore", "author": "Elabore",
"website": "https://github.com/elabore-coop/project-tools", "website": "https://github.com/elabore-coop/project-tools",
"maintainer": "Stéphan Sainléger", "maintainer": "Stéphan Sainléger",
@@ -69,7 +69,6 @@ This module is maintained by Elabore.
"depends": [ "depends": [
"base", "base",
"project", "project",
"project_task_portal_form",
], ],
"qweb": [ "qweb": [
# "static/src/xml/*.xml", # "static/src/xml/*.xml",
@@ -79,6 +78,7 @@ This module is maintained by Elabore.
}, },
# always loaded # always loaded
"data": [ "data": [
"data/project_assignees_data.xml",
"views/project_task.xml", "views/project_task.xml",
"views/portal_template.xml", "views/portal_template.xml",
], ],

View File

@@ -0,0 +1,35 @@
<?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&amp;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>

View File

@@ -4,11 +4,11 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 16.0\n" "Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-11-02 07:56+0000\n" "POT-Creation-Date: 2023-04-12 11:37+0000\n"
"PO-Revision-Date: 2023-11-02 07:56+0000\n" "PO-Revision-Date: 2023-04-12 11:37+0000\n"
"Last-Translator: \n" "Last-Translator: <>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@@ -18,19 +18,66 @@ msgstr ""
#. module: project_assignees #. module: project_assignees
#: model_terms:ir.ui.view,arch_db:project_assignees.portal_my_task_assignees #: model_terms:ir.ui.view,arch_db:project_assignees.portal_my_task_assignees
msgid "<strong>Other assignees</strong>" msgid "<strong>Other assignees</strong>"
msgstr "<strong>Autres intervenants</strong>" msgstr "<strong>Assigné à</strong>"
#. module: project_assignees #. module: project_assignees
#: model:ir.model.fields,field_description:project_assignees.field_project_task__assignee_ids #: model:mail.message.subtype,name:project_assignees.mt_task_assignees
msgid "Assignees" msgid "Assignees change"
msgstr "Autres assignations" msgstr "Changement d'assignation"
#. module: project_assignees
#: model:mail.message.subtype,description:project_assignees.mt_task_assignees
msgid "Assignees changed"
msgstr "Changement d'assignation"
#. module: project_assignees #. module: project_assignees
#: model_terms:ir.ui.view,arch_db:project_assignees.portal_my_task_assignees #: model_terms:ir.ui.view,arch_db:project_assignees.portal_my_task_assignees
msgid "Contact" msgid "Contact"
msgstr "" 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 #. module: project_assignees
#: model:ir.model,name:project_assignees.model_project_task #: model:ir.model,name:project_assignees.model_project_task
msgid "Task" msgid "Task"
msgstr "Tâche" 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é à "

View File

@@ -1,9 +1,106 @@
from odoo import models, fields from odoo import models, fields, _, api
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): class Task(models.Model):
_inherit = "project.task" _inherit = "project.task"
assignee_ids = fields.Many2many('res.users', 'assignee_ids_rel', string='Assignees') assignee_ids = fields.Many2many('res.users', 'assignee_ids_rel', string='Other Assignees', track_visibility='change')
@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)

View File

@@ -1,20 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<template id="portal_my_task_assignees" name="My Task: Assignees" inherit_id="project.portal_my_task" priority="40"> <template id="portal_my_task_assignees" name="My Task: Assignees" inherit_id="project.portal_my_task" priority="40">
<xpath expr="//t[@t-foreach='task.user_ids']" position="after"> <xpath expr="//div[hasclass('flex-grow-0')]/../../.." position="inside">
<div class="col-12 col-md-12 pb-2" t-if="task.assignee_ids"> <div class="col-12 col-md-6 pb-2" t-if="task.assignee_ids">
<strong>Other assignees</strong> <strong>Other assignees</strong>
<div class="row"> <div class="row">
<t t-foreach="task.assignee_ids" t-as="user"> <t t-foreach="task.assignee_ids" t-as="assignee">
<div class="d-flex mb-3 flex-nowrap"> <div class="col flex-grow-0 pr-3">
<img class="rounded-circle mt-1 o_portal_contact_img" t-att-src="image_data_uri(user.avatar_1024)" alt="Contact"/> <img t-if="assignee.image" class="rounded-circle mt-1 o_portal_contact_img" t-att-src="image_data_uri(assignee.image)" alt="Contact" />
<div class="ms-2"> <img t-else="" class="rounded-circle mt-1 o_portal_contact_img" src="/web/static/src/img/user_menu_avatar.png" alt="Contact" />
<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>
<div class="col pl-md-0">
<strong>
<span t-field="assignee.name" />
</strong>
<span t-field="assignee.email" />
<span t-field="assignee.phone" />
</div> </div>
</t> </t>
</div> </div>

View File

@@ -6,7 +6,7 @@
<field name="inherit_id" ref="project.view_task_form2" /> <field name="inherit_id" ref="project.view_task_form2" />
<field name="priority" eval="99" /> <field name="priority" eval="99" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='user_ids']" position="after"> <xpath expr="//field[@name='user_id']" position="after">
<field name="assignee_ids" widget="many2many_tags" /> <field name="assignee_ids" widget="many2many_tags" />
</xpath> </xpath>
</field> </field>
@@ -19,11 +19,8 @@
<field name="priority" eval="99" /> <field name="priority" eval="99" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<filter name="my_tasks" position="attributes"> <filter name="my_tasks" position="attributes">
<attribute name="domain">['|', ('user_ids', 'in', uid), ('assignee_ids', 'in', uid)]</attribute> <attribute name="domain">['|', ('user_id', '=', uid), ('assignee_ids', 'in', uid)]</attribute>
</filter> </filter>
<xpath expr="//field[@name='partner_id']" position="after">
<field name="assignee_ids" filter_domain="[('assignee_ids.user_ids.name', 'ilike', self)]"/>
</xpath>
</field> </field>
</record> </record>
</odoo> </odoo>

View File

@@ -3,7 +3,7 @@
{ {
"name": "project_average_acceptable_time", "name": "project_average_acceptable_time",
"version": "16.0.1.0.0", "version": "12.0.1.0.0",
"author": "Elabore", "author": "Elabore",
"website": "https://github.com/elabore-coop/project-tools", "website": "https://github.com/elabore-coop/project-tools",
"maintainer": "Clément Thomas", "maintainer": "Clément Thomas",

View File

@@ -7,7 +7,7 @@ from odoo.addons.portal.controllers.portal import CustomerPortal
class CustomCustomerPortal(CustomerPortal): class CustomCustomerPortal(CustomerPortal):
@route(["/my/account"], type="http", auth="user", website=True) @route(["/my/account"], type="http", auth="user", website=True)
def account(self, redirect=None, **post): 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 self.OPTIONAL_BILLING_FIELDS.append("average_acceptable_time")
response = super(CustomCustomerPortal, self).account(redirect, **post) response = super(CustomCustomerPortal, self).account(redirect, **post)

View File

@@ -1,3 +1,2 @@
from . import project_project from . import project_project
from . import res_partner

View File

@@ -1,10 +0,0 @@
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

View File

@@ -8,7 +8,7 @@
<field name="inherit_id" ref="project.view_project_kanban"/> <field name="inherit_id" ref="project.view_project_kanban"/>
<field name="priority">999</field> <field name="priority">999</field>
<field name="arch" type="xml"> <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"> <div class="o_project_kanban_boxes">
<span>Average acceptable time:<![CDATA[&nbsp;]]></span> <span>Average acceptable time:<![CDATA[&nbsp;]]></span>
<field name="average_acceptable_time" widget="float_time"/> <field name="average_acceptable_time" widget="float_time"/>
@@ -23,14 +23,9 @@
<field name="model">project.project</field> <field name="model">project.project</field>
<field name="inherit_id" ref="project.edit_project"/> <field name="inherit_id" ref="project.edit_project"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//div[@id='subtask_settings']/div[@class='o_setting_right_pane']" position="inside"> <field name="subtask_project_id" position="after">
<div class="o_settings_average_acceptable_time" style="margin-top:10px;">
<!-- <span>Average acceptable time:<![CDATA[&nbsp;]]></span> -->
<label for="average_acceptable_time"/>
<field name="average_acceptable_time" widget="float_time"/> <field name="average_acceptable_time" widget="float_time"/>
</div> </field>
</xpath>
</field> </field>
</record> </record>
</odoo> </odoo>

View File

@@ -1,43 +0,0 @@
==========================================
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.

View File

@@ -1 +0,0 @@
from . import models

View File

@@ -1,37 +0,0 @@
# 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,
}

View File

@@ -1 +0,0 @@
from . import project_task

View File

@@ -1,7 +0,0 @@
from odoo import models
class Task(models.Model):
_inherit = "project.task"
def _get_last_sol_of_customer(self):
return False

View File

@@ -3,7 +3,7 @@
{ {
"name": "project_funders", "name": "project_funders",
"version": "16.0.1.0.0", "version": "12.0.0.1.0",
"author": "Alusage", "author": "Alusage",
"website": "https://alusage.fr", "website": "https://alusage.fr",
"data": [ "data": [

View File

@@ -1,2 +0,0 @@
from . import models

View File

@@ -1,58 +0,0 @@
# 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)"

View File

@@ -1,2 +0,0 @@
from . import account_move

View File

@@ -1,38 +0,0 @@
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)

View File

@@ -1,32 +0,0 @@
<?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>

View File

@@ -1,2 +0,0 @@
*.*~
*pyc

View File

@@ -1,57 +0,0 @@
=======================
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.

View File

@@ -1,36 +0,0 @@
# 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,
}

View File

@@ -1 +0,0 @@
from . import sale_order, crm_lead

View File

@@ -1,17 +0,0 @@
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)

View File

@@ -1,12 +0,0 @@
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

View File

@@ -1,2 +0,0 @@
*.*~
*pyc

View File

@@ -1,57 +0,0 @@
=======================
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.

View File

@@ -1,2 +0,0 @@
from . import models

View File

@@ -1,36 +0,0 @@
# 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,
}

View File

@@ -1 +0,0 @@
from . import sale_order

View File

@@ -1,11 +0,0 @@
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

View File

@@ -1,86 +0,0 @@
# 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,
}

View File

@@ -1,13 +0,0 @@
<?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>

View File

@@ -3,7 +3,7 @@
{ {
"name": "project_request_data", "name": "project_request_data",
"version": "16.0.1.2.0", "version": "12.0.1.0.0",
"author": "Elabore", "author": "Elabore",
"website": "https://elabore.coop", "website": "https://elabore.coop",
"maintainer": "Stéphan Sainléger", "maintainer": "Stéphan Sainléger",

View File

@@ -4,7 +4,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 14.0\n" "Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-08-26 12:51+0000\n" "POT-Creation-Date: 2022-08-26 12:51+0000\n"
"PO-Revision-Date: 2022-08-26 12:51+0000\n" "PO-Revision-Date: 2022-08-26 12:51+0000\n"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<template id="portal_my_task_request_data" name="My Task: Request Data" inherit_id="project.portal_my_task" priority="40"> <template id="portal_my_task_request_data" name="My Task: Request Data" inherit_id="project.portal_my_task" priority="40">
<xpath expr="//div[@id='card_body']/div[hasclass('row','mb-4','container')]" position="after"> <xpath expr="//t[@t-set='card_body']/div[hasclass('row','mb-4')]" position="after">
<div id="request_data" class="row mb-4"> <div id="request_data" class="row mb-4">
<div class="col-12 col-md-6" t-if="task.service_id"> <div class="col-12 col-md-6" t-if="task.service_id">
<strong>Service:</strong> <strong>Service:</strong>

View File

@@ -12,18 +12,4 @@
</xpath> </xpath>
</field> </field>
</record> </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> </odoo>

View File

@@ -3,7 +3,7 @@
{ {
"name": "project_task_portal_form", "name": "project_task_portal_form",
"version": "16.0.1.1.0", "version": "12.0.1.1.0",
"author": "Elabore", "author": "Elabore",
"website": "https://elabore.coop", "website": "https://elabore.coop",
"maintainer": "Stéphan Sainléger", "maintainer": "Stéphan Sainléger",

View File

@@ -11,9 +11,9 @@ class PortalTaskCreation(CustomerPortal):
"name", "name",
"service_id", "service_id",
"request_type_id", "request_type_id",
"small_description", #not in v14 "small_description",
"access", #not in v14 "access",
"bug_report", #not in v14 "bug_report",
"priority", "priority",
] ]
@@ -51,7 +51,7 @@ class PortalTaskCreation(CustomerPortal):
website=True, website=True,
) )
def portal_task_creation(self, access_token=None, redirect=None, **kw): 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) values = self._task_get_page_view_values(request.env.user.partner_id, access_token, **kw)
request_types = request.env["request.type"].sudo().search([]) request_types = request.env["request.type"].sudo().search([])
task_services = request.env["task.service"].sudo().search([]) task_services = request.env["task.service"].sudo().search([])
priorities = self._get_task_priorities() priorities = self._get_task_priorities()
@@ -79,17 +79,12 @@ class PortalTaskCreation(CustomerPortal):
description = "" description = ""
if values.get("small_description", False): if values.get("small_description", False):
description = description + "<b>DESCRIPTION:</b><br/>" + values["small_description"] description = description + "<b>DESCRIPTION:</b><br/>" + values["small_description"]
del values['small_description']
if values.get("access", False): if values.get("access", False):
description = description + "<br/><br/><b>ACCESS:</b><br/>" + values["access"] description = description + "<br/><br/><b>ACCESS:</b><br/>" + values["access"]
del values['access']
if values.get("bug_report", False): if values.get("bug_report", False):
description = description + "<br/><br/><b>BUG REPORT:</b><br/>" + values["bug_report"] description = description + "<br/><br/><b>BUG REPORT:</b><br/>" + values["bug_report"]
del values['bug_report']
values["description"] = description values["description"] = description
values["attachments"] = request.httprequest.files.getlist("attachment") values["attachments"] = request.httprequest.files.getlist("attachment")
return values return values
@http.route( @http.route(
@@ -105,21 +100,17 @@ class PortalTaskCreation(CustomerPortal):
values = self._compute_form_data(kwargs) values = self._compute_form_data(kwargs)
values["project_id"] = user.default_project_id.id values["project_id"] = user.default_project_id.id
values["partner_id"] = user.partner_id.id values["partner_id"] = user.partner_id.id
values["user_ids"] = [(6, 0, [user.id])] values["user_id"] = user.id
files = values.get("attachments", False)
del values['attachments']
# Create task # 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 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 # Add attachments
for file in files: for file in values.get("attachments", False):
attachment_value = { attachment_value = {
'name': file.filename, 'name': file.filename,
'datas': base64.encodestring(file.read()), 'datas': base64.encodestring(file.read()),
'datas_fname': file.filename,
'res_model': "project.task", 'res_model': "project.task",
'res_id': task_id, 'res_id': task_id,
} }

View File

@@ -3,7 +3,7 @@
{ {
"name": "project_timebox", "name": "project_timebox",
"version": "16.0.1.0.0", "version": "12.0.1.0.0",
"author": "Elabore", "author": "Elabore",
"website": "https://elabore.coop", "website": "https://elabore.coop",
"maintainer": "Stéphan Sainléger", "maintainer": "Stéphan Sainléger",

View File

@@ -15,6 +15,16 @@ msgstr ""
"Content-Transfer-Encoding: \n" "Content-Transfer-Encoding: \n"
"Plural-Forms: \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 #. module: project_timebox
#: model:ir.model.fields,field_description:project_timebox.field_timebox__create_uid #: model:ir.model.fields,field_description:project_timebox.field_timebox__create_uid
msgid "Created by" msgid "Created by"

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<template id="portal_my_task_timebox" name="My Task: Timebox" inherit_id="project.portal_my_task" priority="40"> <template id="portal_my_task_timebox" name="My Task: Timebox" inherit_id="project.portal_my_task" priority="40">
<xpath expr="//div[@t-if='task.date_deadline']" position="after"> <xpath expr="//t[@t-set='card_body']/div[hasclass('row','mb-4')]" position="after">
<div id="timebox" class="row mb-2"> <div id="timebox" class="row mb-2">
<div t-if="task.timebox_min_id"> <div class="col-12 col-md-6" t-if="task.timebox_min_id">
<strong>Timebox Min:</strong> <strong>Timebox Min:</strong>
<span t-field="task.timebox_min_id" /> <span t-field="task.timebox_min_id" />
</div> </div>
<div t-if="task.timebox_max_id"> <div class="col-12 col-md-6" t-if="task.timebox_max_id">
<strong>Timebox Max:</strong> <strong>Timebox Max:</strong>
<span t-field="task.timebox_max_id" /> <span t-field="task.timebox_max_id" />
</div> </div>

View File

@@ -1,16 +1,14 @@
================= ==============================
project_link_from_invoice project_timesheet_funding_wish
================= ==============================
Easily access to your projects from invoices Add a funding wish select field to timesheet line.
View project(s) in invoices tree view
Access to related projects of an invoice from a button
Installation Installation
============ ============
Use Odoo normal procedure to install add-ons to install Use Odoo normal procedure to install add-ons to install
``project_link_from_invoice``. ``project_timesheet_funding_wish``.
Known issues / Roadmap Known issues / Roadmap
====================== ======================
@@ -18,9 +16,8 @@ Known issues / Roadmap
Bug Tracker Bug Tracker
=========== ===========
Bugs are tracked on `our issues website Bugs are tracked on `our issues website <https://github.com/elabore-coop/project-tools/issues>`_. In
<https://github.com/elabore-coop/project-tools/issues>`_. In case of case of trouble, please check there if your issue has already been
trouble, please check there if your issue has already been
reported. If you spotted it first, help us smashing it by providing a reported. If you spotted it first, help us smashing it by providing a
detailed and welcomed feedback. detailed and welcomed feedback.
@@ -33,7 +30,9 @@ Images
Contributors Contributors
------------ ------------
* Clément Thomas * Stéphan Sainléger <https://github.com/stephansainleger>
* Valentin Lab <valentin.lab@kalysto.org>
* Nicolas Jeudy <https://github.com/njeudy>
Funders Funders
------- -------
@@ -43,5 +42,6 @@ The development of this module has been financially supported by:
Maintainer Maintainer
---------- ----------
This module is maintained by Elabore. This module is maintained by Elabore.

View File

@@ -1,2 +1 @@
from . import models from . import models

View File

@@ -2,40 +2,38 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{ {
"name": "project_link_from_invoice", "name": "project_timesheet_funding_wish",
"version": "16.0.1.0.0", "version": "12.0.1.0.0",
"author": "Elabore", "author": "Elabore",
"website": "https://github.com/elabore-coop/project-tools", "website": "https://github.com/elabore-coop/project-tools",
"maintainer": "Clément Thomas", "maintainer": "Stéphan Sainléger",
"license": "AGPL-3", "license": "AGPL-3",
"category": "Tools", "category": "Tools",
"summary": "Add link from invoice to project", "summary": "Add a funding wish select field to timesheet line.",
"description": """ "description": """
:image: https://img.shields.io/badge/licence-AGPL--3-blue.svg :image: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3 :alt: License: AGPL-3
================= ==============================
project_link_from_invoice project_timesheet_funding_wish
================= ==============================
Users can access to related project from invoices Add a funding wish select field to timesheet line.
Installation Installation
============ ============
Install ``project_link_from_invoice``, all dependencies will be installed by default. Use Odoo normal procedure to install add-ons to install
``project_timesheet_funding_wish``.
Known issues / Roadmap Known issues / Roadmap
====================== ======================
None yet.
Bug Tracker Bug Tracker
=========== ===========
Bugs are tracked on `our issues website Bugs are tracked on `our issues website <https://github.com/elabore-coop/project-tools/issues>`_. In
<https://github.com/elabore-coop/project-tools/issues>`_. In case of case of trouble, please check there if your issue has already been
trouble, please check there if your issue has already been
reported. If you spotted it first, help us smashing it by providing a reported. If you spotted it first, help us smashing it by providing a
detailed and welcomed feedback. detailed and welcomed feedback.
@@ -44,17 +42,16 @@ Credits
Images Images
------ ------
* Elabore: `Icon <https://elabore.coop/web/image/res.company/1/logo?unique=f3db262>`_. * Elabore: `Icon <https://elabore.coop/web/image/res.company/1/logo?unique=f3db262>`_.
Contributors Contributors
------------ ------------
* Stéphan Sainléger <https://github.com/stephansainleger>
* Clément Thomas <https://github.com/stephansainleger> * Valentin Lab <valentin.lab@kalysto.org>
* Nicolas Jeudy <https://github.com/njeudy>
Funders Funders
------- -------
The development of this module has been financially supported by: The development of this module has been financially supported by:
* Elabore (https://elabore.coop) * Elabore (https://elabore.coop)
@@ -67,9 +64,7 @@ This module is maintained by Elabore.
# any module necessary for this one to work correctly # any module necessary for this one to work correctly
"depends": [ "depends": [
"base", "base",
"project", "hr_timesheet",
"account",
"sale"
], ],
"qweb": [ "qweb": [
# "static/src/xml/*.xml", # "static/src/xml/*.xml",
@@ -79,7 +74,7 @@ This module is maintained by Elabore.
}, },
# always loaded # always loaded
"data": [ "data": [
"views/account_move_view.xml", "views/hr_timesheet.xml",
], ],
# only loaded in demonstration mode # only loaded in demonstration mode
"demo": [], "demo": [],

View File

@@ -0,0 +1 @@
This directory should contain the *.po for Odoo translation.

View File

@@ -0,0 +1,65 @@
# 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é"

View File

@@ -0,0 +1 @@
from . import hr_timesheet

View File

@@ -0,0 +1,16 @@
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)

View File

@@ -0,0 +1,27 @@
<?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>

View File

@@ -3,7 +3,7 @@
{ {
"name": "project_user_default_project", "name": "project_user_default_project",
"version": "16.0.1.0.0", "version": "12.0.1.0.0",
"author": "Elabore", "author": "Elabore",
"website": "https://elabore.coop", "website": "https://elabore.coop",
"maintainer": "Stéphan Sainléger", "maintainer": "Stéphan Sainléger",

View File

@@ -4,7 +4,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 14.0\n" "Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-08-25 15:58+0000\n" "POT-Creation-Date: 2022-08-25 15:58+0000\n"
"PO-Revision-Date: 2022-08-25 15:58+0000\n" "PO-Revision-Date: 2022-08-25 15:58+0000\n"

View File

@@ -1,45 +0,0 @@
=================
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.

View File

@@ -1,2 +0,0 @@
from . import models

View File

@@ -1,91 +0,0 @@
# 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,
}

View File

@@ -1,100 +0,0 @@
# 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é"

View File

@@ -1,2 +0,0 @@
from . import project_project, project_task

View File

@@ -1,32 +0,0 @@
from odoo import models, fields, api
class Project(models.Model):
_inherit = "project.project"
# A reprendre pour ajouter loption 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

View File

@@ -1,60 +0,0 @@
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

View File

@@ -1,63 +0,0 @@
<?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">[
'|',
'&amp;',
('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>