From bcbf82a5c265b854e5e6c966631d92cbf2cff3e6 Mon Sep 17 00:00:00 2001 From: Jordi Ballester Alomar Date: Tue, 27 Nov 2018 09:35:55 +0100 Subject: [PATCH 01/60] [ADD] mail_activity_team --- mail_activity_team/README.rst | 98 ++++ mail_activity_team/__init__.py | 1 + mail_activity_team/__manifest__.py | 23 + mail_activity_team/models/__init__.py | 3 + mail_activity_team/models/mail_activity.py | 34 ++ .../models/mail_activity_team.py | 14 + mail_activity_team/models/res_users.py | 11 + mail_activity_team/readme/CONTRIBUTORS.rst | 3 + mail_activity_team/readme/DESCRIPTION.rst | 3 + mail_activity_team/readme/USAGE.rst | 17 + .../security/ir.model.access.csv | 4 + .../security/mail_activity_team_security.xml | 15 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 419 ++++++++++++++++++ .../views/mail_activity_team_views.xml | 90 ++++ .../views/mail_activity_views.xml | 70 +++ mail_activity_team/views/res_users_views.xml | 16 + 17 files changed, 821 insertions(+) create mode 100644 mail_activity_team/README.rst create mode 100644 mail_activity_team/__init__.py create mode 100644 mail_activity_team/__manifest__.py create mode 100644 mail_activity_team/models/__init__.py create mode 100644 mail_activity_team/models/mail_activity.py create mode 100644 mail_activity_team/models/mail_activity_team.py create mode 100644 mail_activity_team/models/res_users.py create mode 100644 mail_activity_team/readme/CONTRIBUTORS.rst create mode 100644 mail_activity_team/readme/DESCRIPTION.rst create mode 100644 mail_activity_team/readme/USAGE.rst create mode 100644 mail_activity_team/security/ir.model.access.csv create mode 100644 mail_activity_team/security/mail_activity_team_security.xml create mode 100644 mail_activity_team/static/description/icon.png create mode 100644 mail_activity_team/static/description/index.html create mode 100644 mail_activity_team/views/mail_activity_team_views.xml create mode 100644 mail_activity_team/views/mail_activity_views.xml create mode 100644 mail_activity_team/views/res_users_views.xml diff --git a/mail_activity_team/README.rst b/mail_activity_team/README.rst new file mode 100644 index 000000000..0c79d92e1 --- /dev/null +++ b/mail_activity_team/README.rst @@ -0,0 +1,98 @@ +================== +Mail Activity Team +================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fsocial-lightgray.png?logo=github + :target: https://github.com/OCA/social/tree/11.0/mail_activity_team + :alt: OCA/social +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/social-11-0/social-11-0-mail_activity_team + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/205/11.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds the possibility to assign teams to activities. + + + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To set up new teams: + +#. Go to *Settings / Activate developer mode* +#. Go to *Settings / Technical / Email / Activity Teams* +#. Create a new Team and assign (optionally) the models in which it will + be used, and the members of the team. + +You can also assign a user to Activity teams going to +*Settings / Users & Companies / Users*, and in the *Preferences* tab, field +Activity Teams. + +When you create a new activity the application will propose the user's +assigned team. + +You can report on the activities assigned to a team going to +*Dashboards / Activities*, and then filter by a specific team or group by +teams. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Eficent + +Contributors +~~~~~~~~~~~~ + +* `Eficent `_: + + * Jordi Ballester Alomar (jordi.ballester@eficent.com) + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/social `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_activity_team/__init__.py b/mail_activity_team/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/mail_activity_team/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py new file mode 100644 index 000000000..4963644fb --- /dev/null +++ b/mail_activity_team/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + 'name': 'Mail Activity Team', + 'summary': 'Add Teams to Activities', + 'version': '11.0.1.0.0', + 'development_status': 'Beta', + 'category': 'Social Network', + 'website': 'https://github.com/OCA/social', + 'author': 'Eficent, Odoo Community Association (OCA)', + 'license': 'AGPL-3', + 'installable': True, + 'depends': [ + 'mail_activity_board', + ], + 'data': [ + 'security/ir.model.access.csv', + 'security/mail_activity_team_security.xml', + 'views/mail_activity_team_views.xml', + 'views/mail_activity_views.xml', + 'views/res_users_views.xml', + ], +} diff --git a/mail_activity_team/models/__init__.py b/mail_activity_team/models/__init__.py new file mode 100644 index 000000000..2f37e6ccd --- /dev/null +++ b/mail_activity_team/models/__init__.py @@ -0,0 +1,3 @@ +from . import mail_activity_team +from . import mail_activity +from . import res_users diff --git a/mail_activity_team/models/mail_activity.py b/mail_activity_team/models/mail_activity.py new file mode 100644 index 000000000..51cf198f8 --- /dev/null +++ b/mail_activity_team/models/mail_activity.py @@ -0,0 +1,34 @@ +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import api, models, fields + + +class MailActivity(models.Model): + _inherit = "mail.activity" + + def _get_default_team_id(self): + res_model = self.env.context.get('default_res_model', False) + model = self.env['ir.model'].search([('model', '=', res_model)], + limit=1) + domain = [('member_ids', 'in', [self.env.uid])] + if res_model: + domain.extend(['|', ('res_model_ids', '=', False), + ('res_model_ids', 'in', model.ids)]) + return self.env['mail.activity.team'].search(domain, limit=1) + + team_id = fields.Many2one('mail.activity.team', + default=lambda s: s._get_default_team_id(),) + + @api.onchange('res_model_id', 'user_id') + def _onchange_model_user(self): + res = {'domain': {'team_id': []}} + if self.team_id: + if self.user_id not in self.team_id.member_ids: + self.team_id = False + if self.res_model_id: + res['domain']['team_id'] = [ + ('res_model_ids', 'in', self.res_model_id.ids)] + if self.user_id: + res['domain']['team_id'] = [ + ('member_ids', 'in', self.user_id.ids)] + return res diff --git a/mail_activity_team/models/mail_activity_team.py b/mail_activity_team/models/mail_activity_team.py new file mode 100644 index 000000000..81d0676f6 --- /dev/null +++ b/mail_activity_team/models/mail_activity_team.py @@ -0,0 +1,14 @@ +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import fields, models + + +class MailActivityTeam(models.Model): + _name = "mail.activity.team" + _description = 'Mail Activity Team' + + name = fields.Char(string='Name', required=True, translate=True) + active = fields.Boolean(string='Active', default=True) + res_model_ids = fields.Many2many('ir.model', string='Used models') + member_ids = fields.Many2many('res.users', 'mail_activity_team_users_rel', + string="Team Members") diff --git a/mail_activity_team/models/res_users.py b/mail_activity_team/models/res_users.py new file mode 100644 index 000000000..b55ae842f --- /dev/null +++ b/mail_activity_team/models/res_users.py @@ -0,0 +1,11 @@ +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import models, fields + + +class ResUsers(models.Model): + _inherit = "res.users" + + activity_team_ids = fields.Many2many('mail.activity.team', + 'mail_activity_team_users_rel', + string="Activity Teams") diff --git a/mail_activity_team/readme/CONTRIBUTORS.rst b/mail_activity_team/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..3507ebd1f --- /dev/null +++ b/mail_activity_team/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Eficent `_: + + * Jordi Ballester Alomar (jordi.ballester@eficent.com) diff --git a/mail_activity_team/readme/DESCRIPTION.rst b/mail_activity_team/readme/DESCRIPTION.rst new file mode 100644 index 000000000..c0a2e3ae1 --- /dev/null +++ b/mail_activity_team/readme/DESCRIPTION.rst @@ -0,0 +1,3 @@ +This module adds the possibility to assign teams to activities. + + diff --git a/mail_activity_team/readme/USAGE.rst b/mail_activity_team/readme/USAGE.rst new file mode 100644 index 000000000..a9b4344f8 --- /dev/null +++ b/mail_activity_team/readme/USAGE.rst @@ -0,0 +1,17 @@ +To set up new teams: + +#. Go to *Settings / Activate developer mode* +#. Go to *Settings / Technical / Email / Activity Teams* +#. Create a new Team and assign (optionally) the models in which it will + be used, and the members of the team. + +You can also assign a user to Activity teams going to +*Settings / Users & Companies / Users*, and in the *Preferences* tab, field +Activity Teams. + +When you create a new activity the application will propose the user's +assigned team. + +You can report on the activities assigned to a team going to +*Dashboards / Activities*, and then filter by a specific team or group by +teams. diff --git a/mail_activity_team/security/ir.model.access.csv b/mail_activity_team/security/ir.model.access.csv new file mode 100644 index 000000000..c5efccfc9 --- /dev/null +++ b/mail_activity_team/security/ir.model.access.csv @@ -0,0 +1,4 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +access_mail_activity_team_all,mail.activity.team.all,model_mail_activity_team,,1,0,0,0 +access_mail_activity_team_user,mail.activity.team.user,model_mail_activity_team,base.group_user,1,1,0,0 +access_mail_activity_team_system_user,mail.activity.team.system.user,model_mail_activity_team,base.group_system_user,1,1,1,1 diff --git a/mail_activity_team/security/mail_activity_team_security.xml b/mail_activity_team/security/mail_activity_team_security.xml new file mode 100644 index 000000000..9ac63631b --- /dev/null +++ b/mail_activity_team/security/mail_activity_team_security.xml @@ -0,0 +1,15 @@ + + + + + mail.activity: user: my team + + ['|', '&'('team_id', '=', False),('user_id', '=', user.id),('team_id', '=', user.team_ids.ids)] + + + + + + + + diff --git a/mail_activity_team/static/description/icon.png b/mail_activity_team/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~! zVpnB`o+K7|Al`Q_U;eD$B zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__ zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_ zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)( z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9 zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz# z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K= z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C zuVl&0duN<;uOsB3%T9Fp8t{ED108<+W(nOZd?gDnfNBC3>M8WE61$So|P zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1 zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_ zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8 zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ> zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD z#z-)AXwSRY?OPefw^iI+ z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$ z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6 zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+ z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC) zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x! zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8 z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n= z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@ zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y< zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6 zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6% z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(| z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6 z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d} z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB z z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zl&#s4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6# z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f# zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv! zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG z-wfS zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9 z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE# z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1 zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$ zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV( z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4 z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{ zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx} z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22 zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t< z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{} zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/mail_activity_team/static/description/index.html b/mail_activity_team/static/description/index.html new file mode 100644 index 000000000..8862473c6 --- /dev/null +++ b/mail_activity_team/static/description/index.html @@ -0,0 +1,419 @@ + + + + + + +Mail Activity Team + + + +
+

Mail Activity Team

+ + +

Beta License: AGPL-3 OCA/social Translate me on Weblate Try me on Runbot

+

This module adds the possibility to assign teams to activities.

+

Table of contents

+ +
+

Usage

+

To set up new teams:

+
    +
  1. Go to Settings / Activate developer mode
  2. +
  3. Go to Settings / Technical / Email / Activity Teams
  4. +
  5. Create a new Team and assign (optionally) the models in which it will +be used, and the members of the team.
  6. +
+

You can also assign a user to Activity teams going to +Settings / Users & Companies / Users, and in the Preferences tab, field +Activity Teams.

+

When you create a new activity the application will propose the user’s +assigned team.

+

