mirror of
https://gitlab.com/flectra-hq/flectra.git
synced 2025-02-25 18:55:21 -06:00
[PATCH] Upstream patch - 14042022
This commit is contained in:
@@ -24,6 +24,8 @@ class AccountTestInvoicingCommon(SavepointCase):
|
||||
def setUpClass(cls, chart_template_ref=None):
|
||||
super(AccountTestInvoicingCommon, cls).setUpClass()
|
||||
|
||||
assert 'post_install' in cls.test_tags, 'This test requires a CoA to be installed, it should be tagged "post_install"'
|
||||
|
||||
if chart_template_ref:
|
||||
chart_template = cls.env.ref(chart_template_ref)
|
||||
else:
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
|
||||
from flectra.addons.account_edi.tests.common import AccountEdiTestCommon
|
||||
from unittest.mock import patch
|
||||
from flectra.tests import tagged
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestAccountEdi(AccountEdiTestCommon):
|
||||
|
||||
def test_export_edi(self):
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from flectra.addons.account_edi_extended.tests.common import AccountEdiExtendedTestCommon, _mocked_post, _mocked_post_two_steps, _generate_mocked_needs_web_services, _mocked_cancel_failed, _generate_mocked_support_batching
|
||||
from flectra.tests import tagged
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestAccountEdi(AccountEdiExtendedTestCommon):
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
from flectra.exceptions import UserError
|
||||
from flectra.addons.account.tests.common import AccountTestInvoicingCommon
|
||||
from flectra.tests import tagged
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestSEPAQRCode(AccountTestInvoicingCommon):
|
||||
""" Tests the generation of Swiss QR-codes on invoices
|
||||
"""
|
||||
@@ -60,4 +62,3 @@ class TestSEPAQRCode(AccountTestInvoicingCommon):
|
||||
"""
|
||||
self.sepa_qr_invoice.generate_qr_code()
|
||||
self.assertEqual(self.sepa_qr_invoice.qr_code_method, 'sct_qr', "SEPA QR-code generator should have been chosen for this invoice.")
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from flectra.addons.account_edi.tests.common import AccountEdiTestCommon
|
||||
from flectra.tests.common import tagged
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestUBL(AccountEdiTestCommon):
|
||||
@classmethod
|
||||
def setUpClass(cls, chart_template_ref='l10n_be.l10nbe_chart_template', edi_format_ref='l10n_be_edi.edi_efff_1'):
|
||||
|
||||
@@ -14,9 +14,8 @@ class AccountJournal(models.Model):
|
||||
return
|
||||
|
||||
company = self.env['res.company'].browse(vals['company_id']) if vals.get('company_id') else self.env.company
|
||||
if company.country_id.code == "NL":
|
||||
type_control_ids = vals.get('type_control_ids', [])
|
||||
type_control_ids.append(self.env.ref('account.data_account_type_direct_costs').id)
|
||||
if company.country_id.code == "NL" and not vals.get('type_control_ids')[0][2]:
|
||||
type_control_ids = self.env.ref('account.data_account_type_direct_costs').ids
|
||||
vals['type_control_ids'] = [(6, 0, type_control_ids)]
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<span class="o_ThreadPreview_name" t-att-class="{ 'o-mobile': env.messaging.device.isMobile, 'o-muted': thread.localMessageUnreadCounter === 0 }">
|
||||
<t t-esc="thread.displayName"/>
|
||||
</span>
|
||||
<t t-if="thread.localMessageUnreadCounter > 0">
|
||||
<t t-if="thread.displayCounter > 0">
|
||||
<span class="o_ThreadPreview_counter" t-att-class="{ 'o-muted': thread.localMessageUnreadCounter === 0 }">
|
||||
(<t t-esc="thread.localMessageUnreadCounter"/>)
|
||||
</span>
|
||||
|
||||
@@ -63,7 +63,7 @@ function factory(dependencies) {
|
||||
}
|
||||
const inboxMailbox = this.env.messaging.inbox;
|
||||
const unreadChannels = this.env.models['mail.thread'].all(thread =>
|
||||
thread.localMessageUnreadCounter > 0 &&
|
||||
thread.displayCounter > 0 &&
|
||||
thread.model === 'mail.channel' &&
|
||||
thread.isPinned
|
||||
);
|
||||
|
||||
@@ -1201,6 +1201,17 @@ function factory(dependencies) {
|
||||
return [['unlink']];
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @returns {integer}
|
||||
*/
|
||||
_computeDisplayCounter() {
|
||||
if (this.mass_mailing && this.env.session.notification_type === 'email') {
|
||||
return 0;
|
||||
}
|
||||
return this.localMessageUnreadCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @returns {string}
|
||||
@@ -1858,6 +1869,16 @@ function factory(dependencies) {
|
||||
}),
|
||||
creator: many2one('mail.user'),
|
||||
custom_channel_name: attr(),
|
||||
/**
|
||||
* Determines whether counter should be displayed or not.
|
||||
*/
|
||||
displayCounter: attr({
|
||||
compute: '_computeDisplayCounter',
|
||||
dependencies: [
|
||||
'localMessageUnreadCounter',
|
||||
'mass_mailing',
|
||||
],
|
||||
}),
|
||||
displayName: attr({
|
||||
compute: '_computeDisplayName',
|
||||
dependencies: [
|
||||
|
||||
@@ -478,7 +478,7 @@ class MrpProduction(models.Model):
|
||||
production.state = 'done'
|
||||
elif production.workorder_ids and all(wo_state in ('done', 'cancel') for wo_state in production.workorder_ids.mapped('state')):
|
||||
production.state = 'to_close'
|
||||
elif not production.workorder_ids and production.qty_producing >= production.product_qty:
|
||||
elif not production.workorder_ids and float_compare(production.qty_producing, production.product_qty, precision_rounding=production.product_uom_id.rounding) >= 0:
|
||||
production.state = 'to_close'
|
||||
elif any(wo_state in ('progress', 'done') for wo_state in production.workorder_ids.mapped('state')):
|
||||
production.state = 'progress'
|
||||
|
||||
@@ -56,8 +56,10 @@ class AccountMove(models.Model):
|
||||
acquirer = payment_token.acquirer_id
|
||||
|
||||
if payment_token and payment_token.partner_id != partner:
|
||||
raise ValidationError(_('Invalid token found!'))
|
||||
|
||||
raise ValidationError(_(
|
||||
'The transaction was aborted because you are not the customer of this invoice. '
|
||||
'Log in as %s to be able to use this payment method.'
|
||||
) % partner.name)
|
||||
# Check an acquirer is there.
|
||||
if not acquirer_id and not acquirer:
|
||||
raise ValidationError(_('A payment acquirer is required to create a transaction.'))
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from flectra.addons.sale.tests.common import TestSaleCommon
|
||||
from flectra.tests.common import SavepointCase
|
||||
from flectra.tests import Form
|
||||
from flectra.tests import tagged
|
||||
|
||||
|
||||
class TestSaleStockOnly(TestSaleCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls, chart_template_ref=None):
|
||||
super().setUpClass(chart_template_ref=chart_template_ref)
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestSaleStockOnly(SavepointCase):
|
||||
|
||||
def test_automatic_assign(self):
|
||||
"""
|
||||
@@ -22,7 +20,7 @@ class TestSaleStockOnly(TestSaleCommon):
|
||||
self.env['stock.quant']._update_available_quantity(product, warehouse.lot_stock_id, 3)
|
||||
|
||||
so_form = Form(self.env['sale.order'])
|
||||
so_form.partner_id = self.partner_a
|
||||
so_form.partner_id = self.env['res.partner'].create({'name': 'Res Partner Test'})
|
||||
with so_form.order_line.new() as line:
|
||||
line.product_id = product
|
||||
line.product_uom_qty = 3
|
||||
|
||||
@@ -777,3 +777,9 @@ class SupplierInfo(models.Model):
|
||||
'label': _('Import Template for Vendor Pricelists'),
|
||||
'template': '/product/static/xls/product_supplierinfo.xls'
|
||||
}]
|
||||
|
||||
@api.constrains('product_id', 'product_tmpl_id')
|
||||
def _check_product_variant(self):
|
||||
for supplier in self:
|
||||
if supplier.product_id and supplier.product_tmpl_id and supplier.product_id.product_tmpl_id != supplier.product_tmpl_id:
|
||||
raise ValidationError(_('The product variant must be a variant of the product template.'))
|
||||
|
||||
@@ -660,7 +660,9 @@
|
||||
<field name="name" readonly="1"/>
|
||||
<field name="product_id" readonly="1" optional="hide"
|
||||
invisible="context.get('product_template_invisible_variant', False)"
|
||||
groups="product.group_product_variant"/>
|
||||
groups="product.group_product_variant"
|
||||
domain="[('product_tmpl_id', '=?', context.get('default_product_tmpl_id', False))]"
|
||||
options="{'no_quick_create': True, 'no_create_edit' : True}"/>
|
||||
<field name="product_tmpl_id" string="Product" readonly="1"
|
||||
invisible="context.get('visible_product_tmpl_id', True)"/>
|
||||
<field name="product_name" optional="hide"/>
|
||||
|
||||
@@ -99,16 +99,20 @@ class AccountMove(models.Model):
|
||||
|
||||
|
||||
price_unit = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
|
||||
if line.tax_ids and line.quantity:
|
||||
# We do not want to round the price unit since :
|
||||
# - It does not follow the currency precision
|
||||
# - It may include a discount
|
||||
# Since compute_all still rounds the total, we use an ugly workaround:
|
||||
# multiply then divide the price unit.
|
||||
price_unit *= line.quantity
|
||||
price_unit = line.tax_ids.with_context(round=False, force_sign=move._get_tax_force_sign()).compute_all(
|
||||
price_unit, currency=move.currency_id, quantity=1.0, is_refund=move.move_type == 'in_refund')['total_excluded']
|
||||
price_unit /= line.quantity
|
||||
if line.tax_ids:
|
||||
if line.discount and line.quantity:
|
||||
# We do not want to round the price unit since :
|
||||
# - It does not follow the currency precision
|
||||
# - It may include a discount
|
||||
# Since compute_all still rounds the total, we use an ugly workaround:
|
||||
# multiply then divide the price unit.
|
||||
price_unit *= line.quantity
|
||||
price_unit = line.tax_ids.with_context(round=False, force_sign=move._get_tax_force_sign()).compute_all(
|
||||
price_unit, currency=move.currency_id, quantity=1.0, is_refund=move.move_type == 'in_refund')['total_excluded']
|
||||
price_unit /= line.quantity
|
||||
else:
|
||||
price_unit = line.tax_ids.compute_all(
|
||||
price_unit, currency=move.currency_id, quantity=1.0, is_refund=move.move_type == 'in_refund')['total_excluded']
|
||||
|
||||
price_unit_val_dif = price_unit - valuation_price_unit
|
||||
price_subtotal = line.quantity * price_unit_val_dif
|
||||
|
||||
@@ -1326,3 +1326,28 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
|
||||
self.assertEqual(len(input_aml), 2, "Only two lines should have been generated in stock input account: one when receiving the product, one when making the invoice.")
|
||||
self.assertAlmostEqual(sum(input_aml.mapped('debit')), 90, "Total debit value on stock input account should be equal to the original PO price of the product.")
|
||||
self.assertAlmostEqual(sum(input_aml.mapped('credit')), 90, "Total credit value on stock input account should be equal to the original PO price of the product.")
|
||||
|
||||
def test_anglosaxon_valuation_price_unit_diff_avco(self):
|
||||
"""
|
||||
Inv: price unit: 100
|
||||
"""
|
||||
self.env.company.anglo_saxon_accounting = True
|
||||
self.product1.categ_id.property_cost_method = 'average'
|
||||
self.product1.categ_id.property_valuation = 'real_time'
|
||||
self.product1.categ_id.property_account_creditor_price_difference_categ = self.price_diff_account
|
||||
self.product1.standard_price = 1.01
|
||||
|
||||
invoice = self.env['account.move'].create({
|
||||
'move_type': 'in_invoice',
|
||||
'invoice_date': '2022-03-31',
|
||||
'partner_id': self.partner_id.id,
|
||||
'invoice_line_ids': [
|
||||
(0, 0, {'product_id': self.product1.id, 'quantity': 10.50, 'price_unit': 1.01, 'tax_ids': self.tax_purchase_a.ids})
|
||||
]
|
||||
})
|
||||
|
||||
invoice.action_post()
|
||||
|
||||
# Check if something was posted in the price difference account
|
||||
price_diff_aml = invoice.line_ids.filtered(lambda l: l.account_id == self.price_diff_account)
|
||||
self.assertEqual(len(price_diff_aml), 0, "No line should have been generated in the price difference account.")
|
||||
|
||||
@@ -6,6 +6,7 @@ from flectra.addons.stock_account.tests.test_anglo_saxon_valuation_reconciliatio
|
||||
from flectra.addons.sale.tests.common import TestSaleCommon
|
||||
from flectra.exceptions import UserError
|
||||
from flectra.tests import Form, tagged
|
||||
from flectra.tests.common import SavepointCase
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
@@ -1082,11 +1083,7 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon):
|
||||
self.assertEqual(so.order_line[1].product_uom.id, uom_km_id)
|
||||
|
||||
|
||||
class TestSaleStockOnly(TestSaleCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls, chart_template_ref=None):
|
||||
super().setUpClass(chart_template_ref=chart_template_ref)
|
||||
class TestSaleStockOnly(SavepointCase):
|
||||
|
||||
def test_no_automatic_assign(self):
|
||||
"""
|
||||
@@ -1099,7 +1096,7 @@ class TestSaleStockOnly(TestSaleCommon):
|
||||
self.env['stock.quant']._update_available_quantity(product, warehouse.lot_stock_id, 3)
|
||||
|
||||
so_form = Form(self.env['sale.order'])
|
||||
so_form.partner_id = self.partner_a
|
||||
so_form.partner_id = self.env['res.partner'].create({'name': 'Res Partner Test'})
|
||||
with so_form.order_line.new() as line:
|
||||
line.product_id = product
|
||||
line.product_uom_qty = 3
|
||||
|
||||
@@ -223,7 +223,8 @@ class ProductProduct(models.Model):
|
||||
quantity_svl = product.sudo().quantity_svl
|
||||
if float_compare(quantity_svl, 0.0, precision_rounding=product.uom_id.rounding) <= 0:
|
||||
continue
|
||||
diff = new_price - product.standard_price
|
||||
rounded_new_price = company_id.currency_id.round(new_price)
|
||||
diff = rounded_new_price - product.standard_price
|
||||
value = company_id.currency_id.round(quantity_svl * diff)
|
||||
if company_id.currency_id.is_zero(value):
|
||||
continue
|
||||
@@ -231,7 +232,7 @@ class ProductProduct(models.Model):
|
||||
svl_vals = {
|
||||
'company_id': company_id.id,
|
||||
'product_id': product.id,
|
||||
'description': _('Product value manually modified (from %s to %s)') % (product.standard_price, new_price),
|
||||
'description': _('Product value manually modified (from %s to %s)') % (product.standard_price, rounded_new_price),
|
||||
'value': value,
|
||||
'quantity': 0,
|
||||
}
|
||||
|
||||
@@ -125,6 +125,39 @@ class TestStockValuationLayerRevaluation(TestStockValuationCommon):
|
||||
self.assertEqual(len(credit_lines), 1)
|
||||
self.assertEqual(credit_lines[0].account_id.id, self.stock_valuation_account.id)
|
||||
|
||||
def test_stock_valuation_layer_revaluation_avco_rounding_2_digits(self):
|
||||
"""
|
||||
Check that the rounding of the new price (cost) is equivalent to the rounding of the standard price (cost)
|
||||
The check is done indirectly via the layers valuations.
|
||||
If correct => rounding method is correct too
|
||||
"""
|
||||
self.product1.categ_id.property_cost_method = 'average'
|
||||
|
||||
self.env['decimal.precision'].search([
|
||||
('name', '=', 'Product Price'),
|
||||
]).digits = 2
|
||||
self.product1.write({'standard_price': 0})
|
||||
|
||||
# First Move
|
||||
self.product1.write({'standard_price': 0.022})
|
||||
self._make_in_move(self.product1, 10000)
|
||||
|
||||
self.assertEqual(self.product1.standard_price, 0.02)
|
||||
self.assertEqual(self.product1.quantity_svl, 10000)
|
||||
|
||||
layer = self.product1.stock_valuation_layer_ids
|
||||
self.assertEqual(layer.value, 200)
|
||||
|
||||
# Second Move
|
||||
self.product1.write({'standard_price': 0.053})
|
||||
|
||||
self.assertEqual(self.product1.standard_price, 0.05)
|
||||
self.assertEqual(self.product1.quantity_svl, 10000)
|
||||
|
||||
layers = self.product1.stock_valuation_layer_ids
|
||||
self.assertEqual(layers[0].value, 200)
|
||||
self.assertEqual(layers[1].value, 300)
|
||||
|
||||
def test_stock_valuation_layer_revaluation_fifo(self):
|
||||
self.product1.categ_id.property_cost_method = 'fifo'
|
||||
context = {
|
||||
|
||||
@@ -3094,6 +3094,14 @@ var FieldRadio = FieldSelection.extend({
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @returns {boolean} always true
|
||||
*/
|
||||
isSet: function () {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the currently-checked radio button, or the first one if no radio
|
||||
* button is checked.
|
||||
|
||||
@@ -4910,8 +4910,16 @@ var BasicModel = AbstractModel.extend({
|
||||
var fieldNames = list.getFieldNames();
|
||||
var prom;
|
||||
if (list.__data) {
|
||||
// the data have already been fetched (alonside the groups by the
|
||||
// the data have already been fetched (alongside the groups by the
|
||||
// call to 'web_read_group'), so we can bypass the search_read
|
||||
// But the web_read_group returns the rawGroupBy field's value, which may not be present
|
||||
// in the view. So we filter it out.
|
||||
const fieldNameSet = new Set(fieldNames);
|
||||
fieldNameSet.add("id"); // don't filter out the id
|
||||
list.__data.records.forEach(record =>
|
||||
Object.keys(record)
|
||||
.filter(fieldName => !fieldNameSet.has(fieldName))
|
||||
.forEach(fieldName => delete record[fieldName]));
|
||||
prom = Promise.resolve(list.__data);
|
||||
} else {
|
||||
prom = this._rpc({
|
||||
|
||||
@@ -2023,34 +2023,6 @@ QUnit.module('relational_fields', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('required fieldradio widget on a many2one', async function (assert) {
|
||||
assert.expect(6);
|
||||
|
||||
const form = await createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form>' +
|
||||
'<field name="product_id" widget="radio" required="1"/>' +
|
||||
'</form>',
|
||||
});
|
||||
|
||||
testUtils.mock.intercept(form, 'call_service', function (event) {
|
||||
if (event.data.service === 'notification' && event.data.method === 'notify') {
|
||||
assert.step('danger');
|
||||
assert.equal(event.data.args[0].type, 'danger');
|
||||
assert.equal(event.data.args[0].title, 'Invalid fields:');
|
||||
assert.equal(event.data.args[0].message, '<ul><li>Product</li></ul>');
|
||||
}
|
||||
});
|
||||
|
||||
assert.containsNone(form, 'input:checked', "none of the input should be checked");
|
||||
|
||||
await testUtils.form.clickSave(form);
|
||||
assert.verifySteps(['danger']);
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('fieldradio change value by onchange', async function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
|
||||
@@ -7355,6 +7355,54 @@ QUnit.module('Views', {
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('multi edit in view grouped by field not in view', async function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
this.data.foo.records = [
|
||||
// group 1
|
||||
{id: 1, foo: '1', m2o: 1},
|
||||
{id: 3, foo: '2', m2o: 1},
|
||||
//group 2
|
||||
{id: 2, foo: '1', m2o: 2},
|
||||
{id: 4, foo: '2', m2o: 2},
|
||||
// group 3
|
||||
{id: 5, foo: '2', m2o: 3},
|
||||
];
|
||||
|
||||
const list = await createView({
|
||||
View: ListView,
|
||||
model: 'foo',
|
||||
data: this.data,
|
||||
arch: `<tree expand="1" multi_edit="1">
|
||||
<field name="foo"/>
|
||||
</tree>`,
|
||||
groupBy: ['m2o'],
|
||||
});
|
||||
|
||||
// Select items from the first group
|
||||
await testUtils.dom.click(list.$('.o_data_row .o_list_record_selector input:eq(0)'));
|
||||
await testUtils.dom.click(list.$('.o_data_row .o_list_record_selector input:eq(1)'));
|
||||
|
||||
await testUtils.dom.click(list.$('.o_list_char:eq(0)'));
|
||||
|
||||
await testUtils.fields.editInput(list.$('.o_field_widget[name=foo]'), 'test');
|
||||
|
||||
assert.containsOnce(document.body, '.modal');
|
||||
await testUtils.dom.click($('.modal .modal-footer .btn-primary'));
|
||||
assert.containsNone(document.body, '.modal');
|
||||
|
||||
const allNames = [...document.querySelectorAll('.o_data_cell')].map(n => n.textContent);
|
||||
assert.deepEqual(allNames, [
|
||||
'test',
|
||||
'test',
|
||||
'1',
|
||||
'2',
|
||||
'2',
|
||||
]);
|
||||
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('multi edit reference field batched in grouped list', async function (assert) {
|
||||
assert.expect(18);
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
.s_latest_posts_post_title {
|
||||
@include font-size($h3-font-size);
|
||||
margin-bottom: 0.5em;
|
||||
word-spacing: -0.15em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@
|
||||
.s_latest_posts_post_title {
|
||||
@include font-size($h3-font-size);
|
||||
margin-bottom: 0.5em;
|
||||
word-spacing: -0.15em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
from flectra import api, models, _
|
||||
from flectra.exceptions import UserError
|
||||
from flectra.osv import expression
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
@@ -71,8 +72,10 @@ class SaleOrder(models.Model):
|
||||
if ticket.id:
|
||||
self = self.with_context(event_ticket_id=ticket.id, fixed_price=1)
|
||||
else:
|
||||
line = None
|
||||
ticket = self.env['event.event.ticket'].search([('product_id', '=', product_id)], limit=1)
|
||||
ticket_domain = [('product_id', '=', product_id)]
|
||||
if self.env.context.get("event_ticket_id"):
|
||||
ticket_domain = expression.AND([ticket_domain, [('id', '=', self.env.context['event_ticket_id'])]])
|
||||
ticket = self.env['event.event.ticket'].search(ticket_domain, limit=1)
|
||||
old_qty = 0
|
||||
new_qty = set_qty if set_qty else (add_qty or 0 + old_qty)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user