Merge PR #2487 into 14.0

Signed-off-by pedrobaeza
pull/2573/head
OCA-git-bot 2023-07-24 10:19:58 +00:00
commit d65172bc2c
18 changed files with 405 additions and 0 deletions

View File

@ -0,0 +1 @@
../../../../web_create_write_confirm

View File

@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)

View File

@ -0,0 +1,4 @@
# (C) 2020 Smile (<https://www.smile.eu>)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
from . import models

View File

@ -0,0 +1,21 @@
# (C) 2020 Smile (<https://www.smile.eu>)
# 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,
}

View File

@ -0,0 +1,5 @@
# (C) 2020 Smile (<https://www.smile.eu>)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
from . import base
from . import popup_message

View File

@ -0,0 +1,36 @@
# (C) 2020 Smile (<https://www.smile.eu>)
# 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

View File

@ -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)

View File

@ -0,0 +1,6 @@
* `Smile <https://www.smile.eu/en>`_
* `Ooops404 <https://www.ooops404.com>`__:
* Ilyas <irazor147@gmail.com>

View File

@ -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.

View File

@ -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()

View File

@ -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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_popup_message popup.message model_popup_message base.group_user 1 0 0 0
3 access_popup_message_adm popup.message.admin model_popup_message base.group_erp_manager 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -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));
},
});
});

View File

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

View File

@ -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"
)

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<template id="assets_backend_extension" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script
type="text/javascript"
src="/web_create_write_confirm/static/src/js/pop_up_confirmation.js"
/>
</xpath>
</template>
</data>
</odoo>

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<record id="view_popup_message_tree" model="ir.ui.view">
<field name="name">view.popup.message.tree</field>
<field name="model">popup.message</field>
<field name="arch" type="xml">
<tree string="Popup Message">
<field name="model_id" />
<field name="field_ids" widget="many2many_tags" />
<field name="popup_type" />
<field name="title" />
<field name="message" />
<field name="active" />
</tree>
</field>
</record>
<record id="view_popup_message_form" model="ir.ui.view">
<field name="name">view.popup.message.form</field>
<field name="model">popup.message</field>
<field name="arch" type="xml">
<form string="Popup Message">
<sheet>
<widget
name="web_ribbon"
title="Archived"
bg_color="bg-danger"
attrs="{'invisible': [('active', '=', True)]}"
/>
<group>
<field name="model_id" />
<field name="model" invisible="1" />
<field
name="field_ids"
domain="[('model','=',model)]"
widget="many2many_tags"
/>
<field name="popup_type" />
<field name="title" />
<field name="message" />
<field name="active" widget="boolean_toggle" />
</group>
</sheet>
</form>
</field>
</record>
<record id="action_popup_message_view" model="ir.actions.act_window">
<field name="name">Popup message</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">popup.message</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Add your pop-up!
</p>
</field>
</record>
<menuitem
id="menu_popup_message_categ"
name="Popup message"
parent="base.menu_custom"
sequence="90"
/>
<menuitem
id="menu_popup_message_view"
name="Popup message"
parent="web_create_write_confirm.menu_popup_message_categ"
action="action_popup_message_view"
sequence="10"
/>
</data>
</odoo>