[PATCH] Upstream patch - 05022023

This commit is contained in:
Parthiv Patel committed 2023-02-05 08:35:06 +00:00
1 parent fc680e12a0
commit 64e0e10b2a
15 files changed
+227 -39

No files matched your search

+4 -4
View File
@@ -194,7 +194,7 @@ class ImDispatch(object):
self.started = True
return self
dispatch = None
if not flectra.multi_process or flectra.evented:
# We only use the event dispatcher in threaded and gevent mode
dispatch = ImDispatch()
# Partially undo a2ed3d3d5bdb6025a1ba14ad557a115a86413e65
# IMDispatch has a lazy start, so we could initialize it anyway
# And this avoids the Bus unavailable error messages
dispatch = ImDispatch()
@@ -29,10 +29,11 @@ class ImLivechatChannel(models.Model):
# attribute fields
name = fields.Char('Name', required=True, help="The name of the channel")
button_text = fields.Char('Text of the Button', default='Have a Question? Chat with us.',
help="Default text displayed on the Livechat Support Button")
help="Default text displayed on the Livechat Support Button", translate=True)
default_message = fields.Char('Welcome Message', default='How may I help you?',
help="This is an automated 'welcome' message that your visitor will see when they initiate a new conversation.")
input_placeholder = fields.Char('Chat Input Placeholder', help='Text that prompts the user to initiate the chat.')
help="This is an automated 'welcome' message that your visitor will see when they initiate a new conversation.",
translate=True)
input_placeholder = fields.Char('Chat Input Placeholder', help='Text that prompts the user to initiate the chat.', translate=True)
header_background_color = fields.Char(default="#009EFB", help="Default background color of the channel header once open")
title_color = fields.Char(default="#FFFFFF", help="Default title color of the channel once open")
button_background_color = fields.Char(default="#878787", help="Default background color of the Livechat button")
+1 -1
View File
@@ -181,7 +181,7 @@
<!-- (17) CUIT -->
<t t-if="o.partner_id.vat and o.partner_id.l10n_latam_identification_type_id and o.partner_id.l10n_latam_identification_type_id.l10n_ar_afip_code != '99'">
<br/><strong><t t-esc="o.partner_id.l10n_latam_identification_type_id.name or o.company_id.country_id.vat_label" id="inv_tax_id_label"/>:</strong> <span t-esc="o.partner_id.l10n_ar_formatted_vat if o.partner_id.l10n_latam_identification_type_id.is_vat else o.partner_id.vat"/>
<br/><strong><t t-esc="o.partner_id.l10n_latam_identification_type_id.name or o.company_id.country_id.vat_label" id="inv_tax_id_label"/>:</strong> <span t-esc="o.partner_id.l10n_ar_formatted_vat if o.partner_id.l10n_ar_vat else o.partner_id.vat"/>
</t>
</div>
+10 -10
View File
@@ -7,15 +7,15 @@
<NumeroLinea t-esc="line_dict['line_number']"/>
<CodiceArticolo t-if="line.product_id.barcode">
<CodiceTipo>EAN</CodiceTipo>
<CodiceValore t-esc="format_alphanumeric(line.product_id.barcode)"/>
<CodiceValore t-esc="format_alphanumeric(line.product_id.barcode)[:35]"/>
</CodiceArticolo>
<CodiceArticolo t-elif="line.product_id.default_code">
<CodiceTipo>INTERNAL</CodiceTipo>
<CodiceValore t-esc="format_alphanumeric(line.product_id.default_code)"/>
<CodiceValore t-esc="format_alphanumeric(line.product_id.default_code)[:35]"/>
</CodiceArticolo>
<Descrizione t-esc="format_alphanumeric(line_dict['description'])"/>
<Descrizione t-esc="format_alphanumeric(line_dict['description'])[:1000]"/>
<Quantita t-esc="format_numbers(abs(line.quantity))"/>
<UnitaMisura t-if="line.product_uom_id.category_id != env.ref('uom.product_uom_categ_unit')" t-esc="format_alphanumeric(line.product_uom_id.name)"/>
<UnitaMisura t-if="line.product_uom_id and line.product_uom_id.category_id != env.ref('uom.product_uom_categ_unit')" t-esc="format_alphanumeric(line.product_uom_id.name)[:10]"/>
<PrezzoUnitario t-esc="'%.06f' % (line_dict['unit_price'])"/>
<ScontoMaggiorazione t-if="line.discount != 0">
<Tipo t-esc="discount_type(line.discount)"/>
@@ -52,9 +52,9 @@
<ContattiTrasmittente>
<Telefono t-if="sender_partner.phone" t-esc="format_alphanumeric(format_phone(sender_partner.phone))"/>
<Telefono t-elif="sender_partner.mobile" t-esc="format_alphanumeric(format_phone(sender_partner.mobile))"/>
<Email t-if="sender_partner.email" t-esc="sender_partner.email"/>
<Email t-if="sender_partner.email" t-esc="sender_partner.email[:256]"/>
</ContattiTrasmittente>
<PECDestinatario t-if="not is_self_invoice and partner.l10n_it_pec_email" t-esc="partner.l10n_it_pec_email"/>
<PECDestinatario t-if="not is_self_invoice and partner.l10n_it_pec_email" t-esc="partner.l10n_it_pec_email[:256]"/>
</DatiTrasmissione>
<CedentePrestatore>
<DatiAnagrafici>
@@ -203,10 +203,10 @@
<template id="account_invoice_it_FatturaPA_sede">
<Sede>
<Indirizzo><t t-if="partner.street" t-esc="format_alphanumeric(partner.street)"/> <t t-if="partner.street2" t-esc="format_alphanumeric(partner.street2)"/></Indirizzo>
<CAP><t t-if="partner.country_id.code != 'IT'" t-esc="'00000'"/><t t-else="" t-esc="partner.zip"/></CAP>
<Comune t-esc="format_alphanumeric(partner.city)"/>
<Provincia t-if="partner.country_id.code == 'IT'" t-esc="partner.state_id.code"/>
<Indirizzo><t t-if="partner.street or partner.street2" t-esc="format_alphanumeric((partner.street or '') + ' ' + (partner.street2 or ''))[:60]"/></Indirizzo>
<CAP><t t-if="partner.country_id.code != 'IT'" t-esc="'00000'"/><t t-elif="partner.zip" t-esc="partner.zip"/></CAP>
<Comune t-esc="format_alphanumeric(partner.city[:60])"/>
<Provincia t-if="partner.country_id.code == 'IT' and partner.state_id" t-esc="partner.state_id.code[:2]"/>
<Nazione t-esc="partner.country_id.code"/>
</Sede>
</template>
+2 -2
View File
@@ -1415,7 +1415,7 @@ class MrpProduction(models.Model):
move.product_uom_qty = move.quantity_done
# MRP do not merge move, catch the result of _action_done in order
# to get extra moves.
moves_to_do = moves_to_do._action_done()
moves_to_do = moves_to_do._action_done(cancel_backorder=cancel_backorder)
moves_to_do = order.move_raw_ids.filtered(lambda x: x.state == 'done') - moves_not_to_do
finish_moves = order.move_finished_ids.filtered(lambda m: m.product_id == order.product_id and m.state not in ('done', 'cancel'))
@@ -1560,7 +1560,7 @@ class MrpProduction(models.Model):
backorders = productions_to_backorder._generate_backorder_productions(close_mo=close_mo)
productions_not_to_backorder._post_inventory(cancel_backorder=True)
productions_to_backorder._post_inventory(cancel_backorder=False)
productions_to_backorder._post_inventory(cancel_backorder=True)
# if completed products make other confirmed/partially_available moves available, assign them
done_move_finished_ids = (productions_to_backorder.move_finished_ids | productions_not_to_backorder.move_finished_ids).filtered(lambda m: m.state == 'done')
+75 -2
View File
@@ -111,7 +111,7 @@ class TestMrpOrder(TestMrpCommon):
# check that copy handles moves correctly
mo_copy = man_order.copy()
self.assertEqual(mo_copy.state, 'draft', "Copied production order should be draft.")
self.assertEqual(len(mo_copy.move_raw_ids), 2, "Incorrect number of component moves [i.e. no 0 qty moves should be copied].")
self.assertEqual(len(mo_copy.move_raw_ids), 4, "Incorrect number of component moves [i.e. no 0 qty moves should be copied].")
self.assertEqual(len(mo_copy.move_finished_ids), 1, "Incorrect number of moves for products to produce [i.e. cancelled moves should not be copied")
self.assertEqual(mo_copy.move_finished_ids.product_uom_qty, 2, "Incorrect qty of products to produce")
@@ -120,7 +120,7 @@ class TestMrpOrder(TestMrpCommon):
self.assertEqual(mo_copy.state, 'cancel')
mo_copy_2 = mo_copy.copy()
self.assertEqual(mo_copy_2.state, 'draft', "Copied production order should be draft.")
self.assertEqual(len(mo_copy_2.move_raw_ids), 2, "Incorrect number of component moves.")
self.assertEqual(len(mo_copy_2.move_raw_ids), 4, "Incorrect number of component moves.")
self.assertEqual(len(mo_copy_2.move_finished_ids), 1, "Incorrect number of moves for products to produce [i.e. copying a cancelled MO should copy its cancelled moves]")
self.assertEqual(mo_copy_2.move_finished_ids.product_uom_qty, 2, "Incorrect qty of products to produce")
@@ -197,6 +197,45 @@ class TestMrpOrder(TestMrpCommon):
self.assertEqual(mo.move_raw_ids.mapped('quantity_done'), [1, 10, 1, 1])
self.assertEqual(mo.move_raw_ids.mapped('move_line_ids.qty_done'), [1, 10, 1, 1])
def test_under_consumption(self):
""" Consume less component quantity than the initial demand.
Before done:
p1, to consume = 1, consumed = 0
p2, to consume = 10, consumed = 5
After done:
p1, to consume = 1, consumed = 0, state = cancel
p2, to consume = 5, consumed = 5, state = done
p2, to consume = 5, consumed = 0, state = cancel
"""
mo, _bom, _p_final, _p1, _p2 = self.generate_mo(qty_base_1=10, qty_final=1, qty_base_2=1)
mo.action_assign()
# check is_quantity_done_editable
mo_form = Form(mo)
mo_form.qty_producing = 1
mo = mo_form.save()
details_operation_form = Form(mo.move_raw_ids[0], view=self.env.ref('stock.view_stock_move_operations'))
with details_operation_form.move_line_ids.edit(0) as ml:
ml.qty_done = 0
details_operation_form.save()
details_operation_form = Form(mo.move_raw_ids[1], view=self.env.ref('stock.view_stock_move_operations'))
with details_operation_form.move_line_ids.edit(0) as ml:
ml.qty_done = 5
details_operation_form.save()
self.assertEqual(len(mo.move_raw_ids), 2)
self.assertEqual(len(mo.move_raw_ids.mapped('move_line_ids')), 2)
self.assertEqual(mo.move_raw_ids[0].move_line_ids.mapped('qty_done'), [0])
self.assertEqual(mo.move_raw_ids[1].move_line_ids.mapped('qty_done'), [5])
self.assertEqual(mo.move_raw_ids[0].quantity_done, 0)
self.assertEqual(mo.move_raw_ids[1].quantity_done, 5)
mo.button_mark_done()
self.assertEqual(len(mo.move_raw_ids), 3)
self.assertEqual(len(mo.move_raw_ids.mapped('move_line_ids')), 1)
self.assertEqual(mo.move_raw_ids.mapped('quantity_done'), [0, 5, 0])
self.assertEqual(mo.move_raw_ids.mapped('product_uom_qty'), [1, 5, 5])
self.assertEqual(mo.move_raw_ids.mapped('state'), ['cancel', 'done', 'cancel'])
self.assertEqual(mo.move_raw_ids.mapped('move_line_ids.qty_done'), [5])
def test_update_quantity_1(self):
""" Build 5 final products with different consumed lots,
then edit the finished quantity and update the Manufacturing
@@ -1768,6 +1807,40 @@ class TestMrpOrder(TestMrpCommon):
self.assertEqual(mo.workorder_ids[1].date_planned_start, tuesday.replace(hour=1))
self.assertEqual(mo.workorder_ids[1].date_planned_finished, tuesday.replace(hour=2))
def test_backorder_with_underconsumption(self):
""" Check that the components of the backorder have the correct quantities
when there is underconsumption in the initial MO
"""
mo, _, _, p1, p2 = self.generate_mo(qty_final=20, qty_base_1=1, qty_base_2=1)
mo.action_confirm()
mo.qty_producing = 10
mo.move_raw_ids.filtered(lambda m: m.product_id == p1).quantity_done = 5
mo.move_raw_ids.filtered(lambda m: m.product_id == p2).quantity_done = 10
action = mo.button_mark_done()
backorder = Form(self.env['mrp.production.backorder'].with_context(**action['context']))
backorder.save().action_backorder()
mo_backorder = mo.procurement_group_id.mrp_production_ids[-1]
# Check quantities of the original MO
self.assertEqual(mo.product_uom_qty, 10.0)
self.assertEqual(mo.qty_produced, 10.0)
move_prod_1_done = mo.move_raw_ids.filtered(lambda m: m.product_id == p1 and m.state == 'done')
self.assertEqual(sum(move_prod_1_done.mapped('quantity_done')), 5)
self.assertEqual(sum(move_prod_1_done.mapped('product_uom_qty')), 5)
move_prod_1_cancel = mo.move_raw_ids.filtered(lambda m: m.product_id == p1 and m.state == 'cancel')
self.assertEqual(sum(move_prod_1_cancel.mapped('quantity_done')), 0)
self.assertEqual(sum(move_prod_1_cancel.mapped('product_uom_qty')), 5)
move_prod_2 = mo.move_raw_ids.filtered(lambda m: m.product_id == p2)
self.assertEqual(sum(move_prod_2.mapped('quantity_done')), 10)
self.assertEqual(sum(move_prod_2.mapped('product_uom_qty')), 10)
# Check quantities of the backorder MO
self.assertEqual(mo_backorder.product_uom_qty, 10.0)
move_prod_1_bo = mo_backorder.move_raw_ids.filtered(lambda m: m.product_id == p1)
move_prod_2_bo = mo_backorder.move_raw_ids.filtered(lambda m: m.product_id == p2)
self.assertEqual(sum(move_prod_1_bo.mapped('product_uom_qty')), 10.0)
self.assertEqual(sum(move_prod_2_bo.mapped('product_uom_qty')), 10.0)
def test_products_with_variants(self):
"""Check for product with different variants with same bom"""
product = self.env['product.template'].create({
+10 -4
View File
@@ -537,9 +537,12 @@ class PosSession(models.Model):
for move in stock_moves:
exp_key = move.product_id._get_product_accounts()['expense']
out_key = move.product_id.categ_id.property_stock_account_output_categ_id
amount = move.product_qty * move.product_id._compute_average_price(0, move.product_qty, move)
signed_product_qty = move.product_qty
if move._is_in():
signed_product_qty *= -1
amount = signed_product_qty * move.product_id._compute_average_price(0, move.product_qty, move)
stock_expense[exp_key] = self._update_amounts(stock_expense[exp_key], {'amount': amount}, move.picking_id.date, force_company_currency=True)
if move.location_id.usage == 'customer':
if move._is_in():
stock_return[out_key] = self._update_amounts(stock_return[out_key], {'amount': amount}, move.picking_id.date, force_company_currency=True)
else:
stock_output[out_key] = self._update_amounts(stock_output[out_key], {'amount': amount}, move.picking_id.date, force_company_currency=True)
@@ -563,9 +566,12 @@ class PosSession(models.Model):
for move in stock_moves:
exp_key = move.product_id._get_product_accounts()['expense']
out_key = move.product_id.categ_id.property_stock_account_output_categ_id
amount = move.product_qty * move.product_id._compute_average_price(0, move.product_qty, move)
signed_product_qty = move.product_qty
if move._is_in():
signed_product_qty *= -1
amount = signed_product_qty * move.product_id._compute_average_price(0, move.product_qty, move)
stock_expense[exp_key] = self._update_amounts(stock_expense[exp_key], {'amount': amount}, move.picking_id.date, force_company_currency=True)
if move.location_id.usage == 'customer':
if move._is_in():
stock_return[out_key] = self._update_amounts(stock_return[out_key], {'amount': amount}, move.picking_id.date, force_company_currency=True)
else:
stock_output[out_key] = self._update_amounts(stock_output[out_key], {'amount': amount}, move.picking_id.date, force_company_currency=True)
@@ -247,3 +247,30 @@ class TestPoSStock(TestPoSCommon):
# close the session
self.pos_session.action_pos_session_validate()
def test_04_order_refund(self):
self.categ4 = self.env['product.category'].create({
'name': 'Category 4',
'property_cost_method': 'fifo',
'property_valuation': 'real_time',
})
self.product4 = self.create_product('Product 4', self.categ4, 30.0, 15.0)
self.open_new_session()
orders = []
orders.append(self.create_ui_order_data([(self.product4, 1)]))
order = self.env['pos.order'].create_from_ui(orders)
refund_action = self.env['pos.order'].browse(order[0]['id']).refund()
refund = self.env['pos.order'].browse(refund_action['res_id'])
payment_context = {"active_ids": refund.ids, "active_id": refund.id}
refund_payment = self.env['pos.make.payment'].with_context(**payment_context).create({
'amount': refund.amount_total,
'payment_method_id': self.cash_pm.id,
})
refund_payment.with_context(**payment_context).check()
self.pos_session.action_pos_session_validate()
expense_account_move_line = self.env['account.move.line'].search([('account_id', '=', self.expense_account.id)])
self.assertEqual(expense_account_move_line.balance, 0.0, "Expense account should be 0.0")
+2
View File
@@ -279,6 +279,8 @@ class Repair(models.Model):
return True
def action_repair_cancel(self):
if self.state == 'done':
raise UserError(_("You cannot cancel a completed repair order."))
invoice_to_cancel = self.filtered(lambda repair: repair.invoice_id.state == 'draft').invoice_id
if invoice_to_cancel:
invoice_to_cancel.button_cancel()
+1 -1
View File
@@ -38,7 +38,7 @@
<button name="print_repair_order" states="draft" string="Print Quotation" type="object"/>
<button name="action_repair_cancel_draft" states="cancel" string="Set to Draft" type="object"/>
<button name="action_repair_cancel" string="Cancel Repair" type="object" confirm="Draft invoices for this order will be cancelled. Do you confirm the action?" attrs="{'invisible':['|', ('state', '=', 'cancel'), ('invoice_state', '!=', 'draft')]}"/>
<button name="action_repair_cancel" string="Cancel Repair" type="object" attrs="{'invisible': ['|', ('state','=', 'cancel',), ('invoice_state', '=', 'draft')]}"/>
<button name="action_repair_cancel" string="Cancel Repair" type="object" attrs="{'invisible': ['|', ('state','in', ('cancel','done')), ('invoice_state', '=', 'draft')]}"/>
<field name="state" widget="statusbar" statusbar_visible="draft,confirmed,done"/>
</header>
<sheet string="Repairs order">
+1 -1
View File
@@ -767,7 +767,7 @@ class ProductTemplate(models.Model):
# Forbid changing a product's company when quant(s) exist in another company.
quant = self.env['stock.quant'].sudo().search([
('product_id', 'in', products_changing_company.product_variant_ids.ids),
('company_id', '!=', vals['company_id']),
('company_id', 'not in', [vals['company_id'], False]),
('quantity', '!=', 0),
], order=None, limit=1)
if quant:
+41
View File
@@ -133,6 +133,47 @@ class TestVirtualAvailable(TestStockCommon):
self.env['stock.quant']._unlink_zero_quants()
product.company_id = company2.id # Should work this time.
def test_change_product_company_exclude_vendor_and_customer_location(self):
""" Checks we can change product company where only exist single company
and exist quant in vendor/customer location"""
company1 = self.env.ref('base.main_company')
customer_location = self.env.ref('stock.stock_location_customers')
supplier_location = self.env.ref('stock.stock_location_suppliers')
product = self.env['product.product'].create({
'name': 'Product Single Company',
'type': 'product',
})
# Creates a quant for company 1.
self.env['stock.quant'].create({
'product_id': product.id,
'product_uom_id': self.uom_unit.id,
'location_id': self.location_1.id,
'quantity': 5,
})
# Creates a quant for vendor location.
self.env['stock.quant'].create({
'product_id': product.id,
'product_uom_id': self.uom_unit.id,
'location_id': supplier_location.id,
'quantity': -15,
})
# Creates a quant for customer location.
self.env['stock.quant'].create({
'product_id': product.id,
'product_uom_id': self.uom_unit.id,
'location_id': customer_location.id,
'quantity': 10,
})
# Assigns a company: should be ok because only exist one company (exclude vendor and customer location)
product.company_id = company1.id
# Reset product company to empty
product.company_id = False
company2 = self.env['res.company'].create({'name': 'Second Company'})
# Assigns to another company: should be not okay because exist quants in defferent company (exclude vendor and customer location)
with self.assertRaises(UserError):
product.company_id = company2.id
def test_search_qty_available(self):
product = self.env['product.product'].create({
'name': 'Brand new product',
@@ -474,7 +474,7 @@ return AbstractRenderer.extend({
// Detect if the event occurs in just one day
// note: add & remove 1 min to avoid issues with 00:00
var isSameDayEvent = moment(start).clone().add(1, 'minute').isSame(moment(end).clone().subtract(1, 'minute'), 'day');
if (!event.extendedProps.record.allday && isSameDayEvent) {
if (!event.allDay && isSameDayEvent) {
// For month view: do not show background for non allday, single day events
element.addClass('o_cw_nobg');
if (event.extendedProps.showTime && !self.hideTime) {
@@ -794,7 +794,7 @@ return AbstractRenderer.extend({
var isSameDayEvent = start.clone().add(1, 'minute').isSame(end.clone().subtract(1, 'minute'), 'day');
// Do not display timing if the event occur across multiple days. Otherwise use user's timing preferences
if (!this.hideTime && !eventData.extendedProps.record.allday && isSameDayEvent) {
if (!this.hideTime && !eventData.allDay && isSameDayEvent) {
var dbTimeFormat = this._getDbTimeFormat();
context.eventTime.time = start.clone().format(dbTimeFormat) + ' - ' + end.clone().format(dbTimeFormat);
@@ -813,15 +813,15 @@ return AbstractRenderer.extend({
if (!this.hideDate) {
if (eventData.extendedProps.record.allday && isSameDayEvent) {
if (eventData.allDay && isSameDayEvent) {
context.eventDate.duration = _t("All day");
} else if (eventData.extendedProps.record.allday && !isSameDayEvent) {
} else if (eventData.allDay && !isSameDayEvent) {
var daysLocaleData = moment.localeData();
var days = moment.duration(end.diff(start)).days();
context.eventDate.duration = daysLocaleData.relativeTime(days, true, 'dd');
}
context.eventDate.date = this._getFormattedDate(start, end, true, eventData.extendedProps.record.allday);
context.eventDate.date = this._getFormattedDate(start, end, true, eventData.allDay);
}
return context;
@@ -878,10 +878,17 @@ return AbstractRenderer.extend({
_renderYearEventPopover: function (date, events, $el) {
const groupKeys = [];
const groupedEvents = {};
const records = {};
for(const record of this.state.data) {
records[record.id] = record;
}
for (const event of events) {
const start = moment(event.extendedProps.r_start);
const end = moment(event.extendedProps.r_end);
const key = this._getFormattedDate(start, end, false, event.extendedProps.record.allday);
// get the original record to get the real allDay value as
// the fullcalendar year view enforce allDay to true
const record = records[event.extendedProps.record.id];
const key = this._getFormattedDate(start, end, false, record.allDay);
if (!(key in groupedEvents)) {
groupedEvents[key] = [];
groupKeys.push({
@@ -1374,6 +1374,36 @@ QUnit.module('Views', {
calendar.destroy();
});
QUnit.test("all day event attribute", async function (assert) {
assert.expect(5);
this.data.event.fields.boolfield = { string: "boolean field", type: "boolean" };
this.data.event.records[0].boolfield = true;
const calendar = await createCalendarView({
View: CalendarView,
model: 'event',
data: this.data,
arch: `
<calendar date_start="start" date_stop="stop" all_day="boolfield" mode="month">
<field name="name"/>
</calendar>
`,
archs: archs,
viewOptions: { initialDate },
session: { getTZOffset: () => 120 },
});
assert.containsOnce(calendar, ".fc-event[data-event-id=1]");
assert.containsNone(calendar, ".fc-event[data-event-id=1].o_cw_nobg", "first event is an all day event");
assert.containsOnce(calendar, ".fc-event[data-event-id=2].o_cw_nobg", "second event is not an all day event");
assert.containsN(calendar, ".fc-event[data-event-id=5]", 2);
assert.containsNone(calendar, ".fc-event[data-event-id=5].o_cw_nobg", 2, "fifth event is an all day event");
calendar.destroy();
});
QUnit.test('create all day event in week mode', async function (assert) {
assert.expect(3);
+6 -5
View File
@@ -115,11 +115,12 @@ class Menu(models.Model):
def _compute_visible(self):
for menu in self:
visible = True
if menu.page_id and not menu.user_has_groups('base.group_user') and \
(not menu.page_id.sudo().is_visible or
(not menu.page_id.view_id._handle_visibility(do_raise=False) and
menu.page_id.view_id.visibility != "password")):
visible = False
if menu.page_id and not menu.user_has_groups('base.group_user'):
page_sudo = menu.page_id.sudo()
if (not page_sudo.is_visible
or (not page_sudo.view_id._handle_visibility(do_raise=False)
and page_sudo.view_id.visibility != "password")):
visible = False
menu.is_visible = visible
@api.model