[PATCH] Upstream patch - 13102021

This commit is contained in:
Parthiv Patel
2021-10-13 09:36:12 +00:00
parent bc12627553
commit 3547d9e5e0
16 changed files with 140 additions and 29 deletions
@@ -214,9 +214,9 @@ class AccountBankStatement(models.Model):
reference = fields.Char(string='External Reference', states={'open': [('readonly', False)]}, copy=False, readonly=True, help="Used to hold the reference of the external mean that created this statement (name of imported file, reference of online synchronization...)")
date = fields.Date(required=True, states={'confirm': [('readonly', True)]}, index=True, copy=False, default=fields.Date.context_today)
date_done = fields.Datetime(string="Closed On")
balance_start = fields.Monetary(string='Starting Balance', states={'confirm': [('readonly', True)]}, compute='_compute_starting_balance', readonly=False, store=True)
balance_end_real = fields.Monetary('Ending Balance', states={'confirm': [('readonly', True)]}, compute='_compute_ending_balance', readonly=False, store=True)
state = fields.Selection(string='Status', required=True, readonly=True, copy=False, selection=[
balance_start = fields.Monetary(string='Starting Balance', states={'confirm': [('readonly', True)]}, compute='_compute_starting_balance', readonly=False, store=True, tracking=True)
balance_end_real = fields.Monetary('Ending Balance', states={'confirm': [('readonly', True)]}, compute='_compute_ending_balance', readonly=False, store=True, tracking=True)
state = fields.Selection(string='Status', required=True, readonly=True, copy=False, tracking=True, selection=[
('open', 'New'),
('posted', 'Processing'),
('confirm', 'Validated'),
+1 -1
View File
@@ -91,7 +91,7 @@
<field name="name">account.move.line.kanban</field>
<field name="model">account.move.line</field>
<field name="arch" type="xml">
<kanban class="o_kanban_mobile" create="false">
<kanban class="o_kanban_mobile" create="false" group_create="false">
<field name="date_maturity"/>
<field name="move_id"/>
<field name="name"/>
@@ -120,10 +120,13 @@ class AccountMoveReversal(models.TransientModel):
action.update({
'view_mode': 'form',
'res_id': moves_to_redirect.id,
'context': {'default_move_type': moves_to_redirect.move_type},
})
else:
action.update({
'view_mode': 'tree,form',
'domain': [('id', 'in', moves_to_redirect.ids)],
})
if len(set(moves_to_redirect.mapped('move_type'))) == 1:
action['context'] = {'default_move_type': moves_to_redirect.mapped('move_type').pop()}
return action
@@ -76,7 +76,8 @@ class AccountDebitNote(models.TransientModel):
'name': _('Debit Notes'),
'type': 'ir.actions.act_window',
'res_model': 'account.move',
}
'context': {'default_move_type': default_values['move_type']},
}
if len(new_moves) == 1:
action.update({
'view_mode': 'form',
+3 -3
View File
@@ -91,10 +91,10 @@ class ResPartner(models.Model):
if fragment:
query['redirect'] = base + werkzeug.urls.url_encode(fragment)
url = "/web/%s?%s" % (route, werkzeug.urls.url_encode(query))
signup_url = "/web/%s?%s" % (route, werkzeug.urls.url_encode(query))
if not self.env.context.get('relative_url'):
url = werkzeug.urls.url_join(base_url, url)
res[partner.id] = url
signup_url = werkzeug.urls.url_join(base_url, signup_url)
res[partner.id] = signup_url
return res
+1 -1
View File
@@ -1063,7 +1063,7 @@ class Message(models.Model):
('res_id', 'in', moderated_channel_ids),
'|',
('author_id', '=', self.env.user.partner_id.id),
('moderation_status', '=', 'pending_moderation'),
('need_moderation', '=', True),
]
messages |= self.search(moderated_messages_dom, limit=limit)
# Truncate the results to `limit`
+14 -2
View File
@@ -1748,7 +1748,13 @@ class MrpProduction(models.Model):
duplicates_unbuild = self.env['stock.move.line'].search_count(domain_unbuild + [
('move_id.unbuild_id', '!=', False)
])
if not (duplicates_unbuild and duplicates - duplicates_unbuild == 0):
removed = self.env['stock.move.line'].search_count([
('lot_id', '=', move_line.lot_id.id),
('state', '=', 'done'),
('location_dest_id.scrap_location', '=', True)
])
# Either removed or unbuild
if not ((duplicates_unbuild or removed) and duplicates - duplicates_unbuild - removed == 0):
raise UserError(message)
# Check presence of same sn in current production
duplicates = co_prod_move_lines.filtered(lambda ml: ml.qty_done and ml.lot_id == move_line.lot_id) - move_line
@@ -1784,7 +1790,13 @@ class MrpProduction(models.Model):
duplicates_unbuild = self.env['stock.move.line'].search_count(domain_unbuild + [
('move_id.unbuild_id', '!=', False)
])
if not (duplicates_unbuild and duplicates - duplicates_unbuild == 0):
removed = self.env['stock.move.line'].search_count([
('lot_id', '=', move_line.lot_id.id),
('state', '=', 'done'),
('location_dest_id.scrap_location', '=', True)
])
# Either removed or unbuild
if not ((duplicates_unbuild or removed) and duplicates - duplicates_unbuild - removed == 0):
raise UserError(message)
# Check presence of same sn in current production
duplicates = co_prod_move_lines.filtered(lambda ml: ml.qty_done and ml.lot_id == move_line.lot_id) - move_line
+82
View File
@@ -5,6 +5,8 @@ from flectra.tests import Form, tagged
from flectra.addons.mrp.tests.common import TestMrpCommon
import uuid
@tagged('post_install', '-at_install')
class TestTraceability(TestMrpCommon):
TRACKING_TYPES = ['none', 'serial', 'lot']
@@ -306,3 +308,83 @@ class TestTraceability(TestMrpCommon):
self.assertEqual(byproduct_move_line_2_lot_1.consume_line_ids.filtered(lambda l: l.qty_done), raw_line_raw_1_lot_1 | raw_line_raw_2_lot_1)
byproduct_move_line_2_lot_2 = finished_move_lines.filtered(lambda ml: ml.lot_id.name == 'Byproduct_2_lot_2')
self.assertEqual(byproduct_move_line_2_lot_2.consume_line_ids, raw_line_raw_1_lot_2 | raw_line_raw_2_lot_2)
def test_tracking_repair_production(self):
"""
Test that removing a tracked component with a repair does not block the flow of using that component in another
bom
"""
if 'repair.order' not in self.env: # Module required for that test
return
product_to_repair = self.env['product.product'].create({
'name': 'product first serial to act repair',
'tracking': 'serial',
})
ptrepair_lot = self.env['stock.production.lot'].create({
'name': 'A1',
'product_id': product_to_repair.id,
'company_id': self.env.user.company_id.id
})
product_to_remove = self.env['product.product'].create({
'name': 'other first serial to remove with repair',
'tracking': 'serial',
})
ptremove_lot = self.env['stock.production.lot'].create({
'name': 'B2',
'product_id': product_to_remove.id,
'company_id': self.env.user.company_id.id
})
# Create a manufacturing order with product (with SN A1)
mo = self.env['mrp.production'].create({
'name': 'testing',
'product_id': product_to_repair.id,
'product_uom_id': product_to_repair.uom_id.id,
'product_qty': 1
})
mo_form = Form(mo)
with mo_form.move_raw_ids.new() as move:
move.product_id = product_to_remove
move.product_uom_qty = 1
move.move_line_ids.lot_id = ptremove_lot # Set component serial to B2
mo = mo_form.save()
mo.action_confirm()
# Set serial to A1
mo.lot_producing_id = ptrepair_lot
mo.button_mark_done()
with Form(self.env['repair.order']) as ro_form:
ro_form.name = 'Please repair'
ro_form.product_id = product_to_repair
ro_form.lot_id = ptrepair_lot # Repair product Serial A1
with ro_form.operations.new() as operation:
operation.type = 'remove'
operation.product_id = product_to_remove
operation.lot_id = ptremove_lot # Remove product Serial B2 from the product
ro = ro_form.save()
ro.action_validate()
ro.action_repair_start()
ro.action_repair_end()
# Create a manufacturing order with product (with SN A2)
mo2 = self.env['mrp.production'].create({
'name': 'testing duo',
'product_id': product_to_repair.id,
'product_uom_id': product_to_repair.uom_id.id,
'product_qty': 1
})
mo2_form = Form(mo2)
with mo2_form.move_raw_ids.new() as move:
move.product_id = product_to_remove
move.product_uom_qty = 1
move.move_line_ids.lot_id = ptremove_lot # Set component serial to B2 again, it is possible
mo2 = mo2_form.save()
mo2.action_confirm()
# Set serial to A2
mo2.lot_producing_id = self.env['stock.production.lot'].create({
'name': 'A2',
'product_id': product_to_repair.id,
'company_id': self.env.user.company_id.id
})
# We are not forbidden to use that serial number, so nothing raised here
mo2.button_mark_done()
+2 -1
View File
@@ -574,7 +574,8 @@ class PosConfig(models.Model):
}
def _force_http(self):
if self.other_devices:
enforce_https = self.env['ir.config_parameter'].sudo().get_param('point_of_sale.enforce_https')
if not enforce_https and self.other_devices:
return True
return False
+3 -3
View File
@@ -553,11 +553,11 @@ class PosSession(models.Model):
exp_key = move.product_id._get_product_accounts()['expense']
out_key = move.product_id.categ_id.property_stock_account_output_categ_id
amount = -sum(move.stock_valuation_layer_ids.mapped('value'))
stock_expense[exp_key] = self._update_amounts(stock_expense[exp_key], {'amount': amount}, move.picking_id.date)
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':
stock_return[out_key] = self._update_amounts(stock_return[out_key], {'amount': amount}, move.picking_id.date)
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)
stock_output[out_key] = self._update_amounts(stock_output[out_key], {'amount': amount}, move.picking_id.date, force_company_currency=True)
MoveLine = self.env['account.move.line'].with_context(check_move_validity=False)
data.update({
+2 -1
View File
@@ -32,7 +32,8 @@ class PosConfig(models.Model):
self.set_tip_after_payment = False
def _force_http(self):
if self.printer_ids.filtered(lambda pt: pt.printer_type == 'epson_epos'):
enforce_https = self.env['ir.config_parameter'].sudo().get_param('point_of_sale.enforce_https')
if not enforce_https and self.printer_ids.filtered(lambda pt: pt.printer_type == 'epson_epos'):
return True
return super(PosConfig, self)._force_http()
+2 -1
View File
@@ -8,6 +8,7 @@ class PosConfig(models.Model):
_inherit = 'pos.config'
def _force_http(self):
if self.payment_method_ids.filtered(lambda pm: pm.use_payment_terminal == 'six'):
enforce_https = self.env['ir.config_parameter'].sudo().get_param('point_of_sale.enforce_https')
if not enforce_https and self.payment_method_ids.filtered(lambda pm: pm.use_payment_terminal == 'six'):
return True
return super(PosConfig, self)._force_http()
@@ -166,6 +166,10 @@ flectra.define('web.CustomFilterItem', function (require) {
val => field_utils.format[type](val, { type }, { timezone: false })
);
descriptionArray.push(`"${dateValue.join(" " + this.env._t("and") + " ")}"`);
} else if (type === "selection") {
domainValue = [condition.value];
const formattedValue = field_utils.format[type](condition.value, field);
descriptionArray.push(`"${formattedValue}"`);
} else {
domainValue = [condition.value];
descriptionArray.push(`"${condition.value}"`);
@@ -91,7 +91,7 @@ flectra.define('web.filter_menu_generator_tests', function (require) {
// Default value
expectedFilters = [{
description: 'Color is "black"',
description: 'Color is "Black"',
domain: '[["color","=","black"]]',
type: 'filter',
}];
@@ -101,7 +101,7 @@ flectra.define('web.filter_menu_generator_tests', function (require) {
// Updated value
expectedFilters = [{
description: 'Color is "white"',
description: 'Color is "White"',
domain: '[["color","=","white"]]',
type: 'filter',
}];
+15 -8
View File
@@ -238,17 +238,24 @@ publicWidget.registry.StandardAffixedHeader = BaseAnimatedHeader.extend({
const mainPosScrolled = (scroll > this.headerHeight + this.topGap);
const reachPosScrolled = (scroll > this.scrolledPoint + this.topGap);
const fixedUpdate = (this.fixedHeader !== mainPosScrolled);
const showUpdate = (this.fixedHeaderShow !== reachPosScrolled);
// Switch between static/fixed position of the header
if (this.fixedHeader !== mainPosScrolled) {
this.$el.css('transform', mainPosScrolled ? 'translate(0, -100%)' : '');
if (fixedUpdate || showUpdate) {
this.$el.css('transform',
reachPosScrolled
? `translate(0, -${this.topGap}px)`
: mainPosScrolled
? 'translate(0, -100%)'
: '');
void this.$el[0].offsetWidth; // Force a paint refresh
this._toggleFixedHeader(mainPosScrolled);
}
// Show/hide header
if (this.fixedHeaderShow !== reachPosScrolled) {
this.$el.css('transform', reachPosScrolled ? `translate(0, -${this.topGap}px)` : 'translate(0, -100%)');
this.fixedHeaderShow = reachPosScrolled;
this.fixedHeaderShow = reachPosScrolled;
if (fixedUpdate) {
this._toggleFixedHeader(mainPosScrolled);
} else if (showUpdate) {
this._adaptToHeaderChange();
}
},
@@ -70,11 +70,10 @@
<!-- Note: no need of extra dependency thanks to the apply-to -->
</t>
</div>
<div data-selector=".s_product_catalog_dish"/>
<div data-selector=".s_product_catalog_dish" data-drop-near=".s_product_catalog_dish"/>
</xpath>
<xpath expr="//div[@data-js='SnippetMove']" position="attributes">
<attribute name="data-selector" add=".s_product_catalog_dish" separator=","/>
<attribute name="data-drop-near" add=".s_product_catalog_dish" separator=","/>
</xpath>
</template>