From 55ba3aab3b98568ddd5dea93dd8e222aadefdf6b Mon Sep 17 00:00:00 2001 From: Ilyas Date: Tue, 25 Apr 2023 09:48:29 +0200 Subject: [PATCH] [14.0][ADD] web_create_write_confirm --- .../odoo/addons/web_create_write_confirm | 1 + setup/web_create_write_confirm/setup.py | 6 + web_create_write_confirm/README.rst | 0 web_create_write_confirm/__init__.py | 4 + web_create_write_confirm/__manifest__.py | 21 ++++ web_create_write_confirm/models/__init__.py | 5 + web_create_write_confirm/models/base.py | 36 ++++++ .../models/popup_message.py | 30 +++++ .../readme/CONTRIBUTORS.rst | 6 + .../readme/DESCRIPTION.rst | 3 + web_create_write_confirm/readme/USAGE.rst | 34 ++++++ .../security/ir.model.access.csv | 3 + .../static/description/icon.png | Bin 0 -> 9433 bytes .../static/src/js/pop_up_confirmation.js | 107 ++++++++++++++++++ web_create_write_confirm/tests/__init__.py | 1 + .../tests/test_base_model.py | 55 +++++++++ web_create_write_confirm/views/assets.xml | 15 +++ .../views/popup_message.xml | 78 +++++++++++++ 18 files changed, 405 insertions(+) create mode 120000 setup/web_create_write_confirm/odoo/addons/web_create_write_confirm create mode 100644 setup/web_create_write_confirm/setup.py create mode 100644 web_create_write_confirm/README.rst create mode 100644 web_create_write_confirm/__init__.py create mode 100644 web_create_write_confirm/__manifest__.py create mode 100644 web_create_write_confirm/models/__init__.py create mode 100644 web_create_write_confirm/models/base.py create mode 100644 web_create_write_confirm/models/popup_message.py create mode 100644 web_create_write_confirm/readme/CONTRIBUTORS.rst create mode 100644 web_create_write_confirm/readme/DESCRIPTION.rst create mode 100644 web_create_write_confirm/readme/USAGE.rst create mode 100644 web_create_write_confirm/security/ir.model.access.csv create mode 100644 web_create_write_confirm/static/description/icon.png create mode 100644 web_create_write_confirm/static/src/js/pop_up_confirmation.js create mode 100644 web_create_write_confirm/tests/__init__.py create mode 100644 web_create_write_confirm/tests/test_base_model.py create mode 100644 web_create_write_confirm/views/assets.xml create mode 100644 web_create_write_confirm/views/popup_message.xml diff --git a/setup/web_create_write_confirm/odoo/addons/web_create_write_confirm b/setup/web_create_write_confirm/odoo/addons/web_create_write_confirm new file mode 120000 index 000000000..46be3cc17 --- /dev/null +++ b/setup/web_create_write_confirm/odoo/addons/web_create_write_confirm @@ -0,0 +1 @@ +../../../../web_create_write_confirm \ No newline at end of file diff --git a/setup/web_create_write_confirm/setup.py b/setup/web_create_write_confirm/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/web_create_write_confirm/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/web_create_write_confirm/README.rst b/web_create_write_confirm/README.rst new file mode 100644 index 000000000..e69de29bb diff --git a/web_create_write_confirm/__init__.py b/web_create_write_confirm/__init__.py new file mode 100644 index 000000000..edbd405bf --- /dev/null +++ b/web_create_write_confirm/__init__.py @@ -0,0 +1,4 @@ +# (C) 2020 Smile () +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). + +from . import models diff --git a/web_create_write_confirm/__manifest__.py b/web_create_write_confirm/__manifest__.py new file mode 100644 index 000000000..0f77454c0 --- /dev/null +++ b/web_create_write_confirm/__manifest__.py @@ -0,0 +1,21 @@ +# (C) 2020 Smile () +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). + +{ + "name": "Confirm/Alert pop-up before saving", + "version": "14.0.1.0.0", + "depends": ["web"], + "author": "Smile, Odoo Community Association (OCA)", + "license": "AGPL-3", + "website": "https://github.com/OCA/web", + "category": "Tools", + "sequence": 20, + "data": [ + "security/ir.model.access.csv", + "views/assets.xml", + "views/popup_message.xml", + ], + "auto_install": False, + "installable": True, + "application": False, +} diff --git a/web_create_write_confirm/models/__init__.py b/web_create_write_confirm/models/__init__.py new file mode 100644 index 000000000..9ef27cee6 --- /dev/null +++ b/web_create_write_confirm/models/__init__.py @@ -0,0 +1,5 @@ +# (C) 2020 Smile () +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). + +from . import base +from . import popup_message diff --git a/web_create_write_confirm/models/base.py b/web_create_write_confirm/models/base.py new file mode 100644 index 000000000..b727d54a5 --- /dev/null +++ b/web_create_write_confirm/models/base.py @@ -0,0 +1,36 @@ +# (C) 2020 Smile () +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). +from odoo import models + + +class BaseModel(models.AbstractModel): + _inherit = "base" + + def get_message_informations(self, values=False): + """ + This function gives us the possibility to know + if we display the message or not + - In create self is empty + - In write self is not empty contains current ID + :param values: + - In create dictionary contains all recording + information self is False + - In write we find only values changed + :type values: dict + :return: return dict object popup.message + (self.env['popup.message'].read()) + """ + return False + + def execute_processing(self, values=False): + """ + This function gives us the possibility to execute a + specific treatment after the confirmation of the message + - In create self is empty + - In write self is not empty contains current ID + :param values : a list of dictionaries: + {'name': field, 'value': value of field} + :type dictionary list + :return boolean + """ + return False diff --git a/web_create_write_confirm/models/popup_message.py b/web_create_write_confirm/models/popup_message.py new file mode 100644 index 000000000..7e17516d2 --- /dev/null +++ b/web_create_write_confirm/models/popup_message.py @@ -0,0 +1,30 @@ +from odoo import api, fields, models + + +class PopupMessage(models.Model): + _name = "popup.message" + _rec_name = "title" + _description = "Popup message" + + model_id = fields.Many2one( + comodel_name="ir.model", string="Model", required=True, ondelete="cascade" + ) + model = fields.Char(related="model_id.model") + field_ids = fields.Many2many( + comodel_name="ir.model.fields", required=True, string="Fields" + ) + field_name = fields.Char(compute="_compute_field_name") + popup_type = fields.Selection( + string="Type", + required=True, + default="confirm", + selection=[("confirm", "Confirmation"), ("alert", "Alert")], + ) + title = fields.Char(string="Title") + message = fields.Text(string="Message", required=True) + active = fields.Boolean(string="Active", default=True) + + @api.depends("field_ids") + def _compute_field_name(self): + for message in self: + message.field_name = ",".join(f.name for f in message.field_ids) diff --git a/web_create_write_confirm/readme/CONTRIBUTORS.rst b/web_create_write_confirm/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..bc626348c --- /dev/null +++ b/web_create_write_confirm/readme/CONTRIBUTORS.rst @@ -0,0 +1,6 @@ +* `Smile `_ + + +* `Ooops404 `__: + + * Ilyas diff --git a/web_create_write_confirm/readme/DESCRIPTION.rst b/web_create_write_confirm/readme/DESCRIPTION.rst new file mode 100644 index 000000000..d6406d8c2 --- /dev/null +++ b/web_create_write_confirm/readme/DESCRIPTION.rst @@ -0,0 +1,3 @@ +This module provides feature to create custom confirmation or alert dialog when user creates or writes record. +Module includes only methods that you can use in your code. That means programming is always required. +See usage section for more information. diff --git a/web_create_write_confirm/readme/USAGE.rst b/web_create_write_confirm/readme/USAGE.rst new file mode 100644 index 000000000..e3fb70d92 --- /dev/null +++ b/web_create_write_confirm/readme/USAGE.rst @@ -0,0 +1,34 @@ +Create popup.message record. Specify model_id, field_ids (which fields will trigger alert) and other fields. +Put you code into **get_message_informations** or **execute_processing** method of you model. +Return dict (perform read() to get it). +Here is some examples how you can use this module features in your code. + +Confirm res.partner change: + +.. code-block:: python + + msg = self.env['popup.message'].create( + { + 'model_id': self.env['ir.model'].search([('model', '=', 'res.partner')]).id, + 'field_ids': [(6, 0, self.env['ir.model.fields'].search([('model', '=', 'res.partner')]).ids)], + 'popup_type': 'confirm', + 'title': 'Warning', + 'message': 'Are you sure want to update record?', + } + ) + return msg.read() + +Sale order alert: + +.. code-block:: python + + msg = self.env['popup.message'].create( + { + 'model_id': self.env['ir.model'].search([('model', '=', 'sale.order')]).id, + 'field_ids': [(6, 0, self.env['ir.model.fields'].search([('model', '=', 'sale.order')]).ids)], + 'popup_type': 'alert', + 'title': 'Attention', + 'message': 'Sale order was updated.', + } + ) + return msg.read() diff --git a/web_create_write_confirm/security/ir.model.access.csv b/web_create_write_confirm/security/ir.model.access.csv new file mode 100644 index 000000000..c1abaa9ee --- /dev/null +++ b/web_create_write_confirm/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_popup_message,popup.message,model_popup_message,base.group_user,1,0,0,0 +access_popup_message_adm,popup.message.admin,model_popup_message,base.group_erp_manager,1,1,1,1 diff --git a/web_create_write_confirm/static/description/icon.png b/web_create_write_confirm/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..17984e2d08aac83e8271009bdce6cfdd09195231 GIT binary patch literal 9433 zcmb_?RZv_}v-JQWxO;%$Zo%E%b%wzLg9dj32^!qpEkP4zut5S0mcb!7gFAuX1Oh=q z!cV^X@2&fAAMeAiQ?;tQ&pzGz)Lz}S;tllF32>j`0ssI4O$`+z0052m-@<J>Sdr z3-y{w|6*flqH14M0vKrwn*Q2*#R2Bev;I9b8@m{esn+*|keKnDu)c)x8GA(W%CCOk zjPPT8V$3);8>h6sXVZ#w7CbCzph9I}rf$Nl73#t2k6f>fL(}*As^16oHQjfIGnpLv z3fN5kHqp8Y*dH3OnWB))Q3l{BVkHQP5_Yuee`CbBiT{l;kyHN1?mrkO?|- zXZH{L7wn(ie+Bz5?0>%CANC2ybnywQ^5g@i4Q+2h@K=D&Ab*S-{fr8~Y|uqit%0uL z6~K*O(jKk%LmM_Cs>01o5^#@ghStj+zOeHA&P@=BotQ;qwzd#lARaL7a72QeNX`dq z8+M^t802?!QzZ3fvBa?9p_9XV4wR|pguPKWMZ>bALb$2U{Iby$TmqN_#EiPXVcW*p zqW3Z&B=~>+_ReXLa;pyJk47CA7PCx7UL{$F3e#PEmZd|ZMyJkU5>NwQoe`n~2Ko6L zDQNw>VVa8mzG+$9v4A@}DmfNjrC}k%lhGlU5e6r$UcHq*jRdGZL^M`20o(PJ=-Lz!#1AUrZ&RG!&weY%`<$J9*!Hn!zu$^k^#g7HZ8CaanCY ztcYtxE2?;Y<2*^QM8BrikrmGckj8TsRRRm;pDOke=wEs=; zK4s9~s$n#3K0aJ%8In0UGh53fM6PU^?`NlOo=duxxvr*bgVEpOG#PaymN{;}|ORAS-MLE2C* zB;5F46nh6n+1OKJ8hrEbymimRX$>rb8qxL>7j6W3qiK+U`7CDD(n7g8pJKux{-S3g z^^__|sFrh~sb7Y6G6m>eep0(k061WrVFugm1U+zE#H<+cHyG2I4*;%NC=x_wa3~lU zyAT}U=ITadKBWV>e+{Sh7A|HAb*#;SOD!PsIfM0g(X-UBp(l`cm)R67n1j0ltbIRQ zQg4Ex>2$+&zh47uE1)8*O|}Y=$9udyfW@>kWerM0^&%LhhG|5r(6AykyeWC>Gszwj2o2{m*%z5k3ArXyvJm zh|*okeNl%PsxZi)g=<*ze=oI!F5szprLVYHdEJvR3mxUs^%VMGvo$v49q4IXv7|V_ z;oT90o;q@}CP0_Mme;};STY_5EVLU}h{&0as|l-D9D)>xw> zx^7Vo_BT@27vClEex(=8%-k2&E)gUql+BOcAWffL?nn_gML?EoxzaD&O`CEg-VqRPi>!GV)J#ftpYsd^e}ok=!xKwxP?!! zb^>Sc{V81L#o7*qd{gp%a&m4?OjU!%a$OPq8`#4BtbqL!F`8}<~o38C7d^+6ghgJ8jN&*YU>BCUSuO<>ycG*fW$ zW~dnv&f!j>vi;*uwmtifcq=+%XhwOAz;Jgi7&W9(TcfPwZAvgqyp0V#=xX+>+Gu0d z0t;b&>e@}g-cvs;;}#4SUZ0mHD@H~ZZb_MSJA~o%OYXO6j4La6JlJ?)Hojx|d5oYqI?FHSq?^B#;aGyPsvcJQ5JMAkpwu4xPmCAVkRTNd zW7Fg7(VB?psL`TAfM7tmZ*$vC`$*Y^lyDH5A!x)b*IgoV;b7FV*#V!#%AL$$)u1^B z?!pv`u@t&`WB?u~%O!tKr8J{-|Z6do3ZdQ4VNMMYX6_u^c1 z*SkEM1aWtW6~tu}>LpT|08>H^OOJIi9hHICngmprH54#G-GgE+9PG#^l+*~jY?8Fk z(My!vl8lbDm~qFv(Ca>77g#CHmUGw7Mh?II02@8y4p6o#ZEJ)P%mtSsr=6 z3gX|BkV4v^5HHFGG0Op#d;0Dx=V)cu^iXCFGLs=~bvsk*eoO6FF(2Qp=}No=3fI}i zH7E|l--sN4 zpU*=8y_4QoVSmxX?yimR_o&`mTY5*$)=sj6yQ^*RY=5`p1ltQr2c_AIr6GmXLEdbR zngll_Zoya^NiutgK#HE;*&Cd0n9vJr(LLgo3nb`&5NX1ma&L*(a&I9Kf z1F$AT>ES!o^%9>8dgsd^P{0kHD})(=_f$-+yws+!|Dsuo8=9;!Ye^e}uhM{cboS!! zVgo73f+wQtN!`Nc`QTHG(Lka*H+10}MZ#$mUf$Nvn}e_iywLA`Lv8oB=&Yhi%S-I~ z68kUz?2ks6udy0=uMat$qmoW#C%3FRqr}hs?|Djw5D_}&?)WK8K2>gUb5Y~up2D$t z-_Fy8suPheF|c_?A18?^55V;~^Iy(^Dv5}SmxHpF@+)|SN~}3AIkODJg466;lI*xR zP5hyP0XWd)Q*%BeNZqz!P6qDSXv#8~VTvH8{`2{E0xp<~x+%g9+qW%+rlb#%zI3AG z#<0oO8IilS^K?ByN(2O|QiKS0Fk@a=1rvomAv)VRz+=0j=#0<(5i_b?Y-YVkE)fG< z!#>JG3S~Z~LcafO+Z}v^zMi3azdjWduiS=F9q+CV0UCn{C4@CNq58cAr>K4iSsGs3 zti72avc}QRfhm;7cSgqJ3;ku`I(AY+&5&4OxB-Z&&rB%*OVi&>p@L6mk^GnxE)BL) zBMEc;K+{y6MZv-wfW^aFfrDgw>o1_g^cv50yogQJQR}u?GTePMfdqtNfiYbk`7cCp z^=A+>oc2yO{(0Bp(;DnH-&}iK#TI1*z9P@j94W(#gGOBUnWikc%Ld>pik!$hr_T&%i+p@#HT9i@g(bvV5R^XHY7T)9 z$9g?g>%6kU6hyJcRt@8XnZFc~JCxMG&&yck9PDgm;&vbx+yPsU7=x3k=AT>@<%kO_ z5nByf0i?5n{WoWd4h_`J_-tI#6<@zdXAXTD&e6l;Fo2ynEd7Q)EKb@BtLy0>HNtTI z45AqUMpC7ak{{%tVu2^Ly?y@~LRMZ4R`}^i+28+Ol5vTJXBTY9; zLp_9mz?<`?K+Xs0&D-pUfieBtHt$`&Rwpbx9?y9&?6z0+GE35AXlo zq0+a%oEV~954&i-NYr~CMkxPxYVfn%&ydc0^0!`?@vcun$(0Q{ju$t+JUxLv6rS>} zKNuLgKJrybbpIUl+`iR5bEJ1}xfx3@gP1GhG+*oCPGY96Qf-8ua4~HB{d(OLy5zLD z%aqjcmCWS8KYt?C)1jYVMUIq-JO?dfIVY7*xu*)Ren;51&;XoeVnvNSdcl=Jj{dU& zPLjR0uFTN;mRR+s_1Wc>DcWl6!qRTO!bMEv=|LG6mMvZNVGDBlb}rTHx2cc7D=G9T z2deZ2Z7{u|88ODVv_n`9G*_+{k4LytB+k0)@?%_TGtTDo&IxQ=j07ep5*!v-Mn{NH z0e3TkO5@;emnQUThGn(wp0e)co2a8)Cyt@}Ef%88q0+?QV)>g(K-iB1hMZ|Xb&0iY z*FoWU1MqEPO(Oaz6_(E(GW)aFp9_2em`v|ap0mNQ!BQgI)Z5e9`t3>{&#bi~-?(IB z4&uaWrz~nn?h8bnwZQi{7bXGAhl%?8zRHc?b3K269zy-)+#*LE!EQ{8UVTS^YKz(5 zfRxIq-o_V7kby)O-30D>!5SN?Z(D&3)t>%#AemEPSW424=9rHxFbkO0UVH`8=h%_h3E@3M4=Sb+aiR;mn9eQ+v%a}XsYA#2iM9m5_Nv(e<%0zw()6EBD$Rs&cvv-(SEskOe$v`jKg3h|BF zue?k|voj8>L)q$mVY6)h&$|*{+g1Q=wUmn`^NG{Zcc^JtU^DjFC@>0J;dN)2cZhF3 z>GZpgax`A}Ht=J~4#RnAToTX#)+%(gCJEX4E!jSTu`~&%F{uHU6jhK^GgHM)r)4;v zqcLijrssurIXSFtH&*}npR`@=qZW7m?j7)tu{uqXS1;Wk%Nc>QkI_>A$0eHT5+Nbl z-G3dC3;udfK1x{JloPoJf6v`W3ORo|PHgltW;V`+K@gy+=1bQJp5Sq>V=*- zi^qiHGgYm#3@w^GUA6AGVDJ8Yc^z0qHHpq#TRHhLktC-E*1=`(^Q4y>3<7w4{_`_} zPybhC=fk%qEsRq-1a~qp&MzP9hg3))eWI=sM0KPl)&3TU2dGcFZlurtL1XTkhxJGP zVRP~?4#~=U=r?P$-YbgrRi0kL0aeJr2=|D2FJsNK8V$@Pfi1~)=~Vf<+8(uj@cf@4 z7guZ=h@s^_Ce%Sj1&m(rQ~SH?D7GTc@YTzFWE214?{u!M^?U!@p1>GW3rnlOVo@=5 z{?9_7kqiz&ug2gYxuqaKQlW4N6dje*rX7g zkiN%zSwu-*Bhl%%t6Q?P*TBufrv=4^02M&9Ni005smjueGqkNNyvnolY#zFvvgXH| zZ4@`Wco%Qf_ATB3=a@W$bIY}jbA<@+#BSUG?$Kc-Q5#+Cj8M+1BMuKE6jQ~pQ^wKE zWQ^JqJ#cDWddbw2;EiZ|%!gmAG05eCdfDBdGh!Czk7p0@sVTNy1x%4f(NH1uO6^iK zbtCO!hL3S^_Jpweeopq~ykiqdce)|iarlrilisZi5nW!?(`U$Nxm0WNNm;%pG$=s5 zaZKxQjJ;E@KHgf!7{Zo?q6dg8r@HQhSmMev&To8r8D-3wL#-E|Sx!wUQOMN;z3F_u zsz}5v9om1i{K`Yzd)klP6=(N?MqV-ZdyW=s1s9T5G5~Wjtd7-{8W_m-afEFp;AzXU z#lnRB;@e_at1t`daa!gw6F9H+l*)Y_4i~lGrC{S(5~V|L%RV1lmoinDG9;gv=E%V) zRc7L3CuK25U+ophca1x`8jil5y%#K3Na|S4Mu!?jU|Aj|GG&?x3uOc zJ}uMw?PU%*XbC<8J3h!l#R)OHD9-h0AxXmLZ)d*xe7NaA{`^iNt%XFsAX0 z%z^D$A2%ml=`E4)0A8!m(Gz89`Jr81OlkS+9Dh5}?gzdTGed9F)3VO!eO8OpVI}}B zl+{eqU`5H5sXWsR^~|*HkL#A3W&usO<|?>w;+o-%C8$y>U9v0j!q`ybjtO%IYqKQ^ zm<1Cl$E#0jgchk*3k&CsUsLS{(cdm^UQKdB6JW1is;G{Pg0g@Oh&tzE?on>U*%@KV z7U3H&EIxoZfR54DTE%GTXN(n+*@10iGIn_}A$~d=)9?eNg>*yyV=&j?xA}vpQD3~% z_nwEjh%zrU3O*hSLr|5PX&15_xl82b!K` zIrG%CqrtbP-@wtYrIzWP$JU0mo8-JSNoAfh{&T(;<=wb$$RqH@XBSYeftu-AW#Avl z{<*Gt_#edJZ$8FfWFl(d0*sTN=iL{lvI9&Vsasga?4w^6zg)Lr^SC!Q_{WXwdVapv zW3E@QAyYGr?|7#G#4=UA_V&@UrBpGG<$GwMPNtaQ6EOmNlYsDg{}ipim*w_s9r@j5 zbLi=fD_jk_$CNdD5X_KmxPG_`p%_PM-JO9osWAOnq=oE(s#8R#Tan%q5w=`6wAT%e z%eh7`3s{^Q-_g-k5|CVA`wsnfToo0W$9=lW37^m1B5hLs4j(aGB#q*JQA^qw{st~yV@?{|uTSf3WpYI6=tPO~AIXl9j%*=7&mq^-febD65I)s2*VU!* zd4=;v25uvY zQz;+N(j7#dod|4gFzE=Il_He-d_5IC+%%J&?Y@aT?a+3`J{2*+`RC1jYtbhq`cdb6 zUpXwtSeHaf%LNoB7J7X|8NDzh|*wtk^aoLmQF!K=?kdpS0mmRr_Vg#YBMlL|^o_uJ) zr6UT|ozLRdGHG2EKKEy}w)K0lJ`^wkKUA#s8+U!=3n{K7xI87#`@?soeX1y87Dv;pDDspdUTt*&L6={B(@;q}ePEh6lgg0k%jeDDoatEk2$Wl^6Bxa*t_3w{u`6OY_+-OA$F0&d>? zrw(yY7NP((I_RqzS&kpGCls~375#Hb4vNBlGgbH@VVhB=yo#%~@OzZgR`V+x=Soju zGEk6c0U?^7?&{+VIidJ{_e!KJ#%r6e@9w@vRdSIROaIoK$S7)DF$sQ2R2_K}_N#*{Sm9TcHn_&otbAo859*o$Q=&CIiJsBl?oo;1L5?5278*F zop=0<>H)f=b)oGTn`oUW?b^ZpjBmRf9Bc^c=a8d@AdZW4t8qqxvaiV|R7NHXgTEK~ zngf8BMuqUjDDbv$aD?jDqE*7|94=)r9-t)YV*uIS zn`9$Pg*Dt!?ypke3xH0ndf_apVA;pH+RjcU-r!M!cP4B6&xUUb0qGa}+7PEBvY+2jtSwvRef}*R?XSlu_4-4!Oi-j+ z^ZQ&-!}@w8%kI|qKp#vhbA6WSrtH~h6LGU>v+U9ktlmdXnSQ@^ucgzJm=D4__%#X> zds-=6L7H=nd&uhh9I#))@H0KW5MdxNyRBik=l$IvxhkP8Z@xlAoIq+pY_~6Z0cUw7 zmf9)*+Z*rrUv67|1JMM&t>u%U*hp50=7^tY3EWR#k*mSu@wWY#Jnc4mJ*fjPgU+Y$3Ki5qSWKzelpf;PLMXMO5HBSq#4x$B~jWiOz#b32$5v3 zB6VKc3Bg}^OYJ}xvB*_YI8F`nwWmNORK#)qCqas>7ndyV3Uaw9 zy0nnyXzvbI8GXE(J}F(6@$%}L4XA?T3M40#7U{ooATuZkO_;;m9Zegw zc90PonQXJdpqaUF1BV&Qs4E-@>pmrW7K&VgL$R?T2hMCJEZ((P<`PxeA;z1$hDfj~ z7m);WkN5=)!tcKQjbyf$|8}J+RONa{WkQkT^7@6d->!nJXs`Zx2=G*nR%m%l9aKHz z!^xN7?S~S$(_MLP?oJf2!sCe742F!HzSr`Yf@I_?wyz;-@KcO({H9MS_n3LK66a(( zT;49azm zFSRmdY|bh>%Ulj^jg?c8{P0s*;;|X=eEUW+&kS!2B;oj>!&q12iSRyOPu^jt`Y7j^ z9w)T#ygLT=xJ3elYFB!ep(SQIBFLWv7*)wkfpTwYRmLke)xI+{iE1e^0F9jSW>IPm zLcTcI7rm=r5VnjbNvge(>ibw%dTi^T9()jAou2dl!pwT?u0oRy+R&_mdPn~b{jNg)}0c z*Qi6`;g&BA*NJGf3Q6!R7LSI?kvQMl_;8s`D3ZPYmXg?Df|P=G#c~kO7S^K_KvZf` z6u*Phn&dve7lUdR43M9`->+j_E&;8HLk%D!aheV`GDjJlcyZj7dMWOuAaJZ?Sa(CS zn^s~GLhd+Y-NMO|JJ(2)hbE*AMveAr*Qy4bVyDZ)2Q_xq{kG;Z>Y5Elx5<_8s05ms z3Nvf-@j^ElwsXEh3Mej1G|OPN4*uM=c5RWAVd@SJ0Kk*5e_8+u>J2}-APk;F(8N$R zDToB(6c{-Z`X#xZ2j*k%53(ebs6&}}0BzE&OcnB_?JFw;ADi0V_TG z^z@i2B=>Z2yvpyV5hS{z#ck};CU+g@Tfh!Y-8GN7`Ik59c(w~$kcg&ivxKo2&M$o@ z$ip%6-70@K{--z{O>jld4BXx{*P?r&9B-dIzm*a3My{r1_GW7_`T0-t zt#(_^Q=6x+8wdnBC&}Xu|4k>DhFrjckGxKACGokqV-%_=ZcMSGz`kP75Xjj9XF6;! zZLxwmd?HS2C?NB`+9KqQBPXj;%o@ic1 z?C6Qw#w~M(R>Zv_Z0txyS~7a6dnEQW@wY1v7iRp@hYfKkHt#<7ZveX;Rs3=a zlG%CJVT4RtVnjEwoAQF0jLM?Vh_s^f4cEZ#2sXFBX+DzK3=f7`bZoe!^k;^x3ZA%) zk(c*O)mh6`w^cLam6Q*0F_IaWl}Auya*zENaa{L}u8cQB;GtMhpWDcsFvI=0(0RZR zH!*9i7+;>T9RA~%ft2x?VsdNv&eTK6@Pn*fRnRu)k?eSN@}NiSSoot#B(A18c$`+F zYE3abu@r~ta6jd{!}>tgqr@Z#hv#RVIF&q^QCD4Vaub`)o!w_rhmjUJ<>#gOB$Q03 z3?PFo1Wx-#CauZOpA^I|y6_mUh6VaO$8@ZXhoydIDk;w=9-HeCR9@}Q(3_==Lo!!9 zo6gp{vJKYHWO8Rl(Y52yCf7x=k*#70ctbhb|LSZz3JnX+fUH&-Y`CeRr#Ssm}P{hNBb zXpO!5DA>x5i0G4HGvIjKn}+))_5aY<{C^$J|C#3Ie-rg+yu6p^IFg?1ngy^tYLx(* Ms(LDQN;dEQAN$d}kN^Mx literal 0 HcmV?d00001 diff --git a/web_create_write_confirm/static/src/js/pop_up_confirmation.js b/web_create_write_confirm/static/src/js/pop_up_confirmation.js new file mode 100644 index 000000000..815c0e3db --- /dev/null +++ b/web_create_write_confirm/static/src/js/pop_up_confirmation.js @@ -0,0 +1,107 @@ +odoo.define("web_create_write_confirm.pop_up_confirmation", function (require) { + "use strict"; + + var FormController = require("web.FormController"); + var Dialog = require("web.Dialog"); + + FormController.include({ + getMessageInformation: function (model, nameFunction, record_id, values) { + return this._rpc({ + model: model, + method: nameFunction, + args: [record_id, values], + }); + }, + + _onSave: function (ev) { + var self = this; + var modelName = self.modelName ? self.modelName : false; + var record = self.model.get(self.handle, {raw: true}); + var record_id = + record && record.data && record.data.id ? record.data.id : false; + var changes = self.model.localData[self.handle]._changes; + self.getMessageInformation( + modelName, + "get_message_informations", + record_id, + changes === null ? {} : changes + ).then(function (results) { + this.display_popup(results, record, record_id, ev, changes, modelName); + }); + }, + + display_popup: function ( + popup_values, + record, + record_id, + ev, + changes, + modelName + ) { + var self = this; + var index = 0; + var datas = []; + new Promise(function (resolve) { + if ( + typeof popup_values !== "undefined" && + typeof popup_values !== "boolean" && + popup_values.length + ) { + if (popup_values[index].popup_type === "confirm") { + Dialog.confirm(self, popup_values[index].message, { + title: popup_values[index].title, + confirm_callback: async () => { + var field_names = popup_values[index].field_name.split( + "," + ); + for (var j = 0; j < field_names.length; j++) { + datas.push({ + name: field_names[j], + value: + changes && changes[field_names[j]] + ? changes[field_names[j]] + : record.data[field_names[j]] === "" + ? record.data[field_names[j]] + : false, + }); + } + index++; + if (popup_values.length > index) { + this.display_popup( + popup_values, + record, + record_id, + ev + ); + } else if (popup_values.length === index) { + self.getMessageInformation( + modelName, + "execute_processing", + record_id, + datas + ); + this.save(ev); + } + }, + }).on("closed", null, resolve); + } else if (popup_values[index].popup_type === "alert") { + Dialog.alert(self, popup_values[index].message, { + title: popup_values[index].title, + }); + } + } else { + this.save(ev); + } + }); + }, + + save: function ev() { + var self = this; + ev.stopPropagation(); + self._disableButtons(); + self.saveRecord() + .then(self._enableButtons.bind(self)) + .guardedCatch(self._enableButtons.bind(self)); + }, + }); +}); diff --git a/web_create_write_confirm/tests/__init__.py b/web_create_write_confirm/tests/__init__.py new file mode 100644 index 000000000..9e7f8acd2 --- /dev/null +++ b/web_create_write_confirm/tests/__init__.py @@ -0,0 +1 @@ +from . import test_base_model diff --git a/web_create_write_confirm/tests/test_base_model.py b/web_create_write_confirm/tests/test_base_model.py new file mode 100644 index 000000000..7f10553fa --- /dev/null +++ b/web_create_write_confirm/tests/test_base_model.py @@ -0,0 +1,55 @@ +from odoo.tests.common import SavepointCase + + +class TestBaseModel(SavepointCase): + @classmethod + def setUpClass(cls): + super(TestBaseModel, cls).setUpClass() + cls.base_model = cls.env["base"] + + def test_compute_field_name(self): + """Test correct flow of changing field_name""" + model_field_name = self.env["ir.model.fields"]._get( + "popup.message", "field_name" + ) + vals = { + "model_id": model_field_name.model_id.id, + "field_ids": model_field_name, + "message": "test", + } + test_popup_message = self.env["popup.message"].sudo().create(vals) + self.assertEqual( + test_popup_message.field_name, + model_field_name.name, + msg="Must be equal to name of 'ir.model.fields' field", + ) + + model_field_title = self.env["ir.model.fields"]._get("popup.message", "title") + vals.update({"field_ids": (model_field_name.id, model_field_title.id)}) + test_popup_message_cycle = self.env["popup.message"].sudo().create(vals) + field_name = model_field_name.name + "," + model_field_title.name + self.assertEqual( + test_popup_message_cycle.field_name, + field_name, + msg="Must be equal to 2 join name of 'ir.model.fields' fields", + ) + + def test_get_message_informations(self): + """Test correct flow of get_message_informations method""" + ret_value_of_method = self.base_model.get_message_informations() + check_ret_value = False + if (ret_value_of_method is False) or isinstance( + ret_value_of_method, type(self.env["popup.message"]) + ): + check_ret_value = True + self.assertTrue( + check_ret_value, + msg="Return value must be False or dictionary of popup.message objects", + ) + self.env["popup.message"]._compute_field_name() + + def test_execute_processing(self): + """Test correct flow of execute_processing method""" + self.assertFalse( + self.base_model.execute_processing(), msg="Return value must be False" + ) diff --git a/web_create_write_confirm/views/assets.xml b/web_create_write_confirm/views/assets.xml new file mode 100644 index 000000000..6aec517eb --- /dev/null +++ b/web_create_write_confirm/views/assets.xml @@ -0,0 +1,15 @@ + + + + +