You can report on the activities assigned to a team going to +Dashboards / Activities, and then filter by a specific team or group by +teams.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Eficent
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/social project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/mail_activity_team/views/mail_activity_team_views.xml b/mail_activity_team/views/mail_activity_team_views.xml new file mode 100644 index 000000000..52203d2dd --- /dev/null +++ b/mail_activity_team/views/mail_activity_team_views.xml @@ -0,0 +1,90 @@ + + + + + + + + mail.activity.team.view.form + mail.activity.team + +
+ +
+ +
+ + + + + + + + + + + + + +
+
+
+
+ + + + + mail.activity.team.view.tree + mail.activity.team + + + + + + + + + + + + mail.activity.team.view.search + mail.activity.team + + + + + + + + + + + + + Activity Teams + mail.activity.team + form + tree,form + [] + {} + + + + + + + +
diff --git a/mail_activity_team/views/mail_activity_views.xml b/mail_activity_team/views/mail_activity_views.xml new file mode 100644 index 000000000..93ad71b91 --- /dev/null +++ b/mail_activity_team/views/mail_activity_views.xml @@ -0,0 +1,70 @@ + + + + + mail.activity.view.form.popup + mail.activity + + + + + + + + + + mail.activity.view.tree + mail.activity + + + + + + + + + + mail.activity.view.form + mail.activity + + + + + + + + + + mail.activity.boards.view.kanban + mail.activity + + + + + + +
+
+ Team: +
+
+
+
+ + + + mail.activity.boards.view.search + mail.activity + + + + + + + + + + + + +
diff --git a/mail_activity_team/views/res_users_views.xml b/mail_activity_team/views/res_users_views.xml new file mode 100644 index 000000000..bf79365e4 --- /dev/null +++ b/mail_activity_team/views/res_users_views.xml @@ -0,0 +1,16 @@ + + + + + res.users.form.activity.team + res.users + + + + + + + + + + From 10e6ccde0d3ce1c0cf60a51bdca6bc8c0f9a4cab Mon Sep 17 00:00:00 2001 From: mreficent Date: Tue, 27 Nov 2018 12:22:49 +0100 Subject: [PATCH 02/60] [IMP] Some improvements and fixes --- mail_activity_team/models/mail_activity.py | 70 ++++++++++++++----- .../models/mail_activity_team.py | 69 ++++++++++++++++-- mail_activity_team/models/res_users.py | 8 ++- .../security/ir.model.access.csv | 2 +- .../security/mail_activity_team_security.xml | 4 +- .../views/mail_activity_team_views.xml | 16 +++-- 6 files changed, 134 insertions(+), 35 deletions(-) diff --git a/mail_activity_team/models/mail_activity.py b/mail_activity_team/models/mail_activity.py index 51cf198f8..46dd6de29 100644 --- a/mail_activity_team/models/mail_activity.py +++ b/mail_activity_team/models/mail_activity.py @@ -1,34 +1,66 @@ # Copyright 2018 Eficent Business and IT Consulting Services, S.L. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import api, models, fields +from odoo import api, models, fields, _ +from odoo.exceptions import ValidationError class MailActivity(models.Model): _inherit = "mail.activity" - def _get_default_team_id(self): - res_model = self.env.context.get('default_res_model', False) - model = self.env['ir.model'].search([('model', '=', res_model)], - limit=1) - domain = [('member_ids', 'in', [self.env.uid])] + def _get_default_team_id(self, user_id=None): + if not user_id: + user_id = self.env.uid + res_model = self.env.context.get('default_res_model') + model = self.env['ir.model'].search( + [('model', '=', res_model)], limit=1) + domain = [('member_ids', 'in', [user_id])] if res_model: domain.extend(['|', ('res_model_ids', '=', False), ('res_model_ids', 'in', model.ids)]) return self.env['mail.activity.team'].search(domain, limit=1) - team_id = fields.Many2one('mail.activity.team', - default=lambda s: s._get_default_team_id(),) + team_id = fields.Many2one( + comodel_name='mail.activity.team', + default=lambda s: s._get_default_team_id(), + ) - @api.onchange('res_model_id', 'user_id') - def _onchange_model_user(self): + @api.onchange('user_id') + def _onchange_user_id(self): res = {'domain': {'team_id': []}} - if self.team_id: - if self.user_id not in self.team_id.member_ids: - self.team_id = False - if self.res_model_id: - res['domain']['team_id'] = [ - ('res_model_ids', 'in', self.res_model_id.ids)] - if self.user_id: - res['domain']['team_id'] = [ - ('member_ids', 'in', self.user_id.ids)] + if not self.user_id: + return res + res['domain']['team_id'] = [ + '|', + ('res_model_ids', '=', False), + ('res_model_ids', 'in', self.res_model_id.ids)] + if self.team_id and self.user_id in self.team_id.member_ids: + return res + self.team_id = self.with_context( + default_res_model=self.res_model_id.id).\ + _get_default_team_id(user_id=self.user_id.id) return res + + @api.onchange('team_id') + def _onchange_team_id(self): + res = {'domain': {'user_id': []}} + if not self.team_id: + return res + res['domain']['user_id'] = [('id', 'in', self.team_id.member_ids.ids)] + if self.user_id and self.user_id in self.team_id.member_ids: + return res + if self.team_id.user_id: + self.user_id = self.team_id.user_id + elif self.env.user in self.team_id.member_ids.ids: + self.user_id = self.env.user + else: + self.user_id = self.env['res.users'] + return res + + @api.multi + @api.constrains('team_id', 'user_id') + def _check_team_and_user(self): + for activity in self: + if activity.team_id and activity.user_id and \ + activity.user_id not in self.team_id.member_ids: + raise ValidationError( + _('The assigned user is not member of the team.')) diff --git a/mail_activity_team/models/mail_activity_team.py b/mail_activity_team/models/mail_activity_team.py index 81d0676f6..f97c185b5 100644 --- a/mail_activity_team/models/mail_activity_team.py +++ b/mail_activity_team/models/mail_activity_team.py @@ -1,14 +1,71 @@ # Copyright 2018 Eficent Business and IT Consulting Services, S.L. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import fields, models +from odoo import api, fields, models class MailActivityTeam(models.Model): _name = "mail.activity.team" _description = 'Mail Activity Team' - name = fields.Char(string='Name', required=True, translate=True) - active = fields.Boolean(string='Active', default=True) - res_model_ids = fields.Many2many('ir.model', string='Used models') - member_ids = fields.Many2many('res.users', 'mail_activity_team_users_rel', - string="Team Members") + @api.depends('res_model_ids', 'member_ids') + def _compute_missing_activities(self): + activity_model = self.env['mail.activity'] + for team in self: + domain = [('team_id', '=', False)] + if team.member_ids: + domain.append(('user_id', 'in', team.member_ids.ids)) + if team.res_model_ids: + domain.append(('res_model_id', 'in', team.res_model_ids.ids)) + team.count_missing_activities = activity_model.search( + domain, count=True) + + name = fields.Char( + string='Name', + required=True, + translate=True, + ) + active = fields.Boolean( + string='Active', + default=True, + ) + res_model_ids = fields.Many2many( + comodel_name='ir.model', + string='Used models', + domain=lambda self: [ + ('model', 'in', + [k for k in self.env.registry if issubclass( + type(self.env[k]), type(self.env['mail.activity.mixin'])) + and self.env[k]._auto]) + ], + ) + member_ids = fields.Many2many( + comodel_name='res.users', + relation='mail_activity_team_users_rel', + string="Team Members", + ) + user_id = fields.Many2one( + comodel_name='res.users', + string='Team Leader', + domain="[('id', 'in', member_ids)]", + ) + count_missing_activities = fields.Integer( + string="Missing Activities", + compute='_compute_missing_activities', + default=0, + ) + + @api.onchange('member_ids') + def _onchange_member_ids(self): + if self.user_id and self.user_id not in self.member_ids: + self.user_id = False + + def assign_team_to_unassigned_activities(self): + activity_model = self.env['mail.activity'] + for team in self: + domain = [('team_id', '=', False)] + if team.member_ids: + domain.append(('user_id', 'in', team.member_ids.ids)) + if team.res_model_ids: + domain.append(('res_model_id', 'in', team.res_model_ids.ids)) + missing_activities = activity_model.search(domain) + missing_activities.write({'team_id': team.id}) diff --git a/mail_activity_team/models/res_users.py b/mail_activity_team/models/res_users.py index b55ae842f..e1f9cc33a 100644 --- a/mail_activity_team/models/res_users.py +++ b/mail_activity_team/models/res_users.py @@ -6,6 +6,8 @@ class ResUsers(models.Model): _inherit = "res.users" - activity_team_ids = fields.Many2many('mail.activity.team', - 'mail_activity_team_users_rel', - string="Activity Teams") + activity_team_ids = fields.Many2many( + comodel_name='mail.activity.team', + relation='mail_activity_team_users_rel', + string="Activity Teams", + ) diff --git a/mail_activity_team/security/ir.model.access.csv b/mail_activity_team/security/ir.model.access.csv index c5efccfc9..0a9918d68 100644 --- a/mail_activity_team/security/ir.model.access.csv +++ b/mail_activity_team/security/ir.model.access.csv @@ -1,4 +1,4 @@ "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" access_mail_activity_team_all,mail.activity.team.all,model_mail_activity_team,,1,0,0,0 access_mail_activity_team_user,mail.activity.team.user,model_mail_activity_team,base.group_user,1,1,0,0 -access_mail_activity_team_system_user,mail.activity.team.system.user,model_mail_activity_team,base.group_system_user,1,1,1,1 +access_mail_activity_team_system_user,mail.activity.team.system.user,model_mail_activity_team,base.group_system,1,1,1,1 diff --git a/mail_activity_team/security/mail_activity_team_security.xml b/mail_activity_team/security/mail_activity_team_security.xml index 9ac63631b..e19398ab2 100644 --- a/mail_activity_team/security/mail_activity_team_security.xml +++ b/mail_activity_team/security/mail_activity_team_security.xml @@ -4,10 +4,10 @@ mail.activity: user: my team - ['|', '&'('team_id', '=', False),('user_id', '=', user.id),('team_id', '=', user.team_ids.ids)] + ["|", ('team_id', 'in', user.activity_team_ids.ids), "&", ('team_id', '=', False), ('user_id', '=', user.id)] - + diff --git a/mail_activity_team/views/mail_activity_team_views.xml b/mail_activity_team/views/mail_activity_team_views.xml index 52203d2dd..72b49a1d9 100644 --- a/mail_activity_team/views/mail_activity_team_views.xml +++ b/mail_activity_team/views/mail_activity_team_views.xml @@ -4,26 +4,34 @@ VIEWS --> - mail.activity.team.view.form mail.activity.team
+
+ +
+ options='{"terminology": "archive"}'/>
+ - + From 878cb57718fb20c8f3cfc0245d26121c9c3de378 Mon Sep 17 00:00:00 2001 From: mreficent Date: Wed, 28 Nov 2018 14:24:37 +0100 Subject: [PATCH 03/60] [ADD] tests --- mail_activity_team/tests/__init__.py | 1 + .../tests/test_mail_activity_team.py | 118 ++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 mail_activity_team/tests/__init__.py create mode 100644 mail_activity_team/tests/test_mail_activity_team.py diff --git a/mail_activity_team/tests/__init__.py b/mail_activity_team/tests/__init__.py new file mode 100644 index 000000000..f4a7f5950 --- /dev/null +++ b/mail_activity_team/tests/__init__.py @@ -0,0 +1 @@ +from . import test_mail_activity_team diff --git a/mail_activity_team/tests/test_mail_activity_team.py b/mail_activity_team/tests/test_mail_activity_team.py new file mode 100644 index 000000000..3f7928cbc --- /dev/null +++ b/mail_activity_team/tests/test_mail_activity_team.py @@ -0,0 +1,118 @@ +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo.tests.common import TransactionCase +from odoo.exceptions import ValidationError + + +class TestMailActivityTeam(TransactionCase): + + def setUp(self): + super(TestMailActivityTeam, self).setUp() + + self.env["mail.activity.team"].search([]).unlink() + + self.employee = self.env['res.users'].create({ + 'company_id': self.env.ref("base.main_company").id, + 'name': "Employee", + 'login': "csu", + 'email': "crmuser@yourcompany.com", + 'groups_id': [(6, 0, [ + self.env.ref('base.group_user').id, + self.env.ref('base.group_partner_manager').id])] + }) + + self.employee2 = self.env['res.users'].create({ + 'company_id': self.env.ref("base.main_company").id, + 'name': "Employee 2", + 'login': "csu2", + 'email': "crmuser2@yourcompany.com", + 'groups_id': [(6, 0, [self.env.ref('base.group_user').id])] + }) + + self.partner_ir_model = self.env['ir.model']._get('res.partner') + + activity_type_model = self.env['mail.activity.type'] + self.activity1 = activity_type_model.create({ + 'name': 'Initial Contact', + 'days': 5, + 'summary': 'ACT 1 : Presentation, barbecue, ... ', + 'res_model_id': self.partner_ir_model.id, + }) + self.activity2 = activity_type_model.create({ + 'name': 'Call for Demo', + 'days': 6, + 'summary': 'ACT 2 : I want to show you my ERP !', + 'res_model_id': self.partner_ir_model.id, + }) + + self.partner_client = self.env.ref("base.res_partner_1") + + self.act1 = self.env['mail.activity'].sudo(self.employee).create({ + 'activity_type_id': self.activity1.id, + 'note': 'Partner activity 1.', + 'res_id': self.partner_client.id, + 'res_model_id': self.partner_ir_model.id, + 'user_id': self.employee.id, + }) + + self.team1 = self.env['mail.activity.team'].sudo().create({ + 'name': 'Team 1', + 'res_model_ids': [(6, 0, [self.partner_ir_model.id])], + 'member_ids': [(6, 0, [self.employee.id])], + }) + + self.team2 = self.env['mail.activity.team'].sudo().create({ + 'name': 'Team 2', + 'res_model_ids': [(6, 0, [self.partner_ir_model.id])], + 'member_ids': [(6, 0, [self.employee.id, self.employee2.id])], + }) + + self.act2 = self.env['mail.activity'].sudo(self.employee).create({ + 'activity_type_id': self.activity2.id, + 'note': 'Partner activity 2.', + 'res_id': self.partner_client.id, + 'res_model_id': self.partner_ir_model.id, + 'user_id': self.employee.id, + }) + + def test_missing_activities(self): + self.assertFalse( + self.act1.team_id, 'Error: Activity 1 should not have a team.') + self.assertEqual(self.team1.count_missing_activities, 1) + self.team1.assign_team_to_unassigned_activities() + self.team1._compute_missing_activities() + self.assertEqual(self.team1.count_missing_activities, 0) + self.assertEqual(self.act1.team_id, self.team1) + + def test_activity_onchanges(self): + self.assertEqual( + self.act2.team_id, self.team1, + 'Error: Activity 2 should have Team 1.') + with self.env.do_in_onchange(): + self.act2.team_id = False + self.act2._onchange_team_id() + self.assertEqual(self.act2.user_id, self.employee) + self.act2.team_id = self.team2 + self.act2._onchange_team_id() + self.assertEqual(self.act2.user_id, self.employee) + self.act2.user_id = self.employee2 + self.act2._onchange_user_id() + self.assertEqual(self.act2.team_id, self.team2) + self.act2.team_id = self.team1 + self.act2._onchange_team_id() + self.assertFalse(self.act2.user_id) + with self.assertRaises(ValidationError): + self.act2.write({ + 'user_id': self.employee2.id, + 'team_id': self.team1.id, + }) + + def test_team_onchanges(self): + self.assertFalse( + self.team2.user_id, + 'Error: Team 2 should not have a Team Leader yet.') + with self.env.do_in_onchange(): + self.team2.user_id = self.employee + self.team2.member_ids = [(3, self.employee.id)] + self.team2._onchange_member_ids() + self.assertFalse(self.team2.user_id) From 9790ea3ce29998678dea8010b5b16d1681c9c950 Mon Sep 17 00:00:00 2001 From: mreficent Date: Mon, 3 Dec 2018 13:44:36 +0100 Subject: [PATCH 04/60] [MIG] mail_activity_team: Migration to 12.0 --- mail_activity_team/README.rst | 11 ++++++----- mail_activity_team/__manifest__.py | 2 +- mail_activity_team/readme/CONTRIBUTORS.rst | 1 + mail_activity_team/static/description/index.html | 6 +++--- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/mail_activity_team/README.rst b/mail_activity_team/README.rst index 0c79d92e1..ae233e3b8 100644 --- a/mail_activity_team/README.rst +++ b/mail_activity_team/README.rst @@ -14,13 +14,13 @@ Mail Activity Team :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github - :target: https://github.com/OCA/social/tree/11.0/mail_activity_team + :target: https://github.com/OCA/social/tree/12.0/mail_activity_team :alt: OCA/social .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/social-11-0/social-11-0-mail_activity_team + :target: https://translation.odoo-community.org/projects/social-12-0/social-12-0-mail_activity_team :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/205/11.0 + :target: https://runbot.odoo-community.org/runbot/205/12.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -61,7 +61,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -79,6 +79,7 @@ Contributors * `Eficent `_: * Jordi Ballester Alomar (jordi.ballester@eficent.com) + * Miquel Raïch (miquel.raich@eficent.com) Maintainers ~~~~~~~~~~~ @@ -93,6 +94,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/social `_ project on GitHub. +This module is part of the `OCA/social `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py index 4963644fb..b4f773356 100644 --- a/mail_activity_team/__manifest__.py +++ b/mail_activity_team/__manifest__.py @@ -3,7 +3,7 @@ { 'name': 'Mail Activity Team', 'summary': 'Add Teams to Activities', - 'version': '11.0.1.0.0', + 'version': '12.0.1.0.0', 'development_status': 'Beta', 'category': 'Social Network', 'website': 'https://github.com/OCA/social', diff --git a/mail_activity_team/readme/CONTRIBUTORS.rst b/mail_activity_team/readme/CONTRIBUTORS.rst index 3507ebd1f..6bb24056e 100644 --- a/mail_activity_team/readme/CONTRIBUTORS.rst +++ b/mail_activity_team/readme/CONTRIBUTORS.rst @@ -1,3 +1,4 @@ * `Eficent `_: * Jordi Ballester Alomar (jordi.ballester@eficent.com) + * Miquel Raïch (miquel.raich@eficent.com) diff --git a/mail_activity_team/static/description/index.html b/mail_activity_team/static/description/index.html index 8862473c6..1ee2f86d0 100644 --- a/mail_activity_team/static/description/index.html +++ b/mail_activity_team/static/description/index.html @@ -345,7 +345,7 @@

Mail Activity Team

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/social Translate me on Weblate Try me on Runbot

+

Beta License: AGPL-3 OCA/social Translate me on Weblate Try me on Runbot

This module adds the possibility to assign teams to activities.

Table of contents

@@ -383,7 +383,7 @@

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -410,7 +410,7 @@

Maintainers

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

-

This module is part of the OCA/social project on GitHub.

+

This module is part of the OCA/social project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

