mirror of
https://gitlab.com/flectra-hq/flectra.git
synced 2026-11-03 04:40:20 -06:00
[PATCH] Upstream patch - 30062022
This commit is contained in:
1 parent
a508a77cbc
commit
272d41d48d
9 files changed
+164
-12
No files matched your search
@@ -17,12 +17,52 @@ class TestClocFields(test_cloc.TestClocCustomization):
|
|||||||
'imported': True,
|
'imported': True,
|
||||||
})
|
})
|
||||||
f1 = self.create_field('x_imported_field')
|
f1 = self.create_field('x_imported_field')
|
||||||
self.create_xml_id('import_field', f1.id, 'imported_module')
|
self.create_xml_id('imported_module', 'import_field', f1)
|
||||||
cl = cloc.Cloc()
|
cl = cloc.Cloc()
|
||||||
cl.count_customization(self.env)
|
cl.count_customization(self.env)
|
||||||
self.assertEqual(cl.code.get('imported_module', 0), 1, 'Count fields with xml_id of imported module')
|
self.assertEqual(cl.code.get('imported_module', 0), 1, 'Count fields with xml_id of imported module')
|
||||||
f2 = self.create_field('x_base_field')
|
|
||||||
self.create_xml_id('base_field', f2.id, 'base')
|
def test_fields_from_studio(self):
|
||||||
|
# Studio module does not exist at this stage, so we simulate it
|
||||||
|
# Check for existing module in case the test run on an existing database
|
||||||
|
if not self.env['ir.module.module'].search([('name', '=', 'studio_customization')]):
|
||||||
|
self.env['ir.module.module'].create({
|
||||||
|
'author': 'Flectra',
|
||||||
|
'imported': True,
|
||||||
|
'latest_version': '13.0.1.0.0',
|
||||||
|
'name': 'studio_customization',
|
||||||
|
'state': 'installed',
|
||||||
|
'summary': 'Studio Customization',
|
||||||
|
})
|
||||||
|
|
||||||
|
f1 = self.create_field('x_field_count')
|
||||||
|
self.create_xml_id('studio_customization', 'field_count', f1)
|
||||||
cl = cloc.Cloc()
|
cl = cloc.Cloc()
|
||||||
cl.count_customization(self.env)
|
cl.count_customization(self.env)
|
||||||
self.assertEqual(cl.code.get('base', 0), 0, "Don't count fields from standard module")
|
self.assertEqual(cl.code.get('studio_customization', 0), 0, "Don't count field generated by studio")
|
||||||
|
f2 = self.create_field('x_studio_manual_field')
|
||||||
|
self.create_xml_id('studio_customization', 'manual_field', f2)
|
||||||
|
cl = cloc.Cloc()
|
||||||
|
cl.count_customization(self.env)
|
||||||
|
self.assertEqual(cl.code.get('studio_customization', 0), 1, "Count manual field created via studio")
|
||||||
|
|
||||||
|
def test_fields_module_name(self):
|
||||||
|
"""
|
||||||
|
Check that custom computed fields installed with an imported module
|
||||||
|
is counted as customization
|
||||||
|
"""
|
||||||
|
self.env['ir.module.module'].create({
|
||||||
|
'name': 'imported_module',
|
||||||
|
'state': 'installed',
|
||||||
|
'imported': True,
|
||||||
|
})
|
||||||
|
f1 = self.create_field('x_imported_field')
|
||||||
|
self.create_xml_id('imported_module', 'import_field', f1)
|
||||||
|
self.create_xml_id('__export__', 'import_field', f1)
|
||||||
|
|
||||||
|
sa = self.create_server_action("Test imported double xml_id")
|
||||||
|
self.create_xml_id("imported_module", "first", sa)
|
||||||
|
self.create_xml_id("__export__", "second", sa)
|
||||||
|
cl = cloc.Cloc()
|
||||||
|
cl.count_customization(self.env)
|
||||||
|
self.assertEqual(cl.code.get('imported_module', 0), 3)
|
||||||
@@ -1699,9 +1699,10 @@ class MrpProduction(models.Model):
|
|||||||
order_exception, visited = exception
|
order_exception, visited = exception
|
||||||
order_exceptions.update(order_exception)
|
order_exceptions.update(order_exception)
|
||||||
visited_objects += visited
|
visited_objects += visited
|
||||||
visited_objects = self.env[visited_objects[0]._name].concat(*visited_objects)
|
visited_objects = [sm for sm in visited_objects if sm._name == 'stock.move']
|
||||||
impacted_object = []
|
impacted_object = []
|
||||||
if visited_objects and visited_objects._name == 'stock.move':
|
if visited_objects:
|
||||||
|
visited_objects = self.env[visited_objects[0]._name].concat(*visited_objects)
|
||||||
visited_objects |= visited_objects.mapped('move_orig_ids')
|
visited_objects |= visited_objects.mapped('move_orig_ids')
|
||||||
impacted_object = visited_objects.filtered(lambda m: m.state not in ('done', 'cancel')).mapped('picking_id')
|
impacted_object = visited_objects.filtered(lambda m: m.state not in ('done', 'cancel')).mapped('picking_id')
|
||||||
values = {
|
values = {
|
||||||
|
|||||||
@@ -237,12 +237,27 @@ class MrpWorkorder(models.Model):
|
|||||||
workorder.date_planned_finished = workorder.leave_id.date_to
|
workorder.date_planned_finished = workorder.leave_id.date_to
|
||||||
|
|
||||||
def _set_dates_planned(self):
|
def _set_dates_planned(self):
|
||||||
if self.leave_id and (not self[0].date_planned_start or not self[0].date_planned_finished):
|
if not self[0].date_planned_start or not self[0].date_planned_finished:
|
||||||
|
if not self.leave_id:
|
||||||
|
return
|
||||||
raise UserError(_("It is not possible to unplan one single Work Order. "
|
raise UserError(_("It is not possible to unplan one single Work Order. "
|
||||||
"You should unplan the Manufacturing Order instead in order to unplan all the linked operations."))
|
"You should unplan the Manufacturing Order instead in order to unplan all the linked operations."))
|
||||||
date_from = self[0].date_planned_start
|
date_from = self[0].date_planned_start
|
||||||
date_to = self[0].date_planned_finished
|
date_to = self[0].date_planned_finished
|
||||||
self.mapped('leave_id').sudo().write({
|
to_write = self.env['mrp.workorder']
|
||||||
|
for wo in self.sudo():
|
||||||
|
if wo.leave_id:
|
||||||
|
to_write |= wo
|
||||||
|
else:
|
||||||
|
wo.leave_id = wo.env['resource.calendar.leaves'].create({
|
||||||
|
'name': wo.display_name,
|
||||||
|
'calendar_id': wo.workcenter_id.resource_calendar_id.id,
|
||||||
|
'date_from': date_from,
|
||||||
|
'date_to': date_to,
|
||||||
|
'resource_id': wo.workcenter_id.resource_id.id,
|
||||||
|
'time_type': 'other',
|
||||||
|
})
|
||||||
|
to_write.leave_id.write({
|
||||||
'date_from': date_from,
|
'date_from': date_from,
|
||||||
'date_to': date_to,
|
'date_to': date_to,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
from flectra.tests import Form
|
from flectra.tests import Form
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from freezegun import freeze_time
|
||||||
|
|
||||||
from flectra.fields import Datetime as Dt
|
from flectra.fields import Datetime as Dt
|
||||||
from flectra.exceptions import UserError
|
from flectra.exceptions import UserError
|
||||||
@@ -2293,3 +2294,65 @@ class TestMrpOrder(TestMrpCommon):
|
|||||||
production.workorder_ids[0].button_start()
|
production.workorder_ids[0].button_start()
|
||||||
production.workorder_ids[0].button_start()
|
production.workorder_ids[0].button_start()
|
||||||
self.assertEqual(len(production.workorder_ids[0].time_ids.filtered(lambda t: t.date_start and not t.date_end)), 1)
|
self.assertEqual(len(production.workorder_ids[0].time_ids.filtered(lambda t: t.date_start and not t.date_end)), 1)
|
||||||
|
|
||||||
|
@freeze_time('2022-06-28 08:00')
|
||||||
|
def test_replan_workorders01(self):
|
||||||
|
"""
|
||||||
|
Create two MO, each one with one WO. Set the same scheduled start date
|
||||||
|
to each WO during the creation of the MO. A warning will be displayed.
|
||||||
|
-> The user replans one of the WO: the warnings should disappear and the
|
||||||
|
WO should be postponed.
|
||||||
|
"""
|
||||||
|
mos = self.env['mrp.production']
|
||||||
|
for _ in range(2):
|
||||||
|
mo_form = Form(self.env['mrp.production'])
|
||||||
|
mo_form.bom_id = self.bom_4
|
||||||
|
with mo_form.workorder_ids.edit(0) as wo_line:
|
||||||
|
wo_line.date_planned_start = Dt.now()
|
||||||
|
mos += mo_form.save()
|
||||||
|
mos.action_confirm()
|
||||||
|
|
||||||
|
mo_01, mo_02 = mos
|
||||||
|
wo_01 = mo_01.workorder_ids
|
||||||
|
wo_02 = mo_02.workorder_ids
|
||||||
|
|
||||||
|
self.assertTrue(wo_01.show_json_popover)
|
||||||
|
self.assertTrue(wo_02.show_json_popover)
|
||||||
|
|
||||||
|
wo_02.action_replan()
|
||||||
|
|
||||||
|
self.assertFalse(wo_01.show_json_popover)
|
||||||
|
self.assertFalse(wo_02.show_json_popover)
|
||||||
|
self.assertEqual(wo_01.date_planned_finished, wo_02.date_planned_start)
|
||||||
|
|
||||||
|
@freeze_time('2022-06-28 08:00')
|
||||||
|
def test_replan_workorders02(self):
|
||||||
|
"""
|
||||||
|
Create two MO, each one with one WO. Set the same scheduled start date
|
||||||
|
to each WO after the creation of the MO. A warning will be displayed.
|
||||||
|
-> The user replans one of the WO: the warnings should disappear and the
|
||||||
|
WO should be postponed.
|
||||||
|
"""
|
||||||
|
mos = self.env['mrp.production']
|
||||||
|
for _ in range(2):
|
||||||
|
mo_form = Form(self.env['mrp.production'])
|
||||||
|
mo_form.bom_id = self.bom_4
|
||||||
|
mos += mo_form.save()
|
||||||
|
mos.action_confirm()
|
||||||
|
mo_01, mo_02 = mos
|
||||||
|
|
||||||
|
for mo in mos:
|
||||||
|
with Form(mo) as mo_form:
|
||||||
|
with mo_form.workorder_ids.edit(0) as wo_line:
|
||||||
|
wo_line.date_planned_start = Dt.now()
|
||||||
|
|
||||||
|
wo_01 = mo_01.workorder_ids
|
||||||
|
wo_02 = mo_02.workorder_ids
|
||||||
|
self.assertTrue(wo_01.show_json_popover)
|
||||||
|
self.assertTrue(wo_02.show_json_popover)
|
||||||
|
|
||||||
|
wo_02.action_replan()
|
||||||
|
|
||||||
|
self.assertFalse(wo_01.show_json_popover)
|
||||||
|
self.assertFalse(wo_02.show_json_popover)
|
||||||
|
self.assertEqual(wo_01.date_planned_finished, wo_02.date_planned_start)
|
||||||
@@ -497,7 +497,9 @@ class PaymentAcquirer(models.Model):
|
|||||||
values = method(values)
|
values = method(values)
|
||||||
|
|
||||||
values.update({
|
values.update({
|
||||||
'tx_url': self._context.get('tx_url', self.get_form_action_url()),
|
'tx_url': self._context.get(
|
||||||
|
'tx_url', self.with_context(form_action_url_values=values).get_form_action_url()
|
||||||
|
),
|
||||||
'submit_class': self._context.get('submit_class', 'btn btn-link'),
|
'submit_class': self._context.get('submit_class', 'btn btn-link'),
|
||||||
'submit_txt': self._context.get('submit_txt'),
|
'submit_txt': self._context.get('submit_txt'),
|
||||||
'acquirer': self,
|
'acquirer': self,
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ from flectra.addons.portal.controllers.portal import _build_url_w_params
|
|||||||
|
|
||||||
from flectra.exceptions import UserError
|
from flectra.exceptions import UserError
|
||||||
from flectra.http import request
|
from flectra.http import request
|
||||||
|
from flectra.osv import expression
|
||||||
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -180,8 +182,14 @@ class WebsiteForum(WebsiteProfile):
|
|||||||
|
|
||||||
@http.route('/forum/get_tags', type='http', auth="public", methods=['GET'], website=True, sitemap=False)
|
@http.route('/forum/get_tags', type='http', auth="public", methods=['GET'], website=True, sitemap=False)
|
||||||
def tag_read(self, query='', limit=25, **post):
|
def tag_read(self, query='', limit=25, **post):
|
||||||
|
# TODO: In master always check the forum_id domain part and add forum_id
|
||||||
|
# as required method param, not in **post
|
||||||
|
forum_id = post.get('forum_id')
|
||||||
|
domain = [('name', '=ilike', (query or '') + "%")]
|
||||||
|
if forum_id:
|
||||||
|
domain = expression.AND([domain, [('forum_id', '=', int(forum_id))]])
|
||||||
data = request.env['forum.tag'].search_read(
|
data = request.env['forum.tag'].search_read(
|
||||||
domain=[('name', '=ilike', (query or '') + "%")],
|
domain=domain,
|
||||||
fields=['id', 'name'],
|
fields=['id', 'name'],
|
||||||
limit=int(limit),
|
limit=int(limit),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ class Forum(models.Model):
|
|||||||
self._update_website_count()
|
self._update_website_count()
|
||||||
return super(Forum, self).unlink()
|
return super(Forum, self).unlink()
|
||||||
|
|
||||||
@api.model
|
@api.model # TODO: Remove me, this is not an `api.model` method
|
||||||
def _tag_to_write_vals(self, tags=''):
|
def _tag_to_write_vals(self, tags=''):
|
||||||
Tag = self.env['forum.tag']
|
Tag = self.env['forum.tag']
|
||||||
post_tags = []
|
post_tags = []
|
||||||
@@ -223,7 +223,7 @@ class Forum(models.Model):
|
|||||||
for tag in (tag for tag in tags.split(',') if tag):
|
for tag in (tag for tag in tags.split(',') if tag):
|
||||||
if tag.startswith('_'): # it's a new tag
|
if tag.startswith('_'): # it's a new tag
|
||||||
# check that not already created meanwhile or maybe excluded by the limit on the search
|
# check that not already created meanwhile or maybe excluded by the limit on the search
|
||||||
tag_ids = Tag.search([('name', '=', tag[1:])])
|
tag_ids = Tag.search([('name', '=', tag[1:]), ('forum_id', '=', self.id)])
|
||||||
if tag_ids:
|
if tag_ids:
|
||||||
existing_keep.append(int(tag_ids[0]))
|
existing_keep.append(int(tag_ids[0]))
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
|||||||
return {
|
return {
|
||||||
query: term,
|
query: term,
|
||||||
limit: 50,
|
limit: 50,
|
||||||
|
forum_id: $('#wrapwrap').data('forum_id'),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
results: function (data) {
|
results: function (data) {
|
||||||
|
|||||||
@@ -436,3 +436,25 @@ class TestForum(TestForumCommon):
|
|||||||
not discussions_post.uid_has_answered or discussions_post.forum_id.mode == 'discussions', True)
|
not discussions_post.uid_has_answered or discussions_post.forum_id.mode == 'discussions', True)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
discussions_post.uid_has_answered and discussions_post.forum_id.mode == 'questions', False)
|
discussions_post.uid_has_answered and discussions_post.forum_id.mode == 'questions', False)
|
||||||
|
|
||||||
|
def test_tag_creation_multi_forum(self):
|
||||||
|
Post = self.env['forum.post']
|
||||||
|
forum_1 = self.forum
|
||||||
|
forum_2 = forum_1.copy({
|
||||||
|
'name': 'Questions Forum'
|
||||||
|
})
|
||||||
|
self.user_portal.karma = KARMA['tag_create']
|
||||||
|
Post.with_user(self.user_portal).create({
|
||||||
|
'name': "Post Forum 1",
|
||||||
|
'forum_id': forum_1.id,
|
||||||
|
'tag_ids': forum_1._tag_to_write_vals('_Food'),
|
||||||
|
})
|
||||||
|
Post.with_user(self.user_portal).create({
|
||||||
|
'name': "Post Forum 2",
|
||||||
|
'forum_id': forum_2.id,
|
||||||
|
'tag_ids': forum_2._tag_to_write_vals('_Food'),
|
||||||
|
})
|
||||||
|
food_tags = self.env['forum.tag'].search([('name', '=', 'Food')])
|
||||||
|
self.assertEqual(len(food_tags), 2, "One Food tag should have been created in each forum.")
|
||||||
|
self.assertIn(forum_1, food_tags.forum_id, "One Food tag should have been created for forum 1.")
|
||||||
|
self.assertIn(forum_2, food_tags.forum_id, "One Food tag should have been created for forum 2.")
|
||||||
Reference in new issue
Block a user