[MERGE] forward port branch saas-11.3 up to 55dafc20f6
This commit is contained in:
@@ -504,6 +504,9 @@ class AccountInvoice(models.Model):
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if not vals.get('journal_id') and vals.get('type'):
|
||||
vals['journal_id'] = self.with_context(type=vals.get('type'))._default_journal().id
|
||||
|
||||
onchanges = {
|
||||
'_onchange_partner_id': ['account_id', 'payment_term_id', 'fiscal_position_id', 'partner_bank_id'],
|
||||
'_onchange_journal_id': ['currency_id'],
|
||||
|
||||
@@ -1466,6 +1466,9 @@ class AccountPartialReconcile(models.Model):
|
||||
'''
|
||||
return tax.cash_basis_base_account_id or line.account_id
|
||||
|
||||
def _get_amount_tax_cash_basis(self, amount, line):
|
||||
return line.company_id.currency_id.round(amount)
|
||||
|
||||
def create_tax_cash_basis_entry(self, percentage_before_rec):
|
||||
self.ensure_one()
|
||||
move_date = self.debit_move_id.date
|
||||
@@ -1480,7 +1483,7 @@ class AccountPartialReconcile(models.Model):
|
||||
percentage_after = line._get_matched_percentage()[move.id]
|
||||
#amount is the current cash_basis amount minus the one before the reconciliation
|
||||
amount = line.balance * percentage_after - line.balance * percentage_before
|
||||
rounded_amt = line.company_id.currency_id.round(amount)
|
||||
rounded_amt = self._get_amount_tax_cash_basis(amount, line)
|
||||
if float_is_zero(rounded_amt, precision_rounding=line.company_id.currency_id.rounding):
|
||||
continue
|
||||
if line.tax_line_id and line.tax_line_id.tax_exigibility == 'on_payment':
|
||||
|
||||
@@ -24,6 +24,7 @@ class TestAccountSupplierInvoice(AccountingTestCase):
|
||||
'account_id': invoice_account,
|
||||
'type': 'in_invoice',
|
||||
})
|
||||
self.assertEquals(invoice.journal_id.type, 'purchase')
|
||||
|
||||
self.env['account.invoice.line'].create({'product_id': self.env.ref('product.product_product_4').id,
|
||||
'quantity': 1.0,
|
||||
@@ -79,6 +80,7 @@ class TestAccountSupplierInvoice(AccountingTestCase):
|
||||
'account_id': invoice_account,
|
||||
'type': 'in_invoice',
|
||||
})
|
||||
self.assertEquals(invoice.journal_id.type, 'purchase')
|
||||
|
||||
invoice_line = self.env['account.invoice.line'].create({'product_id': self.env.ref('product.product_product_4').id,
|
||||
'quantity': 5.0,
|
||||
|
||||
@@ -906,7 +906,7 @@
|
||||
<field name="amount" class="oe_inline"/>
|
||||
<span class="o_form_label oe_inline" attrs="{'invisible':[('amount_type','!=','percentage')]}">%</span>
|
||||
</div>
|
||||
<field name="journal_id" domain="[('company_id', '=', company_id)]" widget="selection"
|
||||
<field name="journal_id" domain="[('type', '!=', 'general'), ('company_id', '=', company_id)]" widget="selection"
|
||||
attrs="{'invisible': [('rule_type', '!=', 'writeoff_button')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
@@ -939,7 +939,7 @@
|
||||
<field name="second_amount" class="oe_inline"/>
|
||||
<span class="o_form_label oe_inline" attrs="{'invisible':[('amount_type','!=','percentage')]}">%</span>
|
||||
</div>
|
||||
<field name="second_journal_id" string="Journal" domain="[('company_id', '=', company_id)]" widget="selection"
|
||||
<field name="second_journal_id" string="Journal" domain="[('type', '!=', 'general'), ('company_id', '=', company_id)]" widget="selection"
|
||||
attrs="{'invisible': [('rule_type', '!=', 'writeoff_button')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
@@ -192,7 +192,7 @@ class CompanyLDAP(models.Model):
|
||||
elif conf['create_user']:
|
||||
_logger.debug("Creating new Odoo user \"%s\" from LDAP" % login)
|
||||
values = self._map_ldap_attributes(conf, login, ldap_entry)
|
||||
SudoUser = self.env['res.users'].sudo()
|
||||
SudoUser = self.env['res.users'].sudo().with_context(no_reset_password=True)
|
||||
if conf['user']:
|
||||
values['active'] = True
|
||||
return SudoUser.browse(conf['user'][0]).copy(default=values).id
|
||||
|
||||
@@ -356,3 +356,10 @@ class ResPartner(models.Model):
|
||||
return int(vat[9]) == c1 and int(vat[10]) == c2
|
||||
|
||||
return False
|
||||
|
||||
def check_vat_al(self, vat):
|
||||
try:
|
||||
import stdnum.al
|
||||
return stdnum.al.vat.is_valid(vat)
|
||||
except ImportError:
|
||||
return True
|
||||
|
||||
@@ -120,7 +120,7 @@ class DeliveryCarrier(models.Model):
|
||||
if hasattr(self, '%s_rate_shipment' % self.delivery_type):
|
||||
res = getattr(self, '%s_rate_shipment' % self.delivery_type)(order)
|
||||
# apply margin on computed price
|
||||
res['price'] = res['price'] * (1.0 + (float(self.margin) / 100.0))
|
||||
res['price'] = float(res['price']) * (1.0 + (float(self.margin) / 100.0))
|
||||
# free when order is large enough
|
||||
if res['success'] and self.free_over and order._compute_amount_total_without_delivery() >= self.amount:
|
||||
res['warning_message'] = _('Info:\nThe shipping is free because the order amount exceeds %.2f.\n(The actual shipping cost is: %.2f)') % (self.amount, res['price'])
|
||||
|
||||
@@ -558,6 +558,7 @@
|
||||
<record id="a4512" model="account.account.template">
|
||||
<field name="name">Compte courant administration T.V.A.</field>
|
||||
<field name="code">4512</field>
|
||||
<field name="reconcile" eval="True"/>
|
||||
<field name="user_type_id" ref="account.data_account_type_current_liabilities"/>
|
||||
<field name="chart_template_id" ref="l10nbe_chart_template"/>
|
||||
</record>
|
||||
|
||||
@@ -34,6 +34,7 @@ class TemplatePreview(models.TransientModel):
|
||||
|
||||
res_id = fields.Selection(_get_records, 'Sample Document')
|
||||
partner_ids = fields.Many2many('res.partner', string='Recipients')
|
||||
attachment_ids = fields.Many2many(string='Attachments', store=False)
|
||||
|
||||
@api.onchange('res_id')
|
||||
@api.multi
|
||||
|
||||
@@ -53,6 +53,7 @@ class ChangeProductionQty(models.TransientModel):
|
||||
factor = production.product_uom_id._compute_quantity(production.product_qty - qty_produced, production.bom_id.product_uom_id) / production.bom_id.product_qty
|
||||
boms, lines = production.bom_id.explode(production.product_id, factor, picking_type=production.bom_id.picking_type_id)
|
||||
documents = {}
|
||||
done_quantities = {move: move.quantity_done for move in production.move_raw_ids}
|
||||
for line, line_data in lines:
|
||||
move, old_qty, new_qty = production._update_raw_move(line, line_data)
|
||||
iterate_key = production._get_document_iterate_key(move)
|
||||
@@ -72,6 +73,9 @@ class ChangeProductionQty(models.TransientModel):
|
||||
production._log_downside_manufactured_quantity(finished_moves_modification)
|
||||
moves = production.move_raw_ids.filtered(lambda x: x.state not in ('done', 'cancel'))
|
||||
moves._action_assign()
|
||||
for move in production.move_raw_ids:
|
||||
if move.quantity_done != done_quantities[move]:
|
||||
move._set_quantity_done(done_quantities[move])
|
||||
for wo in production.workorder_ids:
|
||||
operation = wo.operation_id
|
||||
if operation_bom_qty.get(operation.id):
|
||||
|
||||
@@ -1526,7 +1526,8 @@ exports.Orderline = Backbone.Model.extend({
|
||||
return false;
|
||||
}else if(this.get_discount() > 0){ // we don't merge discounted orderlines
|
||||
return false;
|
||||
}else if(price !== orderline.get_product().get_price(orderline.order.pricelist, this.get_quantity())){
|
||||
}else if(!utils.float_is_zero(price - orderline.get_product().get_price(orderline.order.pricelist, this.get_quantity()),
|
||||
this.pos.currency.decimals)){
|
||||
return false;
|
||||
}else if(this.product.tracking == 'lot') {
|
||||
return false;
|
||||
|
||||
@@ -180,7 +180,7 @@ class CustomerPortal(CustomerPortal):
|
||||
# content according to pager and archive selected
|
||||
if groupby == 'project':
|
||||
order = "project_id, %s" % order # force sort on project first to group by project in view
|
||||
tasks = request.env['project.task'].search(domain, order=order, limit=self._items_per_page, offset=pager['offset'])
|
||||
tasks = request.env['project.task'].search(domain, order=order, limit=self._items_per_page, offset=(page - 1) * self._items_per_page)
|
||||
request.session['my_tasks_history'] = tasks.ids[:100]
|
||||
if groupby == 'project':
|
||||
grouped_tasks = [request.env['project.task'].concat(*g) for k, g in groupbyelem(tasks, itemgetter('project_id'))]
|
||||
|
||||
@@ -523,7 +523,6 @@
|
||||
<field name="stage_id" options='{"group_by_tooltip": {"description": "Stage Description", "legend_priority": "Use of stars"}}'/>
|
||||
<field name="user_id"/>
|
||||
<field name="user_email"/>
|
||||
<field name="description"/>
|
||||
<field name="sequence"/>
|
||||
<field name="date_deadline"/>
|
||||
<field name="message_needaction_counter"/>
|
||||
|
||||
@@ -395,7 +395,7 @@ class SaleOrder(models.Model):
|
||||
if 'invoice_status' in values:
|
||||
self.activity_unlink(['sale.mail_act_sale_upsell'])
|
||||
if values['invoice_status'] == 'upselling':
|
||||
for order in self:
|
||||
for order in self.filtered('user_id'):
|
||||
order.activity_schedule(
|
||||
'sale.mail_act_sale_upsell',
|
||||
user_id=order.user_id.id,
|
||||
|
||||
@@ -10,5 +10,13 @@
|
||||
<field name="name">Display incoterms on Sales Order and related invoices</field>
|
||||
<field name="category_id" ref="base.module_category_hidden"/>
|
||||
</record>
|
||||
|
||||
<!-- Stock Portal Access Rules -->
|
||||
<record id="stock_picking_rule_portal" model="ir.rule">
|
||||
<field name="name">Portal Follower Pickings</field>
|
||||
<field name="model_id" ref="stock.model_stock_picking"/>
|
||||
<field name="domain_force">['|', '|', ('message_partner_ids', 'in', [user.partner_id.id]), ('partner_id', '=', user.partner_id.id), ('sale_id.partner_id', '=', user.partner_id.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_portal'))]"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -132,14 +132,6 @@
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<!-- Stock Portal Access Rules -->
|
||||
<record id="stock_picking_rule_portal" model="ir.rule">
|
||||
<field name="name">Portal Follower Pickings</field>
|
||||
<field name="model_id" ref="stock.model_stock_picking"/>
|
||||
<field name="domain_force">['|', '|', ('message_partner_ids', 'in', [user.partner_id.id]), ('partner_id.id', '=', user.partner_id.id), ('sale_id.partner_id.id', '=', user.partner_id.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_portal'))]"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="stock_location_route_comp_rule">
|
||||
<field name="name">stock_location_route multi-company</field>
|
||||
<field name="model_id" ref="model_stock_location_route"/>
|
||||
|
||||
@@ -774,7 +774,7 @@ ActionManager.include({
|
||||
_.object(_.reject(_.pairs(env.context), function (pair) {
|
||||
return pair[0].match('^(?:(?:default_|search_default_|show_).+|' +
|
||||
'.+_view_ref|group_by|group_by_no_leaf|active_id|' +
|
||||
'active_ids)$') !== null;
|
||||
'active_ids|orderedBy)$') !== null;
|
||||
}))
|
||||
);
|
||||
ctx.add(actionData.context || {});
|
||||
|
||||
@@ -2156,6 +2156,62 @@ QUnit.module('ActionManager', {
|
||||
actionManager.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('orderedBy in context is not propagated when executing another action', function (assert) {
|
||||
assert.expect(6);
|
||||
|
||||
this.data.partner.fields.foo.sortable = true,
|
||||
|
||||
this.archs['partner,false,form'] = '<header>' +
|
||||
'<button name="8" string="Execute action" type="action"/>' +
|
||||
'</header>';
|
||||
|
||||
var searchReadCount = 0;
|
||||
var actionManager = createActionManager({
|
||||
actions: this.actions,
|
||||
archs: this.archs,
|
||||
data: this.data,
|
||||
mockRPC: function (route, args) {
|
||||
if (route === '/web/dataset/search_read') {
|
||||
if (searchReadCount === 1) {
|
||||
assert.strictEqual(args.model, 'partner');
|
||||
assert.notOk(args.sort);
|
||||
}
|
||||
if (searchReadCount === 2) {
|
||||
assert.strictEqual(args.model, 'partner');
|
||||
assert.strictEqual(args.sort, "foo ASC");
|
||||
}
|
||||
if (searchReadCount === 3) {
|
||||
assert.strictEqual(args.model, 'pony');
|
||||
assert.notOk(args.sort);
|
||||
}
|
||||
searchReadCount += 1;
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
actionManager.doAction(3);
|
||||
|
||||
// Simulate the activation of a filter
|
||||
var searchData = {
|
||||
domains: [[["foo", "=", "yop"]]],
|
||||
contexts: [{
|
||||
orderedBy: [],
|
||||
}],
|
||||
};
|
||||
actionManager.trigger_up('search', searchData);
|
||||
|
||||
// Sort records
|
||||
actionManager.$('.o_list_view th.o_column_sortable').click();
|
||||
|
||||
// get to the form view of the model, on the first record
|
||||
actionManager.$('.o_data_cell:first').click();
|
||||
|
||||
// Change model by clicking on the button within the form
|
||||
actionManager.$('.o_form_view button').click();
|
||||
|
||||
actionManager.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('breadcrumbs are updated when switching between views', function (assert) {
|
||||
assert.expect(10);
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ class WebsiteMembership(http.Controller):
|
||||
|
||||
# get google maps localization of partners
|
||||
google_map_partner_ids = []
|
||||
if request.env.ref('website_membership.opt_index_google_map').customize_show:
|
||||
if request.env.ref('website_membership.opt_index_google_map').active:
|
||||
google_map_partner_ids = MembershipLine.search(line_domain).get_published_companies(limit=2000)
|
||||
|
||||
search_domain = [('membership_state', '=', 'free'), ('website_published', '=', True)]
|
||||
|
||||
@@ -2582,6 +2582,8 @@ class Many2many(_RelationalMulti):
|
||||
self.column2 = '%s_id' % comodel._table
|
||||
# check validity of table name
|
||||
check_pg_name(self.relation)
|
||||
else:
|
||||
self.relation = self.column1 = self.column2 = None
|
||||
|
||||
def _setup_regular_full(self, model):
|
||||
super(Many2many, self)._setup_regular_full(model)
|
||||
|
||||
Reference in New Issue
Block a user