From ea41ded1928f593139beb93bb557907b4e85c713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Gil=20Sorribes?= Date: Fri, 21 Dec 2018 16:05:49 +0100 Subject: [PATCH 05/60] [IMP] Set team responsible as default user when activity is created --- mail_activity_team/models/mail_activity.py | 15 +++++++-------- mail_activity_team/models/mail_activity_team.py | 11 +++++++++-- .../tests/test_mail_activity_team.py | 2 +- .../views/mail_activity_team_views.xml | 2 +- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/mail_activity_team/models/mail_activity.py b/mail_activity_team/models/mail_activity.py index 46dd6de29..1fccf7463 100644 --- a/mail_activity_team/models/mail_activity.py +++ b/mail_activity_team/models/mail_activity.py @@ -46,14 +46,13 @@ def _onchange_team_id(self): if not self.team_id: return res res['domain']['user_id'] = [('id', 'in', self.team_id.member_ids.ids)] - if self.user_id and self.user_id in self.team_id.member_ids: - return res - if self.team_id.user_id: - self.user_id = self.team_id.user_id - elif self.env.user in self.team_id.member_ids.ids: - self.user_id = self.env.user - else: - self.user_id = self.env['res.users'] + if self.user_id not in self.team_id.member_ids: + if self.team_id.user_id: + self.user_id = self.team_id.user_id + elif len(self.team_id.member_ids) == 1: + self.user_id = self.team_id.member_ids + else: + self.user_id = self.env['res.users'] return res @api.multi diff --git a/mail_activity_team/models/mail_activity_team.py b/mail_activity_team/models/mail_activity_team.py index f97c185b5..1e44e0d7d 100644 --- a/mail_activity_team/models/mail_activity_team.py +++ b/mail_activity_team/models/mail_activity_team.py @@ -46,7 +46,6 @@ def _compute_missing_activities(self): user_id = fields.Many2one( comodel_name='res.users', string='Team Leader', - domain="[('id', 'in', member_ids)]", ) count_missing_activities = fields.Integer( string="Missing Activities", @@ -59,6 +58,13 @@ def _onchange_member_ids(self): if self.user_id and self.user_id not in self.member_ids: self.user_id = False + @api.onchange('user_id') + def _onchange_user_id(self): + if self.user_id and self.user_id not in self.member_ids: + members_ids = self.member_ids.ids + members_ids.append(self.user_id.id) + self.member_ids = [(4, member) for member in members_ids] + def assign_team_to_unassigned_activities(self): activity_model = self.env['mail.activity'] for team in self: @@ -68,4 +74,5 @@ def assign_team_to_unassigned_activities(self): if team.res_model_ids: domain.append(('res_model_id', 'in', team.res_model_ids.ids)) missing_activities = activity_model.search(domain) - missing_activities.write({'team_id': team.id}) + for missing_activity in missing_activities: + missing_activity.write({'team_id': team.id}) diff --git a/mail_activity_team/tests/test_mail_activity_team.py b/mail_activity_team/tests/test_mail_activity_team.py index 3f7928cbc..413e4122a 100644 --- a/mail_activity_team/tests/test_mail_activity_team.py +++ b/mail_activity_team/tests/test_mail_activity_team.py @@ -100,7 +100,7 @@ def test_activity_onchanges(self): self.assertEqual(self.act2.team_id, self.team2) self.act2.team_id = self.team1 self.act2._onchange_team_id() - self.assertFalse(self.act2.user_id) + self.assertEqual(self.act2.user_id, self.team1.member_ids) with self.assertRaises(ValidationError): self.act2.write({ 'user_id': self.employee2.id, diff --git a/mail_activity_team/views/mail_activity_team_views.xml b/mail_activity_team/views/mail_activity_team_views.xml index 72b49a1d9..6ecba09a5 100644 --- a/mail_activity_team/views/mail_activity_team_views.xml +++ b/mail_activity_team/views/mail_activity_team_views.xml @@ -27,7 +27,7 @@ - + Date: Mon, 24 Dec 2018 13:19:52 +0100 Subject: [PATCH 06/60] [IMP] Add search filter for My Team Activities --- mail_activity_team/views/mail_activity_views.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mail_activity_team/views/mail_activity_views.xml b/mail_activity_team/views/mail_activity_views.xml index 93ad71b91..ec0ecd471 100644 --- a/mail_activity_team/views/mail_activity_views.xml +++ b/mail_activity_team/views/mail_activity_views.xml @@ -61,6 +61,9 @@ + + + From 70f5601ac251cb7839b51b5536821e715c3aa475 Mon Sep 17 00:00:00 2001 From: David Beal Date: Wed, 10 Jul 2019 15:41:57 +0200 Subject: [PATCH 07/60] FIX mail_activ_team: always allow superuser --- .../i18n/mail_activity_team.pot | 139 ++++++++++++++++++ mail_activity_team/models/mail_activity.py | 11 +- .../static/description/index.html | 31 +++- 3 files changed, 175 insertions(+), 6 deletions(-) create mode 100644 mail_activity_team/i18n/mail_activity_team.pot diff --git a/mail_activity_team/i18n/mail_activity_team.pot b/mail_activity_team/i18n/mail_activity_team.pot new file mode 100644 index 000000000..a6173eed0 --- /dev/null +++ b/mail_activity_team/i18n/mail_activity_team.pot @@ -0,0 +1,139 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_team +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \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: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__active +msgid "Active" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model,name:mail_activity_team.model_mail_activity +msgid "Activity" +msgstr "" + +#. module: mail_activity_team +#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_team_view_form +msgid "Activity Team" +msgstr "" + +#. module: mail_activity_team +#: model:ir.actions.act_window,name:mail_activity_team.mail_activity_team_action +#: model:ir.model.fields,field_description:mail_activity_team.field_res_users__activity_team_ids +#: model:ir.ui.menu,name:mail_activity_team.menu_mail_activity_team +msgid "Activity Teams" +msgstr "" + +#. module: mail_activity_team +#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_team_view_form +msgid "Assign to missing activities" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__create_uid +msgid "Created by" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__create_date +msgid "Created on" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__display_name +msgid "Display Name" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__id +msgid "ID" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team____last_update +msgid "Last Modified on" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__write_date +msgid "Last Updated on" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model,name:mail_activity_team.model_mail_activity_team +msgid "Mail Activity Team" +msgstr "" + +#. module: mail_activity_team +#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_team_view_form +msgid "Members" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__count_missing_activities +msgid "Missing Activities" +msgstr "" + +#. module: mail_activity_team +#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search +msgid "My Team Activities" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__name +msgid "Name" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id +#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search +msgid "Team" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__user_id +msgid "Team Leader" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__member_ids +msgid "Team Members" +msgstr "" + +#. module: mail_activity_team +#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_kanban +msgid "Team:" +msgstr "" + +#. module: mail_activity_team +#: code:addons/mail_activity_team/models/mail_activity.py:72 +#, python-format +msgid "The assigned user is not member of the team." +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__res_model_ids +msgid "Used models" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model,name:mail_activity_team.model_res_users +msgid "Users" +msgstr "" + diff --git a/mail_activity_team/models/mail_activity.py b/mail_activity_team/models/mail_activity.py index 1fccf7463..bfb0f3516 100644 --- a/mail_activity_team/models/mail_activity.py +++ b/mail_activity_team/models/mail_activity.py @@ -1,6 +1,6 @@ # Copyright 2018 Eficent Business and IT Consulting Services, S.L. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import api, models, fields, _ +from odoo import api, models, fields, _, SUPERUSER_ID from odoo.exceptions import ValidationError @@ -59,7 +59,14 @@ def _onchange_team_id(self): @api.constrains('team_id', 'user_id') def _check_team_and_user(self): for activity in self: - if activity.team_id and activity.user_id and \ + # SUPERUSER is used to put mail.activity on some objects + # like sale.order coming from stock.picking + # (for example with exception type activity, with no backorder). + # SUPERUSER is inactive and then even if you add it + # to member_ids it's not taken account + # To not be blocked we must add it to constraint condition + if activity.user_id.id != SUPERUSER_ID and activity.team_id and \ + activity.user_id and \ activity.user_id not in self.team_id.member_ids: raise ValidationError( _('The assigned user is not member of the team.')) diff --git a/mail_activity_team/static/description/index.html b/mail_activity_team/static/description/index.html index 1ee2f86d0..a48c4f23d 100644 --- a/mail_activity_team/static/description/index.html +++ b/mail_activity_team/static/description/index.html @@ -3,13 +3,13 @@ - + Mail Activity Team -
-

Mail Activity Team

+
+ + +Odoo Community Association + +
+

Mail Activity Team

-

Alpha License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

+

Alpha License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

This module adds the possibility to assign teams to activities.

Important

@@ -392,7 +397,7 @@

Mail Activity Team

-

Usage

+

Usage

To set up new teams:

  1. Go to Settings / Activate developer mode
  2. @@ -409,7 +414,7 @@

    Usage

    / Activities, and then filter by a specific team or group by teams.

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -417,16 +422,16 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • ForgeFlow
  • Sodexis
-

Contributors

+

Contributors

-

Other credits

+

Other credits

The migration of this module from 16.0 to 17.0 was financially supported by Camptocamp

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -478,5 +483,6 @@

Maintainers

+
diff --git a/mail_activity_team/tests/test_mail_activity_team.py b/mail_activity_team/tests/test_mail_activity_team.py index dbefb7a5d..4a20b4039 100644 --- a/mail_activity_team/tests/test_mail_activity_team.py +++ b/mail_activity_team/tests/test_mail_activity_team.py @@ -263,6 +263,17 @@ def test_schedule_activity_default_team_no_user(self): # As we are in a 'team activity' context, the user should not be set self.assertEqual(activity.user_id, self.env["res.users"]) + def test_schedule_activity_no_default_team(self): + """If there are no teams, activities can still be scheduled for users""" + self.env["mail.activity.team"].search([]).unlink() + partner_record = self.employee.partner_id.with_user(self.employee.id) + activity = partner_record.activity_schedule( + activity_type_id=self.activity2.id, + user_id=self.employee2.id, + ) + self.assertFalse(activity.team_id) + self.assertEqual(activity.user_id, self.employee2) + def test_activity_count(self): res = ( self.env["res.users"] From 074ab6c9176b5d2fcd74034a9eaac348bfab4e19 Mon Sep 17 00:00:00 2001 From: Joel Estrada Date: Tue, 22 Jul 2025 12:37:09 +0200 Subject: [PATCH 49/60] [BUILD] mail_post_defer: mark as rebel mail_post_defer breaks tests for mail_tracking, so it's better to split it. https://github.com/OCA/social/commit/b782115eb2b8adf08ff99298dee98a1ac757bc26 @moduon MT-10471 --- mail_activity_team/i18n/es.po | 11 ++++-- mail_activity_team/i18n/fr.po | 11 ++++-- mail_activity_team/i18n/it.po | 11 ++++-- .../i18n/mail_activity_team.pot | 9 +++++ mail_activity_team/patch.py | 36 +++++++++++++------ 5 files changed, 58 insertions(+), 20 deletions(-) diff --git a/mail_activity_team/i18n/es.po b/mail_activity_team/i18n/es.po index e4c13f050..dd1828a10 100644 --- a/mail_activity_team/i18n/es.po +++ b/mail_activity_team/i18n/es.po @@ -16,6 +16,12 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.17\n" +#. module: mail_activity_team +#. odoo-javascript +#: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 +msgid "(Team" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__active msgid "Active" @@ -118,7 +124,6 @@ msgstr "Actividades Pendientes" #. module: mail_activity_team #. odoo-javascript #: code:addons/mail_activity_team/static/src/components/activity_menu_view/activity_menu_view.xml:0 -#, python-format msgid "My Activities" msgstr "Mis Actividades" @@ -138,6 +143,8 @@ msgid "Server Action" msgstr "Acción de Servidor" #. module: mail_activity_team +#. odoo-javascript +#: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id #: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search msgid "Team" @@ -146,7 +153,6 @@ msgstr "Equipo" #. module: mail_activity_team #. odoo-javascript #: code:addons/mail_activity_team/static/src/components/activity_menu_view/activity_menu_view.xml:0 -#, python-format msgid "Team Activities" msgstr "Actividades de Equipo" @@ -179,7 +185,6 @@ msgstr "Equipo:" #. module: mail_activity_team #. odoo-python #: code:addons/mail_activity_team/models/mail_activity.py:0 -#, python-format msgid "" "The assigned user %(user_name)s is not member of the team %(team_name)s." msgstr "" diff --git a/mail_activity_team/i18n/fr.po b/mail_activity_team/i18n/fr.po index ad70cf2d0..9d0bcc27e 100644 --- a/mail_activity_team/i18n/fr.po +++ b/mail_activity_team/i18n/fr.po @@ -16,6 +16,12 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.3.2\n" +#. module: mail_activity_team +#. odoo-javascript +#: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 +msgid "(Team" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__active msgid "Active" @@ -118,7 +124,6 @@ msgstr "" #. module: mail_activity_team #. odoo-javascript #: code:addons/mail_activity_team/static/src/components/activity_menu_view/activity_menu_view.xml:0 -#, python-format msgid "My Activities" msgstr "" @@ -138,6 +143,8 @@ msgid "Server Action" msgstr "" #. module: mail_activity_team +#. odoo-javascript +#: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id #: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search msgid "Team" @@ -146,7 +153,6 @@ msgstr "" #. module: mail_activity_team #. odoo-javascript #: code:addons/mail_activity_team/static/src/components/activity_menu_view/activity_menu_view.xml:0 -#, python-format msgid "Team Activities" msgstr "" @@ -179,7 +185,6 @@ msgstr "" #. module: mail_activity_team #. odoo-python #: code:addons/mail_activity_team/models/mail_activity.py:0 -#, python-format msgid "" "The assigned user %(user_name)s is not member of the team %(team_name)s." msgstr "" diff --git a/mail_activity_team/i18n/it.po b/mail_activity_team/i18n/it.po index 3ed4b2947..f035d2fc7 100644 --- a/mail_activity_team/i18n/it.po +++ b/mail_activity_team/i18n/it.po @@ -16,6 +16,12 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.6.2\n" +#. module: mail_activity_team +#. odoo-javascript +#: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 +msgid "(Team" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__active msgid "Active" @@ -118,7 +124,6 @@ msgstr "Attività Mancanti" #. module: mail_activity_team #. odoo-javascript #: code:addons/mail_activity_team/static/src/components/activity_menu_view/activity_menu_view.xml:0 -#, python-format msgid "My Activities" msgstr "Le mie attività" @@ -138,6 +143,8 @@ msgid "Server Action" msgstr "Azione server" #. module: mail_activity_team +#. odoo-javascript +#: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id #: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search msgid "Team" @@ -146,7 +153,6 @@ msgstr "Team" #. module: mail_activity_team #. odoo-javascript #: code:addons/mail_activity_team/static/src/components/activity_menu_view/activity_menu_view.xml:0 -#, python-format msgid "Team Activities" msgstr "Attività team" @@ -179,7 +185,6 @@ msgstr "Team:" #. module: mail_activity_team #. odoo-python #: code:addons/mail_activity_team/models/mail_activity.py:0 -#, python-format msgid "" "The assigned user %(user_name)s is not member of the team %(team_name)s." msgstr "" diff --git a/mail_activity_team/i18n/mail_activity_team.pot b/mail_activity_team/i18n/mail_activity_team.pot index b0bb7eaac..5cf1bb441 100644 --- a/mail_activity_team/i18n/mail_activity_team.pot +++ b/mail_activity_team/i18n/mail_activity_team.pot @@ -198,9 +198,18 @@ msgid "User" msgstr "" #. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_account_bank_statement_line__activity_team_user_ids +#: model:ir.model.fields,field_description:mail_activity_team.field_account_journal__activity_team_user_ids +#: model:ir.model.fields,field_description:mail_activity_team.field_account_move__activity_team_user_ids +#: model:ir.model.fields,field_description:mail_activity_team.field_account_payment__activity_team_user_ids +#: model:ir.model.fields,field_description:mail_activity_team.field_account_setup_bank_manual_config__activity_team_user_ids #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_mixin__activity_team_user_ids #: model:ir.model.fields,field_description:mail_activity_team.field_mailing_mailing__activity_team_user_ids +#: model:ir.model.fields,field_description:mail_activity_team.field_product_pricelist__activity_team_user_ids +#: model:ir.model.fields,field_description:mail_activity_team.field_product_product__activity_team_user_ids +#: model:ir.model.fields,field_description:mail_activity_team.field_product_template__activity_team_user_ids #: model:ir.model.fields,field_description:mail_activity_team.field_res_partner__activity_team_user_ids +#: model:ir.model.fields,field_description:mail_activity_team.field_res_partner_bank__activity_team_user_ids #: model:ir.model.fields,field_description:mail_activity_team.field_res_users__activity_team_user_ids msgid "test field" msgstr "" diff --git a/mail_activity_team/patch.py b/mail_activity_team/patch.py index ace580836..e6ae6cfda 100644 --- a/mail_activity_team/patch.py +++ b/mail_activity_team/patch.py @@ -6,7 +6,8 @@ @api.model_create_multi def mail_activity__create(self, vals_list): # Monkeypatch for mail's mail.activity's create method to prevent - # UnboundLocalError: cannot access local variable 'activity' where it is not associated with a value + # UnboundLocalError: cannot access local variable 'activity' + # where it is not associated with a value # which occurs when this module creates activities without a user_id. # Patch below is according to https://github.com/odoo/odoo/pull/197864 activities = super(MailActivity, self).create(vals_list) @@ -14,17 +15,21 @@ def mail_activity__create(self, vals_list): # find partners related to responsible users, separate readable from unreadable if any(user != self.env.user for user in activities.user_id): user_partners = activities.user_id.partner_id - readable_user_partners = user_partners._filtered_access('read') + readable_user_partners = user_partners._filtered_access("read") else: readable_user_partners = self.env.user.partner_id # when creating activities for other: send a notification to assigned user; - if self.env.context.get('mail_activity_quick_update'): - activities_to_notify = self.env['mail.activity'] + if self.env.context.get("mail_activity_quick_update"): + activities_to_notify = self.env["mail.activity"] else: - activities_to_notify = activities.filtered(lambda act: act.user_id != self.env.user) + activities_to_notify = activities.filtered( + lambda act: act.user_id != self.env.user + ) if activities_to_notify: - to_sudo = activities_to_notify.filtered(lambda act: act.user_id.partner_id not in readable_user_partners) + to_sudo = activities_to_notify.filtered( + lambda act: act.user_id.partner_id not in readable_user_partners + ) other = activities_to_notify - to_sudo to_sudo.sudo().action_notify() other.action_notify() @@ -32,20 +37,29 @@ def mail_activity__create(self, vals_list): # subscribe (batch by model and user to speedup) for model, activity_data in activities._classify_by_model().items(): per_user = dict() - for activity in activity_data['activities'].filtered(lambda act: act.user_id): + for activity in activity_data["activities"].filtered(lambda act: act.user_id): if activity.user_id not in per_user: per_user[activity.user_id] = [activity.res_id] else: per_user[activity.user_id].append(activity.res_id) for user, res_ids in per_user.items(): - pids = user.partner_id.ids if user.partner_id in readable_user_partners else user.sudo().partner_id.ids + pids = ( + user.partner_id.ids + if user.partner_id in readable_user_partners + else user.sudo().partner_id.ids + ) self.env[model].browse(res_ids).message_subscribe(partner_ids=pids) # send notifications about activity creation - todo_activities = activities.filtered(lambda act: act.date_deadline <= fields.Date.today()) + todo_activities = activities.filtered( + lambda act: act.date_deadline <= fields.Date.today() + ) if todo_activities: # Monkeypatch start - # activity.user_id._bus_send("mail.activity/updated", {"activity_created": True}) - todo_activities.user_id._bus_send("mail.activity/updated", {"activity_created": True}) + # activity.user_id._bus_send("mail.activity/updated", + # {"activity_created": True}) + todo_activities.user_id._bus_send( + "mail.activity/updated", {"activity_created": True} + ) # Monkeypatch end return activities From 142fd57b486c2a786f3f698d546fb5a968ba0bd3 Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 7 Oct 2025 08:16:40 +0000 Subject: [PATCH 50/60] Translated using Weblate (Italian) Currently translated at 100.0% (35 of 35 strings) Translation: mail-18.0/mail-18.0-mail_activity_team Translate-URL: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_activity_team/it/ --- mail_activity_team/i18n/it.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mail_activity_team/i18n/it.po b/mail_activity_team/i18n/it.po index f035d2fc7..5c9ff877c 100644 --- a/mail_activity_team/i18n/it.po +++ b/mail_activity_team/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 13.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-01-19 14:06+0000\n" +"PO-Revision-Date: 2025-10-07 08:20+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,13 +14,13 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.6.2\n" +"X-Generator: Weblate 5.10.4\n" #. module: mail_activity_team #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 msgid "(Team" -msgstr "" +msgstr "(Squadra" #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__active From 227fc8e3f3525af070411827265b449bd941fc52 Mon Sep 17 00:00:00 2001 From: Marie Lejeune Date: Wed, 15 Oct 2025 10:54:49 +0200 Subject: [PATCH 51/60] [IMP] Mail Activity Team: switch to Beta version --- mail_activity_team/README.rst | 11 +++-------- mail_activity_team/__manifest__.py | 4 ++-- mail_activity_team/static/description/index.html | 10 ++-------- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/mail_activity_team/README.rst b/mail_activity_team/README.rst index 5b5b4d01f..752d566a1 100644 --- a/mail_activity_team/README.rst +++ b/mail_activity_team/README.rst @@ -11,12 +11,12 @@ Mail Activity Team !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:2f89995e87d2922a9f795b1c56269d35e8145119ef8a3b116f8cd62b78b3d178 + !! source digest: sha256:51672fdadfaeec24c2ecce86ab4698c99dfcc197c6f803ab4281af9248dd1c0d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status - :alt: Alpha + :alt: Beta .. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 @@ -34,11 +34,6 @@ Mail Activity Team This module adds the possibility to assign teams to activities. -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - **Table of contents** .. contents:: diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py index b1f445dcb..fa7d444fd 100644 --- a/mail_activity_team/__manifest__.py +++ b/mail_activity_team/__manifest__.py @@ -5,8 +5,8 @@ { "name": "Mail Activity Team", "summary": "Add Teams to Activities", - "version": "18.0.1.0.0", - "development_status": "Alpha", + "version": "18.0.1.0.1", + "development_status": "Beta", "category": "Social Network", "website": "https://github.com/OCA/mail", "author": "ForgeFlow, Sodexis, Odoo Community Association (OCA)", diff --git a/mail_activity_team/static/description/index.html b/mail_activity_team/static/description/index.html index a837f3714..07fbbce1d 100644 --- a/mail_activity_team/static/description/index.html +++ b/mail_activity_team/static/description/index.html @@ -372,16 +372,10 @@

Mail Activity Team

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:2f89995e87d2922a9f795b1c56269d35e8145119ef8a3b116f8cd62b78b3d178 +!! source digest: sha256:51672fdadfaeec24c2ecce86ab4698c99dfcc197c6f803ab4281af9248dd1c0d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Alpha License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

This module adds the possibility to assign teams to activities.

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-

Table of contents

    From df6aee58a88de844933c0c4c26f2c40adc006494 Mon Sep 17 00:00:00 2001 From: Stefan Rijnhart Date: Mon, 27 Oct 2025 12:22:24 +0100 Subject: [PATCH 52/60] [REV] mail_activity_team: revert obsolete monkey patch Issue fixed in https://github.com/odoo/odoo/pull/215880 --- mail_activity_team/__init__.py | 1 - mail_activity_team/__manifest__.py | 1 - mail_activity_team/hooks.py | 13 ------ mail_activity_team/patch.py | 65 ------------------------------ 4 files changed, 80 deletions(-) delete mode 100644 mail_activity_team/hooks.py delete mode 100644 mail_activity_team/patch.py diff --git a/mail_activity_team/__init__.py b/mail_activity_team/__init__.py index c19ab79ba..9b4296142 100644 --- a/mail_activity_team/__init__.py +++ b/mail_activity_team/__init__.py @@ -1,3 +1,2 @@ -from .hooks import post_load_hook from . import models from . import wizard diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py index fa7d444fd..09a562f76 100644 --- a/mail_activity_team/__manifest__.py +++ b/mail_activity_team/__manifest__.py @@ -30,5 +30,4 @@ "mail_activity_team/static/src/models/*", ], }, - "post_load": "post_load_hook", } diff --git a/mail_activity_team/hooks.py b/mail_activity_team/hooks.py deleted file mode 100644 index 4611d85f0..000000000 --- a/mail_activity_team/hooks.py +++ /dev/null @@ -1,13 +0,0 @@ -import logging - -from odoo.addons.mail.models.mail_activity import MailActivity - -from .patch import mail_activity__create - -_logger = logging.getLogger(__name__) - - -def post_load_hook(): - """See patch.py for more info""" - MailActivity.create = mail_activity__create - _logger.info("PATCHED mail's mail.activity create") diff --git a/mail_activity_team/patch.py b/mail_activity_team/patch.py deleted file mode 100644 index e6ae6cfda..000000000 --- a/mail_activity_team/patch.py +++ /dev/null @@ -1,65 +0,0 @@ -from odoo import api, fields - -from odoo.addons.mail.models.mail_activity import MailActivity - - -@api.model_create_multi -def mail_activity__create(self, vals_list): - # Monkeypatch for mail's mail.activity's create method to prevent - # UnboundLocalError: cannot access local variable 'activity' - # where it is not associated with a value - # which occurs when this module creates activities without a user_id. - # Patch below is according to https://github.com/odoo/odoo/pull/197864 - activities = super(MailActivity, self).create(vals_list) - - # find partners related to responsible users, separate readable from unreadable - if any(user != self.env.user for user in activities.user_id): - user_partners = activities.user_id.partner_id - readable_user_partners = user_partners._filtered_access("read") - else: - readable_user_partners = self.env.user.partner_id - - # when creating activities for other: send a notification to assigned user; - if self.env.context.get("mail_activity_quick_update"): - activities_to_notify = self.env["mail.activity"] - else: - activities_to_notify = activities.filtered( - lambda act: act.user_id != self.env.user - ) - if activities_to_notify: - to_sudo = activities_to_notify.filtered( - lambda act: act.user_id.partner_id not in readable_user_partners - ) - other = activities_to_notify - to_sudo - to_sudo.sudo().action_notify() - other.action_notify() - - # subscribe (batch by model and user to speedup) - for model, activity_data in activities._classify_by_model().items(): - per_user = dict() - for activity in activity_data["activities"].filtered(lambda act: act.user_id): - if activity.user_id not in per_user: - per_user[activity.user_id] = [activity.res_id] - else: - per_user[activity.user_id].append(activity.res_id) - for user, res_ids in per_user.items(): - pids = ( - user.partner_id.ids - if user.partner_id in readable_user_partners - else user.sudo().partner_id.ids - ) - self.env[model].browse(res_ids).message_subscribe(partner_ids=pids) - - # send notifications about activity creation - todo_activities = activities.filtered( - lambda act: act.date_deadline <= fields.Date.today() - ) - if todo_activities: - # Monkeypatch start - # activity.user_id._bus_send("mail.activity/updated", - # {"activity_created": True}) - todo_activities.user_id._bus_send( - "mail.activity/updated", {"activity_created": True} - ) - # Monkeypatch end - return activities From 1589f36ca823aaa9045594223d7ef850c96e9bcf Mon Sep 17 00:00:00 2001 From: Stefan Rijnhart Date: Tue, 2 Dec 2025 08:26:12 +0100 Subject: [PATCH 53/60] [IMP] mail_activity_team: assign plan activities to teams --- mail_activity_team/README.rst | 43 ++- mail_activity_team/__manifest__.py | 2 + mail_activity_team/models/__init__.py | 5 +- .../models/mail_activity_mixin.py | 7 + .../models/mail_activity_plan_template.py | 95 +++++++ .../models/mail_activity_team.py | 4 +- mail_activity_team/readme/USAGE.md | 3 + .../security/mail_activity_team_security.xml | 2 +- .../static/description/index.html | 30 +-- .../tests/test_mail_activity_team.py | 248 +++++++++++++++++- .../mail_activity_plan_template_views.xml | 24 ++ .../views/mail_activity_plan_views.xml | 15 ++ .../wizard/mail_activity_schedule.py | 80 +++++- 13 files changed, 495 insertions(+), 63 deletions(-) create mode 100644 mail_activity_team/models/mail_activity_plan_template.py create mode 100644 mail_activity_team/views/mail_activity_plan_template_views.xml create mode 100644 mail_activity_team/views/mail_activity_plan_views.xml diff --git a/mail_activity_team/README.rst b/mail_activity_team/README.rst index 752d566a1..234e5710a 100644 --- a/mail_activity_team/README.rst +++ b/mail_activity_team/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ================== Mail Activity Team ================== @@ -17,7 +13,7 @@ Mail Activity Team .. |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/license-AGPL--3-blue.png +.. |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%2Fmail-lightgray.png?logo=github @@ -56,6 +52,9 @@ Teams. When you create a new activity the application will propose the user's assigned team. +When creating activity plans, instead of assigning an activity to a +user, there is also the option to assign it to a team instead. + You can report on the activities assigned to a team going to *Dashboards / Activities*, and then filter by a specific team or group by teams. @@ -81,35 +80,35 @@ Authors Contributors ------------ -- `ForgeFlow `__: +- `ForgeFlow `__: - - Jordi Ballester Alomar (jordi.ballester@forgeflow.com) - - Miquel Raïch (miquel.raich@forgeflow.com) - - Bernat Puig Font (bernat.puig@forgeflow.com) + - Jordi Ballester Alomar (jordi.ballester@forgeflow.com) + - Miquel Raïch (miquel.raich@forgeflow.com) + - Bernat Puig Font (bernat.puig@forgeflow.com) -- Pedro Gonzalez (pedro.gonzalez@pesol.es) -- `Tecnativa `__: +- Pedro Gonzalez (pedro.gonzalez@pesol.es) +- `Tecnativa `__: - - David Vidal + - David Vidal -- `Dynapps `__: +- `Dynapps `__: - - Raf Ven + - Raf Ven -- [Trobz] (https://trobz.com): +- [Trobz] (https://trobz.com): - - Son Ho sonhd@trobz.com + - Son Ho sonhd@trobz.com -- [Camptocamp] (https://camptocamp.com): +- [Camptocamp] (https://camptocamp.com): - - Vincent Van Rossem vincent.vanrossem@camptocamp.com - - Italo Lopes italo.lopes@camptocamp.com + - Vincent Van Rossem vincent.vanrossem@camptocamp.com + - Italo Lopes italo.lopes@camptocamp.com -- `CorporateHub `__ +- `CorporateHub `__ - - Alexey Pelykh alexey.pelykh@corphub.eu + - Alexey Pelykh alexey.pelykh@corphub.eu -- Stefan Rijnhart (stefan@opener.amsterdam) +- Stefan Rijnhart (stefan@opener.amsterdam) Other credits ------------- diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py index 09a562f76..d4df902c0 100644 --- a/mail_activity_team/__manifest__.py +++ b/mail_activity_team/__manifest__.py @@ -18,6 +18,8 @@ "security/mail_activity_team_security.xml", "wizard/mail_activity_schedule.xml", "views/ir_actions_server_views.xml", + "views/mail_activity_plan_template_views.xml", + "views/mail_activity_plan_views.xml", "views/mail_activity_type.xml", "views/mail_activity_team_views.xml", "views/mail_activity_views.xml", diff --git a/mail_activity_team/models/__init__.py b/mail_activity_team/models/__init__.py index 32109baf1..ccd0cec35 100644 --- a/mail_activity_team/models/__init__.py +++ b/mail_activity_team/models/__init__.py @@ -1,6 +1,7 @@ from . import ir_actions_server -from . import mail_activity_team +from . import mail_activity_team # Has to load early from . import mail_activity from . import mail_activity_mixin -from . import res_users +from . import mail_activity_plan_template from . import mail_activity_type +from . import res_users diff --git a/mail_activity_team/models/mail_activity_mixin.py b/mail_activity_team/models/mail_activity_mixin.py index d24c6af9c..0cc1ccb65 100644 --- a/mail_activity_team/models/mail_activity_mixin.py +++ b/mail_activity_team/models/mail_activity_mixin.py @@ -44,6 +44,13 @@ def activity_schedule( user-team missmatch. We can hook onto `act_values` dict as it's passed to the create activity method. """ + # Pick up some defaults from mail.activity.schedule + for field in ("team_id", "team_user_id", "user_id"): + if self.env.context.get(f"schedule_default_{field}") and not act_values.get( + field + ): + act_values[field] = self.env.context[f"schedule_default_{field}"] + if self.env.context.get("force_activity_team"): act_values["team_id"] = self.env.context["force_activity_team"].id if "team_id" not in act_values: diff --git a/mail_activity_team/models/mail_activity_plan_template.py b/mail_activity_team/models/mail_activity_plan_template.py new file mode 100644 index 000000000..d6e8e41d6 --- /dev/null +++ b/mail_activity_team/models/mail_activity_plan_template.py @@ -0,0 +1,95 @@ +from odoo import api, fields, models +from odoo.exceptions import ValidationError + + +class MailActivityPlanTemplate(models.Model): + _inherit = "mail.activity.plan.template" + + activity_team_user_id = fields.Many2one( + comodel_name="res.users", + compute="_compute_activity_team_user_id", + readonly=False, + help="The team member that the activity will be assigned to specifically", + store=True, + string="Team user", + ) + activity_team_id = fields.Many2one( + comodel_name="mail.activity.team", + compute="_compute_activity_team_id", + ondelete="restrict", + readonly=False, + store=True, + string="Team assigned to", + ) + activity_team_required = fields.Boolean( + compute="_compute_activity_team_required", + help="Indicate if this plan template must have an activity team", + ) + # Add compute method to existing field + responsible_id = fields.Many2one( + compute="_compute_responsible_id", + readonly=False, + store=True, + ) + responsible_type = fields.Selection( + ondelete={"team": "set default"}, + selection_add=[("team", "Team")], + ) + + @api.depends("responsible_type") + def _compute_activity_team_required(self): + """Hook to override requiredness of activity team""" + for template in self: + template.activity_team_required = template.responsible_type == "team" + + @api.depends("activity_team_id", "responsible_type") + def _compute_activity_team_user_id(self): + """Ensure consistency between the activity team and the team user""" + for template in self: + user = template.activity_team_user_id + if template.activity_team_required: + team = template.activity_team_id + if team: + if not user or user not in team.member_ids: + if team.user_id: + template.activity_team_user_id = team.user_id + elif len(team.member_ids) == 1: + template.activity_team_user_id = team.member_ids + elif user: + template.activity_team_user_id = False + elif user: + template.activity_team_user_id = False + elif user: + template.activity_team_user_id = False + + @api.depends("activity_type_id", "responsible_type") + def _compute_activity_team_id(self): + """Assign the default team from the activity type""" + for template in self: + if template.activity_team_required: + if template.activity_type_id.default_team_id: + template.activity_team_id = ( + template.activity_type_id.default_team_id + ) + elif template.activity_team_id: + template.activity_team_id = False + + @api.depends("responsible_type") + def _compute_responsible_id(self): + """Wipe responsible if field is not visible (c.q. allowed)""" + for template in self: + if template.activity_team_required and template.responsible_id: + template.responsible_id = False + + @api.constrains("responsible_type", "activity_team_id") + def _check_activity_team(self): + for template in self: + if template.activity_team_required and not template.activity_team_id: + raise ValidationError(self.env._("Please enter an activity team.")) + + def _determine_responsible(self, on_demand_responsible, applied_on_record): + # Avoid signalling an error for a 'team' template without a user. + self.ensure_one() + if self.activity_team_required: + return {"error": False} + return super()._determine_responsible(on_demand_responsible, applied_on_record) diff --git a/mail_activity_team/models/mail_activity_team.py b/mail_activity_team/models/mail_activity_team.py index 6c6a71c50..88cd01cd6 100644 --- a/mail_activity_team/models/mail_activity_team.py +++ b/mail_activity_team/models/mail_activity_team.py @@ -52,9 +52,7 @@ def _compute_missing_activities(self): @api.onchange("user_id") def _onchange_user_id(self): if self.user_id and self.user_id not in self.member_ids: - members_ids = self.member_ids.ids - members_ids.append(self.user_id.id) - self.member_ids = [(4, member) for member in members_ids] + self.member_ids += self.user_id def assign_team_to_unassigned_activities(self): activity_model = self.env["mail.activity"] diff --git a/mail_activity_team/readme/USAGE.md b/mail_activity_team/readme/USAGE.md index 3da67bd8e..e0729e6af 100644 --- a/mail_activity_team/readme/USAGE.md +++ b/mail_activity_team/readme/USAGE.md @@ -12,5 +12,8 @@ Teams. When you create a new activity the application will propose the user's assigned team. +When creating activity plans, instead of assigning an activity to a user, there +is also the option to assign it to a team instead. + You can report on the activities assigned to a team going to *Dashboards / Activities*, and then filter by a specific team or group by teams. diff --git a/mail_activity_team/security/mail_activity_team_security.xml b/mail_activity_team/security/mail_activity_team_security.xml index ece5bff24..f62afb42d 100644 --- a/mail_activity_team/security/mail_activity_team_security.xml +++ b/mail_activity_team/security/mail_activity_team_security.xml @@ -6,7 +6,7 @@ [('team_id', 'in', user.activity_team_ids.ids)] - + diff --git a/mail_activity_team/static/description/index.html b/mail_activity_team/static/description/index.html index 07fbbce1d..6d8bc9d4a 100644 --- a/mail_activity_team/static/description/index.html +++ b/mail_activity_team/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Mail Activity Team -
    +
    +

    Mail Activity Team

    - - -Odoo Community Association - -
    -

    Mail Activity Team

    -

    Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

    This module adds the possibility to assign teams to activities.

    Table of contents

    @@ -391,7 +386,7 @@

    Mail Activity Team

-

Usage

+

Usage

To set up new teams:

  1. Go to Settings / Activate developer mode
  2. @@ -404,11 +399,13 @@

    Usage

    Teams.

    When you create a new activity the application will propose the user’s assigned team.

    +

    When creating activity plans, instead of assigning an activity to a +user, there is also the option to assign it to a team instead.

    You can report on the activities assigned to a team going to Dashboards / Activities, and then filter by a specific team or group by teams.

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -416,16 +413,16 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • ForgeFlow
  • Sodexis
-

Contributors

+

Contributors

-

Other credits

+

Other credits

The migration of this module from 16.0 to 17.0 was financially supported by Camptocamp

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -477,6 +474,5 @@

Maintainers

- diff --git a/mail_activity_team/tests/test_mail_activity_team.py b/mail_activity_team/tests/test_mail_activity_team.py index 4a20b4039..643bd0863 100644 --- a/mail_activity_team/tests/test_mail_activity_team.py +++ b/mail_activity_team/tests/test_mail_activity_team.py @@ -4,6 +4,7 @@ from datetime import date from odoo.exceptions import ValidationError +from odoo.fields import Command from odoo.modules.migration import load_script from odoo.tests import Form from odoo.tests.common import TransactionCase @@ -24,9 +25,7 @@ def setUpClass(cls): "login": "csu", "email": "crmuser@yourcompany.com", "groups_id": [ - ( - 6, - 0, + Command.set( [ cls.env.ref("base.group_user").id, cls.env.ref("base.group_partner_manager").id, @@ -41,7 +40,7 @@ def setUpClass(cls): "name": "Employee 2", "login": "csu2", "email": "crmuser2@yourcompany.com", - "groups_id": [(6, 0, [cls.env.ref("base.group_user").id])], + "groups_id": [Command.set([cls.env.ref("base.group_user").id])], } ) cls.employee3 = cls.env["res.users"].create( @@ -50,7 +49,7 @@ def setUpClass(cls): "name": "Employee 3", "login": "csu3", "email": "crmuser3@yourcompany.com", - "groups_id": [(6, 0, [cls.env.ref("base.group_user").id])], + "groups_id": [Command.set([cls.env.ref("base.group_user").id])], } ) # Create Activity Types @@ -91,15 +90,15 @@ def setUpClass(cls): cls.team1 = cls.env["mail.activity.team"].create( { "name": "Team 1", - "res_model_ids": [(6, 0, [cls.partner_ir_model.id])], - "member_ids": [(6, 0, [cls.employee.id])], + "res_model_ids": [Command.set([cls.partner_ir_model.id])], + "member_ids": [Command.set([cls.employee.id])], } ) cls.team2 = cls.env["mail.activity.team"].create( { "name": "Team 2", - "res_model_ids": [(6, 0, [cls.partner_ir_model.id])], - "member_ids": [(6, 0, [cls.employee.id, cls.employee2.id])], + "res_model_ids": [Command.set([cls.partner_ir_model.id])], + "member_ids": [Command.set([cls.employee.id, cls.employee2.id])], } ) cls.act2 = ( @@ -318,6 +317,62 @@ def test_activity_schedule_next(self): # As we are in a 'team activity' context, the user should not be set self.assertEqual(next_activities.user_id, self.env["res.users"]) + def test_mail_activity_schedule_wizard(self): + self.activity1.default_team_id = self.team1 + wizard_form = Form( + self.env["mail.activity.schedule"].with_context( + active_ids=self.partner_client.ids, + active_model=self.partner_client._name, + ) + ) + wizard_form.activity_type_id = self.activity1 + # The activity's default team is set, and its member is the assigned user + self.assertEqual(wizard_form.activity_team_id, self.team1) + self.assertEqual(wizard_form.activity_team_user_id, self.employee) + + # Assign a team with a default member + self.team2.user_id = self.employee2 + wizard_form.activity_team_id = self.team2 + # Original team user is kept because it is also a member of the new team + self.assertEqual(wizard_form.activity_team_user_id, self.employee) + + # Reset some values and assign the team with the default user again + wizard_form.activity_team_user_id = self.env["res.users"] + wizard_form.activity_team_id = self.team2 + # Now the team user is the default user of the team + self.assertEqual(wizard_form.activity_team_user_id, self.employee2) + + other_team = self.env["mail.activity.team"].create( + { + "name": "Team 3", + "member_ids": [ + Command.link(self.employee.id), + Command.link(self.employee3.id), + ], + }, + ) + wizard_form.activity_team_id = other_team + # Employee 2 is not a member of the new team, so team user is reset + self.assertFalse(wizard_form.activity_team_user_id) + + # Set one of the members of the team and schedule the activity + wizard_form.activity_team_user_id = self.employee3 + + activities = self.partner_client.activity_ids + # Schedule the activity + wizard_form.save().action_schedule_activities() + activity = self.partner_client.activity_ids - activities + self.assertRecordValues( + activity, + [ + { + "activity_type_id": self.activity1.id, + "team_id": other_team.id, + "user_id": self.employee3.id, + }, + ], + ) + def test_schedule_activity_from_server_action(self): partner = self.env["res.partner"].create({"name": "Test Partner"}) action = self.env["ir.actions.server"].create( @@ -447,3 +502,178 @@ def test_migration(self): mod.migrate(self.env.cr, "18.0.1.0.0") self.assertFalse(rule.perm_create) + + def test_mail_activity_plan_ui_logic(self): + """Check team/team user consistency in plan template view""" + plan = self.env["mail.activity.plan"].create( + { + "name": __name__, + "res_model": "res.partner", + } + ) + self.activity1.default_team_id = self.team1 + template = self.env["mail.activity.plan.template"].create( + { + "summary": __name__, + "responsible_type": "other", + "responsible_id": self.employee3.id, + "activity_type_id": self.activity1.id, + "plan_id": plan.id, + "sequence": 1, + "delay_count": 1, + } + ) + # Team is not set by default + self.assertFalse(template.activity_team_id) + # If template is set to assign to team, default team of the activity is set + template.responsible_type = "team" + self.assertEqual(template.activity_team_id, self.team1) + + # Can't just remove the team without changing the assignment type + with self.assertRaisesRegex( + ValidationError, + "Please enter an activity team", + ): + with self.env.cr.savepoint(): + template.activity_team_id = False + + # Team is reset if type is not team + template.write( + { + "responsible_type": "other", + "responsible_id": self.env.user.id, + }, + ) + self.assertFalse(template.activity_team_id) + + # The default team user is set to the only member of the team + template.write( + { + "responsible_type": "team", + "activity_team_id": self.team1.id, + } + ) + self.assertEqual(template.activity_team_user_id, self.employee) + # The responsible is reset if assignment is changed to team + self.assertFalse(template.responsible_id) + # Assign a team with a default member + self.team2.user_id = self.employee2 + template.activity_team_id = self.team2 + # Original team user is kept because it is also a member of the new team + self.assertEqual(template.activity_team_user_id, self.employee) + # Team user is reset if team is reset + template.write( + { + "responsible_type": "other", + "responsible_id": self.env.user.id, + "activity_team_id": False, + }, + ) + self.assertFalse(template.activity_team_user_id) + # Assign the team with the default user again + template.write( + { + "responsible_type": "team", + "activity_team_id": self.team2.id, + }, + ) + # Now the team user is the default user of the team + self.assertEqual(template.activity_team_user_id, self.employee2) + + other_team = self.env["mail.activity.team"].create( + { + "name": "Team 3", + "member_ids": [ + Command.link(self.employee.id), + Command.link(self.employee3.id), + ], + }, + ) + template.activity_team_id = other_team + # Employee 2 is not a member of the new team, so team user is reset + self.assertFalse(template.activity_team_user_id) + + def test_mail_activity_plan(self): + """Activities for teams can be scheduled using an activity plan""" + plan = self.env["mail.activity.plan"].create( + { + "name": __name__, + "res_model": "res.partner", + } + ) + self.env["mail.activity.plan.template"].create( + { + "summary": __name__, + "responsible_type": "other", + "responsible_id": self.employee3.id, + "activity_type_id": self.activity1.id, + "plan_id": plan.id, + "sequence": 1, + "delay_count": 1, + } + ) + self.env["mail.activity.plan.template"].create( + { + "summary": __name__, + "responsible_type": "team", + "activity_team_id": self.team1.id, + "activity_type_id": self.activity2.id, + "plan_id": plan.id, + "sequence": 2, + "delay_count": 2, + } + ) + activities = self.partner_client.activity_ids + + wizard = ( + self.env["mail.activity.schedule"] + .with_context( + active_ids=self.partner_client.ids, + active_model=self.partner_client._name, + ) + .create( + { + "plan_id": plan.id, + "plan_date": date.today(), + } + ) + ) + wizard.action_schedule_plan() + new_activities = self.partner_client.activity_ids - activities + self.assertRecordValues( + new_activities, + [ + { + "activity_type_id": self.activity2.id, + "team_id": self.team1.id, + "user_id": False, + }, + { + "activity_type_id": self.activity1.id, + "team_id": False, + "user_id": self.employee3.id, + }, + ], + ) + + # Coverage: _plan_filter_activity_templates_to_schedule will still + # return both activities if called without special context key + self.assertEqual( + wizard._plan_filter_activity_templates_to_schedule(), + plan.template_ids, + ) + # or when upper frame inspection fails + with self.assertLogs( + "odoo.addons.mail_activity_team.wizard.mail_activity_schedule", + level="WARNING", + ) as log_catcher: + self.assertEqual( + wizard.with_context( + fire_team_activities=True, + )._plan_filter_activity_templates_to_schedule(), + plan.template_ids, + ) + self.assertIn( + "Could not find 'activity_descriptions' list in inspected frames", + log_catcher.output[0], + ) diff --git a/mail_activity_team/views/mail_activity_plan_template_views.xml b/mail_activity_team/views/mail_activity_plan_template_views.xml new file mode 100644 index 000000000..cf9a2e093 --- /dev/null +++ b/mail_activity_team/views/mail_activity_plan_template_views.xml @@ -0,0 +1,24 @@ + + + + + mail.activity.plan.template + + + + + + + + diff --git a/mail_activity_team/views/mail_activity_plan_views.xml b/mail_activity_team/views/mail_activity_plan_views.xml new file mode 100644 index 000000000..e6c95b13b --- /dev/null +++ b/mail_activity_team/views/mail_activity_plan_views.xml @@ -0,0 +1,15 @@ + + + + + mail.activity.plan + + + + + + + diff --git a/mail_activity_team/wizard/mail_activity_schedule.py b/mail_activity_team/wizard/mail_activity_schedule.py index c8a18eed1..56b02c59c 100644 --- a/mail_activity_team/wizard/mail_activity_schedule.py +++ b/mail_activity_team/wizard/mail_activity_schedule.py @@ -1,8 +1,13 @@ # Copyright 2024 Camptocamp SA # Copyright 2024 CorporateHub # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import inspect +import logging from odoo import api, fields, models +from odoo.tools.misc import format_date + +_logger = logging.getLogger(__name__) class MailActivitySchedule(models.TransientModel): @@ -60,13 +65,70 @@ def _onchange_activity_team_user_id(self): ) def _action_schedule_activities(self): - return self._get_applied_on_records().activity_schedule( - activity_type_id=self.activity_type_id.id, - automated=False, - summary=self.summary, - note=self.note, - user_id=self.activity_team_user_id.id, - team_user_id=self.activity_team_user_id.id, - team_id=self.activity_team_id.id, - date_deadline=self.date_deadline, + # Insert default team data which is picked up for activities that are + # created without a team already. + self = self.with_context( + schedule_default_team_id=self.activity_team_id.id, + schedule_default_team_user_id=self.activity_team_user_id.id, + schedule_default_user_id=self.activity_team_user_id.id, + ) + return super()._action_schedule_activities() + + def action_schedule_plan(self): + # Triggering scheduled team activities in + # _plan_filter_activity_templates_to_schedule which is called from the + # super method to fetch the activities that need to be scheduled. + # This is because activity parameters are determined inline in the + # super method, and the activity team cannot be inserted there in a + # clean override. + self = self.with_context(fire_team_activities=True) + return super().action_schedule_plan() + + @staticmethod + def _get_activity_schedule_plan_data(): + """Fetch some variables defined in action_schedule_plan""" + frame = inspect.currentframe() + while frame.f_back: + frame = frame.f_back + f_locals = frame.f_locals + if "activity_descriptions" in f_locals and "record" in f_locals: + return f_locals["record"], f_locals["activity_descriptions"] + _logger.warning( + "Could not find 'activity_descriptions' list in inspected frames" ) + return None, None + + def _plan_filter_activity_templates_to_schedule(self): + # Instead of returning all templates, including those with a team, + # go ahead and schedule only those with a team and only return + # the remaining activity templates. + res = super()._plan_filter_activity_templates_to_schedule() + if self.env.context.get("fire_team_activities"): + # Immediately schedule team activities + record, activity_descriptions = self._get_activity_schedule_plan_data() + if record is None: + return res + templates = res.filtered("activity_team_required") + others = res - templates + for template in templates: + date_deadline = template._get_date_deadline(self.plan_date) + record.activity_schedule( + activity_type_id=template.activity_type_id.id, + automated=False, + summary=template.summary, + note=template.note, + user_id=template.activity_team_user_id.id, + team_id=template.activity_team_id.id, + date_deadline=date_deadline, + ) + activity_descriptions.append( + self.env._( + "%(activity)s, assigned to team %(name)s, " + "due on the %(deadline)s", + activity=template.summary or template.activity_type_id.name, + name=template.activity_team_id.name, + deadline=format_date(self.env, date_deadline), + ) + ) + return others + return res From 51768db4e94a21899962f1f63e96b86efbfb4c65 Mon Sep 17 00:00:00 2001 From: Christopher Rogos Date: Thu, 11 Dec 2025 08:47:41 +0000 Subject: [PATCH 54/60] [IMP] mail_activity_team: remove mail_activity_board dependency --- mail_activity_team/README.rst | 42 ++++++++------- mail_activity_team/__manifest__.py | 4 +- mail_activity_team/i18n/es.po | 14 ++--- mail_activity_team/i18n/fr.po | 11 ++-- mail_activity_team/i18n/it.po | 14 ++--- .../i18n/mail_activity_team.pot | 11 ++-- .../static/description/index.html | 30 ++++++----- .../views/mail_activity_views.xml | 53 +++++-------------- 8 files changed, 81 insertions(+), 98 deletions(-) diff --git a/mail_activity_team/README.rst b/mail_activity_team/README.rst index 234e5710a..12b741645 100644 --- a/mail_activity_team/README.rst +++ b/mail_activity_team/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ================== Mail Activity Team ================== @@ -7,13 +11,13 @@ Mail Activity Team !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:51672fdadfaeec24c2ecce86ab4698c99dfcc197c6f803ab4281af9248dd1c0d + !! source digest: sha256:4ddbbf29e9941ec7189251a2a0c0219aa7dbf652e67e7684b632cebbeb498393 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fmail-lightgray.png?logo=github @@ -80,35 +84,35 @@ Authors Contributors ------------ -- `ForgeFlow `__: +- `ForgeFlow `__: - - Jordi Ballester Alomar (jordi.ballester@forgeflow.com) - - Miquel Raïch (miquel.raich@forgeflow.com) - - Bernat Puig Font (bernat.puig@forgeflow.com) + - Jordi Ballester Alomar (jordi.ballester@forgeflow.com) + - Miquel Raïch (miquel.raich@forgeflow.com) + - Bernat Puig Font (bernat.puig@forgeflow.com) -- Pedro Gonzalez (pedro.gonzalez@pesol.es) -- `Tecnativa `__: +- Pedro Gonzalez (pedro.gonzalez@pesol.es) +- `Tecnativa `__: - - David Vidal + - David Vidal -- `Dynapps `__: +- `Dynapps `__: - - Raf Ven + - Raf Ven -- [Trobz] (https://trobz.com): +- [Trobz] (https://trobz.com): - - Son Ho sonhd@trobz.com + - Son Ho sonhd@trobz.com -- [Camptocamp] (https://camptocamp.com): +- [Camptocamp] (https://camptocamp.com): - - Vincent Van Rossem vincent.vanrossem@camptocamp.com - - Italo Lopes italo.lopes@camptocamp.com + - Vincent Van Rossem vincent.vanrossem@camptocamp.com + - Italo Lopes italo.lopes@camptocamp.com -- `CorporateHub `__ +- `CorporateHub `__ - - Alexey Pelykh alexey.pelykh@corphub.eu + - Alexey Pelykh alexey.pelykh@corphub.eu -- Stefan Rijnhart (stefan@opener.amsterdam) +- Stefan Rijnhart (stefan@opener.amsterdam) Other credits ------------- diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py index d4df902c0..aa6b68dc7 100644 --- a/mail_activity_team/__manifest__.py +++ b/mail_activity_team/__manifest__.py @@ -5,14 +5,14 @@ { "name": "Mail Activity Team", "summary": "Add Teams to Activities", - "version": "18.0.1.0.1", + "version": "18.0.1.0.2", "development_status": "Beta", "category": "Social Network", "website": "https://github.com/OCA/mail", "author": "ForgeFlow, Sodexis, Odoo Community Association (OCA)", "license": "AGPL-3", "installable": True, - "depends": ["mail_activity_board", "web"], + "depends": ["mail", "web"], "data": [ "security/ir.model.access.csv", "security/mail_activity_team_security.xml", diff --git a/mail_activity_team/i18n/es.po b/mail_activity_team/i18n/es.po index dd1828a10..6e3f88f37 100644 --- a/mail_activity_team/i18n/es.po +++ b/mail_activity_team/i18n/es.po @@ -22,6 +22,11 @@ msgstr "" msgid "(Team" msgstr "" +#. module: mail_activity_team +#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_kanban_open_target +msgid "Team: " +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__active msgid "Active" @@ -146,7 +151,6 @@ msgstr "Acción de Servidor" #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search msgid "Team" msgstr "Equipo" @@ -177,11 +181,6 @@ msgstr "" msgid "Team user" msgstr "Usuario del Equipo" -#. module: mail_activity_team -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_kanban -msgid "Team:" -msgstr "Equipo:" - #. module: mail_activity_team #. odoo-python #: code:addons/mail_activity_team/models/mail_activity.py:0 @@ -218,5 +217,8 @@ msgstr "Usuario" msgid "test field" msgstr "campo de prueba" +#~ msgid "Team:" +#~ msgstr "Equipo:" + #~ msgid "Last Modified on" #~ msgstr "Última Modificación el" diff --git a/mail_activity_team/i18n/fr.po b/mail_activity_team/i18n/fr.po index 9d0bcc27e..45a963f64 100644 --- a/mail_activity_team/i18n/fr.po +++ b/mail_activity_team/i18n/fr.po @@ -22,6 +22,11 @@ msgstr "" msgid "(Team" msgstr "" +#. module: mail_activity_team +#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_kanban_open_target +msgid "Team: " +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__active msgid "Active" @@ -146,7 +151,6 @@ msgstr "" #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search msgid "Team" msgstr "" @@ -177,11 +181,6 @@ msgstr "" msgid "Team user" msgstr "" -#. module: mail_activity_team -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_kanban -msgid "Team:" -msgstr "" - #. module: mail_activity_team #. odoo-python #: code:addons/mail_activity_team/models/mail_activity.py:0 diff --git a/mail_activity_team/i18n/it.po b/mail_activity_team/i18n/it.po index 5c9ff877c..f7bf010e3 100644 --- a/mail_activity_team/i18n/it.po +++ b/mail_activity_team/i18n/it.po @@ -22,6 +22,11 @@ msgstr "" msgid "(Team" msgstr "(Squadra" +#. module: mail_activity_team +#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_kanban_open_target +msgid "Team: " +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__active msgid "Active" @@ -146,7 +151,6 @@ msgstr "Azione server" #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search msgid "Team" msgstr "Team" @@ -177,11 +181,6 @@ msgstr "Team assegnato a" msgid "Team user" msgstr "Utente del team" -#. module: mail_activity_team -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_kanban -msgid "Team:" -msgstr "Team:" - #. module: mail_activity_team #. odoo-python #: code:addons/mail_activity_team/models/mail_activity.py:0 @@ -218,6 +217,9 @@ msgstr "Utente" msgid "test field" msgstr "campo test" +#~ msgid "Team:" +#~ msgstr "Team:" + #~ msgid "Last Modified on" #~ msgstr "Ultima modifica il" diff --git a/mail_activity_team/i18n/mail_activity_team.pot b/mail_activity_team/i18n/mail_activity_team.pot index 5cf1bb441..40bf6c7b3 100644 --- a/mail_activity_team/i18n/mail_activity_team.pot +++ b/mail_activity_team/i18n/mail_activity_team.pot @@ -19,6 +19,11 @@ msgstr "" msgid "(Team" msgstr "" +#. module: mail_activity_team +#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_kanban_open_target +msgid "Team: " +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__active msgid "Active" @@ -143,7 +148,6 @@ msgstr "" #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search msgid "Team" msgstr "" @@ -174,11 +178,6 @@ msgstr "" msgid "Team user" msgstr "" -#. module: mail_activity_team -#: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_kanban -msgid "Team:" -msgstr "" - #. module: mail_activity_team #. odoo-python #: code:addons/mail_activity_team/models/mail_activity.py:0 diff --git a/mail_activity_team/static/description/index.html b/mail_activity_team/static/description/index.html index 6d8bc9d4a..7f4265496 100644 --- a/mail_activity_team/static/description/index.html +++ b/mail_activity_team/static/description/index.html @@ -3,7 +3,7 @@ -Mail Activity Team +README.rst -
-

Mail Activity Team

+
+ + +Odoo Community Association + +
+

Mail Activity Team

-

Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

This module adds the possibility to assign teams to activities.

Table of contents

@@ -386,7 +391,7 @@

Mail Activity Team

-

Usage

+

Usage

To set up new teams:

  1. Go to Settings / Activate developer mode
  2. @@ -405,7 +410,7 @@

    Usage

    / Activities, and then filter by a specific team or group by teams.

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -413,16 +418,16 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • ForgeFlow
  • Sodexis
-

Contributors

+

Contributors

-

Other credits

+

Other credits

The migration of this module from 16.0 to 17.0 was financially supported by Camptocamp

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -474,5 +479,6 @@

Maintainers

+
diff --git a/mail_activity_team/views/mail_activity_views.xml b/mail_activity_team/views/mail_activity_views.xml index a1ec3bc16..07fb47f3a 100644 --- a/mail_activity_team/views/mail_activity_views.xml +++ b/mail_activity_team/views/mail_activity_views.xml @@ -22,7 +22,6 @@ - mail.activity.view.tree mail.activity @@ -34,44 +33,16 @@ - - mail.activity.view.form - mail.activity - - - - not team_id - - - - - - - - - + mail.activity.boards.view.kanban mail.activity - + - - - - -
+
- Team: -
+ Team: + +
@@ -80,22 +51,22 @@ mail.activity.boards.view.search mail.activity - + - + - + - - - + + + From bd8165a6beb93eef8616edc7200cf726547035a9 Mon Sep 17 00:00:00 2001 From: mymage Date: Sun, 14 Dec 2025 19:15:55 +0000 Subject: [PATCH 55/60] Translated using Weblate (Italian) Currently translated at 100.0% (35 of 35 strings) Translation: mail-18.0/mail-18.0-mail_activity_team Translate-URL: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_activity_team/it/ --- mail_activity_team/README.rst | 2 +- mail_activity_team/__manifest__.py | 2 +- mail_activity_team/i18n/it.po | 8 ++++---- mail_activity_team/static/description/index.html | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mail_activity_team/README.rst b/mail_activity_team/README.rst index 12b741645..fbaa7b49a 100644 --- a/mail_activity_team/README.rst +++ b/mail_activity_team/README.rst @@ -11,7 +11,7 @@ Mail Activity Team !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:4ddbbf29e9941ec7189251a2a0c0219aa7dbf652e67e7684b632cebbeb498393 + !! source digest: sha256:ca0203ad2f0fed4e4686b319424332ac44446e2380683a802c1052f78584cfa4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py index aa6b68dc7..a708741a7 100644 --- a/mail_activity_team/__manifest__.py +++ b/mail_activity_team/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Mail Activity Team", "summary": "Add Teams to Activities", - "version": "18.0.1.0.2", + "version": "18.0.1.0.3", "development_status": "Beta", "category": "Social Network", "website": "https://github.com/OCA/mail", diff --git a/mail_activity_team/i18n/it.po b/mail_activity_team/i18n/it.po index f7bf010e3..59132e078 100644 --- a/mail_activity_team/i18n/it.po +++ b/mail_activity_team/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 13.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-10-07 08:20+0000\n" +"PO-Revision-Date: 2026-02-18 11:09+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.10.4\n" +"X-Generator: Weblate 5.15.2\n" #. module: mail_activity_team #. odoo-javascript @@ -25,7 +25,7 @@ msgstr "(Squadra" #. module: mail_activity_team #: model_terms:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_kanban_open_target msgid "Team: " -msgstr "" +msgstr "Team: " #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__active @@ -109,7 +109,7 @@ msgstr "Ultimo aggiornamento di" #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__write_date msgid "Last Updated on" -msgstr "Ultima Modifica il" +msgstr "Ultimo aggiornamento il" #. module: mail_activity_team #: model:ir.model,name:mail_activity_team.model_mail_activity_team diff --git a/mail_activity_team/static/description/index.html b/mail_activity_team/static/description/index.html index 7f4265496..cef90284d 100644 --- a/mail_activity_team/static/description/index.html +++ b/mail_activity_team/static/description/index.html @@ -372,7 +372,7 @@

Mail Activity Team

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:4ddbbf29e9941ec7189251a2a0c0219aa7dbf652e67e7684b632cebbeb498393 +!! source digest: sha256:ca0203ad2f0fed4e4686b319424332ac44446e2380683a802c1052f78584cfa4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

This module adds the possibility to assign teams to activities.

From 93e7bf00f45ea2e23012fd3aef40be1c0f891675 Mon Sep 17 00:00:00 2001 From: Christopher Rogos Date: Fri, 20 Feb 2026 11:36:32 +0000 Subject: [PATCH 56/60] [IMP] mail_activity_team: Improve default team_id retrieval --- mail_activity_team/models/mail_activity.py | 50 ++- .../models/mail_activity_mixin.py | 3 +- mail_activity_team/tests/__init__.py | 1 + .../tests/test_mail_activity.py | 291 ++++++++++++++++++ .../wizard/mail_activity_schedule.py | 14 +- 5 files changed, 339 insertions(+), 20 deletions(-) create mode 100644 mail_activity_team/tests/test_mail_activity.py diff --git a/mail_activity_team/models/mail_activity.py b/mail_activity_team/models/mail_activity.py index f70019e01..a40fc16aa 100644 --- a/mail_activity_team/models/mail_activity.py +++ b/mail_activity_team/models/mail_activity.py @@ -8,17 +8,34 @@ class MailActivity(models.Model): _inherit = "mail.activity" - def _get_default_team_id(self, user_id=None): + @api.model + def _get_default_team_id(self, user_id=None, model_id=None): if not user_id: user_id = self.env.uid - res_model = self.env.context.get("default_res_model") - model = self.sudo().env["ir.model"].search([("model", "=", res_model)], limit=1) + if not model_id: + res_model = self.env.context.get("default_res_model") + model = ( + self.sudo().env["ir.model"].search([("model", "=", res_model)], limit=1) + ) + model_id = model.id if model else None domain = [("member_ids", "in", [user_id])] - if res_model: + if model_id: domain.extend( - ["|", ("res_model_ids", "=", False), ("res_model_ids", "in", model.ids)] + [ + "|", + ("res_model_ids", "=", False), + ("res_model_ids", "in", [model_id]), + ] + ) + results = self.env["mail.activity.team"].search(domain) + if model_id: + result_with_model = results.filtered( + lambda team: model_id in team.res_model_ids.ids ) - return self.env["mail.activity.team"].search(domain, limit=1) + if result_with_model: + return result_with_model[0] + + return results[0] if results else self.env["mail.activity.team"] user_id = fields.Many2one(string="User", required=False, default=False) team_user_id = fields.Many2one( @@ -27,7 +44,6 @@ def _get_default_team_id(self, user_id=None): team_id = fields.Many2one( comodel_name="mail.activity.team", - default=lambda s: s._get_default_team_id(), index=True, ) @@ -45,8 +61,20 @@ def create(self, vals_list): if vals.get("team_id"): # using team, we have user_id = team_user_id, # so if we don't have a user_team_id we don't want user_id too - if "user_id" in vals and not vals.get("team_user_id", False): + if "user_id" in vals and not vals.get("team_user_id"): del vals["user_id"] + elif ( + "team_id" not in vals + and "user_id" in vals + and "team_user_id" not in vals + ): + # legacy behavior, if we have user_id but no team_id, set the team_id + team_id = self._get_default_team_id( + vals["user_id"], vals.get("res_model_id") + ) + if team_id: + vals["team_id"] = team_id.id + vals["team_user_id"] = vals["user_id"] return super().create(vals_list) @api.onchange("user_id") @@ -55,9 +83,9 @@ def _onchange_user_id(self): self.team_id and self.user_id in self.team_id.member_ids ): return - self.team_id = self.with_context( - default_res_model=self.sudo().res_model_id.model - )._get_default_team_id(user_id=self.user_id.id) + self.team_id = self._get_default_team_id( + self.user_id.id, self.sudo().res_model_id.id + ) @api.onchange("team_id") def _onchange_team_id(self): diff --git a/mail_activity_team/models/mail_activity_mixin.py b/mail_activity_team/models/mail_activity_mixin.py index 0cc1ccb65..8766a7785 100644 --- a/mail_activity_team/models/mail_activity_mixin.py +++ b/mail_activity_team/models/mail_activity_mixin.py @@ -81,7 +81,8 @@ def activity_schedule( ) ._get_default_team_id(user_id=user_id) ) - act_values.update({"team_id": team.id}) + if team: + act_values.update({"team_id": team.id}) return super().activity_schedule( act_type_xmlid=act_type_xmlid, date_deadline=date_deadline, diff --git a/mail_activity_team/tests/__init__.py b/mail_activity_team/tests/__init__.py index f4a7f5950..2ebbcd085 100644 --- a/mail_activity_team/tests/__init__.py +++ b/mail_activity_team/tests/__init__.py @@ -1 +1,2 @@ from . import test_mail_activity_team +from . import test_mail_activity diff --git a/mail_activity_team/tests/test_mail_activity.py b/mail_activity_team/tests/test_mail_activity.py new file mode 100644 index 000000000..fdc8d979b --- /dev/null +++ b/mail_activity_team/tests/test_mail_activity.py @@ -0,0 +1,291 @@ +from odoo import Command +from odoo.tests import users + +from odoo.addons.base.tests.common import BaseCommon + + +class TestMailActivity(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + + # Create Users + cls.user = cls.env["res.users"].create( + { + "company_id": cls.env.ref("base.main_company").id, + "name": "Employee", + "login": "csu", + "email": "crmuser@yourcompany.com", + "groups_id": [ + Command.set( + [ + cls.env.ref("base.group_user").id, + cls.env.ref("base.group_partner_manager").id, + ] + ) + ], + } + ) + cls.user2 = cls.env["res.users"].create( + { + "company_id": cls.env.ref("base.main_company").id, + "name": "Employee 2", + "login": "csu2", + "email": "crmuser2@yourcompany.com", + "groups_id": [Command.set([cls.env.ref("base.group_user").id])], + } + ) + cls.partner_ir_model = cls.env["ir.model"]._get("res.partner") + cls.partner_client = cls.env.ref("base.res_partner_1") + # Create Activity Types + cls.activity1 = cls.env["mail.activity.type"].create( + { + "name": "Initial Contact", + "delay_count": 5, + "delay_unit": "days", + "summary": "ACT 1 : Presentation, barbecue, ... ", + "res_model": "res.partner", + } + ) + + @users("csu") + def test_get_default_team_id_one_team_with_model(self): + """Test _get_default_team_id correctly finds team with specified model_id""" + # Create a team specific to res.partner model + team_partner = ( + self.env["mail.activity.team"] + .sudo() + .create( + { + "name": "Partner Team", + "res_model_ids": [Command.set([self.partner_ir_model.id])], + "member_ids": [Command.set([self.user.id])], + } + ) + ) + # Test with model_id parameter - should find the team + result_team_from_user = ( + self.env["mail.activity"] + .with_context(default_res_model="res.partner") + ._get_default_team_id(user_id=self.user.id) + ) + self.assertEqual( + result_team_from_user, + team_partner, + "Should return the team matching the model_id", + ) + result_team = self.env["mail.activity"]._get_default_team_id( + user_id=self.user.id, model_id=self.partner_ir_model.id + ) + self.assertEqual( + result_team, + team_partner, + "Should return the team matching the model_id", + ) + result_team_from_model = self.env["mail.activity"]._get_default_team_id( + model_id=self.partner_ir_model.id + ) + self.assertEqual( + result_team_from_model, + team_partner, + "Should return the team matching the model_id", + ) + + @users("csu") + def test_get_default_team_id_one_team_without_model_restriction(self): + """Test _get_default_team_id finds team without model restrictions""" + # Create a team without model restrictions + team_generic = ( + self.env["mail.activity.team"] + .sudo() + .create( + { + "name": "Generic Team", + "res_model_ids": [Command.clear()], # No model restrictions + "member_ids": [Command.set([self.user.id])], + } + ) + ) + # Test with a different model - should find the generic team + user_ir_model = self.env["ir.model"]._get("res.users") + result_team = self.env["mail.activity"]._get_default_team_id( + user_id=self.user.id, model_id=user_ir_model.id + ) + self.assertEqual( + result_team, + team_generic, + "Should return team without model restrictions", + ) + result_team_from_user = self.env["mail.activity"]._get_default_team_id( + user_id=self.user.id + ) + self.assertEqual( + result_team_from_user, + team_generic, + "Should return team without model restrictions", + ) + result_team_from_model = ( + self.env["mail.activity"] + .with_context(default_res_model="res.partner") + ._get_default_team_id(model_id=user_ir_model.id) + ) + self.assertEqual( + result_team_from_model, + team_generic, + "Should return team without model restrictions", + ) + + def test_get_default_team_id_no_match(self): + """Test _get_default_team_id returns empty when no team matches""" + # Create a team for a specific model + user_ir_model = self.env["ir.model"]._get("res.users") + self.env["mail.activity.team"].sudo().create( + { + "name": "Users Team", + "res_model_ids": [Command.set([user_ir_model.id])], + "member_ids": [Command.set([self.user.id])], + } + ) + # Search for a different user who is not a member + result_team = self.env["mail.activity"]._get_default_team_id( + user_id=self.user2.id, model_id=user_ir_model.id + ) + self.assertFalse( + result_team, + "Should return empty recordset when user is not a team member", + ) + + def test_get_default_team_id_priority_model_match(self): + """Test _get_default_team_id returns first matching team""" + # Create two teams for the same model and user + self.env["mail.activity.team"].create( + { + "name": "Team A", + "res_model_ids": [Command.clear()], # No model restrictions + "member_ids": [Command.set([self.user.id])], + } + ) + team_b = self.env["mail.activity.team"].create( + { + "name": "Team B", + "res_model_ids": [Command.set([self.partner_ir_model.id])], + "member_ids": [Command.set([self.user.id])], + } + ) + # Test - should return the first match (based on search order) + result_team = self.env["mail.activity"]._get_default_team_id( + user_id=self.user.id, model_id=self.partner_ir_model.id + ) + self.assertEqual( + result_team, + team_b, + "Should return the team with model match", + ) + # Verify it's a single record + self.assertEqual(len(result_team), 1, "Should return only one team") + + def test_create_activity_without_team_assigns_no_team(self): + """Test creating activity with user_id but no team_id assigns default team""" + # Clean up existing activities + self.env["mail.activity"].search([]).unlink() + # Create a team for the partner model + self.env["mail.activity.team"].create( + { + "name": "Auto Assign Team", + "res_model_ids": [Command.set([self.partner_ir_model.id])], + "member_ids": [Command.set([self.user.id])], + } + ) + # Create an activity with team_user_id but no team_id + activity = self.env["mail.activity"].create( + { + "activity_type_id": self.activity1.id, + "note": "Test auto team assignment", + "res_id": self.partner_client.id, + "res_model_id": self.partner_ir_model.id, + "team_user_id": self.user.id, + } + ) + # Verify team was not assigned + self.assertFalse( + activity.team_id, + "Team should not be assigned when team_user_id is used without team_id", + ) + + def test_create_activity_without_team_assigns_correct_team(self): + """Test creating activity with user_id but no team_id assigns default team""" + # Clean up existing activities + self.env["mail.activity"].search([]).unlink() + # Create a team for the partner model + team_auto = self.env["mail.activity.team"].create( + { + "name": "Auto Assign Team", + "res_model_ids": [Command.set([self.partner_ir_model.id])], + "member_ids": [Command.set([self.user.id])], + } + ) + # Create an activity with user_id but no team_id + activity = self.env["mail.activity"].create( + { + "activity_type_id": self.activity1.id, + "note": "Test auto team assignment", + "res_id": self.partner_client.id, + "res_model_id": self.partner_ir_model.id, + "user_id": self.user.id, + } + ) + # Verify team was automatically assigned + self.assertEqual( + activity.team_id, + team_auto, + "Team should be automatically assigned based on user and model", + ) + + def test_create_activity_with_team_false(self): + """Test creating activity with user_id but no team_id assigns default team""" + # Clean up existing activities + self.env["mail.activity"].search([]).unlink() + # Create a team for the partner model + self.env["mail.activity.team"].create( + { + "name": "Auto Assign Team", + "res_model_ids": [Command.set([self.partner_ir_model.id])], + "member_ids": [Command.set([self.user.id])], + } + ) + # Create an activity with user_id but no team_id + activity = self.env["mail.activity"].create( + { + "activity_type_id": self.activity1.id, + "note": "Test auto team assignment", + "res_id": self.partner_client.id, + "res_model_id": self.partner_ir_model.id, + "team_user_id": self.user.id, + "team_id": False, # Explicitly set team_id to False + } + ) + # Verify that no team was assigned + self.assertFalse( + activity.team_id, + "Team should not be assigned when team_id is explicitly set to False", + ) + + def test_create_keeps_user_when_team_explicitly_false(self): + """Explicit team_id=False must not drop an explicit assignee.""" + activity = ( + self.env["mail.activity"] + .with_user(self.user) + .sudo() + .create( + { + "activity_type_id": self.activity1.id, + "note": "Regression check: keep explicit assignee.", + "res_id": self.partner_client.id, + "res_model_id": self.partner_ir_model.id, + "user_id": self.user2.id, + "team_id": False, + } + ) + ) + self.assertFalse(activity.team_id) + self.assertEqual(activity.user_id, self.user2) diff --git a/mail_activity_team/wizard/mail_activity_schedule.py b/mail_activity_team/wizard/mail_activity_schedule.py index 56b02c59c..710e26c7b 100644 --- a/mail_activity_team/wizard/mail_activity_schedule.py +++ b/mail_activity_team/wizard/mail_activity_schedule.py @@ -30,10 +30,10 @@ def _compute_activity_team_id(self): if scheduler.activity_type_id.default_team_id: scheduler.activity_team_id = scheduler.activity_type_id.default_team_id elif not scheduler.activity_team_id: - scheduler.activity_team_id = ( - self.env["mail.activity"] - .with_context(default_res_model=scheduler.sudo().res_model_id.model) - ._get_default_team_id(user_id=scheduler.activity_team_user_id.id) + scheduler.activity_team_id = self.env[ + "mail.activity" + ]._get_default_team_id( + scheduler.activity_team_user_id.id, scheduler.sudo().res_model_id.id ) @api.onchange("activity_team_id") @@ -58,10 +58,8 @@ def _onchange_activity_team_user_id(self): and self.activity_team_user_id in self.activity_team_id.member_ids ): return - self.activity_team_id = ( - self.env["mail.activity"] - .with_context(default_res_model=self.sudo().res_model_id.model) - ._get_default_team_id(user_id=self.activity_team_user_id.id) + self.activity_team_id = self.env["mail.activity"]._get_default_team_id( + self.activity_team_user_id.id, self.sudo().res_model_id.id ) def _action_schedule_activities(self): From 5ec5d0bb8973a96e6cb82db1bfe60ff8ff112050 Mon Sep 17 00:00:00 2001 From: Stefan Rijnhart Date: Sun, 15 Mar 2026 12:57:23 +0100 Subject: [PATCH 57/60] [REF] mail_activity_team: implement team_id compute method to simplify code --- mail_activity_team/README.rst | 2 +- mail_activity_team/__manifest__.py | 2 +- mail_activity_team/models/mail_activity.py | 87 +++++++-------- .../models/mail_activity_mixin.py | 12 --- .../static/description/index.html | 2 +- .../tests/test_mail_activity.py | 102 +++++++++--------- 6 files changed, 91 insertions(+), 116 deletions(-) diff --git a/mail_activity_team/README.rst b/mail_activity_team/README.rst index fbaa7b49a..340dcc671 100644 --- a/mail_activity_team/README.rst +++ b/mail_activity_team/README.rst @@ -11,7 +11,7 @@ Mail Activity Team !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:ca0203ad2f0fed4e4686b319424332ac44446e2380683a802c1052f78584cfa4 + !! source digest: sha256:1232b4696929762d5c9fffdeb7e8cccc98e77117d0d2dbeece66322d960c3297 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py index a708741a7..22e8a5367 100644 --- a/mail_activity_team/__manifest__.py +++ b/mail_activity_team/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Mail Activity Team", "summary": "Add Teams to Activities", - "version": "18.0.1.0.3", + "version": "18.0.1.1.0", "development_status": "Beta", "category": "Social Network", "website": "https://github.com/OCA/mail", diff --git a/mail_activity_team/models/mail_activity.py b/mail_activity_team/models/mail_activity.py index a40fc16aa..748e057f2 100644 --- a/mail_activity_team/models/mail_activity.py +++ b/mail_activity_team/models/mail_activity.py @@ -8,34 +8,26 @@ class MailActivity(models.Model): _inherit = "mail.activity" - @api.model - def _get_default_team_id(self, user_id=None, model_id=None): - if not user_id: - user_id = self.env.uid - if not model_id: - res_model = self.env.context.get("default_res_model") - model = ( - self.sudo().env["ir.model"].search([("model", "=", res_model)], limit=1) + def _get_default_team_id(self): + self.ensure_one() + domain = [] + domain.append(("member_ids", "=", self.user_id.id or self.env.user.id)) + if self.res_model_id: + domain += [ + "|", + ("res_model_ids", "=", False), + ("res_model_ids", "=", self.res_model_id.id), + ] + if not domain: + return self.env["mail.activity.team"] + teams = self.env["mail.activity.team"].search(domain) + if self.res_model_id: + # Prefer teams with a matching model + teams = ( + teams.filtered(lambda mat: self.res_model_id in mat.res_model_ids) + or teams ) - model_id = model.id if model else None - domain = [("member_ids", "in", [user_id])] - if model_id: - domain.extend( - [ - "|", - ("res_model_ids", "=", False), - ("res_model_ids", "in", [model_id]), - ] - ) - results = self.env["mail.activity.team"].search(domain) - if model_id: - result_with_model = results.filtered( - lambda team: model_id in team.res_model_ids.ids - ) - if result_with_model: - return result_with_model[0] - - return results[0] if results else self.env["mail.activity.team"] + return teams[:1] user_id = fields.Many2one(string="User", required=False, default=False) team_user_id = fields.Many2one( @@ -45,8 +37,27 @@ def _get_default_team_id(self, user_id=None, model_id=None): team_id = fields.Many2one( comodel_name="mail.activity.team", index=True, + compute="_compute_team_id", + store=True, + readonly=False, ) + @api.depends("res_model_id", "user_id") + def _compute_team_id(self): + """Assign team if no team yet or team is incompatible""" + for activity in self: + if ( + not activity.team_id + or activity.user_id + and activity.user_id not in activity.team_id.member_ids + or ( + activity.res_model_id + and activity.team_id.res_model_ids + and activity.res_model_id not in activity.team_id.res_model_ids + ) + ): + activity.team_id = activity._get_default_team_id() + @api.model_create_multi def create(self, vals_list): # Differently from the previous odoo version, @@ -63,30 +74,8 @@ def create(self, vals_list): # so if we don't have a user_team_id we don't want user_id too if "user_id" in vals and not vals.get("team_user_id"): del vals["user_id"] - elif ( - "team_id" not in vals - and "user_id" in vals - and "team_user_id" not in vals - ): - # legacy behavior, if we have user_id but no team_id, set the team_id - team_id = self._get_default_team_id( - vals["user_id"], vals.get("res_model_id") - ) - if team_id: - vals["team_id"] = team_id.id - vals["team_user_id"] = vals["user_id"] return super().create(vals_list) - @api.onchange("user_id") - def _onchange_user_id(self): - if not self.user_id or ( - self.team_id and self.user_id in self.team_id.member_ids - ): - return - self.team_id = self._get_default_team_id( - self.user_id.id, self.sudo().res_model_id.id - ) - @api.onchange("team_id") def _onchange_team_id(self): if self.team_id and self.user_id not in self.team_id.member_ids: diff --git a/mail_activity_team/models/mail_activity_mixin.py b/mail_activity_team/models/mail_activity_mixin.py index 8766a7785..2157bc6ef 100644 --- a/mail_activity_team/models/mail_activity_mixin.py +++ b/mail_activity_team/models/mail_activity_mixin.py @@ -71,18 +71,6 @@ def activity_schedule( act_values.update( {"user_id": activity_type.default_team_id.member_ids[:1].id} ) - else: - user_id = act_values.get("user_id") - if user_id: - team = ( - self.env["mail.activity"] - .with_context( - default_res_model=self._name, - ) - ._get_default_team_id(user_id=user_id) - ) - if team: - act_values.update({"team_id": team.id}) return super().activity_schedule( act_type_xmlid=act_type_xmlid, date_deadline=date_deadline, diff --git a/mail_activity_team/static/description/index.html b/mail_activity_team/static/description/index.html index cef90284d..04f8743fe 100644 --- a/mail_activity_team/static/description/index.html +++ b/mail_activity_team/static/description/index.html @@ -372,7 +372,7 @@

Mail Activity Team

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:ca0203ad2f0fed4e4686b319424332ac44446e2380683a802c1052f78584cfa4 +!! source digest: sha256:1232b4696929762d5c9fffdeb7e8cccc98e77117d0d2dbeece66322d960c3297 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

This module adds the possibility to assign teams to activities.

diff --git a/mail_activity_team/tests/test_mail_activity.py b/mail_activity_team/tests/test_mail_activity.py index fdc8d979b..28bdaf281 100644 --- a/mail_activity_team/tests/test_mail_activity.py +++ b/mail_activity_team/tests/test_mail_activity.py @@ -1,5 +1,5 @@ from odoo import Command -from odoo.tests import users +from odoo.tests import Form, users from odoo.addons.base.tests.common import BaseCommon @@ -63,30 +63,20 @@ def test_get_default_team_id_one_team_with_model(self): } ) ) - # Test with model_id parameter - should find the team - result_team_from_user = ( - self.env["mail.activity"] - .with_context(default_res_model="res.partner") - ._get_default_team_id(user_id=self.user.id) - ) - self.assertEqual( - result_team_from_user, - team_partner, - "Should return the team matching the model_id", - ) - result_team = self.env["mail.activity"]._get_default_team_id( - user_id=self.user.id, model_id=self.partner_ir_model.id + form_team_from_user = Form( + self.env["mail.activity"].with_context( + default_res_model="res.partner", + default_res_id=self.partner_client.id, + ) ) self.assertEqual( - result_team, + form_team_from_user.team_id, team_partner, "Should return the team matching the model_id", ) - result_team_from_model = self.env["mail.activity"]._get_default_team_id( - model_id=self.partner_ir_model.id - ) + activity = form_team_from_user.save() self.assertEqual( - result_team_from_model, + activity.team_id, team_partner, "Should return the team matching the model_id", ) @@ -106,31 +96,22 @@ def test_get_default_team_id_one_team_without_model_restriction(self): } ) ) - # Test with a different model - should find the generic team - user_ir_model = self.env["ir.model"]._get("res.users") - result_team = self.env["mail.activity"]._get_default_team_id( - user_id=self.user.id, model_id=user_ir_model.id - ) - self.assertEqual( - result_team, - team_generic, - "Should return team without model restrictions", - ) - result_team_from_user = self.env["mail.activity"]._get_default_team_id( - user_id=self.user.id - ) + # Test without a model - should find the generic team + form_result_team = Form(self.env["mail.activity"]) self.assertEqual( - result_team_from_user, + form_result_team.team_id, team_generic, "Should return team without model restrictions", ) - result_team_from_model = ( - self.env["mail.activity"] - .with_context(default_res_model="res.partner") - ._get_default_team_id(model_id=user_ir_model.id) + # Test with a model - still finds the generic team + form_result_team_from_model = Form( + self.env["mail.activity"].with_context( + default_res_model="res.partner", + default_res_id=self.partner_client.id, + ), ) self.assertEqual( - result_team_from_model, + form_result_team_from_model.team_id, team_generic, "Should return team without model restrictions", ) @@ -138,20 +119,28 @@ def test_get_default_team_id_one_team_without_model_restriction(self): def test_get_default_team_id_no_match(self): """Test _get_default_team_id returns empty when no team matches""" # Create a team for a specific model - user_ir_model = self.env["ir.model"]._get("res.users") self.env["mail.activity.team"].sudo().create( { "name": "Users Team", - "res_model_ids": [Command.set([user_ir_model.id])], + "res_model_ids": [Command.set([self.partner_ir_model.id])], "member_ids": [Command.set([self.user.id])], } ) # Search for a different user who is not a member - result_team = self.env["mail.activity"]._get_default_team_id( - user_id=self.user2.id, model_id=user_ir_model.id + form_result_team = Form( + self.env["mail.activity"].with_context( + default_res_model="res.partner", + default_res_id=self.partner_client.id, + ) + ) + form_result_team.user_id = self.user2 + self.assertFalse( + form_result_team.team_id, + "Should return empty recordset when user is not a team member", ) + activity = form_result_team.save() self.assertFalse( - result_team, + activity.team_id, "Should return empty recordset when user is not a team member", ) @@ -173,23 +162,31 @@ def test_get_default_team_id_priority_model_match(self): } ) # Test - should return the first match (based on search order) - result_team = self.env["mail.activity"]._get_default_team_id( - user_id=self.user.id, model_id=self.partner_ir_model.id + form_result_team = Form( + self.env["mail.activity"].with_context( + default_res_model_id=self.partner_ir_model.id, + default_res_id=self.partner_client.id, + ) ) + form_result_team.user_id = self.user self.assertEqual( - result_team, + form_result_team.team_id, + team_b, + "Should return the team with model match", + ) + activity = form_result_team.save() + self.assertEqual( + activity.team_id, team_b, "Should return the team with model match", ) - # Verify it's a single record - self.assertEqual(len(result_team), 1, "Should return only one team") - def test_create_activity_without_team_assigns_no_team(self): + def test_create_activity_without_team_assigns_team_by_model_and_user(self): """Test creating activity with user_id but no team_id assigns default team""" # Clean up existing activities self.env["mail.activity"].search([]).unlink() # Create a team for the partner model - self.env["mail.activity.team"].create( + team = self.env["mail.activity.team"].create( { "name": "Auto Assign Team", "res_model_ids": [Command.set([self.partner_ir_model.id])], @@ -207,9 +204,10 @@ def test_create_activity_without_team_assigns_no_team(self): } ) # Verify team was not assigned - self.assertFalse( + self.assertEqual( activity.team_id, - "Team should not be assigned when team_user_id is used without team_id", + team, + "Team should be selected by model and (team) user", ) def test_create_activity_without_team_assigns_correct_team(self): From 8c507abcfa4d7afbf1d6742c5aeb3aedbcaafb59 Mon Sep 17 00:00:00 2001 From: Christopher Rogos Date: Tue, 31 Mar 2026 07:54:38 +0000 Subject: [PATCH 58/60] [FIX] mail_activity_team: enhance _get_default_team_id method to handle user and model IDs --- mail_activity_team/README.rst | 2 +- mail_activity_team/__manifest__.py | 2 +- mail_activity_team/i18n/es.po | 45 ++++++++ mail_activity_team/i18n/fr.po | 45 ++++++++ mail_activity_team/i18n/it.po | 45 ++++++++ .../i18n/mail_activity_team.pot | 45 ++++++++ mail_activity_team/models/mail_activity.py | 23 ++-- .../static/description/index.html | 2 +- .../tests/test_mail_activity_team.py | 109 ++++++++++++++++++ 9 files changed, 307 insertions(+), 11 deletions(-) diff --git a/mail_activity_team/README.rst b/mail_activity_team/README.rst index 340dcc671..2450f3d64 100644 --- a/mail_activity_team/README.rst +++ b/mail_activity_team/README.rst @@ -11,7 +11,7 @@ Mail Activity Team !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:1232b4696929762d5c9fffdeb7e8cccc98e77117d0d2dbeece66322d960c3297 + !! source digest: sha256:d6186630bb2bcead6b33ef289ce1d21d47a0da189cc8709d637007d325eab1b2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py index 22e8a5367..0b8b78332 100644 --- a/mail_activity_team/__manifest__.py +++ b/mail_activity_team/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Mail Activity Team", "summary": "Add Teams to Activities", - "version": "18.0.1.1.0", + "version": "18.0.1.2.0", "development_status": "Beta", "category": "Social Network", "website": "https://github.com/OCA/mail", diff --git a/mail_activity_team/i18n/es.po b/mail_activity_team/i18n/es.po index 6e3f88f37..2271aa3ea 100644 --- a/mail_activity_team/i18n/es.po +++ b/mail_activity_team/i18n/es.po @@ -16,6 +16,12 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.17\n" +#. module: mail_activity_team +#. odoo-python +#: code:addons/mail_activity_team/wizard/mail_activity_schedule.py:0 +msgid "%(activity)s, assigned to team %(name)s, due on the %(deadline)s" +msgstr "" + #. module: mail_activity_team #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 @@ -49,6 +55,11 @@ msgstr "Mezclador de Actividad" msgid "Activity Team" msgstr "Equipo de Actividad" +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_required +msgid "Activity Team Required" +msgstr "" + #. module: mail_activity_team #: model:ir.actions.act_window,name:mail_activity_team.mail_activity_team_action #: model:ir.model.fields,field_description:mail_activity_team.field_res_users__activity_team_ids @@ -61,6 +72,11 @@ msgstr "Equipos de Actividad" msgid "Activity Type" msgstr "Tipo de Actividad" +#. module: mail_activity_team +#: model:ir.model,name:mail_activity_team.model_mail_activity_plan_template +msgid "Activity plan template" +msgstr "" + #. module: mail_activity_team #: model:ir.model,name:mail_activity_team.model_mail_activity_schedule msgid "Activity schedule plan Wizard" @@ -76,6 +92,16 @@ msgstr "Archivado" msgid "Assign to missing activities" msgstr "Asignar a Actividades pendientes" +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__responsible_id +msgid "Assigned to" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__responsible_type +msgid "Assignment" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__create_uid msgid "Created by" @@ -101,6 +127,11 @@ msgstr "Mostrar Nombre" msgid "ID" msgstr "ID (identificación)" +#. module: mail_activity_team +#: model:ir.model.fields,help:mail_activity_team.field_mail_activity_plan_template__activity_team_required +msgid "Indicate if this plan template must have an activity team" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__write_uid msgid "Last Updated by" @@ -142,6 +173,12 @@ msgstr "Mis Actividades en Equipo" msgid "Name" msgstr "nombre" +#. module: mail_activity_team +#. odoo-python +#: code:addons/mail_activity_team/models/mail_activity_plan_template.py:0 +msgid "Please enter an activity team." +msgstr "" + #. module: mail_activity_team #: model:ir.model,name:mail_activity_team.model_ir_actions_server msgid "Server Action" @@ -151,6 +188,7 @@ msgstr "Acción de Servidor" #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id +#: model:ir.model.fields.selection,name:mail_activity_team.selection__mail_activity_plan_template__responsible_type__team msgid "Team" msgstr "Equipo" @@ -171,12 +209,14 @@ msgid "Team Members" msgstr "Miembros del Equipo" #. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_id #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_schedule__activity_team_id msgid "Team assigned to" msgstr "" #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_user_id +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_user_id #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_schedule__activity_team_user_id msgid "Team user" msgstr "Usuario del Equipo" @@ -189,6 +229,11 @@ msgid "" msgstr "" "El usuario asignado %(user_name)s no es miembro del equipo %(team_name)s." +#. module: mail_activity_team +#: model:ir.model.fields,help:mail_activity_team.field_mail_activity_plan_template__activity_team_user_id +msgid "The team member that the activity will be assigned to specifically" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__res_model_ids msgid "Used models" diff --git a/mail_activity_team/i18n/fr.po b/mail_activity_team/i18n/fr.po index 45a963f64..1e218152c 100644 --- a/mail_activity_team/i18n/fr.po +++ b/mail_activity_team/i18n/fr.po @@ -16,6 +16,12 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.3.2\n" +#. module: mail_activity_team +#. odoo-python +#: code:addons/mail_activity_team/wizard/mail_activity_schedule.py:0 +msgid "%(activity)s, assigned to team %(name)s, due on the %(deadline)s" +msgstr "" + #. module: mail_activity_team #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 @@ -49,6 +55,11 @@ msgstr "Combinaison d'activités" msgid "Activity Team" msgstr "Equipe d'activité" +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_required +msgid "Activity Team Required" +msgstr "" + #. module: mail_activity_team #: model:ir.actions.act_window,name:mail_activity_team.mail_activity_team_action #: model:ir.model.fields,field_description:mail_activity_team.field_res_users__activity_team_ids @@ -61,6 +72,11 @@ msgstr "Equipes d'activité" msgid "Activity Type" msgstr "" +#. module: mail_activity_team +#: model:ir.model,name:mail_activity_team.model_mail_activity_plan_template +msgid "Activity plan template" +msgstr "" + #. module: mail_activity_team #: model:ir.model,name:mail_activity_team.model_mail_activity_schedule msgid "Activity schedule plan Wizard" @@ -76,6 +92,16 @@ msgstr "" msgid "Assign to missing activities" msgstr "Assigner une équipe aux activités manquantes" +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__responsible_id +msgid "Assigned to" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__responsible_type +msgid "Assignment" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__create_uid msgid "Created by" @@ -101,6 +127,11 @@ msgstr "" msgid "ID" msgstr "" +#. module: mail_activity_team +#: model:ir.model.fields,help:mail_activity_team.field_mail_activity_plan_template__activity_team_required +msgid "Indicate if this plan template must have an activity team" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__write_uid msgid "Last Updated by" @@ -142,6 +173,12 @@ msgstr "Activités de mon équipe" msgid "Name" msgstr "" +#. module: mail_activity_team +#. odoo-python +#: code:addons/mail_activity_team/models/mail_activity_plan_template.py:0 +msgid "Please enter an activity team." +msgstr "" + #. module: mail_activity_team #: model:ir.model,name:mail_activity_team.model_ir_actions_server msgid "Server Action" @@ -151,6 +188,7 @@ msgstr "" #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id +#: model:ir.model.fields.selection,name:mail_activity_team.selection__mail_activity_plan_template__responsible_type__team msgid "Team" msgstr "" @@ -171,12 +209,14 @@ msgid "Team Members" msgstr "" #. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_id #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_schedule__activity_team_id msgid "Team assigned to" msgstr "" #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_user_id +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_user_id #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_schedule__activity_team_user_id msgid "Team user" msgstr "" @@ -188,6 +228,11 @@ msgid "" "The assigned user %(user_name)s is not member of the team %(team_name)s." msgstr "" +#. module: mail_activity_team +#: model:ir.model.fields,help:mail_activity_team.field_mail_activity_plan_template__activity_team_user_id +msgid "The team member that the activity will be assigned to specifically" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__res_model_ids msgid "Used models" diff --git a/mail_activity_team/i18n/it.po b/mail_activity_team/i18n/it.po index 59132e078..e211378ea 100644 --- a/mail_activity_team/i18n/it.po +++ b/mail_activity_team/i18n/it.po @@ -16,6 +16,12 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.15.2\n" +#. module: mail_activity_team +#. odoo-python +#: code:addons/mail_activity_team/wizard/mail_activity_schedule.py:0 +msgid "%(activity)s, assigned to team %(name)s, due on the %(deadline)s" +msgstr "" + #. module: mail_activity_team #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 @@ -49,6 +55,11 @@ msgstr "Mixin attività" msgid "Activity Team" msgstr "Team Attività" +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_required +msgid "Activity Team Required" +msgstr "" + #. module: mail_activity_team #: model:ir.actions.act_window,name:mail_activity_team.mail_activity_team_action #: model:ir.model.fields,field_description:mail_activity_team.field_res_users__activity_team_ids @@ -61,6 +72,11 @@ msgstr "Team Attività" msgid "Activity Type" msgstr "Tipo attività" +#. module: mail_activity_team +#: model:ir.model,name:mail_activity_team.model_mail_activity_plan_template +msgid "Activity plan template" +msgstr "" + #. module: mail_activity_team #: model:ir.model,name:mail_activity_team.model_mail_activity_schedule msgid "Activity schedule plan Wizard" @@ -76,6 +92,16 @@ msgstr "In archivio" msgid "Assign to missing activities" msgstr "Assegna ad attività mancanti" +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__responsible_id +msgid "Assigned to" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__responsible_type +msgid "Assignment" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__create_uid msgid "Created by" @@ -101,6 +127,11 @@ msgstr "Nome visualizzato" msgid "ID" msgstr "ID" +#. module: mail_activity_team +#: model:ir.model.fields,help:mail_activity_team.field_mail_activity_plan_template__activity_team_required +msgid "Indicate if this plan template must have an activity team" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__write_uid msgid "Last Updated by" @@ -142,6 +173,12 @@ msgstr "Attività del mio team" msgid "Name" msgstr "Nome" +#. module: mail_activity_team +#. odoo-python +#: code:addons/mail_activity_team/models/mail_activity_plan_template.py:0 +msgid "Please enter an activity team." +msgstr "" + #. module: mail_activity_team #: model:ir.model,name:mail_activity_team.model_ir_actions_server msgid "Server Action" @@ -151,6 +188,7 @@ msgstr "Azione server" #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id +#: model:ir.model.fields.selection,name:mail_activity_team.selection__mail_activity_plan_template__responsible_type__team msgid "Team" msgstr "Team" @@ -171,12 +209,14 @@ msgid "Team Members" msgstr "Membri Team" #. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_id #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_schedule__activity_team_id msgid "Team assigned to" msgstr "Team assegnato a" #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_user_id +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_user_id #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_schedule__activity_team_user_id msgid "Team user" msgstr "Utente del team" @@ -189,6 +229,11 @@ msgid "" msgstr "" "L'utente assegnato %(user_name)s nn è un membro del team %(team_name)s." +#. module: mail_activity_team +#: model:ir.model.fields,help:mail_activity_team.field_mail_activity_plan_template__activity_team_user_id +msgid "The team member that the activity will be assigned to specifically" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__res_model_ids msgid "Used models" diff --git a/mail_activity_team/i18n/mail_activity_team.pot b/mail_activity_team/i18n/mail_activity_team.pot index 40bf6c7b3..cc57a7f39 100644 --- a/mail_activity_team/i18n/mail_activity_team.pot +++ b/mail_activity_team/i18n/mail_activity_team.pot @@ -13,6 +13,12 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: mail_activity_team +#. odoo-python +#: code:addons/mail_activity_team/wizard/mail_activity_schedule.py:0 +msgid "%(activity)s, assigned to team %(name)s, due on the %(deadline)s" +msgstr "" + #. module: mail_activity_team #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 @@ -46,6 +52,11 @@ msgstr "" msgid "Activity Team" msgstr "" +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_required +msgid "Activity Team Required" +msgstr "" + #. module: mail_activity_team #: model:ir.actions.act_window,name:mail_activity_team.mail_activity_team_action #: model:ir.model.fields,field_description:mail_activity_team.field_res_users__activity_team_ids @@ -58,6 +69,11 @@ msgstr "" msgid "Activity Type" msgstr "" +#. module: mail_activity_team +#: model:ir.model,name:mail_activity_team.model_mail_activity_plan_template +msgid "Activity plan template" +msgstr "" + #. module: mail_activity_team #: model:ir.model,name:mail_activity_team.model_mail_activity_schedule msgid "Activity schedule plan Wizard" @@ -73,6 +89,16 @@ msgstr "" msgid "Assign to missing activities" msgstr "" +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__responsible_id +msgid "Assigned to" +msgstr "" + +#. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__responsible_type +msgid "Assignment" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__create_uid msgid "Created by" @@ -98,6 +124,11 @@ msgstr "" msgid "ID" msgstr "" +#. module: mail_activity_team +#: model:ir.model.fields,help:mail_activity_team.field_mail_activity_plan_template__activity_team_required +msgid "Indicate if this plan template must have an activity team" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__write_uid msgid "Last Updated by" @@ -139,6 +170,12 @@ msgstr "" msgid "Name" msgstr "" +#. module: mail_activity_team +#. odoo-python +#: code:addons/mail_activity_team/models/mail_activity_plan_template.py:0 +msgid "Please enter an activity team." +msgstr "" + #. module: mail_activity_team #: model:ir.model,name:mail_activity_team.model_ir_actions_server msgid "Server Action" @@ -148,6 +185,7 @@ msgstr "" #. odoo-javascript #: code:addons/mail_activity_team/static/src/core/web/activity.xml:0 #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_id +#: model:ir.model.fields.selection,name:mail_activity_team.selection__mail_activity_plan_template__responsible_type__team msgid "Team" msgstr "" @@ -168,12 +206,14 @@ msgid "Team Members" msgstr "" #. module: mail_activity_team +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_id #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_schedule__activity_team_id msgid "Team assigned to" msgstr "" #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity__team_user_id +#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_user_id #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_schedule__activity_team_user_id msgid "Team user" msgstr "" @@ -185,6 +225,11 @@ msgid "" "The assigned user %(user_name)s is not member of the team %(team_name)s." msgstr "" +#. module: mail_activity_team +#: model:ir.model.fields,help:mail_activity_team.field_mail_activity_plan_template__activity_team_user_id +msgid "The team member that the activity will be assigned to specifically" +msgstr "" + #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__res_model_ids msgid "Used models" diff --git a/mail_activity_team/models/mail_activity.py b/mail_activity_team/models/mail_activity.py index 748e057f2..eb8cf3af3 100644 --- a/mail_activity_team/models/mail_activity.py +++ b/mail_activity_team/models/mail_activity.py @@ -8,23 +8,28 @@ class MailActivity(models.Model): _inherit = "mail.activity" - def _get_default_team_id(self): - self.ensure_one() + def _get_default_team_id(self, user_id=None, model_id=None): + if not user_id: + user_id = self.user_id.id or self.env.user.id + if not model_id: + model_id = self.res_model_id.id if self.res_model_id else None domain = [] - domain.append(("member_ids", "=", self.user_id.id or self.env.user.id)) - if self.res_model_id: + domain.append(("member_ids", "=", user_id)) + if model_id: domain += [ "|", ("res_model_ids", "=", False), - ("res_model_ids", "=", self.res_model_id.id), + ("res_model_ids", "=", model_id), ] if not domain: return self.env["mail.activity.team"] teams = self.env["mail.activity.team"].search(domain) - if self.res_model_id: + if model_id: # Prefer teams with a matching model teams = ( - teams.filtered(lambda mat: self.res_model_id in mat.res_model_ids) + teams.filtered( + lambda mat, model_id=model_id: model_id in mat.res_model_ids.ids + ) or teams ) return teams[:1] @@ -56,7 +61,9 @@ def _compute_team_id(self): and activity.res_model_id not in activity.team_id.res_model_ids ) ): - activity.team_id = activity._get_default_team_id() + activity.team_id = activity._get_default_team_id( + activity.user_id.id, activity.res_model_id.id + ) @api.model_create_multi def create(self, vals_list): diff --git a/mail_activity_team/static/description/index.html b/mail_activity_team/static/description/index.html index 04f8743fe..6c3938cf2 100644 --- a/mail_activity_team/static/description/index.html +++ b/mail_activity_team/static/description/index.html @@ -372,7 +372,7 @@

Mail Activity Team

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:1232b4696929762d5c9fffdeb7e8cccc98e77117d0d2dbeece66322d960c3297 +!! source digest: sha256:d6186630bb2bcead6b33ef289ce1d21d47a0da189cc8709d637007d325eab1b2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

This module adds the possibility to assign teams to activities.

diff --git a/mail_activity_team/tests/test_mail_activity_team.py b/mail_activity_team/tests/test_mail_activity_team.py index 643bd0863..1b1e2d06d 100644 --- a/mail_activity_team/tests/test_mail_activity_team.py +++ b/mail_activity_team/tests/test_mail_activity_team.py @@ -115,6 +115,21 @@ def setUpClass(cls): } ) ) + cls.schedule_act2 = ( + cls.env["mail.activity.schedule"] + .with_user(cls.employee) + .with_context( + active_model=cls.partner_client._name, + active_ids=cls.partner_client.ids, + default_activity_user_id=cls.employee.id, + ) + .create( + { + "activity_type_id": cls.activity2.id, + "note": "Partner activity 2.", + } + ) + ) def test_activity_members(self): self.team1.member_ids |= self.employee2 @@ -223,6 +238,100 @@ def test_activity_onchanges_activity_type_no_team(self): form.activity_type_id = self.activity1 self.assertEqual(form.team_id, self.team1) + ### Test mail.activity.schedule onchange / compute functionality, analogous + ### to the mail.activity tests above. + def test_schedule_activity_onchanges_keep_user(self): + self.assertEqual( + self.schedule_act2.activity_team_id, + self.team1, + "Error: wizard should have Team 1.", + ) + with Form(self.schedule_act2) as form: + form.activity_team_id = self.env["mail.activity.team"] + self.assertEqual(form.activity_user_id, self.employee) + + def test_schedule_activity_onchanges_user_no_member_team(self): + self.assertEqual( + self.schedule_act2.activity_team_id, + self.team1, + "Error: Activity 2 should have Team 1.", + ) + with self.assertRaises( + AssertionError, msg="can't write on invisible field user_id" + ): + with Form(self.schedule_act2) as form: + form.activity_user_id = self.employee2 + + def test_schedule_activity_onchanges_user_no_team(self): + self.assertEqual( + self.schedule_act2.activity_team_id, + self.team1, + "Error: Activity 2 should have Team 1.", + ) + with Form(self.schedule_act2) as form: + form.activity_team_id = self.env["mail.activity.team"] + form.activity_user_id = self.employee2 + self.assertEqual(form.activity_team_id, self.team2) + + def test_schedule_activity_onchanges_team_no_member(self): + self.assertEqual( + self.schedule_act2.activity_team_id, + self.team1, + "Error: Activity 2 should have Team 1.", + ) + self.team2.user_id = False + self.team2.member_ids = False + with Form(self.schedule_act2) as form: + form.activity_team_id = self.team2 + self.assertFalse(form.activity_user_id) + + def test_schedule_activity_onchanges_team_different_member(self): + self.assertEqual( + self.schedule_act2.activity_team_id, + self.team1, + "Error: Activity 2 should have Team 1.", + ) + self.team2.user_id = self.employee2 + self.team2.member_ids = self.employee2 + with Form(self.schedule_act2) as form: + form.activity_team_id = self.team2 + self.assertEqual(form.activity_user_id, self.employee2) + + def test_schedule_activity_onchanges_team_different_member_no_leader(self): + self.assertEqual( + self.schedule_act2.activity_team_id, + self.team1, + "Error: Activity 2 should have Team 1.", + ) + self.team2.user_id = False + self.team2.member_ids = self.employee2 + with Form(self.schedule_act2) as form: + form.activity_team_id = self.team2 + self.assertEqual(form.activity_user_id, self.employee2) + + def test_schedule_activity_onchanges_activity_type_set_team(self): + self.assertEqual( + self.schedule_act2.activity_team_id, + self.team1, + "Error: Activity 2 should have Team 1.", + ) + self.activity1.default_team_id = self.team2 + self.assertEqual(self.schedule_act2.activity_type_id, self.activity2) + with Form(self.schedule_act2) as form: + form.activity_type_id = self.activity1 + self.assertEqual(form.activity_team_id, self.team2) + + def test_schedule_activity_onchanges_activity_type_no_team(self): + self.assertEqual( + self.schedule_act2.activity_team_id, + self.team1, + "Error: Activity 2 should have Team 1.", + ) + self.assertEqual(self.schedule_act2.activity_type_id, self.activity2) + with Form(self.schedule_act2) as form: + form.activity_type_id = self.activity1 + self.assertEqual(form.activity_team_id, self.team1) + def test_activity_constrain(self): with self.assertRaises(ValidationError): self.act2.write({"user_id": self.employee2.id, "team_id": self.team1.id}) From 0b4be7c1478d93daca306a527ad33de311842a96 Mon Sep 17 00:00:00 2001 From: mymage Date: Fri, 3 Apr 2026 07:34:22 +0000 Subject: [PATCH 59/60] Translated using Weblate (Italian) Currently translated at 100.0% (43 of 43 strings) Translation: mail-18.0/mail-18.0-mail_activity_team Translate-URL: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_activity_team/it/ --- mail_activity_team/i18n/it.po | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mail_activity_team/i18n/it.po b/mail_activity_team/i18n/it.po index e211378ea..2d004c06a 100644 --- a/mail_activity_team/i18n/it.po +++ b/mail_activity_team/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 13.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2026-02-18 11:09+0000\n" +"PO-Revision-Date: 2026-04-03 09:45+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -20,7 +20,7 @@ msgstr "" #. odoo-python #: code:addons/mail_activity_team/wizard/mail_activity_schedule.py:0 msgid "%(activity)s, assigned to team %(name)s, due on the %(deadline)s" -msgstr "" +msgstr "%(activity)s, assegnata al team %(name)s, con scadenza il %(deadline)s" #. module: mail_activity_team #. odoo-javascript @@ -58,7 +58,7 @@ msgstr "Team Attività" #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__activity_team_required msgid "Activity Team Required" -msgstr "" +msgstr "Richiesto team attività" #. module: mail_activity_team #: model:ir.actions.act_window,name:mail_activity_team.mail_activity_team_action @@ -75,7 +75,7 @@ msgstr "Tipo attività" #. module: mail_activity_team #: model:ir.model,name:mail_activity_team.model_mail_activity_plan_template msgid "Activity plan template" -msgstr "" +msgstr "Modello piano attività" #. module: mail_activity_team #: model:ir.model,name:mail_activity_team.model_mail_activity_schedule @@ -95,12 +95,12 @@ msgstr "Assegna ad attività mancanti" #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__responsible_id msgid "Assigned to" -msgstr "" +msgstr "Assegnata a" #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_plan_template__responsible_type msgid "Assignment" -msgstr "" +msgstr "Incarico" #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__create_uid @@ -130,7 +130,7 @@ msgstr "ID" #. module: mail_activity_team #: model:ir.model.fields,help:mail_activity_team.field_mail_activity_plan_template__activity_team_required msgid "Indicate if this plan template must have an activity team" -msgstr "" +msgstr "Indica se questo modello piano deve avere un team attività" #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__write_uid @@ -177,7 +177,7 @@ msgstr "Nome" #. odoo-python #: code:addons/mail_activity_team/models/mail_activity_plan_template.py:0 msgid "Please enter an activity team." -msgstr "" +msgstr "Inserire un team attività." #. module: mail_activity_team #: model:ir.model,name:mail_activity_team.model_ir_actions_server @@ -232,7 +232,7 @@ msgstr "" #. module: mail_activity_team #: model:ir.model.fields,help:mail_activity_team.field_mail_activity_plan_template__activity_team_user_id msgid "The team member that the activity will be assigned to specifically" -msgstr "" +msgstr "Il membro del team a cui verrà specificatamente assegnata l'attività" #. module: mail_activity_team #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team__res_model_ids From e61bc8350dd58169a9005b7cb0425e4749cc492c Mon Sep 17 00:00:00 2001 From: Christopher Rogos Date: Wed, 15 Apr 2026 08:48:06 +0000 Subject: [PATCH 60/60] [MIG] mail_activity_team: Migration to 19.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migration changes: - Bump version to 19.0.1.0.0 - Remove legacy 18.0 migrations directory - Replace _() with self.env._() for 19.0 translation API - Replace groups_id with group_ids (field renamed in 19.0) - Rewrite _get_activity_groups to match 19.0 ORM-based API (replaces raw SQL with ORM search, per-record counting, access rights checks, and new return format with domain/view_type) - Update JS: fetchData → fetchStoreData for 19.0 store API - Replace self._context with self.env.context - Update tests for new per-record counting semantics - Remove obsolete migration test --- mail_activity_team/README.rst | 44 +++++++++---------- mail_activity_team/__manifest__.py | 2 +- .../migrations/18.0.1.0.0/post-migration.py | 9 ---- mail_activity_team/models/mail_activity.py | 7 +-- .../models/mail_activity_mixin.py | 2 +- .../models/mail_activity_plan_template.py | 6 ++- .../static/description/index.html | 6 +-- .../static/src/models/activity_menu.esm.js | 2 +- .../tests/test_mail_activity.py | 6 +-- .../tests/test_mail_activity_team.py | 32 +++----------- .../views/mail_activity_views.xml | 2 +- 11 files changed, 47 insertions(+), 71 deletions(-) delete mode 100644 mail_activity_team/migrations/18.0.1.0.0/post-migration.py diff --git a/mail_activity_team/README.rst b/mail_activity_team/README.rst index 2450f3d64..a61ac7dd2 100644 --- a/mail_activity_team/README.rst +++ b/mail_activity_team/README.rst @@ -21,13 +21,13 @@ Mail Activity Team :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmail-lightgray.png?logo=github - :target: https://github.com/OCA/mail/tree/18.0/mail_activity_team + :target: https://github.com/OCA/mail/tree/19.0/mail_activity_team :alt: OCA/mail .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_activity_team + :target: https://translation.odoo-community.org/projects/mail-19-0/mail-19-0-mail_activity_team :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=18.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=19.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -68,7 +68,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -84,35 +84,35 @@ Authors Contributors ------------ -- `ForgeFlow `__: +- `ForgeFlow `__: - - Jordi Ballester Alomar (jordi.ballester@forgeflow.com) - - Miquel Raïch (miquel.raich@forgeflow.com) - - Bernat Puig Font (bernat.puig@forgeflow.com) + - Jordi Ballester Alomar (jordi.ballester@forgeflow.com) + - Miquel Raïch (miquel.raich@forgeflow.com) + - Bernat Puig Font (bernat.puig@forgeflow.com) -- Pedro Gonzalez (pedro.gonzalez@pesol.es) -- `Tecnativa `__: +- Pedro Gonzalez (pedro.gonzalez@pesol.es) +- `Tecnativa `__: - - David Vidal + - David Vidal -- `Dynapps `__: +- `Dynapps `__: - - Raf Ven + - Raf Ven -- [Trobz] (https://trobz.com): +- [Trobz] (https://trobz.com): - - Son Ho sonhd@trobz.com + - Son Ho sonhd@trobz.com -- [Camptocamp] (https://camptocamp.com): +- [Camptocamp] (https://camptocamp.com): - - Vincent Van Rossem vincent.vanrossem@camptocamp.com - - Italo Lopes italo.lopes@camptocamp.com + - Vincent Van Rossem vincent.vanrossem@camptocamp.com + - Italo Lopes italo.lopes@camptocamp.com -- `CorporateHub `__ +- `CorporateHub `__ - - Alexey Pelykh alexey.pelykh@corphub.eu + - Alexey Pelykh alexey.pelykh@corphub.eu -- Stefan Rijnhart (stefan@opener.amsterdam) +- Stefan Rijnhart (stefan@opener.amsterdam) Other credits ------------- @@ -133,6 +133,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/mail `_ project on GitHub. +This module is part of the `OCA/mail `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_activity_team/__manifest__.py b/mail_activity_team/__manifest__.py index 0b8b78332..9b10e5835 100644 --- a/mail_activity_team/__manifest__.py +++ b/mail_activity_team/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Mail Activity Team", "summary": "Add Teams to Activities", - "version": "18.0.1.2.0", + "version": "19.0.1.0.0", "development_status": "Beta", "category": "Social Network", "website": "https://github.com/OCA/mail", diff --git a/mail_activity_team/migrations/18.0.1.0.0/post-migration.py b/mail_activity_team/migrations/18.0.1.0.0/post-migration.py deleted file mode 100644 index f75fc0224..000000000 --- a/mail_activity_team/migrations/18.0.1.0.0/post-migration.py +++ /dev/null @@ -1,9 +0,0 @@ -from odoo import SUPERUSER_ID, api - - -def migrate(cr, version): - """Update noupdate ir.rule data record""" - env = api.Environment(cr, SUPERUSER_ID, {}) - rule = env.ref("mail_activity_team.mail_activity_rule_my_team") - rule.domain_force = "[('team_id', 'in', user.activity_team_ids.ids)]" - rule.perm_create = False diff --git a/mail_activity_team/models/mail_activity.py b/mail_activity_team/models/mail_activity.py index eb8cf3af3..c2e864461 100644 --- a/mail_activity_team/models/mail_activity.py +++ b/mail_activity_team/models/mail_activity.py @@ -1,7 +1,7 @@ # Copyright 2018-22 ForgeFlow S.L. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import SUPERUSER_ID, _, api, fields, models +from odoo import SUPERUSER_ID, api, fields, models from odoo.exceptions import ValidationError @@ -28,7 +28,8 @@ def _get_default_team_id(self, user_id=None, model_id=None): # Prefer teams with a matching model teams = ( teams.filtered( - lambda mat, model_id=model_id: model_id in mat.res_model_ids.ids + lambda mat, model_id=model_id: model_id + in mat.sudo().res_model_ids.ids ) or teams ) @@ -112,7 +113,7 @@ def _check_team_and_user(self): not in activity.team_id.with_context(active_test=False).member_ids ): raise ValidationError( - _( + self.env._( "The assigned user %(user_name)s is " "not member of the team %(team_name)s.", user_name=activity.user_id.name, diff --git a/mail_activity_team/models/mail_activity_mixin.py b/mail_activity_team/models/mail_activity_mixin.py index 2157bc6ef..af79770f9 100644 --- a/mail_activity_team/models/mail_activity_mixin.py +++ b/mail_activity_team/models/mail_activity_mixin.py @@ -19,7 +19,7 @@ def _compute_activity_team_user_ids(self): rec.activity_team_user_ids = rec.activity_ids.mapped("team_id.member_ids") def _search_my_activity_date_deadline(self, operator, operand): - if not self._context.get("team_activities", False): + if not self.env.context.get("team_activities", False): return super()._search_my_activity_date_deadline(operator, operand) activity_ids = self.env["mail.activity"]._search( [ diff --git a/mail_activity_team/models/mail_activity_plan_template.py b/mail_activity_team/models/mail_activity_plan_template.py index d6e8e41d6..da62cac45 100644 --- a/mail_activity_team/models/mail_activity_plan_template.py +++ b/mail_activity_team/models/mail_activity_plan_template.py @@ -91,5 +91,9 @@ def _determine_responsible(self, on_demand_responsible, applied_on_record): # Avoid signalling an error for a 'team' template without a user. self.ensure_one() if self.activity_team_required: - return {"error": False} + return { + "responsible": self.activity_team_user_id, + "error": False, + "warning": False, + } return super()._determine_responsible(on_demand_responsible, applied_on_record) diff --git a/mail_activity_team/static/description/index.html b/mail_activity_team/static/description/index.html index 6c3938cf2..03f9493e9 100644 --- a/mail_activity_team/static/description/index.html +++ b/mail_activity_team/static/description/index.html @@ -374,7 +374,7 @@

Mail Activity Team

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:d6186630bb2bcead6b33ef289ce1d21d47a0da189cc8709d637007d325eab1b2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

This module adds the possibility to assign teams to activities.

Table of contents

@@ -414,7 +414,7 @@

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -474,7 +474,7 @@

Maintainers

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

-

This module is part of the OCA/mail project on GitHub.

+

This module is part of the OCA/mail project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

diff --git a/mail_activity_team/static/src/models/activity_menu.esm.js b/mail_activity_team/static/src/models/activity_menu.esm.js index 142417287..e129737b9 100644 --- a/mail_activity_team/static/src/models/activity_menu.esm.js +++ b/mail_activity_team/static/src/models/activity_menu.esm.js @@ -15,7 +15,7 @@ patch(ActivityMenu.prototype, { filter_el.classList.add("active"); this.currentFilter = filter_el.dataset.filter; this.updateTeamActivitiesContext(); - this.store.fetchData({systray_get_activities: true}); + this.store.fetchStoreData("systray_get_activities"); }, updateTeamActivitiesContext() { var active = false; diff --git a/mail_activity_team/tests/test_mail_activity.py b/mail_activity_team/tests/test_mail_activity.py index 28bdaf281..72ace0758 100644 --- a/mail_activity_team/tests/test_mail_activity.py +++ b/mail_activity_team/tests/test_mail_activity.py @@ -16,7 +16,7 @@ def setUpClass(cls): "name": "Employee", "login": "csu", "email": "crmuser@yourcompany.com", - "groups_id": [ + "group_ids": [ Command.set( [ cls.env.ref("base.group_user").id, @@ -32,11 +32,11 @@ def setUpClass(cls): "name": "Employee 2", "login": "csu2", "email": "crmuser2@yourcompany.com", - "groups_id": [Command.set([cls.env.ref("base.group_user").id])], + "group_ids": [Command.set([cls.env.ref("base.group_user").id])], } ) cls.partner_ir_model = cls.env["ir.model"]._get("res.partner") - cls.partner_client = cls.env.ref("base.res_partner_1") + cls.partner_client = cls.env["res.partner"].create({"name": "Test Partner"}) # Create Activity Types cls.activity1 = cls.env["mail.activity.type"].create( { diff --git a/mail_activity_team/tests/test_mail_activity_team.py b/mail_activity_team/tests/test_mail_activity_team.py index 1b1e2d06d..8841aa8af 100644 --- a/mail_activity_team/tests/test_mail_activity_team.py +++ b/mail_activity_team/tests/test_mail_activity_team.py @@ -1,11 +1,9 @@ # Copyright 2018-22 ForgeFlow S.L. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -import os from datetime import date from odoo.exceptions import ValidationError from odoo.fields import Command -from odoo.modules.migration import load_script from odoo.tests import Form from odoo.tests.common import TransactionCase @@ -24,7 +22,7 @@ def setUpClass(cls): "name": "Employee", "login": "csu", "email": "crmuser@yourcompany.com", - "groups_id": [ + "group_ids": [ Command.set( [ cls.env.ref("base.group_user").id, @@ -40,7 +38,7 @@ def setUpClass(cls): "name": "Employee 2", "login": "csu2", "email": "crmuser2@yourcompany.com", - "groups_id": [Command.set([cls.env.ref("base.group_user").id])], + "group_ids": [Command.set([cls.env.ref("base.group_user").id])], } ) cls.employee3 = cls.env["res.users"].create( @@ -49,7 +47,7 @@ def setUpClass(cls): "name": "Employee 3", "login": "csu3", "email": "crmuser3@yourcompany.com", - "groups_id": [Command.set([cls.env.ref("base.group_user").id])], + "group_ids": [Command.set([cls.env.ref("base.group_user").id])], } ) # Create Activity Types @@ -72,7 +70,7 @@ def setUpClass(cls): } ) # Create Teams and Activities - cls.partner_client = cls.env.ref("base.res_partner_1") + cls.partner_client = cls.env["res.partner"].create({"name": "Test Partner"}) cls.partner_ir_model = cls.env["ir.model"]._get("res.partner") cls.act1 = ( cls.env["mail.activity"] @@ -406,7 +404,7 @@ def test_activity_count(self): self.assertEqual(res[0]["total_count"], 1) self.assertEqual(res[0]["today_count"], 2) res = self.env["res.users"].with_user(self.employee.id)._get_activity_groups() - self.assertEqual(res[0]["total_count"], 2) + self.assertEqual(res[0]["total_count"], 1) def test_activity_schedule_next(self): self.activity1.write( @@ -557,7 +555,7 @@ def test_web_search_read(self): # Create a non-team activity for our second employee, for a second partner self.team1.member_ids |= self.employee2 partner2 = self.partner_client.copy() - self.employee2.groups_id += self.env.ref("base.group_partner_manager") + self.employee2.group_ids += self.env.ref("base.group_partner_manager") # Craft the activity without a team act3 = ( @@ -594,24 +592,6 @@ def test_web_search_read(self): set(self.partner_client.ids), ) - def test_migration(self): - """Check that the 18.0.1.0.0 migration script runs without error""" - rule = self.env.ref("mail_activity_team.mail_activity_rule_my_team") - rule.perm_create = True - - # Run the migration script - pyfile = os.path.join( - "mail_activity_team", - "migrations", - "18.0.1.0.0", - "post-migration.py", - ) - name, ext = os.path.splitext(os.path.basename(pyfile)) - mod = load_script(pyfile, name) - mod.migrate(self.env.cr, "18.0.1.0.0") - - self.assertFalse(rule.perm_create) - def test_mail_activity_plan_ui_logic(self): """Check team/team user consistency in plan template view""" plan = self.env["mail.activity.plan"].create( diff --git a/mail_activity_team/views/mail_activity_views.xml b/mail_activity_team/views/mail_activity_views.xml index 07fb47f3a..6aa89acd3 100644 --- a/mail_activity_team/views/mail_activity_views.xml +++ b/mail_activity_team/views/mail_activity_views.xml @@ -54,7 +54,7 @@ - +