summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2018-05-02 19:36:16 +0200
committerChristophe Simonis <chs@odoo.com>2018-05-02 19:36:16 +0200
commit87e21ccdc5c181960fa0d137e3ed880673032ca9 (patch)
tree5aa3efc5a04796733c242129d91343149839abcb
parent3596e67afb72aac22d9a71ddf542cc5bbe00bce0 (diff)
parent521414b1c106187ceac972ba7ae6f5c342959940 (diff)
[MERGE] forward port branch 11.0 up to 521414b1c10
-rw-r--r--addons/account/models/account_move.py21
-rw-r--r--addons/account/models/partner.py9
-rw-r--r--addons/account/static/src/js/reconciliation/reconciliation_model.js4
-rw-r--r--addons/account/tests/test_reconciliation.py48
-rw-r--r--addons/account_check_printing/models/account_payment.py2
-rw-r--r--addons/barcodes/static/src/js/barcode_events.js6
-rw-r--r--addons/base_vat_autocomplete/models/res_partner.py3
-rw-r--r--addons/delivery/models/stock_picking.py2
-rw-r--r--addons/delivery/tests/test_delivery_cost.py4
-rw-r--r--addons/hr_expense/models/hr_expense.py3
-rw-r--r--addons/l10n_be/i18n_extra/nl_BE.po453
-rw-r--r--addons/l10n_do/models/chart_template.py43
-rw-r--r--addons/l10n_fr_certification/data/account_move.xml2
-rw-r--r--addons/l10n_fr_pos_cert/data/pos_inalterability.xml1
-rw-r--r--addons/mail/models/mail_activity.py3
-rw-r--r--addons/mail/static/src/js/services/chat_manager.js8
-rw-r--r--addons/mrp/models/mrp_production.py2
-rw-r--r--addons/payment/models/__init__.py1
-rw-r--r--addons/payment/models/chart_template.py14
-rw-r--r--addons/payment/models/payment_acquirer.py72
-rw-r--r--addons/payment/views/payment_views.xml4
-rw-r--r--addons/payment_adyen/__init__.py1
-rw-r--r--addons/payment_adyen/__manifest__.py1
-rw-r--r--addons/payment_authorize/__init__.py1
-rw-r--r--addons/payment_authorize/__manifest__.py1
-rw-r--r--addons/payment_buckaroo/__init__.py1
-rw-r--r--addons/payment_buckaroo/__manifest__.py1
-rw-r--r--addons/payment_ogone/__init__.py1
-rw-r--r--addons/payment_ogone/__manifest__.py1
-rw-r--r--addons/payment_paypal/__init__.py1
-rw-r--r--addons/payment_paypal/__manifest__.py1
-rw-r--r--addons/payment_payumoney/__init__.py1
-rw-r--r--addons/payment_payumoney/__manifest__.py1
-rw-r--r--addons/payment_sips/__init__.py1
-rw-r--r--addons/payment_sips/__manifest__.py1
-rw-r--r--addons/payment_stripe/__init__.py1
-rw-r--r--addons/payment_stripe/__manifest__.py1
-rw-r--r--addons/payment_transfer/__init__.py1
-rw-r--r--addons/payment_transfer/__manifest__.py1
-rw-r--r--addons/payment_transfer/models/payment.py13
-rw-r--r--addons/product/models/product.py11
-rw-r--r--addons/product/tests/test_variants.py9
-rw-r--r--addons/purchase/models/account_invoice.py5
-rw-r--r--addons/purchase/models/purchase.py4
-rw-r--r--addons/purchase/tests/test_stockvaluation.py137
-rw-r--r--addons/sale_payment/models/payment.py13
-rw-r--r--addons/stock/models/stock_move.py48
-rw-r--r--addons/stock/tests/test_move.py227
-rw-r--r--addons/stock/tests/test_move2.py32
-rw-r--r--addons/stock_account/models/stock.py19
-rw-r--r--addons/web/static/src/js/core/ajax.js8
-rw-r--r--addons/web/static/src/js/services/data_manager.js19
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js42
-rw-r--r--addons/web/static/src/js/views/calendar/calendar_view.js16
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_model.js8
-rw-r--r--addons/web/static/src/js/views/list/list_editable_renderer.js7
-rw-r--r--addons/web/static/src/js/views/pivot/pivot_model.js6
-rw-r--r--addons/web/static/src/less/list_view.less8
-rw-r--r--addons/web/static/tests/fields/relational_fields_tests.js46
-rw-r--r--addons/web/static/tests/helpers/mock_server.js6
-rw-r--r--addons/web/static/tests/views/calendar_tests.js95
-rw-r--r--addons/web/static/tests/views/kanban_tests.js41
-rw-r--r--addons/web/static/tests/views/pivot_tests.js33
-rw-r--r--addons/web/tests/test_js.py4
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/module/Clipboard.js287
-rw-r--r--addons/web_editor/static/src/js/editor/rte.summernote.js2
-rw-r--r--addons/website_quote/controllers/main.py9
-rw-r--r--addons/website_sale/controllers/main.py9
-rw-r--r--addons/website_slides/controllers/main.py7
-rw-r--r--addons/website_slides/models/slides.py7
-rw-r--r--doc/cla/individual/nomadic-coding.md11
-rw-r--r--doc/reference/views.rst4
-rw-r--r--odoo/addons/base/models/res_currency.py1
73 files changed, 1078 insertions, 839 deletions
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
index 0c4aebef0ab..a6288da6a22 100644
--- a/addons/account/models/account_move.py
+++ b/addons/account/models/account_move.py
@@ -102,8 +102,7 @@ class AccountMove(models.Model):
partner_id = fields.Many2one('res.partner', compute='_compute_partner_id', string="Partner", store=True, readonly=True)
amount = fields.Monetary(compute='_amount_compute', store=True)
narration = fields.Text(string='Internal Note')
- company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', store=True, readonly=True,
- default=lambda self: self.env.user.company_id)
+ company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', store=True, readonly=True)
matched_percentage = fields.Float('Percentage Matched', compute='_compute_matched_percentage', digits=0, store=True, readonly=True, help="Technical field used in cash basis method")
# Dummy Account field to search on account.move by account_id
dummy_account_id = fields.Many2one('account.account', related='line_ids.account_id', string='Account', store=False, readonly=True)
@@ -1174,19 +1173,22 @@ class AccountMoveLine(models.Model):
#create an empty move that will hold all the exchange rate adjustments
exchange_move = False
- if aml_to_balance_currency:
+ if aml_to_balance_currency and any([residual for dummy, residual in aml_to_balance_currency.values()]):
exchange_move = self.env['account.move'].create(
self.env['account.full.reconcile']._prepare_exchange_diff_move(move_date=maxdate, company=self[0].company_id))
for currency, values in aml_to_balance_currency.items():
aml_to_balance = values[0]
total_amount_currency = values[1]
- #eventually create journal entries to book the difference due to foreign currency's exchange rate that fluctuates
- aml_recs, partial_recs = self.env['account.partial.reconcile'].create_exchange_rate_entry(aml_to_balance, 0.0, total_amount_currency, currency, exchange_move)
+ if total_amount_currency:
+ #eventually create journal entries to book the difference due to foreign currency's exchange rate that fluctuates
+ aml_recs, partial_recs = self.env['account.partial.reconcile'].create_exchange_rate_entry(aml_to_balance, 0.0, total_amount_currency, currency, exchange_move)
- #add the exchange rate line and the exchange rate partial reconciliation in the et of the full reconcile
- self |= aml_recs
- partial_rec_set |= partial_recs
+ # add the exchange rate line and the exchange rate partial reconciliation in the et of the full reconcile
+ self |= aml_recs
+ partial_rec_set |= partial_recs
+ else:
+ aml_to_balance.reconcile()
if exchange_move:
exchange_move.post()
@@ -1214,8 +1216,9 @@ class AccountMoveLine(models.Model):
rec_move_ids += account_move_line.matched_credit_ids
if self.env.context.get('invoice_id'):
current_invoice = self.env['account.invoice'].browse(self.env.context['invoice_id'])
+ aml_to_keep = current_invoice.move_id.line_ids | current_invoice.move_id.line_ids.mapped('full_reconcile_id.exchange_move_id.line_ids')
rec_move_ids = rec_move_ids.filtered(
- lambda r: (r.debit_move_id + r.credit_move_id) & current_invoice.move_id.line_ids
+ lambda r: (r.debit_move_id + r.credit_move_id) & aml_to_keep
)
return rec_move_ids.unlink()
diff --git a/addons/account/models/partner.py b/addons/account/models/partner.py
index 40b1cd90ff5..4590fc250da 100644
--- a/addons/account/models/partner.py
+++ b/addons/account/models/partner.py
@@ -394,8 +394,7 @@ class ResPartner(models.Model):
required=True)
property_account_position_id = fields.Many2one('account.fiscal.position', company_dependent=True,
string="Fiscal Position",
- help="The fiscal position will determine taxes and accounts used for the partner.", oldname="property_account_position",
- domain="[('company_id', 'in', [company_id, False])]")
+ help="The fiscal position will determine taxes and accounts used for the partner.", oldname="property_account_position")
property_payment_term_id = fields.Many2one('account.payment.term', company_dependent=True,
string='Customer Payment Terms',
help="This payment term will be used instead of the default one for sales orders and customer invoices", oldname="property_payment_term")
@@ -445,5 +444,9 @@ class ResPartner(models.Model):
@api.onchange('company_id')
def _onchange_company_id(self):
+ company = self.env['res.company']
if self.company_id:
- return {'domain': {'property_account_position_id': [('company_id', 'in', [self.company_id.id, False])]}}
+ company = self.company_id
+ else:
+ company = self.env.user.company_id
+ return {'domain': {'property_account_position_id': [('company_id', 'in', [company.id, False])]}}
diff --git a/addons/account/static/src/js/reconciliation/reconciliation_model.js b/addons/account/static/src/js/reconciliation/reconciliation_model.js
index 7b80e0bbaa7..0df19adea56 100644
--- a/addons/account/static/src/js/reconciliation/reconciliation_model.js
+++ b/addons/account/static/src/js/reconciliation/reconciliation_model.js
@@ -990,6 +990,7 @@ var StatementModel = BasicModel.extend({
var formatOptions = {
currency_id: line.st_line.currency_id,
};
+ var amount = values.amount !== undefined ? values.amount : line.balance.amount;
var prop = {
'id': _.uniqueId('createLine'),
'label': values.label || line.st_line.name,
@@ -1002,8 +1003,7 @@ var StatementModel = BasicModel.extend({
'debit': 0,
'credit': 0,
'base_amount': values.amount_type !== "percentage" ?
- (values.amount || line.balance.amount) :
- line.balance.amount * values.amount / 100,
+ (amount) : line.balance.amount * values.amount / 100,
'percent': values.amount_type === "percentage" ? values.amount : null,
'link': values.link,
'display': true,
diff --git a/addons/account/tests/test_reconciliation.py b/addons/account/tests/test_reconciliation.py
index 09945c6e15b..4a50c812620 100644
--- a/addons/account/tests/test_reconciliation.py
+++ b/addons/account/tests/test_reconciliation.py
@@ -661,6 +661,54 @@ class TestReconciliation(AccountingTestCase):
self.assertAlmostEquals(inv1.residual, 10)
self.assertAlmostEquals(inv2.residual, 20)
+ def test_unreconcile_exchange(self):
+ # Use case:
+ # - Company currency in EUR
+ # - Create 2 rates for USD:
+ # 1.0 on 2018-01-01
+ # 0.5 on 2018-02-01
+ # - Create an invoice on 2018-01-02 of 111 USD
+ # - Register a payment on 2018-02-02 of 111 USD
+ # - Unreconcile the payment
+
+ self.env['res.currency.rate'].create({
+ 'name': time.strftime('%Y') + '-07-01',
+ 'rate': 1.0,
+ 'currency_id': self.currency_usd_id,
+ 'company_id': self.env.ref('base.main_company').id
+ })
+ self.env['res.currency.rate'].create({
+ 'name': time.strftime('%Y') + '-08-01',
+ 'rate': 0.5,
+ 'currency_id': self.currency_usd_id,
+ 'company_id': self.env.ref('base.main_company').id
+ })
+ inv = self.create_invoice(invoice_amount=111, currency_id=self.currency_usd_id)
+ payment = self.env['account.payment'].create({
+ 'payment_type': 'inbound',
+ 'payment_method_id': self.env.ref('account.account_payment_method_manual_in').id,
+ 'partner_type': 'customer',
+ 'partner_id': self.partner_agrolait_id,
+ 'amount': 111,
+ 'currency_id': self.currency_usd_id,
+ 'journal_id': self.bank_journal_usd.id,
+ 'payment_date': time.strftime('%Y') + '-08-01',
+ })
+ payment.post()
+ credit_aml = payment.move_line_ids.filtered('credit')
+
+ # Check residual before assignation
+ self.assertAlmostEquals(inv.residual, 111)
+
+ # Assign credit, check exchange move and residual
+ inv.assign_outstanding_credit(credit_aml.id)
+ self.assertEqual(len(payment.move_line_ids.mapped('full_reconcile_id').exchange_move_id), 1)
+ self.assertAlmostEquals(inv.residual, 0)
+
+ # Unreconcile invoice and check residual
+ credit_aml.with_context(invoice_id=inv.id).remove_move_reconcile()
+ self.assertAlmostEquals(inv.residual, 111)
+
def test_partial_reconcile_currencies_02(self):
####
# Day 1: Invoice Cust/001 to customer (expressed in USD)
diff --git a/addons/account_check_printing/models/account_payment.py b/addons/account_check_printing/models/account_payment.py
index 4edf4517ba2..61ed7176ca1 100644
--- a/addons/account_check_printing/models/account_payment.py
+++ b/addons/account_check_printing/models/account_payment.py
@@ -34,7 +34,7 @@ class AccountRegisterPayments(models.TransientModel):
res = super(AccountRegisterPayments, self)._prepare_payment_vals(invoices)
if self.payment_method_id == self.env.ref('account_check_printing.account_payment_method_check'):
res.update({
- 'check_manual_sequencing': self.check_manual_sequencing,
+ 'check_amount_in_words': self.check_amount_in_words,
})
return res
diff --git a/addons/barcodes/static/src/js/barcode_events.js b/addons/barcodes/static/src/js/barcode_events.js
index 71e07030ffd..a2e5808f8be 100644
--- a/addons/barcodes/static/src/js/barcode_events.js
+++ b/addons/barcodes/static/src/js/barcode_events.js
@@ -53,7 +53,7 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, {
navigator.userAgent.match(/iPod/i) ||
navigator.userAgent.match(/BlackBerry/i) ||
navigator.userAgent.match(/Windows Phone/i);
- this.isChromeMobile = isMobile && window.chrome;
+ this.isChromeMobile = isMobile && navigator.userAgent.match(/Chrome/i);
// Creates an input who will receive the barcode scanner value.
if (this.isChromeMobile) {
@@ -61,7 +61,9 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, {
name: 'barcode',
type: 'text',
css: {
- 'position': 'absolute',
+ 'position': 'fixed',
+ 'top': '50%',
+ 'transform': 'translateY(-50%)',
'opacity': 0,
},
});
diff --git a/addons/base_vat_autocomplete/models/res_partner.py b/addons/base_vat_autocomplete/models/res_partner.py
index 93d74c497f8..f62c2e53b8c 100644
--- a/addons/base_vat_autocomplete/models/res_partner.py
+++ b/addons/base_vat_autocomplete/models/res_partner.py
@@ -12,6 +12,9 @@ _logger = logging.getLogger(__name__)
try:
import stdnum.eu.vat as stdnum_vat
+ if not hasattr(stdnum_vat, "country_codes"):
+ # stdnum version >= 1.9
+ stdnum_vat.country_codes = stdnum_vat._country_codes
except ImportError:
_logger.warning('Python `stdnum` library not found, unable to call VIES service to detect address based on VAT number.')
stdnum_vat = None
diff --git a/addons/delivery/models/stock_picking.py b/addons/delivery/models/stock_picking.py
index 5b993bc68a1..d58c77972f1 100644
--- a/addons/delivery/models/stock_picking.py
+++ b/addons/delivery/models/stock_picking.py
@@ -159,6 +159,8 @@ class StockPicking(models.Model):
def send_to_shipper(self):
self.ensure_one()
res = self.carrier_id.send_shipping(self)[0]
+ if self.carrier_id.free_over and self.sale_id._compute_amount_total_without_delivery() >= self.carrier_id.amount:
+ res['exact_price'] = 0.0
self.carrier_price = res['exact_price']
self.carrier_tracking_ref = res['tracking_number']
order_currency = self.sale_id.currency_id or self.company_id.currency_id
diff --git a/addons/delivery/tests/test_delivery_cost.py b/addons/delivery/tests/test_delivery_cost.py
index d027906ef6a..62ffc253328 100644
--- a/addons/delivery/tests/test_delivery_cost.py
+++ b/addons/delivery/tests/test_delivery_cost.py
@@ -30,7 +30,9 @@ class TestDeliveryCost(common.TransactionCase):
self.free_delivery = self.env.ref('delivery.free_delivery_carrier')
# as the tests hereunder assume all the prices in USD, we must ensure
# that the company actually uses USD
- self.env.user.company_id.write({'currency_id': self.env.ref('base.USD').id})
+ self.env.cr.execute(
+ "UPDATE res_company SET currency_id = %s WHERE id = %s",
+ [self.env.ref('base.USD').id, self.env.user.company_id.id])
def test_00_delivery_cost(self):
# In order to test Carrier Cost
diff --git a/addons/hr_expense/models/hr_expense.py b/addons/hr_expense/models/hr_expense.py
index 3e96acb2bb7..b86ed7b050d 100644
--- a/addons/hr_expense/models/hr_expense.py
+++ b/addons/hr_expense/models/hr_expense.py
@@ -418,6 +418,7 @@ class HrExpense(models.Model):
expense_description = expense_description.replace(product_code.group(), '')
products = self.env['product.product'].search([('default_code', 'ilike', product_code.group(1))]) or default_product
product = products.filtered(lambda p: p.default_code == product_code.group(1)) or products[0]
+ account = product.product_tmpl_id._get_product_accounts()['expense']
pattern = '[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?'
# Match the last occurence of a float in the string
@@ -444,6 +445,8 @@ class HrExpense(models.Model):
'unit_amount': price,
'company_id': employee.company_id.id,
})
+ if account:
+ custom_values['account_id'] = account.id
return super(HrExpense, self).message_new(msg_dict, custom_values)
diff --git a/addons/l10n_be/i18n_extra/nl_BE.po b/addons/l10n_be/i18n_extra/nl_BE.po
index 88d6c4b61ee..2a4b067ee33 100644
--- a/addons/l10n_be/i18n_extra/nl_BE.po
+++ b/addons/l10n_be/i18n_extra/nl_BE.po
@@ -18,935 +18,774 @@ msgstr ""
"X-Generator: Poedit 1.8.12\n"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-00
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-00
msgid "0% Biens d'investissement"
msgstr "0% Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-00-G
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-00-G
msgid "0% Biens divers"
msgstr "0% Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-OUT-00-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-OUT-00-CC
msgid "0% Cocont."
msgstr "0% Medecont."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-00-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-00-CC
msgid "0% Cocont. - Biens d'investissement"
msgstr "0% Medecont. - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-00-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-00-CC
msgid "0% Cocont. M."
msgstr "0% Medecont. G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-00-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-00-CC
msgid "0% Cocont. S."
msgstr "0% Medecont. D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-00-EU
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-00-EU
msgid "0% EU - Biens d'investissement"
msgstr "0% EU - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-00-EU-G
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-00-EU-G
msgid "0% EU - Biens divers"
msgstr "0% EU - Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-00-EU
-#: model:account.tax,name:l10n_be.1_attn_VAT-OUT-00-EU-L
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-00-EU
#: model:account.tax.template,name:l10n_be.attn_VAT-OUT-00-EU-L
msgid "0% EU M."
msgstr "0% EU G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-00-EU-S
-#: model:account.tax,name:l10n_be.1_attn_VAT-OUT-00-EU-S
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-00-EU-S
#: model:account.tax.template,name:l10n_be.attn_VAT-OUT-00-EU-S
msgid "0% EU S."
msgstr "0% EU D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-OUT-00-EU-T
#: model:account.tax.template,name:l10n_be.attn_VAT-OUT-00-EU-T
msgid "0% EU T."
msgstr "0% EU. T."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-00
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-00
msgid "0% M."
msgstr "0% G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-OUT-00-ROW
#: model:account.tax.template,name:l10n_be.attn_VAT-OUT-00-ROW
msgid "0% Non EU"
msgstr "0% Non EU"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-00-ROW-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-00-ROW-CC
msgid "0% Non EU - Biens d'investissement"
msgstr "0% Niet EU - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-00-ROW-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-00-ROW-CC
msgid "0% Non EU M."
msgstr "0% Non EU G. "
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-00-ROW-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-00-ROW-CC
msgid "0% Non EU S."
msgstr "0% Non EU D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-00-S
-#: model:account.tax,name:l10n_be.1_attn_VAT-OUT-00-S
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-00-S
#: model:account.tax.template,name:l10n_be.attn_VAT-OUT-00-S
msgid "0% S."
msgstr "0% D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-OUT-12-L
#: model:account.tax.template,name:l10n_be.attn_VAT-OUT-12-L
msgid "12%"
msgstr "12%"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-12
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-12
msgid "12% Biens d'investissement"
msgstr "12% Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-G
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-G
msgid "12% Biens divers"
msgstr "12% Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-12-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-12-CC
msgid "12% Cocont. - Biens d'investissement"
msgstr "12% Medecont. - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-12-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-12-CC-C1
msgid "12% Cocont. Déductible - Biens d'investissement"
msgstr "12% Medecont. Aftrekbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-12-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-12-CC-C1
msgid "12% Cocont. Déductible M."
msgstr "12% Medecont. Aftrekbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-CC-C1
msgid "12% Cocont. Déductible S."
msgstr "12% Medecont. Aftrekbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-12-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-12-CC
msgid "12% Cocont. M."
msgstr "12% Medecont. G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-12-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-12-CC-C2
msgid "12% Cocont. Récupérable - Biens d'investissement"
msgstr "12% Medecont. Verhaalbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-12-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-12-CC-C2
msgid "12% Cocont. Récupérable M."
msgstr "12% Medecont. Verhaalbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-CC-C2
msgid "12% Cocont. Récupérable S."
msgstr "12% Medecont. Verhaalbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-CC
msgid "12% Cocont. S."
msgstr "12% Medecont. D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-12-EU
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-12-EU
msgid "12% EU - Biens d'investissement"
msgstr "12% EU - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-EU-G
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-EU-G
msgid "12% EU - Biens divers"
msgstr "12% EU - Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-12-EU-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-12-EU-C1
msgid "12% EU Déductible - Biens d'investissement"
msgstr "12% EU Aftrekbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-EU-G-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-EU-G-C1
msgid "12% EU Déductible - Biens divers"
msgstr "12% EU Aftrekbaar - Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-12-EU-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-12-EU-C1
msgid "12% EU Déductible M."
msgstr "12% EU Aftrekbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-EU-S-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-EU-S-C1
msgid "12% EU Déductible S."
msgstr "12% EU Aftrekbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-12-EU
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-12-EU
msgid "12% EU M."
msgstr "12% EU G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-12-EU-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-12-EU-C2
msgid "12% EU Récupérable - Biens d'investissement"
msgstr "12% EU Verhaalbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-12-EU-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-12-EU-C2
msgid "12% EU Récupérable M."
msgstr "12% EU Verhaalbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-EU-S-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-EU-S-C2
msgid "12% EU Récupérable S."
msgstr "12% EU Verhaalbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-EU-S
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-EU-S
msgid "12% EU S."
msgstr "12% EU D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-12
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-12
msgid "12% M."
msgstr "12% G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-12-ROW-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-12-ROW-CC
msgid "12% Non EU - Biens d'investissement"
msgstr "12% Niet EU - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-12-ROW-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-12-ROW-CC-C1
msgid "12% Non EU Déductible - Biens d'investissement"
msgstr "12% Niet EU Aftrekbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-12-ROW-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-12-ROW-CC-C1
msgid "12% Non EU Déductible M."
msgstr "12% Non EU Aftrekbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-ROW-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-ROW-CC-C1
msgid "12% Non EU Déductible S."
msgstr "12% Niet EU Aftrekbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-12-ROW-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-12-ROW-CC
msgid "12% Non EU M."
msgstr "12% Niet EU G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-12-ROW-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-12-ROW-CC-C2
msgid "12% Non EU Récupérable - Biens d'investissement"
msgstr "12% Niet EU Verhaalbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-12-ROW-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-12-ROW-CC-C2
msgid "12% Non EU Récupérable M."
msgstr "12% Niet EU Verhaalbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-ROW-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-ROW-CC-C2
msgid "12% Non EU Récupérable S."
msgstr "12% Non EU Verhaalbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-ROW-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-ROW-CC
msgid "12% Non EU S."
msgstr "12% Niet EU D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-S
-#: model:account.tax,name:l10n_be.1_attn_VAT-OUT-12-S
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-S
#: model:account.tax.template,name:l10n_be.attn_VAT-OUT-12-S
msgid "12% S."
msgstr "12% D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-OUT-21-L
#: model:account.tax.template,name:l10n_be.attn_VAT-OUT-21-L
msgid "21%"
msgstr "21%"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-21
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-21
msgid "21% Biens d'investissement"
msgstr "21% Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-G
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-G
msgid "21% Biens divers"
msgstr "21% Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-CC
msgid "21% Cocont .S."
msgstr "21% Medecont. D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-21-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-21-CC
msgid "21% Cocont. - Biens d'investissement"
msgstr "21% Medecont. - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-21-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-21-CC-C1
msgid "21% Cocont. Déductible - Biens d'investissement"
msgstr "21% Medecont. Aftrekbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-21-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-21-CC-C1
msgid "21% Cocont. Déductible M."
msgstr "21% Medecont. Aftrekbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-CC-C1
msgid "21% Cocont. Déductible S."
msgstr "21% Medecont. Aftrekbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-21-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-21-CC
msgid "21% Cocont. M."
msgstr "21% Medecont. G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-21-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-21-CC-C2
msgid "21% Cocont. Récupérable - Biens d'investissement"
msgstr "21% Medecont. Verhaalbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-21-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-21-CC-C2
msgid "21% Cocont. Récupérable M."
msgstr "21% Medecont. Verhaalbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-CC-C2
msgid "21% Cocont. Récupérable S."
msgstr "21% Medecont. Verhaalbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-21-EU
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-21-EU
msgid "21% EU - Biens d'investissement"
msgstr "21% EU - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-EU-G
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-EU-G
msgid "21% EU - Biens divers"
msgstr "21% EU - Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-21-EU-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-21-EU-C1
msgid "21% EU Déductible - Biens d'investissement"
msgstr "21% EU Aftrekbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-EU-G-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-EU-G-C1
msgid "21% EU Déductible - Biens divers"
msgstr "21% EU Aftrekbaar - Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-21-EU-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-21-EU-C1
msgid "21% EU Déductible M."
msgstr "21% EU Aftrekbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-EU-S-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-EU-S-C1
msgid "21% EU Déductible S."
msgstr "21% EU Aftrekbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-21-EU
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-21-EU
msgid "21% EU M."
msgstr "21% EU. G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-21-EU-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-21-EU-C2
msgid "21% EU Récupérable - Biens d'investissement"
msgstr "21% EU Verhaalbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-EU-G-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-EU-G-C2
msgid "21% EU Récupérable - Biens divers"
msgstr "21% EU Verhaalbaar - Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-21-EU-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-21-EU-C2
msgid "21% EU Récupérable M."
msgstr "21% EU Verhaalbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-EU-S-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-EU-S-C2
msgid "21% EU Récupérable S."
msgstr "21% EU Verhaalbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-EU-S
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-EU-S
msgid "21% EU S."
msgstr "21% EU D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-21
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-21
msgid "21% M."
msgstr "21% G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-21-ROW-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-21-ROW-CC
msgid "21% Non EU - Biens d'investissement"
msgstr "21% Niet EU - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-21-ROW-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-21-ROW-CC-C1
msgid "21% Non EU Déductible - Biens d'investissement"
msgstr "21% Non EU Aftrekbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-21-ROW-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-21-ROW-CC-C1
msgid "21% Non EU Déductible M."
msgstr "21% Non EU Aftrekbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-ROW-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-ROW-CC-C1
msgid "21% Non EU Déductible S."
msgstr "21% Non EU Aftrekbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-21-ROW-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-21-ROW-CC
msgid "21% Non EU M."
msgstr "21% Niet EU G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-21-ROW-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-21-ROW-CC-C2
msgid "21% Non EU Récupérable - Biens d'investissement"
msgstr "21% Non EU Verhaalbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-21-ROW-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-21-ROW-CC-C2
msgid "21% Non EU Récupérable M."
msgstr "21% Non EU Verhaalbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-ROW-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-ROW-CC-C2
msgid "21% Non EU Récupérable S."
msgstr "21% Niet EU Verhaalbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-ROW-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-ROW-CC
msgid "21% Non EU S."
msgstr "21% Non EU D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-21-S
-#: model:account.tax,name:l10n_be.1_attn_VAT-OUT-21-S
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-21-S
#: model:account.tax.template,name:l10n_be.attn_VAT-OUT-21-S
msgid "21% S."
msgstr "21% D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_TVA-21-inclus-dans-prix
#: model:account.tax.template,name:l10n_be.attn_TVA-21-inclus-dans-prix
msgid "21% S. TTC"
msgstr "21% D. (Inclusief BTW)"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-CAR-EXC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-CAR-EXC-C2
msgid "50% Déductible - Frais de voiture (Prix Excl.)"
msgstr "50% Aftrekbaar - Autokosten (Prijs Excl.)"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-CAR-EXC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-CAR-EXC-C1
msgid "50% Non Déductible - Frais de voiture"
msgstr "50% Niet Aftrekbaar - Autokosten"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-CAR-EXC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-CAR-EXC
msgid "50% Non Déductible - Frais de voiture (Prix Excl.)"
msgstr "50% Niet Aftrekbaar - Autokosten (Prijs Excl.)"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-06
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-06
msgid "6% Biens d'investissement"
msgstr "6% Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-G
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-G
msgid "6% Biens divers"
msgstr "6% Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-06-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-06-CC
msgid "6% Cocont. - Biens d'investissement"
msgstr "6% Medecont. - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-06-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-06-CC-C1
msgid "6% Cocont. Déductible - Biens d'investissement"
msgstr "6% Medecont. Aftrekbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-06-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-06-CC-C1
msgid "6% Cocont. Déductible M."
msgstr "6% Medecont. Aftrekbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-CC-C1
msgid "6% Cocont. Déductible S."
msgstr "6% Medecont. Aftrekbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-06-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-06-CC
msgid "6% Cocont. M."
msgstr "6% Medecont. G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-06-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-06-CC-C2
msgid "6% Cocont. Récupérable - Biens d'investissement"
msgstr "6% Medecont. Verhaalbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-06-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-06-CC-C2
msgid "6% Cocont. Récupérable M."
msgstr "6% Medecont. Verhaalbaar G. "
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-CC-C2
msgid "6% Cocont. Récupérable S."
msgstr "6% Medecont. Verhaalbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-CC
msgid "6% Cocont. S."
msgstr "6% Medecont. D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-06-EU
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-06-EU
msgid "6% EU - Biens d'investissement"
msgstr "6% EU - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-EU-G
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-EU-G
msgid "6% EU - Biens divers"
msgstr "6% EU - Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-06-EU-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-06-EU-C1
msgid "6% EU Déductible - Biens d'investissement"
msgstr "6% EU Aftrekbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-EU-G-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-EU-G-C1
msgid "6% EU Déductible - Biens divers"
msgstr "6% EU Aftrekbaar - Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-06-EU-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-06-EU-C1
msgid "6% EU Déductible M."
msgstr "6% EU Aftrekbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-EU-S-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-EU-S-C1
msgid "6% EU Déductible S."
msgstr "6% EU Aftrekbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-06-EU
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-06-EU
msgid "6% EU M."
msgstr "6% EU G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-06-EU-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-06-EU-C2
msgid "6% EU Récupérable - Biens d'investissement"
msgstr "6% EU Verhaalbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-EU-G-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-EU-G-C2
msgid "6% EU Récupérable - Biens divers"
msgstr "6% EU Verhaalbaar - Diverse goederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-06-EU-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-06-EU-C2
msgid "6% EU Récupérable M."
msgstr "6% EU Verhaalbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-EU-S-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-EU-S-C2
msgid "6% EU Récupérable S."
msgstr "6% EU Verhaalbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-EU-S
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-EU-S
msgid "6% EU S."
msgstr "6% EU D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-06
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-06
msgid "6% M."
msgstr "6% G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-06-ROW-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-06-ROW-CC
msgid "6% Non EU - Biens d'investissement"
msgstr "6% Niet EU - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-06-ROW-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-06-ROW-CC-C1
msgid "6% Non EU Déductible - Biens d'investissement"
msgstr "6% Niet EU Aftrekbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-06-ROW-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-06-ROW-CC-C1
msgid "6% Non EU Déductible M."
msgstr "6% Niet EU Aftrekbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-ROW-CC-C1
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-ROW-CC-C1
msgid "6% Non EU Déductible S."
msgstr "6% Niet EU Aftrekbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-06-ROW-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-06-ROW-CC
msgid "6% Non EU M."
msgstr "6% Niet EU G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V83-06-ROW-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V83-06-ROW-CC-C2
msgid "6% Non EU Récupérable - Biens d'investissement"
msgstr "6% Non EU Verhaalbaar - Investeringsgoederen"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V81-06-ROW-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V81-06-ROW-CC-C2
msgid "6% Non EU Récupérable M."
msgstr "6% Niet EU Verhaalbaar G."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-ROW-CC-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-ROW-CC-C2
msgid "6% Non EU Récupérable S."
msgstr "6% Niet EU Verhaalbaar D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-ROW-CC
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-ROW-CC
msgid "6% Non EU S."
msgstr "6% Niet EU D."
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-06-S
-#: model:account.tax,name:l10n_be.1_attn_VAT-OUT-06-S
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-06-S
#: model:account.tax.template,name:l10n_be.attn_VAT-OUT-06-S
msgid "6% S."
msgstr "6% D."
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a601
#: model:account.account.template,name:l10n_be.a601
msgid "Achats de fournitures"
msgstr "Aankopen van hulpstoffen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a604
#: model:account.account.template,name:l10n_be.a604
msgid "Achats de marchandises"
msgstr "Aankopen van handelsgoederen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a600
#: model:account.account.template,name:l10n_be.a600
msgid "Achats de matières premières"
msgstr "Aankopen van grondstoffen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a602
#: model:account.account.template,name:l10n_be.a602
msgid "Achats de services, travaux et études"
msgstr "Aankopen van diensten, werk en studies"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a446
#: model:account.account.template,name:l10n_be.a446
msgid "Acomptes reçus"
msgstr "Ontvangen voorschotten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a176
#: model:account.account.template,name:l10n_be.a176
msgid "Acomptes reçus sur commandes"
msgstr "Ontvangen vooruitbetalingen op bestellingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a406
#: model:account.account.template,name:l10n_be.a406
msgid "Acomptes versés"
msgstr "Vooruitbetalingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a360
#: model:account.account.template,name:l10n_be.a360
msgid "Acomptes versés sur achats pour stocks"
msgstr "Vooruitbetalingen op aankopen voor aandelen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4550
#: model:account.account.template,name:l10n_be.a4550
msgid "Administrateurs, gérants et commissaires"
msgstr "Bestuurders, zaakvoerders en commissarissen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2119
#: model:account.account.template,name:l10n_be.a2119
msgid "Amortissements sur concessions, brevets, etc..."
msgstr "Afschrijvingen op consessies, octrooien, licenties, ..."
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2690
#: model:account.account.template,name:l10n_be.a2690
msgid "Amortissements sur frais d'aménagement des locaux pris en location"
msgstr "Op inrichtingskosten gehuurde lokalen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2009
#: model:account.account.template,name:l10n_be.a2009
msgid "Amortissements sur frais de constitution et d'augmentation de capital"
msgstr "Afschrijvingen op oprichtingskosten en kapitaalverhoging"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2109
#: model:account.account.template,name:l10n_be.a2109
msgid "Amortissements sur frais de recherche et de mise au point"
msgstr "Afschrijving van kosten van onderzoek en ontwikkeling"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a24190
#: model:account.account.template,name:l10n_be.a24190
msgid "Amortissements sur matériel automobile"
msgstr "Afschrijvingen op wagenuitrusting"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a24090
#: model:account.account.template,name:l10n_be.a24090
msgid "Amortissements sur mobilier"
msgstr "Afschrijvingen op meubilair"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2529
#: model:account.account.template,name:l10n_be.a2529
msgid "Amortissements sur mobilier et matériel roulant en leasing"
msgstr "Afschrijvingen op geleasd rollend materieel"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a614
#: model:account.account.template,name:l10n_be.a614
msgid "Annonces, publicité, propagande et documentation"
msgstr "Advertenties, publiciteit, propaganda en documentatie"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a3100
#: model:account.account.template,name:l10n_be.a3100
msgid "Approvisionements et fournitures"
msgstr "Materialen en benodigdheden"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4160
#: model:account.account.template,name:l10n_be.a4160
msgid "Associés"
msgstr "Vennoten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a45932
#: model:account.account.template,name:l10n_be.a45932
msgid "Assurance groupe "
msgstr "Groepsverzekering"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a45930
#: model:account.account.template,name:l10n_be.a45930
msgid "Assurance loi"
msgstr "Wetsverzekering"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a45931
#: model:account.account.template,name:l10n_be.a45931
msgid "Assurance salaire garanti "
msgstr "Verzekering gewaarborgd inkomen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a45933
#: model:account.account.template,name:l10n_be.a45933
msgid "Assurances individuelles"
msgstr "Individuele verzekering"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a41671
#: model:account.account.template,name:l10n_be.a41671
msgid "Autres créances"
msgstr "Overige vorderingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a174
-#: model:account.account,name:l10n_be.1_a424
#: model:account.account.template,name:l10n_be.a174
#: model:account.account.template,name:l10n_be.a424
msgid "Autres emprunts"
msgstr "Overige leningen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4125
#: model:account.account.template,name:l10n_be.a4125
msgid "Autres impôts belges"
msgstr "Overige Belgische belastingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a49102
-#: model:account.account,name:l10n_be.1_a740
#: model:account.account.template,name:l10n_be.a49102
#: model:account.account.template,name:l10n_be.a740
msgid "Autres produits d'exploitation"
msgstr "Andere bedrijfsopbrengsten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4538
#: model:account.account.template,name:l10n_be.a4538
msgid "Autres précomptes retenus"
msgstr "Andere ingehouden voorheffingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4161
#: model:account.account.template,name:l10n_be.a4161
msgid "Avances et prêts au personnel"
msgstr "Voorschotten en leningen aan het personeel"
@@ -1132,854 +971,701 @@ msgid "Belgium VAT Form: grid 88"
msgstr ""
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a140
#: model:account.account.template,name:l10n_be.a140
msgid "Bénéfice reporté"
msgstr "Overgedragen winst"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a790
#: model:account.account.template,name:l10n_be.a790
msgid "Bénéfice reporté de l'exercice précédent"
msgstr "Overgedragen winst van het vorige boekjaar"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a693
#: model:account.account.template,name:l10n_be.a693
msgid "Bénéfice à reporter"
msgstr "Over te dragen winst"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4594
#: model:account.account.template,name:l10n_be.a4594
msgid "Caisse d'assurances sociales pour travailleurs indépendants"
msgstr "Sociale kas voor zelfstandigen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a24105
#: model:account.account.template,name:l10n_be.a24105
msgid "Camions"
msgstr "Vrachtwagens"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a1000
#: model:account.account.template,name:l10n_be.a1000
msgid "Capital"
msgstr "Kapitaal"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a418
#: model:account.account.template,name:l10n_be.a418
msgid "Cautionnements versés en numéraires"
msgstr "Borgtochten betaald in contanten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6600
#: model:account.account.template,name:l10n_be.a6600
msgid "Charges exceptionelles"
msgstr "Uitzonderlijke kosten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6101
#: model:account.account.template,name:l10n_be.a6101
msgid "Charges locatives"
msgstr "Huurlasten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a492
#: model:account.account.template,name:l10n_be.a492
msgid "Charges à imputer"
msgstr "Toe te rekenen kosten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a490
#: model:account.account.template,name:l10n_be.a490
msgid "Charges à reporter"
msgstr "Over te dragen kosten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a540
#: model:account.account.template,name:l10n_be.a540
msgid "Chèques à encaisser"
msgstr "Te incasseren cheques"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4000
#: model:account.account.template,name:l10n_be.a4000
msgid "Clients"
msgstr "Klanten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a370
#: model:account.account.template,name:l10n_be.a370
msgid "Commandes en cours d'exécution"
msgstr "Lopende opdrachten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a49101
#: model:account.account.template,name:l10n_be.a49101
msgid "Commissions à obtenir"
msgstr "Te ontvangen commissies"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a448
#: model:account.account.template,name:l10n_be.a448
msgid "Compensations fournisseurs"
msgstr "Compensaties leveranciers"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4112
-#: model:account.account,name:l10n_be.1_a4512
#: model:account.account.template,name:l10n_be.a4112
#: model:account.account.template,name:l10n_be.a4512
msgid "Compte courant administration T.V.A."
msgstr "Rekening Courant BTW-Administratie"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4163
#: model:account.account.template,name:l10n_be.a4163
msgid "Compte courant des administrateurs et gérants"
msgstr "Rekening courant bestuurders en zaakvoerders"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4162
#: model:account.account.template,name:l10n_be.a4162
msgid "Compte courant des associés en S.P.R.L."
msgstr "Rekening courant vennoten in B.V.B.A"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4990
#: model:account.account.template,name:l10n_be.a4990
msgid "Compte d'attente"
msgstr "Wachtrekening"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2110
#: model:account.account.template,name:l10n_be.a2110
msgid "Concessions, brevets, licences, savoir-faire, marques, etc..."
msgstr "Consessies, octrooien, licenties, ..."
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2501
#: model:account.account.template,name:l10n_be.a2501
msgid "Constructions"
msgstr "Gebouwen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a621
#: model:account.account.template,name:l10n_be.a621
msgid "Cotisations patronales d'assurances sociales"
msgstr "Werkgeversbijdragen voor sociale verzekeringen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a29000
#: model:account.account.template,name:l10n_be.a29000
msgid "Créances commerciales"
msgstr "Handelsvorderingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a407
-#: model:account.account,name:l10n_be.1_a417
#: model:account.account.template,name:l10n_be.a407
#: model:account.account.template,name:l10n_be.a417
msgid "Créances douteuses"
msgstr "Dubieuze debiteuren"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4164
#: model:account.account.template,name:l10n_be.a4164
msgid "Créances sur sociétés apparentées"
msgstr "Vorderingen op gerelateerde bedrijven"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a1720
#: model:account.account.template,name:l10n_be.a1720
msgid "Dettes de location-financement de biens immobiliers"
msgstr "Leasingschulden van onroerende goederen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a1721
#: model:account.account.template,name:l10n_be.a1721
msgid "Dettes de location-financement de biens mobiliers"
msgstr "Leasingschulden van roerende goederen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a17300
#: model:account.account.template,name:l10n_be.a17300
msgid "Dettes en compte \\ Banque A"
msgstr "Schulden op rekeningen \\Bank A"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4597
#: model:account.account.template,name:l10n_be.a4597
msgid "Dettes et provisions sociales diverses"
msgstr "Diverse sociale schulden en provisies"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4500
#: model:account.account.template,name:l10n_be.a4500
msgid "Dettes fiscales estimées"
msgstr "Geraamd bedrag der belastingschulden"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a1722
#: model:account.account.template,name:l10n_be.a1722
msgid "Dettes sur droits réels sur immeubles"
msgstr "Schulden op zakelijke rechten op gebouwen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a654
-#: model:account.account,name:l10n_be.1_a754
#: model:account.account.template,name:l10n_be.a654
#: model:account.account.template,name:l10n_be.a754
msgid "Différences de change"
msgstr "Wisselresultaten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4551
-#: model:account.account,name:l10n_be.1_a4560
#: model:account.account.template,name:l10n_be.a4551
#: model:account.account.template,name:l10n_be.a4560
msgid "Direction"
msgstr "Directiepersoneel"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6302
#: model:account.account.template,name:l10n_be.a6302
msgid "Dotations aux amortissements sur immobilisations corporelles"
msgstr "Afschrijvingen op materiële vaste activa"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6301
#: model:account.account.template,name:l10n_be.a6301
msgid "Dotations aux amortissements sur immobilisations incorporelles"
msgstr "Afschrijvingen op immateriële vaste activa"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a755
#: model:account.account.template,name:l10n_be.a755
msgid "Ecarts de conversion des devises"
msgstr "Resultaten uit de omrekening van vreemde valuta"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a175111
#: model:account.account.template,name:l10n_be.a175111
msgid "Effets à payer \\ Fournisseurs C.E.E."
msgstr "Te betalen wissels: Leveranciers van de EEG"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a175110
#: model:account.account.template,name:l10n_be.a175110
msgid "Effets à payer \\ Fournisseurs belges"
msgstr "Te betalen wissels: Belgische leveranciers"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a175112
#: model:account.account.template,name:l10n_be.a175112
msgid "Effets à payer \\ Fournisseurs importation"
msgstr "Te betalen wissels: Import leveranciers"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4166
#: model:account.account.template,name:l10n_be.a4166
msgid "Emballages et matériel à rendre"
msgstr "Terug te geven materiaal en verpakkingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4552
-#: model:account.account,name:l10n_be.1_a4561
#: model:account.account.template,name:l10n_be.a4552
#: model:account.account.template,name:l10n_be.a4561
msgid "Employés"
msgstr "Bedienden"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a3200
#: model:account.account.template,name:l10n_be.a3200
msgid "En cours de fabrication"
msgstr "Goederen in bewerking"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a611
#: model:account.account.template,name:l10n_be.a611
msgid "Entretien et réparation"
msgstr "Onderhoud en herstellingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a653
#: model:account.account.template,name:l10n_be.a653
msgid "Escomptes clients"
msgstr ""
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a757
#: model:account.account.template,name:l10n_be.a757
msgid "Escomptes obtenus"
msgstr "Bekomen kortingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4230
#: model:account.account.template,name:l10n_be.a4230
msgid "Etablissements de crédit"
msgstr "Kredietinstellingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a430
#: model:account.account.template,name:l10n_be.a430
msgid "Etablissements de crédit. Emprunts en compte à terme fixe"
msgstr "Kredietinstellingen - Leningen op rekeningen met vaste termijn"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a444
#: model:account.account.template,name:l10n_be.a444
msgid "Factures à recevoir"
msgstr "Te ontvangen facturen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4220
#: model:account.account.template,name:l10n_be.a4220
msgid "Financement de biens immobiliers"
msgstr "Financiering vastgoed"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4221
#: model:account.account.template,name:l10n_be.a4221
msgid "Financement de biens mobiliers"
msgstr "Financiering roerend goed"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a440
#: model:account.account.template,name:l10n_be.a440
msgid "Fournisseurs"
msgstr "Leveranciers"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a612
#: model:account.account.template,name:l10n_be.a612
msgid "Fournitures"
msgstr "Diverse leveringen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a260
#: model:account.account.template,name:l10n_be.a260
msgid "Frais d'aménagements de locaux pris en location"
msgstr "Inrichtingskosten gehuurde lokalen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a656
#: model:account.account.template,name:l10n_be.a656
msgid "Frais de banques, de chèques postaux"
msgstr "Bank en chequekosten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2000
#: model:account.account.template,name:l10n_be.a2000
msgid "Frais de constitution et d'augmentation de capital"
msgstr "Oprichtingskosten en kapitaalverhoging"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2100
#: model:account.account.template,name:l10n_be.a2100
msgid "Frais de recherche et de mise au point"
msgstr "Kosten van onderzoek en ontwikkeling"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a3500
#: model:account.account.template,name:l10n_be.a3500
msgid "Immeubles destinés à la vente"
msgstr "Onroerende goederen bestemd voor verkoop"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2800
#: model:account.account.template,name:l10n_be.a2800
msgid "Immobilisations Financières"
msgstr "Financiële vaste activa"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4120
#: model:account.account.template,name:l10n_be.a4120
msgid "Impôts belges sur le résultat"
msgstr "Belgische belastingen op het resultaat"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6700
#: model:account.account.template,name:l10n_be.a6700
msgid "Impôts et précomptes dus ou versés"
msgstr "Verschuldigde of gestorte belastingen en voorheffingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4128
#: model:account.account.template,name:l10n_be.a4128
msgid "Impôts étrangers"
msgstr "Buitenlandse belastingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6100
#: model:account.account.template,name:l10n_be.a6100
msgid "Loyers divers"
msgstr "Diverse huren"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a3400
#: model:account.account.template,name:l10n_be.a3400
msgid "Marchandises"
msgstr "Goederen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a300
#: model:account.account.template,name:l10n_be.a300
msgid "Matières premières"
msgstr "Grondstoffen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a24011
#: model:account.account.template,name:l10n_be.a24011
msgid "Matériel de bureau de bâtiments administratifs et commerciaux"
msgstr "Kantooruitrusting voor gebouwen met adminestratieve en commerciële functie"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a24010
#: model:account.account.template,name:l10n_be.a24010
msgid "Matériel de bureau de bâtiments industriels"
msgstr "Kantooruitrusting voor gebouwen met industriële functie"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2521
#: model:account.account.template,name:l10n_be.a2521
msgid "Matériel roulant"
msgstr "Rollend materieel"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2520
#: model:account.account.template,name:l10n_be.a2520
msgid "Mobilier"
msgstr "Meubilair"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a24001
#: model:account.account.template,name:l10n_be.a24001
msgid "Mobilier des bâtiments administratifs et commerciaux"
msgstr "Van administratieve en commerciële gebouwen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a24000
#: model:account.account.template,name:l10n_be.a24000
msgid "Mobilier des bâtiments industriels"
msgstr "Van industriële gebouwen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a151
#: model:account.account.template,name:l10n_be.a151
msgid "Montants transférés aux résultats"
msgstr "Bedragen komende van het resultaat"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4541
#: model:account.account.template,name:l10n_be.a4541
msgid "ONSS. 1er trimestre"
msgstr "R.S.Z. 1ste kwartaal"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4542
#: model:account.account.template,name:l10n_be.a4542
msgid "ONSS. 2ème trimestre"
msgstr "R.S.Z. 2de kwartaal"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4543
#: model:account.account.template,name:l10n_be.a4543
msgid "ONSS. 3ème trimestre"
msgstr "R.S.Z. 3de kwartaal"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4544
#: model:account.account.template,name:l10n_be.a4544
msgid "ONSS. 4ème trimestre"
msgstr "R.S.Z. 4de kwartaal"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4540
#: model:account.account.template,name:l10n_be.a4540
msgid "ONSS. Arriérés"
msgstr "Achterstallige bijdragen RSZ"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4553
-#: model:account.account,name:l10n_be.1_a4562
#: model:account.account.template,name:l10n_be.a4553
#: model:account.account.template,name:l10n_be.a4562
msgid "Ouvriers"
msgstr "Arbeiders"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a141
#: model:account.account.template,name:l10n_be.a141
msgid "Perte reportée"
msgstr "Overgedragen verlies (-)"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a690
#: model:account.account.template,name:l10n_be.a690
msgid "Perte reportée de l'exercice précédent"
msgstr "Overgedragen verlies van het vorige boekjaar"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a793
#: model:account.account.template,name:l10n_be.a793
msgid "Perte à reporter"
msgstr "Over te dragen verlies"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2118
#: model:account.account.template,name:l10n_be.a2118
msgid "Plus-values actées sur concessions, brevets, etc..."
msgstr "Gerealiseerde meerwaarden op consessies, octrooien, licenties, ..."
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2108
#: model:account.account.template,name:l10n_be.a2108
msgid "Plus-values actées sur frais de recherche et de mise au point"
msgstr "Gerealiseerde meerwaarden op onderzoek en ontwikkeling"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2528
#: model:account.account.template,name:l10n_be.a2528
msgid "Plus-values actées sur mobilier et matériel roulant en leasing"
msgstr "Gerealiseerde meerwaarden op geleasd rollend materieel"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a752
#: model:account.account.template,name:l10n_be.a752
msgid "Plus-values sur réalisations d'actifs circulants"
msgstr "Meerwaarden op de realisatie van vlottende activa"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7051
#: model:account.account.template,name:l10n_be.a7051
msgid "Prestations de services dans les pays membres de la C.E.E."
msgstr "Dienstverlening in lidstaten van de E.E.G."
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7050
#: model:account.account.template,name:l10n_be.a7050
msgid "Prestations de services en Belgique"
msgstr "Dienstverlening in België"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7052
#: model:account.account.template,name:l10n_be.a7052
msgid "Prestations de services en vue de l'exportation"
msgstr "Dienstverlening buiten de E.E.G. (export)"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a11
#: model:account.account.template,name:l10n_be.a11
msgid "Primes d'émission"
msgstr "Uitgifte premies"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4930
#: model:account.account.template,name:l10n_be.a4930
msgid "Produits d'exploitation à reporter"
msgstr "Over te dragen bedrijfsopbrengsten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a751
#: model:account.account.template,name:l10n_be.a751
msgid "Produits des actifs circulants"
msgstr "Opbrengsten uit vlottende activa"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a756
#: model:account.account.template,name:l10n_be.a756
msgid "Produits des autres créances"
msgstr "Diverse financiële opbrengsten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7600
#: model:account.account.template,name:l10n_be.a7600
msgid "Produits exceptionnels"
msgstr "Uitzonderlijke opbrengsten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a3300
#: model:account.account.template,name:l10n_be.a3300
msgid "Produits finis"
msgstr "Gereed product"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a404
-#: model:account.account,name:l10n_be.1_a414
#: model:account.account.template,name:l10n_be.a404
#: model:account.account.template,name:l10n_be.a414
msgid "Produits à recevoir"
msgstr "Te innen opbrengsten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4590
#: model:account.account.template,name:l10n_be.a4590
msgid "Provision pour gratifications de fin d'année"
msgstr "Voorziening voor eindejaarspremie"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a1600
#: model:account.account.template,name:l10n_be.a1600
msgid "Provisions pour risques et charges"
msgstr "Voorzieningen voor risico's en kosten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4533
#: model:account.account.template,name:l10n_be.a4533
msgid "Précompte mobilier retenu sur intérêts payés"
msgstr "Roerende voorheffing ingehouden op betaalde intresten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4530
#: model:account.account.template,name:l10n_be.a4530
msgid "Précompte professionnel retenu sur rémunérations"
msgstr "Bedrijfsvoorheffing ingehouden op bezoldigingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a791
#: model:account.account.template,name:l10n_be.a791
msgid "Prélèvement sur le capital et les primes d'émission"
msgstr "Onttrekking aan het kapitaal en aan de uitgiftepremies"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a780
#: model:account.account.template,name:l10n_be.a780
msgid "Prélèvements sur les impôts différés"
msgstr "Onttrekking aan de uitgestelde belastingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a789
#: model:account.account.template,name:l10n_be.a789
msgid "Prélèvements sur les réserves immunisées"
msgstr "Onttrekking aan de reserves"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a706
#: model:account.account.template,name:l10n_be.a706
msgid "Pénalités et dédits obtenus par l'entreprise"
msgstr "Boeten en verbeurdverklaringen verkregen door de onderneming"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4168
#: model:account.account.template,name:l10n_be.a4168
msgid "Rabais, ristournes, remises à obtenir et autres avoirs non encore reçus"
msgstr "Kortingen, rabatten en andere nog te ontvangen tegoeden"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7500
#: model:account.account.template,name:l10n_be.a7500
msgid "Revenus des actions"
msgstr "Opbrengsten uit aandelen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7502
#: model:account.account.template,name:l10n_be.a7502
msgid "Revenus des créances à plus d'un an"
msgstr "Inkomsten uit schuld > 1 jaar"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7501
#: model:account.account.template,name:l10n_be.a7501
msgid "Revenus des obligations"
msgstr "Opbrengsten uit obligaties"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a49100
#: model:account.account.template,name:l10n_be.a49100
msgid "Ristournes, rabais à obtenir"
msgstr "Te ontvangen kortingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a329
-#: model:account.account,name:l10n_be.1_a419
#: model:account.account.template,name:l10n_be.a329
#: model:account.account.template,name:l10n_be.a419
msgid "Réductions de valeur actées"
msgstr "Geboekte waardeverminderingen (-)"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6320
#: model:account.account.template,name:l10n_be.a6320
msgid "Réductions de valeur sur commandes en cours d'exécution"
msgstr "Waardeverminderingen op bestellingen in uitvoering"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6310
#: model:account.account.template,name:l10n_be.a6310
msgid "Réductions de valeur sur stocks"
msgstr "Waardeverminderingen op voorraden"
#. module: l10n_be
-#: model:account.fiscal.position,name:l10n_be.1_fiscal_position_template_4
#: model:account.fiscal.position.template,name:l10n_be.fiscal_position_template_4
msgid "Régime Cocontractant"
msgstr "Medecontractant"
#. module: l10n_be
-#: model:account.fiscal.position,name:l10n_be.1_fiscal_position_template_2
#: model:account.fiscal.position.template,name:l10n_be.fiscal_position_template_2
msgid "Régime Extra-Communautaire"
msgstr "Export"
#. module: l10n_be
-#: model:account.fiscal.position,name:l10n_be.1_fiscal_position_template_3
#: model:account.fiscal.position.template,name:l10n_be.fiscal_position_template_3
msgid "Régime Intra-Communautaire"
msgstr "Intra-Communautair"
#. module: l10n_be
-#: model:account.fiscal.position,name:l10n_be.1_fiscal_position_template_1
#: model:account.fiscal.position.template,name:l10n_be.fiscal_position_template_1
msgid "Régime National"
msgstr "Nationaal"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V61
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V61
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V61
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V61
msgid "Régularisation en faveur de l'état"
msgstr ""
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V62
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V62
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V62
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V62
msgid "Régularisation en faveur du déclarant"
msgstr ""
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7710
#: model:account.account.template,name:l10n_be.a7710
msgid "Régularisations d'impôts dus ou versés"
msgstr "Regularisering van verschuldigde of betaalde belastingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7711
#: model:account.account.template,name:l10n_be.a7711
msgid "Régularisations d'impôts estimés"
msgstr "Regularisering van geraamde belastingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6200
#: model:account.account.template,name:l10n_be.a6200
msgid "Rémunérations: Administrateurs ou gérants"
msgstr "Bezoldigingen: Bestuurders of zaakvoerders"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6204
#: model:account.account.template,name:l10n_be.a6204
msgid "Rémunérations: Autres membres du personnel"
msgstr "Bezoldigingen: Andere personeelsleden, verbonden met een arbeidsovereenkomst"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6202
#: model:account.account.template,name:l10n_be.a6202
msgid "Rémunérations: Employés"
msgstr "Bezoldigingen: Arbeiders"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6203
#: model:account.account.template,name:l10n_be.a6203
msgid "Rémunérations: Ouvriers"
msgstr "Bezoldigingen: Bedienden"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a6201
#: model:account.account.template,name:l10n_be.a6201
msgid "Rémunérations: Personnel de direction"
msgstr "Bezoldigingen: Directiepersoneel"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a130
#: model:account.account.template,name:l10n_be.a130
msgid "Réserve légale"
msgstr "Wettelijke reserve"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a132
#: model:account.account.template,name:l10n_be.a132
msgid "Réserves immunisées"
msgstr "Belastingvrije reserves"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a613
#: model:account.account.template,name:l10n_be.a613
msgid "Rétributions de tiers"
msgstr "Vergoedingen aan derden"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a603
#: model:account.account.template,name:l10n_be.a603
msgid "Sous-traitances générales"
msgstr "Algemene onderaannemingen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a753
#: model:account.account.template,name:l10n_be.a753
msgid "Subsides en capital et en intérêts"
msgstr "Kapitaal- en interestsubsidies"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a150
#: model:account.account.template,name:l10n_be.a150
msgid "Subsides obtenus"
msgstr "Verkregen subsidies"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a41670
#: model:account.account.template,name:l10n_be.a41670
msgid "Subsides à recevoir"
msgstr "Te ontvangen subsidies"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a411059
#: model:account.account.template,name:l10n_be.a411059
msgid "T.V.A Déductible"
msgstr "Aftrekbare BTW"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a64012
#: model:account.account.template,name:l10n_be.a64012
msgid "T.V.A. non déductible"
msgstr "Niet aftrekbare BTW"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a451054
#: model:account.account.template,name:l10n_be.a451054
msgid "T.V.A. à payer"
msgstr "Te betalen BTW"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a451056
#: model:account.account.template,name:l10n_be.a451056
msgid "T.V.A. à payer - Cocontractant"
msgstr "Te betalen BTW - Medecontractant"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a451057
#: model:account.account.template,name:l10n_be.a451057
msgid "T.V.A. à payer - Import"
msgstr "Te betalen BTW - Import"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a451055
#: model:account.account.template,name:l10n_be.a451055
msgid "T.V.A. à payer - Intra-communautaire"
msgstr "Te betalen BTW - Intracommunautair"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-00
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-00-G
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-00-S
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-00
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-00-L
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-00-S
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-00
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-00-G
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-00-S
@@ -1990,10 +1676,6 @@ msgid "TVA 0%"
msgstr "BTW 0%"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-00-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-00-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-00-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-00-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-00-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-00-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-00-CC
@@ -2002,13 +1684,6 @@ msgid "TVA 0% Cocont."
msgstr "BTW 0% Medecont."
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-00-EU
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-00-EU-G
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-00-EU-S
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-00-EU
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-00-EU-L
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-00-EU-S
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-00-EU-T
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-00-EU
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-00-EU-G
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-00-EU-S
@@ -2020,10 +1695,6 @@ msgid "TVA 0% EU"
msgstr "BTW 0% EU"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-00-ROW-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-00-ROW-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-00-ROW-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-00-ROW
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-00-ROW-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-00-ROW-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-00-ROW-CC
@@ -2032,12 +1703,6 @@ msgid "TVA 0% Non EU"
msgstr "BTW 0% Non EU"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-12
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-G
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-S
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-12
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-12-L
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-12-S
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-12
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-G
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-S
@@ -2048,9 +1713,6 @@ msgid "TVA 12%"
msgstr "BTW 12%"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-12-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-12-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-12-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-12-CC
@@ -2058,9 +1720,6 @@ msgid "TVA 12% Cocont."
msgstr "BTW 12% Medecont."
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-12-CC-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-CC-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-12-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-12-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-12-CC-C1
@@ -2068,9 +1727,6 @@ msgid "TVA 12% Cocont. Déductible"
msgstr "BTW 12% Medecont. Aftrekbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-12-CC-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-CC-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-12-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-12-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-12-CC-C2
@@ -2078,10 +1734,6 @@ msgid "TVA 12% Cocont. Récupérable"
msgstr "BTW 12% Medecont. Verhaalbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-12-EU
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-EU-G
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-EU-S
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-12-EU
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-12-EU
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-EU-G
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-EU-S
@@ -2090,10 +1742,6 @@ msgid "TVA 12% EU"
msgstr "BTW 12% EU"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-12-EU-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-EU-G-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-EU-S-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-12-EU-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-12-EU-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-EU-G-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-EU-S-C1
@@ -2102,10 +1750,6 @@ msgid "TVA 12% EU Déductible"
msgstr "BTW 12% EU Aftrekbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-12-EU-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-EU-G-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-EU-S-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-12-EU-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-12-EU-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-EU-G-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-EU-S-C2
@@ -2114,15 +1758,11 @@ msgid "TVA 12% EU Récupérable"
msgstr "BTW 12% EU Verhaalbaar"
#. module: l10n_be
-#: model:account.tax,name:l10n_be.1_attn_VAT-IN-V82-12-EU-G-C2
#: model:account.tax.template,name:l10n_be.attn_VAT-IN-V82-12-EU-G-C2
msgid "TVA 12% EU Récupérable - Biens divers"
msgstr "BTW 12% EU Verhaalbaar - Diverse goederen"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-12-ROW-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-ROW-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-12-ROW-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-12-ROW-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-ROW-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-12-ROW-CC
@@ -2130,9 +1770,6 @@ msgid "TVA 12% Non EU"
msgstr "BTW 12% Niet EU"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-12-ROW-CC-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-ROW-CC-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-12-ROW-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-12-ROW-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-ROW-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-12-ROW-CC-C1
@@ -2140,9 +1777,6 @@ msgid "TVA 12% Non EU Déductible"
msgstr "BTW 12% Niet EU Aftrekbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-12-ROW-CC-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-12-ROW-CC-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-12-ROW-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-12-ROW-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-12-ROW-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-12-ROW-CC-C2
@@ -2150,12 +1784,6 @@ msgid "TVA 12% Non EU Récupérable"
msgstr "BTW 12% Niet EU Verhaalbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-21
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-G
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-S
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-21
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-21-L
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-21-S
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-21
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-G
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-S
@@ -2166,9 +1794,6 @@ msgid "TVA 21%"
msgstr "BTW 21%"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-21-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-21-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-21-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-21-CC
@@ -2176,9 +1801,6 @@ msgid "TVA 21% Cocont."
msgstr "BTW 21% Medecont."
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-21-CC-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-CC-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-21-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-21-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-21-CC-C1
@@ -2186,9 +1808,6 @@ msgid "TVA 21% Cocont. Déductible"
msgstr "BTW 21% Medecont. Aftrekbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-21-CC-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-CC-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-21-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-21-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-21-CC-C2
@@ -2196,10 +1815,6 @@ msgid "TVA 21% Cocont. Récupérable"
msgstr "BTW 21% Medecont. Verhaalbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-21-EU
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-EU-G
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-EU-S
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-21-EU
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-21-EU
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-EU-G
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-EU-S
@@ -2208,10 +1823,6 @@ msgid "TVA 21% EU"
msgstr "BTW 21% EU"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-21-EU-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-EU-G-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-EU-S-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-21-EU-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-21-EU-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-EU-G-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-EU-S-C1
@@ -2220,10 +1831,6 @@ msgid "TVA 21% EU Déductible"
msgstr "BTW 21% EU Aftrekbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-21-EU-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-EU-G-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-EU-S-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-21-EU-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-21-EU-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-EU-G-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-EU-S-C2
@@ -2232,9 +1839,6 @@ msgid "TVA 21% EU Récupérable"
msgstr "BTW 21% EU Verhaalbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-21-ROW-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-ROW-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-21-ROW-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-21-ROW-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-ROW-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-21-ROW-CC
@@ -2242,9 +1846,6 @@ msgid "TVA 21% Non EU"
msgstr "BTW 21% Niet EU"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-21-ROW-CC-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-ROW-CC-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-21-ROW-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-21-ROW-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-ROW-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-21-ROW-CC-C1
@@ -2252,9 +1853,6 @@ msgid "TVA 21% Non EU Déductible"
msgstr "BTW 21% Niet EU Aftrekbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-21-ROW-CC-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-21-ROW-CC-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-21-ROW-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-21-ROW-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-21-ROW-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-21-ROW-CC-C2
@@ -2262,30 +1860,21 @@ msgid "TVA 21% Non EU Récupérable"
msgstr "BTW 21% Niet EU Verhaalbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_TVA-21-inclus-dans-prix
#: model:account.tax.template,description:l10n_be.attn_TVA-21-inclus-dans-prix
msgid "TVA 21% TTC"
msgstr "VAT 21% (inclusief BTW)"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-CAR-EXC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-CAR-EXC-C2
msgid "TVA 50% Déductible - Frais de voiture (Prix Excl.)"
msgstr "BTW 5°% Aftrekbaar - Auto kosten (Prijs Excl.)"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-CAR-EXC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-CAR-EXC
msgid "TVA 50% Non Déductible - Frais de voiture (Prix Excl.)"
msgstr "BTW 50% Niet Aftrekbaar - Auto kosten (Prijs Excl.)"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-06
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-G
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-S
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-06
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-06-L
-#: model:account.tax,description:l10n_be.1_attn_VAT-OUT-06-S
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-06
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-G
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-S
@@ -2296,9 +1885,6 @@ msgid "TVA 6%"
msgstr "BTW 6%"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-06-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-06-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-06-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-06-CC
@@ -2306,9 +1892,6 @@ msgid "TVA 6% Cocont."
msgstr "BTW 6% Medecont."
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-06-CC-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-CC-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-06-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-06-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-06-CC-C1
@@ -2316,9 +1899,6 @@ msgid "TVA 6% Cocont. Déductible"
msgstr "BTW 6% Medecont. Aftrekbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-06-CC-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-CC-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-06-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-06-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-06-CC-C2
@@ -2326,10 +1906,6 @@ msgid "TVA 6% Cocont. Récupérable"
msgstr "BTW 6% Medecont. Verhaalbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-06-EU
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-EU-G
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-EU-S
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-06-EU
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-06-EU
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-EU-G
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-EU-S
@@ -2338,10 +1914,6 @@ msgid "TVA 6% EU"
msgstr "BTW 6% EU"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-06-EU-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-EU-G-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-EU-S-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-06-EU-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-06-EU-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-EU-G-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-EU-S-C1
@@ -2350,10 +1922,6 @@ msgid "TVA 6% EU Déductible"
msgstr "BTW 6% EU Aftrekbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-06-EU-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-EU-G-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-EU-S-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-06-EU-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-06-EU-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-EU-G-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-EU-S-C2
@@ -2362,9 +1930,6 @@ msgid "TVA 6% EU Récupérable"
msgstr "BTW 6% EU Verhaalbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-06-ROW-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-ROW-CC
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-06-ROW-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-06-ROW-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-ROW-CC
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-06-ROW-CC
@@ -2372,9 +1937,6 @@ msgid "TVA 6% Non EU"
msgstr "BTW 6% Niet EU"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-06-ROW-CC-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-ROW-CC-C1
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-06-ROW-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-06-ROW-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-ROW-CC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-06-ROW-CC-C1
@@ -2382,9 +1944,6 @@ msgid "TVA 6% Non EU Déductible"
msgstr "BTW 6% Niet EU Aftrekbaar"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V81-06-ROW-CC-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-06-ROW-CC-C2
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V83-06-ROW-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V81-06-ROW-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-06-ROW-CC-C2
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V83-06-ROW-CC-C2
@@ -2392,73 +1951,61 @@ msgid "TVA 6% Non EU Récupérable"
msgstr "BTW 6% Niet EU Verhaalbaar"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a4118
#: model:account.account.template,name:l10n_be.a4118
msgid "Taxe d'égalisation due"
msgstr "Verschuldigde egalisatiebelasting"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a64000
#: model:account.account.template,name:l10n_be.a64000
msgid "Taxes sur autos et camions"
msgstr "Verkeersbelasting bedrijfswagens"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a2500
#: model:account.account.template,name:l10n_be.a2500
msgid "Terrains"
msgstr "Terreinen"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_trans
#: model:account.account.template,name:l10n_be.trans
msgid "Transferts"
msgstr "Transferten"
#. module: l10n_be
-#: model:account.tax,description:l10n_be.1_attn_VAT-IN-V82-CAR-EXC-C1
#: model:account.tax.template,description:l10n_be.attn_VAT-IN-V82-CAR-EXC-C1
msgid "VAT 50% Non Déductible - Frais de voiture"
msgstr "BTW 50% Niet Aftrekbaar - Auto kosten"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7001
#: model:account.account.template,name:l10n_be.a7001
msgid "Ventes dans les pays membres de la C.E.E. (marchandises)"
msgstr "Verkopen: leden van de Europese gemeenschap (handelsgoederen)"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7011
#: model:account.account.template,name:l10n_be.a7011
msgid "Ventes dans les pays membres de la C.E.E. (produits finis)"
msgstr "Verkopen: leden van de Europese gemeenschap (gereed product)"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7000
#: model:account.account.template,name:l10n_be.a7000
msgid "Ventes en Belgique (marchandises)"
msgstr "Verkopen: België (handelsgoederen)"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7010
#: model:account.account.template,name:l10n_be.a7010
msgid "Ventes en Belgique (produits finis)"
msgstr "Verkopen: België (gereed product)"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7002
#: model:account.account.template,name:l10n_be.a7002
msgid "Ventes à l'exportation (marchandises)"
msgstr "Verkopen: export (handelsgoederen)"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a7012
#: model:account.account.template,name:l10n_be.a7012
msgid "Ventes à l'exportation (produits finis)"
msgstr "Verkopen: export (gereed product)"
#. module: l10n_be
-#: model:account.account,name:l10n_be.1_a24100
#: model:account.account.template,name:l10n_be.a24100
msgid "Voitures"
msgstr "Wagens"
diff --git a/addons/l10n_do/models/chart_template.py b/addons/l10n_do/models/chart_template.py
index 73e99589873..97d0833fef6 100644
--- a/addons/l10n_do/models/chart_template.py
+++ b/addons/l10n_do/models/chart_template.py
@@ -13,6 +13,49 @@ class WizardMultiChartsAccounts(models.TransientModel):
return [
{'acc_name': _('Cash'), 'account_type': 'cash'},
{'acc_name': _('Caja Chica'), 'account_type': 'cash'},
+ {'acc_name': _('Cheques Clientes'), 'account_type': 'cash'},
{'acc_name': _('Bank'), 'account_type': 'bank'}
]
return super(WizardMultiChartsAccounts, self)._get_default_bank_account_ids()
+
+
+class AccountChartTemplate(models.Model):
+ _inherit = "account.chart.template"
+
+ @api.multi
+ def _prepare_all_journals(self, acc_template_ref, company, journals_dict=None):
+ """Create fiscal journals for buys"""
+ res = super(AccountChartTemplate, self)._prepare_all_journals(
+ acc_template_ref, company, journals_dict=journals_dict)
+ if not self == self.env.ref('l10n_do.do_chart_template'):
+ return res
+ for journal in res:
+ if journal['code'] == 'FACT':
+ journal['name'] = _('Compras Fiscales')
+ res += [{
+ 'type': 'purchase',
+ 'name': _('Compras Informales'),
+ 'code': 'CINF',
+ 'company_id': company.id,
+ 'show_on_dashboard': True
+ }, {
+ 'type': 'purchase',
+ 'name': _('Gastos Menores'),
+ 'code': 'GASM',
+ 'company_id': company.id,
+ 'show_on_dashboard': True
+ }, {
+ 'type': 'purchase',
+ 'name': _('Compras al Exterior'),
+ 'code': 'CEXT',
+ 'company_id': company.id,
+ 'show_on_dashboard': True
+ }, {
+ 'type': 'purchase',
+ 'name': _('Gastos No Deducibles'),
+ 'code': 'GASTO',
+ 'company_id': company.id,
+ 'show_on_dashboard': True
+ }]
+ return res
+
diff --git a/addons/l10n_fr_certification/data/account_move.xml b/addons/l10n_fr_certification/data/account_move.xml
index 2794e6364f9..c4d735d2b14 100644
--- a/addons/l10n_fr_certification/data/account_move.xml
+++ b/addons/l10n_fr_certification/data/account_move.xml
@@ -3,6 +3,7 @@
<field name="name">Data Inalterability Check</field>
<field name="model_id" ref="account.model_account_move"/>
<field name="type">ir.actions.server</field>
+ <field name="state">code</field>
<field name="code">
action = env['account.move']._check_hash_integrity(env.user.company_id.id)
</field>
@@ -12,6 +13,7 @@
<field name="name">Get the certification now!</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="account.model_res_company"/>
+ <field name="state">code</field>
<field name="code">
db_uuid = env['ir.config_parameter'].sudo().get_param('database.uuid')
action = {"type": "ir.actions.act_url",
diff --git a/addons/l10n_fr_pos_cert/data/pos_inalterability.xml b/addons/l10n_fr_pos_cert/data/pos_inalterability.xml
index ace4c3de24d..377204b73c6 100644
--- a/addons/l10n_fr_pos_cert/data/pos_inalterability.xml
+++ b/addons/l10n_fr_pos_cert/data/pos_inalterability.xml
@@ -8,6 +8,7 @@
<field name="name">Pos Orders Inalterability Check</field>
<field name="model_id" ref="point_of_sale.model_pos_order"/>
<field name="type">ir.actions.server</field>
+ <field name="state">code</field>
<field name="code">
action = env['pos.order']._check_hash_integrity(env.user.company_id.id)
</field>
diff --git a/addons/mail/models/mail_activity.py b/addons/mail/models/mail_activity.py
index e49fbb61363..47e0c37408f 100644
--- a/addons/mail/models/mail_activity.py
+++ b/addons/mail/models/mail_activity.py
@@ -150,7 +150,8 @@ class MailActivity(models.Model):
@api.onchange('recommended_activity_type_id')
def _onchange_recommended_activity_type_id(self):
- self.activity_type_id = self.recommended_activity_type_id
+ if self.recommended_activity_type_id:
+ self.activity_type_id = self.recommended_activity_type_id
@api.multi
def _check_access(self, operation):
diff --git a/addons/mail/static/src/js/services/chat_manager.js b/addons/mail/static/src/js/services/chat_manager.js
index 8ae45486e16..074d3d192d3 100644
--- a/addons/mail/static/src/js/services/chat_manager.js
+++ b/addons/mail/static/src/js/services/chat_manager.js
@@ -1279,7 +1279,15 @@ var ChatManager = AbstractService.extend({
_.each(_.keys(this.emojiSubstitutions), function (key) {
var escapedKey = String(key).replace(/([.*+?=^!:${}()|[\]/\\])/g, '\\$1');
var regexp = new RegExp("(?:^|\\s|<[a-z]*>)(" + escapedKey + ")(?=\\s|$|</[a-z]*>)", "g");
+ var msg_bak = msg.body;
msg.body = msg.body.replace(regexp, ' <span class="o_mail_emoji">'+self.emojiSubstitutions[key]+'</span> ');
+ // Idiot-proof limit. If the user had the amazing idea of copy-pasting thousands of emojis,
+ // the image rendering can lead to memory overflow errors on some browsers (e.g. Chrome).
+ // Set an arbitrary limit to 200 from which we simply don't replace them (anyway, they are
+ // already replaced by the unicode counterpart).
+ if (_.str.count(msg.body, 'o_mail_emoji') > 200) {
+ msg.body = msg_bak;
+ }
});
function propertyDescr(channel) {
diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py
index 64422c2c0d7..8b39d73d3ae 100644
--- a/addons/mrp/models/mrp_production.py
+++ b/addons/mrp/models/mrp_production.py
@@ -558,7 +558,7 @@ class MrpProduction(models.Model):
order._cal_price(moves_to_do)
moves_to_finish = order.move_finished_ids.filtered(lambda x: x.state not in ('done','cancel'))
moves_to_finish._action_done()
- #order.action_assign()
+ order.action_assign()
consume_move_lines = moves_to_do.mapped('active_move_line_ids')
for moveline in moves_to_finish.mapped('active_move_line_ids'):
if moveline.product_id == order.product_id and moveline.move_id.has_tracking != 'none':
diff --git a/addons/payment/models/__init__.py b/addons/payment/models/__init__.py
index 3a1c7ce052a..ed704df85d1 100644
--- a/addons/payment/models/__init__.py
+++ b/addons/payment/models/__init__.py
@@ -3,3 +3,4 @@
from . import payment_acquirer
from . import res_partner
from . import account_payment
+from . import chart_template
diff --git a/addons/payment/models/chart_template.py b/addons/payment/models/chart_template.py
new file mode 100644
index 00000000000..515103316be
--- /dev/null
+++ b/addons/payment/models/chart_template.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+
+from odoo import api, fields, models, _
+
+
+class WizardMultiChartsAccounts(models.TransientModel):
+ _inherit = 'wizard.multi.charts.accounts'
+
+ @api.multi
+ def _create_bank_journals_from_o2m(self, company, acc_template_ref):
+ res = super(WizardMultiChartsAccounts, self)._create_bank_journals_from_o2m(company, acc_template_ref)
+
+ # Try to generate the missing journals
+ return res + self.env['payment.acquirer']._create_missing_journal_for_acquirers(company=company)
diff --git a/addons/payment/models/payment_acquirer.py b/addons/payment/models/payment_acquirer.py
index a67aea945d7..2d07a174a7e 100644
--- a/addons/payment/models/payment_acquirer.py
+++ b/addons/payment/models/payment_acquirer.py
@@ -9,6 +9,7 @@ from odoo import api, exceptions, fields, models, _
from odoo.tools import consteq, float_round, image_resize_images, image_resize_image, ustr
from odoo.addons.base.models import ir_module
from odoo.exceptions import ValidationError
+from odoo import api, SUPERUSER_ID
_logger = logging.getLogger(__name__)
@@ -21,6 +22,11 @@ def _partner_split_name(partner_name):
return [' '.join(partner_name.split()[:-1]), ' '.join(partner_name.split()[-1:])]
+def create_missing_journal_for_acquirers(cr, registry):
+ env = api.Environment(cr, SUPERUSER_ID, {})
+ env['payment.acquirer']._create_missing_journal_for_acquirers()
+
+
class PaymentAcquirer(models.Model):
""" Acquirer Model. Each specific acquirer can extend the model by adding
its own fields, using the acquirer_name as a prefix for the new fields.
@@ -52,6 +58,9 @@ class PaymentAcquirer(models.Model):
_description = 'Payment Acquirer'
_order = 'website_published desc, sequence, name'
+ def _get_default_view_template_id(self):
+ return self.env.ref('payment.default_acquirer_button', raise_if_not_found=False)
+
name = fields.Char('Name', required=True, translate=True)
description = fields.Html('Description')
sequence = fields.Integer('Sequence', default=10, help="Determine the display order")
@@ -62,7 +71,8 @@ class PaymentAcquirer(models.Model):
'res.company', 'Company',
default=lambda self: self.env.user.company_id.id, required=True)
view_template_id = fields.Many2one(
- 'ir.ui.view', 'Form Button Template', required=True)
+ 'ir.ui.view', 'Form Button Template', required=True,
+ default=_get_default_view_template_id)
registration_view_template_id = fields.Many2one(
'ir.ui.view', 'S2S Form Template', domain=[('type', '=', 'qweb')],
help="Template for method registration")
@@ -197,6 +207,58 @@ class PaymentAcquirer(models.Model):
"""
return dict(authorize=[], tokenize=[], fees=[])
+ @api.multi
+ def _prepare_account_journal_vals(self):
+ '''Prepare the values to create the acquirer's journal.
+ :return: a dictionary to create a account.journal record.
+ '''
+ self.ensure_one()
+ account_vals = self.env['account.journal']._prepare_liquidity_account(
+ self.name, self.company_id, None, 'bank')
+ account_vals['user_type_id'] = self.env.ref('account.data_account_type_current_assets').id
+ account_vals['reconcile'] = True
+ account = self.env['account.account'].create(account_vals)
+ return {
+ 'name': self.name,
+ 'code': self.name.upper(),
+ 'sequence': 999,
+ 'type': 'bank',
+ 'company_id': self.company_id.id,
+ 'default_debit_account_id': account.id,
+ 'default_credit_account_id': account.id,
+ # Show the journal on dashboard if the acquirer is published on the website.
+ 'show_on_dashboard': self.website_published,
+ # Don't show payment methods in the backend.
+ 'inbound_payment_method_ids': [],
+ 'outbound_payment_method_ids': [],
+ }
+
+ @api.model
+ def _create_missing_journal_for_acquirers(self, company=None):
+ '''Create the journal for active acquirers.
+ We want one journal per acquirer. However, we can't create them during the 'create' of the payment.acquirer
+ because every acquirers are defined on the 'payment' module but is active only when installing their own module
+ (e.g. payment_paypal for Paypal). We can't do that in such modules because we have no guarantee the chart template
+ is already installed.
+ '''
+ # Search for installed acquirers modules.
+ # If this method is triggered by a post_init_hook, the module is 'to install'.
+ # If the trigger comes from the chart template wizard, the modules are already installed.
+ acquirer_modules = self.env['ir.module.module'].search(
+ [('name', 'like', 'payment_%'), ('state', 'in', ('to install', 'installed'))])
+ acquirer_names = [a.name.split('_')[1] for a in acquirer_modules]
+
+ # Search for acquirers having no journal
+ company = company or self.env.user.company_id
+ acquirers = self.env['payment.acquirer'].search(
+ [('provider', 'in', acquirer_names), ('journal_id', '=', False), ('company_id', '=', company.id)])
+
+ journals = self.env['account.journal']
+ for acquirer in acquirers.filtered(lambda l: not l.journal_id and l.company_id.chart_template_id):
+ acquirer.journal_id = self.env['account.journal'].create(acquirer._prepare_account_journal_vals())
+ journals += acquirer.journal_id
+ return journals
+
@api.model
def create(self, vals):
image_resize_images(vals)
@@ -209,7 +271,13 @@ class PaymentAcquirer(models.Model):
@api.multi
def toggle_website_published(self):
- self.write({'website_published': not self.website_published})
+ ''' When clicking on the website publish toggle button, the website_published is reversed and
+ the acquirer journal is set or not in favorite on the dashboard.
+ '''
+ self.ensure_one()
+ self.website_published = not self.website_published
+ if self.journal_id:
+ self.journal_id.show_on_dashboard = self.website_published
return True
@api.multi
diff --git a/addons/payment/views/payment_views.xml b/addons/payment/views/payment_views.xml
index f3c8c0af16d..84d45c47eae 100644
--- a/addons/payment/views/payment_views.xml
+++ b/addons/payment/views/payment_views.xml
@@ -81,7 +81,7 @@
</page>
<page string="Configuration">
<group name="acquirer_config">
- <field name="journal_id" context="{'default_type': 'bank'}" required="1"/>
+ <field name="journal_id" context="{'default_type': 'bank'}"/>
<field name="capture_manually" attrs="{'invisible': [('authorize_implemented', '=', False)]}"/>
<field name="save_token" widget="radio" attrs="{'invisible': ['|', ('token_implemented', '=', False), ('payment_flow', '=', 's2s')]}"/>
<field name="fees_active" attrs="{'invisible': [('fees_implemented', '=', False)]}"/>
@@ -113,7 +113,7 @@
</div>
<field name="registration_view_template_id" groups="base.group_no_one"/>
<field name="payment_icon_ids" widget="many2many_tags"/>
- <field name="payment_flow" widget="radio"/>
+ <field name="payment_flow" widget="radio" attrs="{'invisible': [('token_implemented', '=', False)]}"/>
</group>
</page>
</notebook>
diff --git a/addons/payment_adyen/__init__.py b/addons/payment_adyen/__init__.py
index 8c67f893b37..f2ff55f0433 100644
--- a/addons/payment_adyen/__init__.py
+++ b/addons/payment_adyen/__init__.py
@@ -3,3 +3,4 @@
from . import models
from . import controllers
+from odoo.addons.payment.models.payment_acquirer import create_missing_journal_for_acquirers
diff --git a/addons/payment_adyen/__manifest__.py b/addons/payment_adyen/__manifest__.py
index 1e26a8808ca..8b04a9834e2 100644
--- a/addons/payment_adyen/__manifest__.py
+++ b/addons/payment_adyen/__manifest__.py
@@ -13,4 +13,5 @@
'data/payment_acquirer_data.xml',
],
'installable': True,
+ 'post_init_hook': 'create_missing_journal_for_acquirers',
}
diff --git a/addons/payment_authorize/__init__.py b/addons/payment_authorize/__init__.py
index 8c67f893b37..f2ff55f0433 100644
--- a/addons/payment_authorize/__init__.py
+++ b/addons/payment_authorize/__init__.py
@@ -3,3 +3,4 @@
from . import models
from . import controllers
+from odoo.addons.payment.models.payment_acquirer import create_missing_journal_for_acquirers
diff --git a/addons/payment_authorize/__manifest__.py b/addons/payment_authorize/__manifest__.py
index 4a8eafa8b73..af6c1e946b9 100644
--- a/addons/payment_authorize/__manifest__.py
+++ b/addons/payment_authorize/__manifest__.py
@@ -13,4 +13,5 @@
'data/payment_acquirer_data.xml',
],
'installable': True,
+ 'post_init_hook': 'create_missing_journal_for_acquirers',
}
diff --git a/addons/payment_buckaroo/__init__.py b/addons/payment_buckaroo/__init__.py
index 8c67f893b37..f2ff55f0433 100644
--- a/addons/payment_buckaroo/__init__.py
+++ b/addons/payment_buckaroo/__init__.py
@@ -3,3 +3,4 @@
from . import models
from . import controllers
+from odoo.addons.payment.models.payment_acquirer import create_missing_journal_for_acquirers
diff --git a/addons/payment_buckaroo/__manifest__.py b/addons/payment_buckaroo/__manifest__.py
index 3e56a451c52..f08e9152473 100644
--- a/addons/payment_buckaroo/__manifest__.py
+++ b/addons/payment_buckaroo/__manifest__.py
@@ -13,4 +13,5 @@
'data/payment_acquirer_data.xml',
],
'installable': True,
+ 'post_init_hook': 'create_missing_journal_for_acquirers',
}
diff --git a/addons/payment_ogone/__init__.py b/addons/payment_ogone/__init__.py
index 8c67f893b37..f2ff55f0433 100644
--- a/addons/payment_ogone/__init__.py
+++ b/addons/payment_ogone/__init__.py
@@ -3,3 +3,4 @@
from . import models
from . import controllers
+from odoo.addons.payment.models.payment_acquirer import create_missing_journal_for_acquirers
diff --git a/addons/payment_ogone/__manifest__.py b/addons/payment_ogone/__manifest__.py
index 1fd1ee9c55b..3866d1e115b 100644
--- a/addons/payment_ogone/__manifest__.py
+++ b/addons/payment_ogone/__manifest__.py
@@ -13,4 +13,5 @@
'data/payment_acquirer_data.xml',
],
'installable': True,
+ 'post_init_hook': 'create_missing_journal_for_acquirers',
}
diff --git a/addons/payment_paypal/__init__.py b/addons/payment_paypal/__init__.py
index 8c67f893b37..f2ff55f0433 100644
--- a/addons/payment_paypal/__init__.py
+++ b/addons/payment_paypal/__init__.py
@@ -3,3 +3,4 @@
from . import models
from . import controllers
+from odoo.addons.payment.models.payment_acquirer import create_missing_journal_for_acquirers
diff --git a/addons/payment_paypal/__manifest__.py b/addons/payment_paypal/__manifest__.py
index 352b130e051..bf2e9e90b51 100644
--- a/addons/payment_paypal/__manifest__.py
+++ b/addons/payment_paypal/__manifest__.py
@@ -13,4 +13,5 @@
'data/payment_acquirer_data.xml',
],
'installable': True,
+ 'post_init_hook': 'create_missing_journal_for_acquirers',
}
diff --git a/addons/payment_payumoney/__init__.py b/addons/payment_payumoney/__init__.py
index 8c67f893b37..f2ff55f0433 100644
--- a/addons/payment_payumoney/__init__.py
+++ b/addons/payment_payumoney/__init__.py
@@ -3,3 +3,4 @@
from . import models
from . import controllers
+from odoo.addons.payment.models.payment_acquirer import create_missing_journal_for_acquirers
diff --git a/addons/payment_payumoney/__manifest__.py b/addons/payment_payumoney/__manifest__.py
index 794ba6b6de1..66f83456fcb 100644
--- a/addons/payment_payumoney/__manifest__.py
+++ b/addons/payment_payumoney/__manifest__.py
@@ -16,4 +16,5 @@
'views/payment_payumoney_templates.xml',
'data/payment_acquirer_data.xml',
],
+ 'post_init_hook': 'create_missing_journal_for_acquirers',
}
diff --git a/addons/payment_sips/__init__.py b/addons/payment_sips/__init__.py
index f7209b17100..c7d74c9c782 100644
--- a/addons/payment_sips/__init__.py
+++ b/addons/payment_sips/__init__.py
@@ -1,2 +1,3 @@
from . import models
from . import controllers
+from odoo.addons.payment.models.payment_acquirer import create_missing_journal_for_acquirers
diff --git a/addons/payment_sips/__manifest__.py b/addons/payment_sips/__manifest__.py
index 6039f962009..2764807c5ea 100644
--- a/addons/payment_sips/__manifest__.py
+++ b/addons/payment_sips/__manifest__.py
@@ -20,4 +20,5 @@ payments acquirer using Worldline SIPS.""",
'data/payment_acquirer_data.xml',
],
'installable': True,
+ 'post_init_hook': 'create_missing_journal_for_acquirers',
}
diff --git a/addons/payment_stripe/__init__.py b/addons/payment_stripe/__init__.py
index 8c67f893b37..f2ff55f0433 100644
--- a/addons/payment_stripe/__init__.py
+++ b/addons/payment_stripe/__init__.py
@@ -3,3 +3,4 @@
from . import models
from . import controllers
+from odoo.addons.payment.models.payment_acquirer import create_missing_journal_for_acquirers
diff --git a/addons/payment_stripe/__manifest__.py b/addons/payment_stripe/__manifest__.py
index 6eb664791cb..247fe74859b 100644
--- a/addons/payment_stripe/__manifest__.py
+++ b/addons/payment_stripe/__manifest__.py
@@ -14,4 +14,5 @@
],
'images': ['static/description/icon.png'],
'installable': True,
+ 'post_init_hook': 'create_missing_journal_for_acquirers',
}
diff --git a/addons/payment_transfer/__init__.py b/addons/payment_transfer/__init__.py
index 8c67f893b37..f2ff55f0433 100644
--- a/addons/payment_transfer/__init__.py
+++ b/addons/payment_transfer/__init__.py
@@ -3,3 +3,4 @@
from . import models
from . import controllers
+from odoo.addons.payment.models.payment_acquirer import create_missing_journal_for_acquirers
diff --git a/addons/payment_transfer/__manifest__.py b/addons/payment_transfer/__manifest__.py
index 9f8704467dc..530fe49ede4 100644
--- a/addons/payment_transfer/__manifest__.py
+++ b/addons/payment_transfer/__manifest__.py
@@ -14,4 +14,5 @@
],
'installable': True,
'auto_install': True,
+ 'post_init_hook': 'create_missing_journal_for_acquirers',
}
diff --git a/addons/payment_transfer/models/payment.py b/addons/payment_transfer/models/payment.py
index 00a34ac0ad4..18c74d2246d 100644
--- a/addons/payment_transfer/models/payment.py
+++ b/addons/payment_transfer/models/payment.py
@@ -15,6 +15,19 @@ class TransferPaymentAcquirer(models.Model):
provider = fields.Selection(selection_add=[('transfer', 'Wire Transfer')], default='transfer')
+ @api.model
+ def _create_missing_journal_for_acquirers(self, company=None):
+ # By default, the wire transfer method uses the default Bank journal.
+ company = company or self.env.user.company_id
+ acquirers = self.env['payment.acquirer'].search(
+ [('provider', '=', 'transfer'), ('journal_id', '=', False), ('company_id', '=', company.id)])
+
+ bank_journal = self.env['account.journal'].search(
+ [('type', '=', 'bank'), ('company_id', '=', company.id)], limit=1)
+ if bank_journal:
+ acquirers.write({'journal_id': bank_journal.id})
+ return super(TransferPaymentAcquirer, self)._create_missing_journal_for_acquirers(company=company)
+
def transfer_get_form_action_url(self):
return '/payment/transfer/feedback'
diff --git a/addons/product/models/product.py b/addons/product/models/product.py
index c0a892a3853..b00eaa33f62 100644
--- a/addons/product/models/product.py
+++ b/addons/product/models/product.py
@@ -230,9 +230,9 @@ class ProductProduct(models.Model):
for supplier_info in self.seller_ids:
if supplier_info.name.id == self._context.get('partner_id'):
product_name = supplier_info.product_name or self.default_code
+ self.partner_ref = '%s%s' % (self.code and '[%s] ' % self.code or '', product_name)
else:
- product_name = self.name
- self.partner_ref = '%s%s' % (self.code and '[%s] ' % self.code or '', product_name)
+ self.partner_ref = self.name_get()[0][1]
@api.one
@api.depends('image_variant', 'product_tmpl_id.image')
@@ -431,7 +431,12 @@ class ProductProduct(models.Model):
limit2 = (limit - len(products)) if limit else False
products += self.search(args + [('name', operator, name), ('id', 'not in', products.ids)], limit=limit2)
elif not products and operator in expression.NEGATIVE_TERM_OPERATORS:
- products = self.search(args + ['&', ('default_code', operator, name), ('name', operator, name)], limit=limit)
+ domain = expression.OR([
+ ['&', ('default_code', operator, name), ('name', operator, name)],
+ ['&', ('default_code', '=', False), ('name', operator, name)],
+ ])
+ domain = expression.AND([args, domain])
+ products = self.search(domain, limit=limit)
if not products and operator in positive_operators:
ptrn = re.compile('(\[(.*?)\])')
res = ptrn.search(name)
diff --git a/addons/product/tests/test_variants.py b/addons/product/tests/test_variants.py
index 7917a0d4a2b..804bbc55c95 100644
--- a/addons/product/tests/test_variants.py
+++ b/addons/product/tests/test_variants.py
@@ -40,6 +40,15 @@ class TestVariantsSearch(TransactionCase):
self.assertIn(self.product_shirt_template, search_value,
'Shirt should be found searching L')
+ def test_name_search(self):
+ self.product_slip_template = self.env['product.template'].create({
+ 'name': 'Slip',
+ })
+ res = self.env['product.product'].name_search('Shirt', [], 'not ilike', None)
+ res_ids = [r[0] for r in res]
+ self.assertIn(self.product_slip_template.product_variant_ids.id, res_ids,
+ 'Slip should be found searching \'not ilike\'')
+
class TestVariants(common.TestProductCommon):
diff --git a/addons/purchase/models/account_invoice.py b/addons/purchase/models/account_invoice.py
index 4847ddf11ee..7f170d4e814 100644
--- a/addons/purchase/models/account_invoice.py
+++ b/addons/purchase/models/account_invoice.py
@@ -168,6 +168,11 @@ class AccountInvoice(models.Model):
valuation_price_unit = i_line.purchase_line_id.product_uom._compute_price(i_line.purchase_line_id.price_unit, i_line.uom_id)
stock_move_obj = self.env['stock.move']
valuation_stock_move = stock_move_obj.search([('purchase_line_id', '=', i_line.purchase_line_id.id), ('state', '=', 'done')])
+ if self.type == 'in_refund':
+ valuation_stock_move = valuation_stock_move.filtered(lambda m: m._is_out())
+ elif self.type == 'in_invoice':
+ valuation_stock_move = valuation_stock_move.filtered(lambda m: m._is_in())
+
if valuation_stock_move:
valuation_price_unit_total = 0
valuation_total_qty = 0
diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py
index 994142c7362..08995f2aac6 100644
--- a/addons/purchase/models/purchase.py
+++ b/addons/purchase/models/purchase.py
@@ -92,7 +92,7 @@ class PurchaseOrder(models.Model):
@api.depends('picking_ids', 'picking_ids.state')
def _compute_is_shipped(self):
for order in self:
- if order.picking_ids and all([x.state == 'done' for x in order.picking_ids]):
+ if order.picking_ids and all([x.state in ['done', 'cancel'] for x in order.picking_ids]):
order.is_shipped = True
READONLY_STATES = {
@@ -1054,7 +1054,7 @@ class ProcurementRule(models.Model):
gpo = self.group_propagation_option
group = (gpo == 'fixed' and self.group_id.id) or \
- (gpo == 'propagate' and 'group_id' in values and values['group_id'].id) or False
+ (gpo == 'propagate' and values.get('group_id') and values['group_id'].id) or False
return {
'partner_id': partner.id,
diff --git a/addons/purchase/tests/test_stockvaluation.py b/addons/purchase/tests/test_stockvaluation.py
index cb5e4b2040e..f7e320a50ce 100644
--- a/addons/purchase/tests/test_stockvaluation.py
+++ b/addons/purchase/tests/test_stockvaluation.py
@@ -5,6 +5,7 @@ import time
from datetime import datetime
from odoo.tests.common import TransactionCase
+from odoo.addons.account.tests.account_test_classes import AccountingTestCase
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
@@ -271,3 +272,139 @@ class TestStockValuation(TransactionCase):
self.assertEqual(move2.price_unit, 100)
self.assertEqual(move2.product_qty, 5)
+
+class TestStockValuationWithCOA(AccountingTestCase):
+ def setUp(self):
+ super(TestStockValuationWithCOA, self).setUp()
+ self.supplier_location = self.env.ref('stock.stock_location_suppliers')
+ self.stock_location = self.env.ref('stock.stock_location_stock')
+ self.partner_id = self.env.ref('base.res_partner_1')
+ self.product1 = self.env.ref('product.product_product_8')
+ Account = self.env['account.account']
+ self.stock_input_account = Account.create({
+ 'name': 'Stock Input',
+ 'code': 'StockIn',
+ 'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
+ })
+ self.stock_output_account = Account.create({
+ 'name': 'Stock Output',
+ 'code': 'StockOut',
+ 'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
+ })
+ self.stock_valuation_account = Account.create({
+ 'name': 'Stock Valuation',
+ 'code': 'Stock Valuation',
+ 'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
+ })
+ self.stock_journal = self.env['account.journal'].create({
+ 'name': 'Stock Journal',
+ 'code': 'STJTEST',
+ 'type': 'general',
+ })
+ self.product1.categ_id.write({
+ 'property_stock_account_input_categ_id': self.stock_input_account.id,
+ 'property_stock_account_output_categ_id': self.stock_output_account.id,
+ 'property_stock_valuation_account_id': self.stock_valuation_account.id,
+ 'property_stock_journal': self.stock_journal.id,
+ })
+
+ def test_fifo_anglosaxon_return(self):
+ self.env.user.company_id.anglo_saxon_accounting = True
+ self.product1.product_tmpl_id.cost_method = 'fifo'
+ self.product1.product_tmpl_id.valuation = 'real_time'
+ self.product1.product_tmpl_id.invoice_policy = 'delivery'
+ price_diff_account = self.env['account.account'].create({
+ 'name': 'price diff account',
+ 'code': 'price diff account',
+ 'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
+ })
+ self.product1.property_account_creditor_price_difference = price_diff_account
+
+ # Receive 10@10 ; create the vendor bill
+ po1 = self.env['purchase.order'].create({
+ 'partner_id': self.partner_id.id,
+ 'order_line': [
+ (0, 0, {
+ 'name': self.product1.name,
+ 'product_id': self.product1.id,
+ 'product_qty': 10.0,
+ 'product_uom': self.product1.uom_po_id.id,
+ 'price_unit': 10.0,
+ 'date_planned': datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
+ }),
+ ],
+ })
+ po1.button_confirm()
+ receipt_po1 = po1.picking_ids[0]
+ receipt_po1.move_lines.quantity_done = 10
+ receipt_po1.button_validate()
+
+ invoice_po1 = self.env['account.invoice'].create({
+ 'partner_id': self.partner_id.id,
+ 'purchase_id': po1.id,
+ 'account_id': self.partner_id.property_account_payable_id.id,
+ 'type': 'in_invoice',
+ })
+ invoice_po1.purchase_order_change()
+ invoice_po1.action_invoice_open()
+
+ # Receive 10@20 ; create the vendor bill
+ po2 = self.env['purchase.order'].create({
+ 'partner_id': self.partner_id.id,
+ 'order_line': [
+ (0, 0, {
+ 'name': self.product1.name,
+ 'product_id': self.product1.id,
+ 'product_qty': 10.0,
+ 'product_uom': self.product1.uom_po_id.id,
+ 'price_unit': 20.0,
+ 'date_planned': datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
+ }),
+ ],
+ })
+ po2.button_confirm()
+ receipt_po2 = po2.picking_ids[0]
+ receipt_po2.move_lines.quantity_done = 10
+ receipt_po2.button_validate()
+
+ invoice_po2 = self.env['account.invoice'].create({
+ 'partner_id': self.partner_id.id,
+ 'purchase_id': po2.id,
+ 'account_id': self.partner_id.property_account_payable_id.id,
+ 'type': 'in_invoice',
+ })
+ invoice_po2.purchase_order_change()
+ invoice_po2.action_invoice_open()
+
+ # valuation of product1 should be 300
+ self.assertEqual(self.product1.stock_value, 300)
+
+ # return the second po
+ stock_return_picking = self.env['stock.return.picking']\
+ .with_context(active_ids=receipt_po2.ids, active_id=receipt_po2.ids[0])\
+ .create({})
+ stock_return_picking.product_return_moves.quantity = 10
+ stock_return_picking_action = stock_return_picking.create_returns()
+ return_pick = self.env['stock.picking'].browse(stock_return_picking_action['res_id'])
+ return_pick.move_lines[0].move_line_ids[0].qty_done = 10
+ return_pick.do_transfer()
+
+ # valuation of product1 should be 200 as the first items will be sent out
+ self.assertEqual(self.product1.stock_value, 200)
+
+ # create a credit note for po2
+ creditnote_po2 = self.env['account.invoice'].create({
+ 'partner_id': self.partner_id.id,
+ 'purchase_id': po2.id,
+ 'account_id': self.partner_id.property_account_payable_id.id,
+ 'type': 'in_refund',
+ })
+
+ creditnote_po2.purchase_order_change()
+ creditnote_po2.invoice_line_ids[0].quantity = 10
+ creditnote_po2.action_invoice_open()
+
+ # check the anglo saxon entries
+ price_diff_entry = self.env['account.move.line'].search([('account_id', '=', price_diff_account.id)])
+ self.assertEqual(price_diff_entry.credit, 100)
+
diff --git a/addons/sale_payment/models/payment.py b/addons/sale_payment/models/payment.py
index 8076addab09..831af37550f 100644
--- a/addons/sale_payment/models/payment.py
+++ b/addons/sale_payment/models/payment.py
@@ -3,6 +3,7 @@
import logging
from odoo import api, fields, models, _
+from odoo.exceptions import UserError
from odoo.tools import float_compare
_logger = logging.getLogger(__name__)
@@ -84,8 +85,16 @@ class PaymentTransaction(models.Model):
# force_company needed for company_dependent fields
ctx_company = {'company_id': self.sale_order_id.company_id.id,
'force_company': self.sale_order_id.company_id.id}
- created_invoice = self.sale_order_id.with_context(**ctx_company).action_invoice_create()
- created_invoice = self.env['account.invoice'].browse(created_invoice).with_context(**ctx_company)
+
+ # We might fail to create the invoice because there is no invoiceable lines. This will
+ # raise a UserError and break the workflow. Better catch the error.
+ try:
+ created_invoice = self.sale_order_id.with_context(**ctx_company).action_invoice_create()
+ created_invoice = self.env['account.invoice'].browse(created_invoice).with_context(**ctx_company)
+ except UserError:
+ _logger.warning('<%s> transaction completed, could not auto-generate invoice for %s (ID %s)',
+ self.acquirer_id.provider, self.sale_order_id.name, self.sale_order_id.id, exc_info=True)
+ return
if created_invoice:
_logger.info('<%s> transaction completed, auto-generated invoice %s (ID %s) for %s (ID %s)',
diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py
index 5ab7b982f2f..f3788f8592f 100644
--- a/addons/stock/models/stock_move.py
+++ b/addons/stock/models/stock_move.py
@@ -487,9 +487,19 @@ class StockMove(models.Model):
}
def _do_unreserve(self):
- if any(move.state in ('done', 'cancel') for move in self):
- raise UserError(_('Cannot unreserve a done move'))
- self.mapped('move_line_ids').unlink()
+ moves_to_unreserve = self.env['stock.move']
+ for move in self:
+ if move.state == 'cancel':
+ # We may have cancelled move in an open picking in a "propagate_cancel" scenario.
+ continue
+ if move.state == 'done':
+ if move.scrapped:
+ # We may have done move in an open picking in a scrap scenario.
+ continue
+ else:
+ raise UserError(_('Cannot unreserve a done move'))
+ moves_to_unreserve |= move
+ moves_to_unreserve.mapped('move_line_ids').unlink()
return True
def _push_apply(self):
@@ -590,7 +600,7 @@ class StockMove(models.Model):
# We are using propagate to False in order to not cancel destination moves merged in moves[0]
moves_to_unlink.write({'propagate': False})
moves_to_unlink._action_cancel()
- moves_to_unlink.unlink()
+ moves_to_unlink.sudo().unlink()
return (self | self.env['stock.move'].concat(*moves_to_merge)) - moves_to_unlink
def _get_relevant_state_among_moves(self):
@@ -806,7 +816,12 @@ class StockMove(models.Model):
}
if quantity:
uom_quantity = self.product_id.uom_id._compute_quantity(quantity, self.product_uom, rounding_method='HALF-UP')
- vals = dict(vals, product_uom_qty=uom_quantity)
+ uom_quantity_back_to_product_uom = self.product_uom._compute_quantity(uom_quantity, self.product_id.uom_id, rounding_method='HALF-UP')
+ rounding = self.env['decimal.precision'].precision_get('Product Unit of Measure')
+ if float_compare(quantity, uom_quantity_back_to_product_uom, precision_digits=rounding) == 0:
+ vals = dict(vals, product_uom_qty=uom_quantity)
+ else:
+ vals = dict(vals, product_uom_qty=quantity, product_uom_id=self.product_id.uom_id.id)
if reserved_quant:
vals = dict(
vals,
@@ -836,11 +851,20 @@ class StockMove(models.Model):
# is if the move's unit of measure's rounding does not allow fractional reservation. We chose
# to convert `taken_quantity` to the move's unit of measure with a down rounding method and
# then get it back in the quants unit of measure with an half-up rounding_method. This
- # way, we'll never reserve more than allowed.
- taken_quantity_move_uom = self.product_id.uom_id._compute_quantity(taken_quantity, self.product_uom, rounding_method='DOWN')
- taken_quantity = self.product_uom._compute_quantity(taken_quantity_move_uom, self.product_id.uom_id, rounding_method='HALF-UP')
+ # way, we'll never reserve more than allowed. We do not apply this logic if
+ # `available_quantity` is brought by a chained move line. In this case, `_prepare_move_line_vals`
+ # will take care of changing the UOM to the UOM of the product.
+ if not strict:
+ taken_quantity_move_uom = self.product_id.uom_id._compute_quantity(taken_quantity, self.product_uom, rounding_method='DOWN')
+ taken_quantity = self.product_uom._compute_quantity(taken_quantity_move_uom, self.product_id.uom_id, rounding_method='HALF-UP')
quants = []
+
+ if self.product_id.tracking == 'serial':
+ rounding = self.env['decimal.precision'].precision_get('Product Unit of Measure')
+ if float_compare(taken_quantity, int(taken_quantity), precision_digits=rounding) != 0:
+ taken_quantity = 0
+
try:
if not float_is_zero(taken_quantity, precision_rounding=self.product_id.uom_id.rounding):
quants = self.env['stock.quant']._update_reserved_quantity(
@@ -860,7 +884,7 @@ class StockMove(models.Model):
to_update = self.move_line_ids.filtered(lambda m: m.product_id.tracking != 'serial' and
m.location_id.id == reserved_quant.location_id.id and m.lot_id.id == reserved_quant.lot_id.id and m.package_id.id == reserved_quant.package_id.id and m.owner_id.id == reserved_quant.owner_id.id)
if to_update:
- to_update[0].with_context(bypass_reservation_update=True).product_uom_qty += self.product_id.uom_id._compute_quantity(quantity, self.product_uom, rounding_method='HALF-UP')
+ to_update[0].with_context(bypass_reservation_update=True).product_uom_qty += self.product_id.uom_id._compute_quantity(quantity, to_update.product_uom_id, rounding_method='HALF-UP')
else:
if self.product_id.tracking == 'serial':
for i in range(0, int(quantity)):
@@ -1017,8 +1041,8 @@ class StockMove(models.Model):
# create the extra moves
extra_move_quantity = float_round(
self.quantity_done - self.product_uom_qty,
- precision_rounding=self.product_uom.rounding,
- rounding_method ='UP')
+ precision_rounding=rounding,
+ rounding_method='HALF-UP')
extra_move_vals = self._prepare_extra_move_vals(extra_move_quantity)
extra_move = self.copy(default=extra_move_vals)
if extra_move.picking_id:
@@ -1088,7 +1112,7 @@ class StockMove(models.Model):
pass
# If you were already putting stock.move.lots on the next one in the work order, transfer those to the new move
- move.move_line_ids.filtered(lambda x: x.qty_done == 0.0).write({'move_id': new_move})
+ move.move_line_ids.filtered(lambda x: x.qty_done == 0.0).write({'move_id': new_move, 'product_uom_qty': 0})
move.move_line_ids._action_done()
# Check the consistency of the result packages; there should be an unique location across
# the contained quants.
diff --git a/addons/stock/tests/test_move.py b/addons/stock/tests/test_move.py
index c7f24401108..32e815b7af3 100644
--- a/addons/stock/tests/test_move.py
+++ b/addons/stock/tests/test_move.py
@@ -884,6 +884,47 @@ class StockMove(TransactionCase):
move._action_done()
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product1, self.customer_location), 12.0)
+ def test_availability_7(self):
+ """ Check that, in the scenario where a move is in a bigger uom than the uom of the quants
+ and this uom only allows entire numbers, we only reserve quantity honouring the uom's
+ rounding even if the quantity is set across multiple quants.
+ """
+ # on the dozen uom, set the rounding set 1.0
+ self.uom_dozen.rounding = 1
+
+ # make 12 quants of 1
+ for i in range(1, 13):
+ lot_id = self.env['stock.production.lot'].create({
+ 'name': 'lot%s' % str(i),
+ 'product_id': self.product2.id,
+ })
+ self.env['stock.quant']._update_available_quantity(self.product2, self.stock_location, 1.0, lot_id=lot_id)
+
+ # the move should be reserved
+ move = self.env['stock.move'].create({
+ 'name': 'test_availability_7',
+ 'location_id': self.stock_location.id,
+ 'location_dest_id': self.customer_location.id,
+ 'product_id': self.product2.id,
+ 'product_uom': self.uom_dozen.id,
+ 'product_uom_qty': 1,
+ })
+ move._action_confirm()
+ move._action_assign()
+ self.assertEqual(move.state, 'assigned')
+ self.assertEqual(len(move.move_line_ids.mapped('product_uom_id')), 1)
+ self.assertEqual(move.move_line_ids.mapped('product_uom_id'), self.uom_unit)
+
+ for move_line in move.move_line_ids:
+ move_line.qty_done = 1
+ move._action_done()
+
+ self.assertEqual(move.product_uom_qty, 1)
+ self.assertEqual(move.product_uom.id, self.uom_dozen.id)
+ self.assertEqual(move.state, 'done')
+ self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product2, self.customer_location), 12.0)
+ self.assertEqual(len(self.env['stock.quant']._gather(self.product2, self.customer_location)), 12)
+
def test_unreserve_1(self):
""" Check that unreserving a stock move sets the products reserved as available and
set the state back to confirmed.
@@ -1486,7 +1527,10 @@ class StockMove(TransactionCase):
# the second move should not be reservable because of the rounding on the dozen
move_pack_cust._action_assign()
- self.assertEqual(move_pack_cust.state, 'waiting')
+ self.assertEqual(move_pack_cust.state, 'partially_available')
+ move_line_pack_cust = move_pack_cust.move_line_ids
+ self.assertEqual(move_line_pack_cust.product_uom_qty, 6)
+ self.assertEqual(move_line_pack_cust.product_uom_id.id, self.uom_unit.id)
# move a dozen on the backorder to see how we handle the extra move
backorder = self.env['stock.picking'].search([('backorder_id', '=', picking_stock_pack.id)])
@@ -1514,6 +1558,152 @@ class StockMove(TransactionCase):
# the second move should now be reservable
move_pack_cust._action_assign()
self.assertEqual(move_pack_cust.state, 'assigned')
+ self.assertEqual(move_line_pack_cust.product_uom_qty, 12)
+ self.assertEqual(move_line_pack_cust.product_uom_id.id, self.uom_unit.id)
+ self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product1, move_stock_pack.location_dest_id), 6)
+
+ def test_link_assign_8(self):
+ """ Set the rounding of the dozen to 1.0, create a chain of two move for a dozen, the product
+ concerned is tracked by serial number. Check that the flow is ok.
+ """
+ # on the dozen uom, set the rounding set 1.0
+ self.uom_dozen.rounding = 1
+
+ # 6 units are available in stock
+ for i in range(1, 13):
+ lot_id = self.env['stock.production.lot'].create({
+ 'name': 'lot%s' % str(i),
+ 'product_id': self.product2.id,
+ })
+ self.env['stock.quant']._update_available_quantity(self.product2, self.stock_location, 1.0, lot_id=lot_id)
+
+ # create pickings and moves for a pick -> pack mto scenario
+ picking_stock_pack = self.env['stock.picking'].create({
+ 'location_id': self.stock_location.id,
+ 'location_dest_id': self.pack_location.id,
+ 'picking_type_id': self.env.ref('stock.picking_type_internal').id,
+ })
+ move_stock_pack = self.env['stock.move'].create({
+ 'name': 'test_link_assign_7',
+ 'location_id': self.stock_location.id,
+ 'location_dest_id': self.pack_location.id,
+ 'product_id': self.product2.id,
+ 'product_uom': self.uom_dozen.id,
+ 'product_uom_qty': 1.0,
+ 'picking_id': picking_stock_pack.id,
+ })
+ picking_pack_cust = self.env['stock.picking'].create({
+ 'location_id': self.pack_location.id,
+ 'location_dest_id': self.customer_location.id,
+ 'picking_type_id': self.env.ref('stock.picking_type_out').id,
+ })
+ move_pack_cust = self.env['stock.move'].create({
+ 'name': 'test_link_assign_7',
+ 'location_id': self.pack_location.id,
+ 'location_dest_id': self.customer_location.id,
+ 'product_id': self.product2.id,
+ 'product_uom': self.uom_dozen.id,
+ 'product_uom_qty': 1.0,
+ 'picking_id': picking_pack_cust.id,
+ })
+ move_stock_pack.write({'move_dest_ids': [(4, move_pack_cust.id, 0)]})
+ move_pack_cust.write({'move_orig_ids': [(4, move_stock_pack.id, 0)]})
+ (move_stock_pack + move_pack_cust)._action_confirm()
+
+ move_stock_pack._action_assign()
+ self.assertEqual(move_stock_pack.state, 'assigned')
+ move_pack_cust._action_assign()
+ self.assertEqual(move_pack_cust.state, 'waiting')
+
+ for ml in move_stock_pack.move_line_ids:
+ ml.qty_done = 1
+ picking_stock_pack.button_validate()
+ self.assertEqual(move_pack_cust.state, 'assigned')
+ for ml in move_pack_cust.move_line_ids:
+ self.assertEqual(ml.product_uom_qty, 1)
+ self.assertEqual(ml.product_uom_id.id, self.uom_unit.id)
+ self.assertTrue(bool(ml.lot_id.id))
+
+ def test_link_assign_9(self):
+ """ Create an uom "3 units" which is 3 times the units but without rounding. Create 3
+ quants in stock and two chained moves. The first move will bring the 3 quants but the
+ second only validate 2 and create a backorder for the last one. Check that the reservation
+ is correctly cleared up for the last one.
+ """
+ uom_3units = self.env['product.uom'].create({
+ 'name': '3 units',
+ 'category_id': self.uom_unit.category_id.id,
+ 'factor_inv': 3,
+ 'rounding': 1,
+ })
+ for i in range(1, 4):
+ lot_id = self.env['stock.production.lot'].create({
+ 'name': 'lot%s' % str(i),
+ 'product_id': self.product2.id,
+ })
+ self.env['stock.quant']._update_available_quantity(self.product2, self.stock_location, 1.0, lot_id=lot_id)
+
+ picking_stock_pack = self.env['stock.picking'].create({
+ 'location_id': self.stock_location.id,
+ 'location_dest_id': self.pack_location.id,
+ 'picking_type_id': self.env.ref('stock.picking_type_internal').id,
+ })
+ move_stock_pack = self.env['stock.move'].create({
+ 'name': 'test_link_assign_9',
+ 'location_id': self.stock_location.id,
+ 'location_dest_id': self.pack_location.id,
+ 'product_id': self.product2.id,
+ 'product_uom': uom_3units.id,
+ 'product_uom_qty': 1.0,
+ 'picking_id': picking_stock_pack.id,
+ })
+ picking_pack_cust = self.env['stock.picking'].create({
+ 'location_id': self.pack_location.id,
+ 'location_dest_id': self.customer_location.id,
+ 'picking_type_id': self.env.ref('stock.picking_type_out').id,
+ })
+ move_pack_cust = self.env['stock.move'].create({
+ 'name': 'test_link_assign_0',
+ 'location_id': self.pack_location.id,
+ 'location_dest_id': self.customer_location.id,
+ 'product_id': self.product2.id,
+ 'product_uom': uom_3units.id,
+ 'product_uom_qty': 1.0,
+ 'picking_id': picking_pack_cust.id,
+ })
+ move_stock_pack.write({'move_dest_ids': [(4, move_pack_cust.id, 0)]})
+ move_pack_cust.write({'move_orig_ids': [(4, move_stock_pack.id, 0)]})
+ (move_stock_pack + move_pack_cust)._action_confirm()
+
+ picking_stock_pack.action_assign()
+ for ml in picking_stock_pack.move_lines.move_line_ids:
+ ml.qty_done = 1
+ picking_stock_pack.button_validate()
+ self.assertEqual(picking_pack_cust.state, 'assigned')
+ for ml in picking_pack_cust.move_lines.move_line_ids:
+ if ml.lot_id.name != 'lot3':
+ ml.qty_done = 1
+ res_dict_for_back_order = picking_pack_cust.button_validate()
+ backorder_wizard = self.env[(res_dict_for_back_order.get('res_model'))].browse(res_dict_for_back_order.get('res_id'))
+ backorder_wizard.with_context(debug=True).process()
+ backorder = self.env['stock.picking'].search([('backorder_id', '=', picking_pack_cust.id)])
+ backordered_ml = backorder.move_line_ids
+ quant_lot3 = self.env['stock.quant'].search([('lot_id', '=', backordered_ml.lot_id.id)])
+
+ # due to the rounding, the backordered quantity is 0.999 ; we shoudln't be able to reserve
+ # 0.999 on a tracked by serial number quant
+ self.assertEqual(backordered_ml.product_uom_qty, 0)
+ self.assertTrue(backordered_ml.lot_id)
+
+ # force the serial number and validate
+ backordered_ml.qty_done = 1
+
+ overprocessed_wizard = backorder.button_validate()
+ overprocessed_wizard = self.env['stock.overprocessed.transfer'].browse(overprocessed_wizard['res_id'])
+ overprocessed_wizard.action_confirm()
+
+ self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product2, self.customer_location), 3)
+ self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product2, self.pack_location), 0)
def test_use_unreserved_move_line_1(self):
""" Test that validating a stock move linked to an untracked product reserved by another one
@@ -1943,7 +2133,7 @@ class StockMove(TransactionCase):
self.assertEqual(move_line.product_qty, 5)
move_line.qty_done = 5.0
self.assertEqual(move_line.product_qty, 5) # don't change reservation
- move_line.with_context(debug=True).lot_id = lot1
+ move_line.lot_id = lot1
self.assertEqual(move_line.product_qty, 5) # don't change reservation when assgning a lot now
move1._action_done()
@@ -3325,39 +3515,6 @@ class StockMove(TransactionCase):
self.assertEqual(self.product1.qty_available, 5.0)
self.assertEqual(self.product1.with_context(company_owned=True).qty_available, 10.0)
- def test_split_1(self):
- """ When we split a move line and having one without quantity done, we want to keep reservation
- on the new one as it has not been unreserved during the copy.
- """
- move1 = self.env['stock.move'].create({
- 'name': 'test_split_1',
- 'location_id': self.stock_location.id,
- 'location_dest_id': self.customer_location.id,
- 'product_id': self.product1.id,
- 'product_uom': self.uom_unit.id,
- 'product_uom_qty': 10.0,
- 'picking_type_id': self.env.ref('stock.picking_type_in').id,
- })
-
- self.env['stock.quant']._update_available_quantity(self.product1, self.stock_location, 10)
-
- move1._action_confirm()
- move1._action_assign()
- move_line = move1.move_line_ids
-
- default = {'product_uom_qty': 3,
- 'qty_done': 3}
- move_line.copy(default=default)
- move_line.with_context(bypass_reservation_update=True).write({'product_uom_qty': 7, 'qty_done': 0})
- move1._action_done()
-
- new_move = self.env['stock.move'].search([('name', '=', 'test_split_1'), ('state', '=', 'confirmed')])
-
- self.assertEqual(move1.move_line_ids.product_uom_qty, 0.0)
- self.assertEqual(move1.move_line_ids.qty_done, 3.0)
- self.assertEqual(new_move.move_line_ids.product_uom_qty, 7.0)
- self.assertEqual(new_move.move_line_ids.qty_done, 0.0)
-
def test_edit_initial_demand_1(self):
""" Increase initial demand once everything is reserved and check if
the existing move_line is updated.
diff --git a/addons/stock/tests/test_move2.py b/addons/stock/tests/test_move2.py
index 5d253b46f1d..4e22335cad2 100644
--- a/addons/stock/tests/test_move2.py
+++ b/addons/stock/tests/test_move2.py
@@ -1059,6 +1059,38 @@ class TestSinglePicking(TestStockCommon):
for move in delivery.move_lines:
self.assertEqual(move.quantity_done, move.product_uom_qty, 'Initial demand should be equals to quantity done')
+ def test_extra_move_5(self):
+ """ Create a picking a move that is problematic with
+ rounding (5.95 - 5.5 = 0.4500000000000002). Ensure that
+ initial demand is corrct afer action_done and backoder
+ are not created.
+ """
+ delivery = self.env['stock.picking'].create({
+ 'location_id': self.stock_location,
+ 'location_dest_id': self.customer_location,
+ 'partner_id': self.partner_delta_id,
+ 'picking_type_id': self.picking_type_out,
+ })
+ self.MoveObj.create({
+ 'name': self.productA.name,
+ 'product_id': self.productA.id,
+ 'product_uom_qty': 5.5,
+ 'quantity_done': 5.95,
+ 'product_uom': self.productA.uom_id.id,
+ 'picking_id': delivery.id,
+ 'location_id': self.stock_location,
+ 'location_dest_id': self.customer_location,
+ })
+ stock_location = self.env['stock.location'].browse(self.stock_location)
+ self.env['stock.quant']._update_available_quantity(self.productA, stock_location, 5.5)
+ delivery.action_confirm()
+ delivery.action_assign()
+ delivery.action_done()
+ self.assertEqual(delivery.move_lines.product_uom_qty, 5.95, 'Move initial demand should be 5.95')
+
+ back_order = self.env['stock.picking'].search([('backorder_id', '=', delivery.id)])
+ self.assertFalse(back_order, 'There should be no back order')
+
def test_recheck_availability_1(self):
""" Check the good behavior of check availability. I create a DO for 2 unit with
only one in stock. After the first check availability, I should have 1 reserved
diff --git a/addons/stock_account/models/stock.py b/addons/stock_account/models/stock.py
index c29215f2b79..113ff99b87a 100644
--- a/addons/stock_account/models/stock.py
+++ b/addons/stock_account/models/stock.py
@@ -260,7 +260,7 @@ class StockMove(models.Model):
# Update the standard price with the price of the last used candidate, if any.
if new_standard_price and move.product_id.cost_method == 'fifo':
- move.product_id.standard_price = new_standard_price
+ move.product_id.sudo().standard_price = new_standard_price
# If there's still quantity to value but we're out of candidates, we fall in the
# negative stock use case. We chose to value the out move at the price of the
@@ -312,7 +312,9 @@ class StockMove(models.Model):
self.write(vals)
elif self._is_out():
valued_move_lines = self.move_line_ids.filtered(lambda ml: ml.location_id._should_be_valued() and not ml.location_dest_id._should_be_valued() and not ml.owner_id)
- valued_quantity = sum(valued_move_lines.mapped('qty_done'))
+ valued_quantity = 0
+ for valued_move_line in valued_move_lines:
+ valued_quantity += valued_move_line.product_uom_id._compute_quantity(valued_move_line.qty_done, self.product_id.uom_id)
self.env['stock.move']._run_fifo(self, quantity=quantity)
if self.product_id.cost_method in ['standard', 'average']:
curr_rounding = self.company_id.currency_id.rounding
@@ -528,17 +530,6 @@ class StockMove(models.Model):
raise UserError(_("The cost of %s is currently equal to 0. Change the cost or the configuration of your product to avoid an incorrect valuation.") % (self.product_id.name,))
credit_value = debit_value
- if self.product_id.cost_method == 'average' and self.company_id.anglo_saxon_accounting:
- # in case of a supplier return in anglo saxon mode, for products in average costing method, the stock_input
- # account books the real purchase price, while the stock account books the average price. The difference is
- # booked in the dedicated price difference account.
- if self.location_dest_id.usage == 'supplier' and self.origin_returned_move_id and self.origin_returned_move_id.purchase_line_id:
- debit_value = self.origin_returned_move_id.price_unit * qty
- # in case of a customer return in anglo saxon mode, for products in average costing method, the stock valuation
- # is made using the original average price to negate the delivery effect.
- if self.location_id.usage == 'customer' and self.origin_returned_move_id:
- debit_value = self.origin_returned_move_id.price_unit * qty
- credit_value = debit_value
partner_id = (self.picking_id.partner_id and self.env['res.partner']._find_accounting_partner(self.picking_id.partner_id).id) or False
debit_line_vals = {
'name': self.name,
@@ -602,7 +593,7 @@ class StockMove(models.Model):
move_lines = self.with_context(forced_ref=ref)._prepare_account_move_line(quantity, abs(self.value), credit_account_id, debit_account_id)
if move_lines:
date = self._context.get('force_period_date', fields.Date.context_today(self))
- new_account_move = AccountMove.create({
+ new_account_move = AccountMove.sudo().create({
'journal_id': journal_id,
'line_ids': move_lines,
'date': date,
diff --git a/addons/web/static/src/js/core/ajax.js b/addons/web/static/src/js/core/ajax.js
index 0ee6d2ad1ed..2912b319df2 100644
--- a/addons/web/static/src/js/core/ajax.js
+++ b/addons/web/static/src/js/core/ajax.js
@@ -260,8 +260,12 @@ function get_file(options) {
if (options.error) {
var body = this.contentDocument.body;
var nodes = body.children.length === 0 ? body.childNodes : body.children;
- var node = nodes[1] || nodes[0];
- options.error(JSON.parse(node.textContent));
+ options.error({
+ message: nodes.length > 1 ? nodes[1].textContent : '',
+ data: {
+ title: nodes.length > 0 ? nodes[0].textContent : '',
+ },
+ });
}
} finally {
complete();
diff --git a/addons/web/static/src/js/services/data_manager.js b/addons/web/static/src/js/services/data_manager.js
index bb7f25d206b..da9621b085e 100644
--- a/addons/web/static/src/js/services/data_manager.js
+++ b/addons/web/static/src/js/services/data_manager.js
@@ -204,6 +204,25 @@ return core.Class.extend({
_invalidate: function (cache, key) {
delete cache[key];
},
+ // Attribute that contains for each viewType the fields for
+ // that viewType as defaults and
+ // All the fields of the other viewTypes
+ // useful to ensure that every field is present
+ // when swithcing from view to view
+ attrs.mergeViewsFields = {};
+ _.each(attrs.views, function(firstObj, firstViewType) {
+ if (!attrs.mergeViewsFields[firstViewType]) {
+ attrs.mergeViewsFields[firstViewType] = {};
+ }
+ _.defaults(attrs.mergeViewsFields[firstViewType], firstObj.fields);
+
+ // We need to double-traverse the attrs.views to ensure
+ // every viewType contains all the other's fields
+ _.each(attrs.views, function(secondObj, secondViewType) {
+ _.defaults(attrs.mergeViewsFields[firstViewType], secondObj.fields);
+ });
+ });
+
});
});
diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js
index e02f51259ef..42eea2ccfd6 100644
--- a/addons/web/static/src/js/views/basic/basic_model.js
+++ b/addons/web/static/src/js/views/basic/basic_model.js
@@ -208,6 +208,8 @@ var BasicModel = AbstractModel.extend({
* assume main viewType from the record
* @param {Array} [options.fieldNames] list of field names for which a
* default value must be generated (used to complete the values dict)
+ * @param {record} [options.parentRecord] The parent record of the current one
+ * usefull to get all the fields from all the views the model can be displayed on.
* @returns {Deferred}
*/
applyDefaultValues: function (recordID, values, options) {
@@ -219,6 +221,20 @@ var BasicModel = AbstractModel.extend({
var fieldName;
record._changes = record._changes || {};
+ /* Get the field's definition in the parent record if it is
+ * not present in the current one.
+ *
+ * @param {string} fieldName The name of the field we try to get the definition for
+ * in the parent record
+ * @returns {Object} the field's definition
+ */
+ function getFieldsFromOtherViews(fieldName) {
+ return options.parentRecord
+ && options.parentRecord.mergedViewsFields[viewType]
+ && options.parentRecord.mergedViewsFields[viewType][fieldName]
+ || {};
+ }
+
// ignore values for non requested fields (for instance, fields that are
// not in the view)
values = _.pick(values, fieldNames);
@@ -227,7 +243,7 @@ var BasicModel = AbstractModel.extend({
for (var i = 0; i < fieldNames.length; i++) {
fieldName = fieldNames[i];
if (!(fieldName in values) && !(fieldName in record._changes)) {
- field = record.fields[fieldName];
+ field = record.fields[fieldName] || getFieldsFromOtherViews(fieldName);
if (field.type === 'float' ||
field.type === 'integer' ||
field.type === 'monetary') {
@@ -243,7 +259,7 @@ var BasicModel = AbstractModel.extend({
// parse each value and create dataPoints for relational fields
var defs = [];
for (fieldName in values) {
- field = record.fields[fieldName];
+ field = record.fields[fieldName] || getFieldsFromOtherViews(fieldName);
record.data[fieldName] = null;
var dp;
if (field.type === 'many2one' && values[fieldName]) {
@@ -2496,6 +2512,7 @@ var BasicModel = AbstractModel.extend({
var fieldNames = options && options.fieldNames || record.getFieldNames();
var viewType = options && options.viewType || record.viewType;
_.each(fieldNames, function (fieldName) {
+ var mergedViewsFields = record.fieldsInfo[viewType] && record.fieldsInfo[viewType][fieldName].mergeViewsFields || {};
var field = record.fields[fieldName];
if (field.type === 'one2many' || field.type === 'many2many') {
var fieldInfo = record.fieldsInfo[viewType][fieldName];
@@ -2518,6 +2535,7 @@ var BasicModel = AbstractModel.extend({
rawContext: rawContext,
relationField: field.relation_field,
viewType: view ? view.type : fieldInfo.viewType,
+ mergedViewsFields: mergedViewsFields,
});
record.data[fieldName] = list.id;
if (!fieldInfo.__no_fetch) {
@@ -3222,6 +3240,8 @@ var BasicModel = AbstractModel.extend({
* @param {string} [params.type='record'|'list']
* @param {[type]} [params.value]
* @param {string} [params.viewType] the type of the view, e.g. 'list' or 'form'
+ * @param {Object} [params.mergedViewsFields] Contains for each viewType
+ * all the other viewTypes' fields plus its own to allow switching views more smoothly
* @returns {Object} the resource created
*/
_makeDataPoint: function (params) {
@@ -3281,6 +3301,7 @@ var BasicModel = AbstractModel.extend({
type: type, // 'record' | 'list'
value: value,
viewType: params.viewType,
+ mergedViewsFields: params.mergedViewsFields || {},
};
// _editionViewType is a dict whose keys are field names and which is populated when a field
@@ -3324,22 +3345,15 @@ var BasicModel = AbstractModel.extend({
*/
_makeDefaultRecord: function (modelName, params) {
var self = this;
-
+ var parentRecord = self.localData[params.parentID];
var determineExtraFields = function() {
// Fields that are present in the originating view, that need to be initialized
// Hence preventing their value to crash when getting back to the originating view
- var parentRecord = self.localData[params.parentID];
-
var originView = parentRecord && parentRecord.fieldsInfo;
if (!originView || !originView[parentRecord.viewType])
return [];
- var fieldsFromOrigin = _.filter(Object.keys(originView[parentRecord.viewType]),
- function(fieldname) {
- return params.fields[fieldname] !== undefined;
- });
-
- return fieldsFromOrigin;
+ return Object.keys(originView[parentRecord.viewType]);
}
var fieldNames = Object.keys(params.fieldsInfo[params.viewType]);
@@ -3364,7 +3378,7 @@ var BasicModel = AbstractModel.extend({
viewType: params.viewType,
});
- return self.applyDefaultValues(record.id, result, {fieldNames: _.union(fieldNames, extraFields)})
+ return self.applyDefaultValues(record.id, result, {fieldNames: _.union(fieldNames, extraFields), parentRecord: parentRecord})
.then(function () {
var def = $.Deferred();
self._performOnChange(record, fields_key).always(function () {
@@ -3847,6 +3861,10 @@ var BasicModel = AbstractModel.extend({
var emptyGroupsIDs = _.difference(_.pluck(previousGroups, 'id'), list.data);
_.each(emptyGroupsIDs, function (groupID) {
list.data.push(groupID);
+ var emptyGroup = self.localData[groupID];
+ // this attribute hasn't been updated in the previous
+ // loop for empty groups
+ emptyGroup.aggregateValues = {};
});
}
return $.when.apply($, defs).then(function () {
diff --git a/addons/web/static/src/js/views/calendar/calendar_view.js b/addons/web/static/src/js/views/calendar/calendar_view.js
index 217f6240711..009ad103a99 100644
--- a/addons/web/static/src/js/views/calendar/calendar_view.js
+++ b/addons/web/static/src/js/views/calendar/calendar_view.js
@@ -114,8 +114,20 @@ var CalendarView = AbstractView.extend({
//if quick_add = is NOT False and IS specified in view, we this one for widgets.QuickCreate'
this.controllerParams.quickAddPop = (!('quick_add' in attrs) || utils.toBoolElse(attrs.quick_add+'', true));
this.controllerParams.disableQuickCreate = params.disable_quick_create || !this.controllerParams.quickAddPop;
- // If this field is set ot true, we don't open the event in form view, but in a popup with the view_id passed by this parameter
- this.controllerParams.formViewId = !attrs.form_view_id || !utils.toBoolElse(attrs.form_view_id, true) ? false : attrs.form_view_id;
+
+ // If form_view_id is set, then the calendar view will open a form view
+ // with this id, when it needs to edit or create an event.
+ this.controllerParams.formViewId =
+ attrs.form_view_id ? parseInt(attrs.form_view_id, 10) : false;
+ if (!this.controllerParams.formViewId && params.action) {
+ var formViewDescr = _.find(params.action.views, function (v) {
+ return v[1] === 'form';
+ });
+ if (formViewDescr) {
+ this.controllerParams.formViewId = formViewDescr[0];
+ }
+ }
+
this.controllerParams.readonlyFormViewId = !attrs.readonly_form_view_id || !utils.toBoolElse(attrs.readonly_form_view_id, true) ? false : attrs.readonly_form_view_id;
this.controllerParams.eventOpenPopup = utils.toBoolElse(attrs.event_open_popup || '', false);
this.controllerParams.mapping = mapping;
diff --git a/addons/web/static/src/js/views/kanban/kanban_model.js b/addons/web/static/src/js/views/kanban/kanban_model.js
index 411d4cc7b14..bf607d760d2 100644
--- a/addons/web/static/src/js/views/kanban/kanban_model.js
+++ b/addons/web/static/src/js/views/kanban/kanban_model.js
@@ -398,9 +398,8 @@ var KanbanModel = BasicModel.extend({
return $.when();
},
/**
- * Reloads all progressbar data if the given id is a record's one. This is
- * done after given deferred and insures that the given deferred's result is
- * not lost.
+ * Reloads all progressbar data. This is done after given deferred and
+ * insures that the given deferred's result is not lost.
*
* @private
* @param {string} recordID
@@ -409,9 +408,6 @@ var KanbanModel = BasicModel.extend({
*/
_reloadProgressBarGroupFromRecord: function (recordID, def) {
var element = this.localData[recordID];
- if (element.type !== 'record') {
- return def;
- }
// If we updated a record, then we must potentially update columns'
// progressbars, so we need to load groups info again
diff --git a/addons/web/static/src/js/views/list/list_editable_renderer.js b/addons/web/static/src/js/views/list/list_editable_renderer.js
index 9d7555cad19..53ef5bccd2d 100644
--- a/addons/web/static/src/js/views/list/list_editable_renderer.js
+++ b/addons/web/static/src/js/views/list/list_editable_renderer.js
@@ -537,8 +537,13 @@ ListRenderer.include({
* @returns {Deferred} this deferred is resolved immediately
*/
_renderView: function () {
+ var self = this;
this.currentRow = null;
- return this._super.apply(this, arguments);
+ return this._super.apply(this, arguments).then(function () {
+ if (self._isEditable()) {
+ self.$('table').addClass('o_editable_list');
+ }
+ });
},
/**
* Force the resequencing of the items in the list.
diff --git a/addons/web/static/src/js/views/pivot/pivot_model.js b/addons/web/static/src/js/views/pivot/pivot_model.js
index 6eddd44ffe7..76e22c8b4e5 100644
--- a/addons/web/static/src/js/views/pivot/pivot_model.js
+++ b/addons/web/static/src/js/views/pivot/pivot_model.js
@@ -17,6 +17,7 @@ odoo.define('web.PivotModel', function (require) {
*/
var AbstractModel = require('web.AbstractModel');
+var concurrency = require('web.concurrency');
var core = require('web.core');
var session = require('web.session');
var utils = require('web.utils');
@@ -32,6 +33,7 @@ var PivotModel = AbstractModel.extend({
this._super.apply(this, arguments);
this.numbering = {};
this.data = null;
+ this._loadDataDropPrevious = new concurrency.DropPrevious();
},
//--------------------------------------------------------------------------
@@ -532,7 +534,7 @@ var PivotModel = AbstractModel.extend({
}
}
- return $.when.apply(null, groupBys.map(function (groupBy) {
+ return this._loadDataDropPrevious.add($.when.apply(null, groupBys.map(function (groupBy) {
return self._rpc({
model: self.modelName,
method: 'read_group',
@@ -542,7 +544,7 @@ var PivotModel = AbstractModel.extend({
groupBy: groupBy,
lazy: false,
});
- })).then(function () {
+ }))).then(function () {
var data = Array.prototype.slice.call(arguments);
if (data[0][0].__count === 0) {
self.data.has_data = false;
diff --git a/addons/web/static/src/less/list_view.less b/addons/web/static/src/less/list_view.less
index 73bd50e1966..1e57f9253bc 100644
--- a/addons/web/static/src/less/list_view.less
+++ b/addons/web/static/src/less/list_view.less
@@ -6,6 +6,14 @@
background-color: @odoo-view-background-color;
margin-bottom: 0px;
+ // Checkbox in editable list
+ // should be clickable and activate the row
+ &.o_editable_list .o_data_row:not(.o_selected_row) .o_data_cell {
+ .o_checkbox:not(.o_readonly_modifier) {
+ pointer-events: none;
+ }
+ }
+
&.table {
td, th {
vertical-align: middle;
diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js
index 29d3dad6056..1c050edf3f4 100644
--- a/addons/web/static/tests/fields/relational_fields_tests.js
+++ b/addons/web/static/tests/fields/relational_fields_tests.js
@@ -2331,6 +2331,50 @@ QUnit.module('relational_fields', {
QUnit.module('FieldOne2Many');
+ QUnit.test('one2many with two inline views', function (assert) {
+ assert.expect(1);
+
+ // The inline list view has and uses a field that the inline form view doesn't have
+ // We need to test that returning from the form view to the list view unfolds smoothly
+ // Even if a field needed in the list is not set in the form
+
+ var form = createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: '<form string="Partners">' +
+ '<field name="turtles">' +
+ '<tree>' +
+ '<field name="turtle_foo"/>' +
+ '<field name="display_name" attrs="{\'readonly\': [(\'turtle_foo\', \'=\', \'lol\')]}"/>' +
+ '</tree>' +
+ '<form>' +
+ '<field name="display_name"/>' +
+ '</form>' +
+ '</field>' +
+ '</form>',
+ res_id: 1,
+ viewOptions: {
+ mode: 'edit',
+ },
+ });
+
+ // Add a record with the form view
+ form.$('.o_field_x2many_list .o_field_x2many_list_row_add a').click();
+ var modal = $('.modal-dialog');
+ // Fill in the only field
+ modal.find('input[name=display_name]').val('lol').trigger('input');
+ // Save the record
+ modal.find('.btn-primary').first().click();
+
+ // Now back to the list, verifying that the record is present
+ var $newRecord = form.$('.o_field_x2many_list tbody .o_data_row').eq(1);
+ assert.equal($newRecord.find('.o_data_cell').eq(1).text(), 'lol',
+ 'We should have created a record in the One2Many');
+
+ form.destroy();
+ });
+
QUnit.test('one2many list editable with cell readonly modifier', function (assert) {
assert.expect(4);
@@ -5699,7 +5743,7 @@ QUnit.module('relational_fields', {
rpcCount++;
if (args.method === 'write') {
assert.deepEqual(args.args[1].p, [[0, args.args[1].p[0][1], {
- int_field: 123, product_id: 41
+ int_field: 123, product_id: 41, foo: false,
}]]);
}
return this._super(route, args);
diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js
index 163961497d8..6c1d113951a 100644
--- a/addons/web/static/tests/helpers/mock_server.js
+++ b/addons/web/static/tests/helpers/mock_server.js
@@ -116,12 +116,12 @@ var MockServer = Class.extend({
console.log('%c[rpc] response' + route, 'color: blue; font-weight: bold;', JSON.parse(resultString));
}
return JSON.parse(resultString);
- }).fail(function (result) {
+ }, function (result, event) {
var errorString = JSON.stringify(result || false);
if (debug) {
console.log('%c[rpc] response (error) ' + route, 'color: orange; font-weight: bold;', JSON.parse(errorString));
}
- return JSON.parse(errorString);
+ return $.Deferred().reject(errorString, event || $.Event());
});
},
@@ -813,7 +813,7 @@ var MockServer = Class.extend({
*/
_mockReadProgressBar: function (model, kwargs) {
var domain = kwargs.domain;
- var groupBy = kwargs.groupBy;
+ var groupBy = kwargs.group_by;
var progress_bar = kwargs.progress_bar;
var records = this._getRecords(model, domain || []);
diff --git a/addons/web/static/tests/views/calendar_tests.js b/addons/web/static/tests/views/calendar_tests.js
index 81eff3a30f8..a54ba356224 100644
--- a/addons/web/static/tests/views/calendar_tests.js
+++ b/addons/web/static/tests/views/calendar_tests.js
@@ -1875,6 +1875,101 @@ QUnit.module('Views', {
calendar.destroy();
});
+
+ QUnit.test('form_view_id attribute works (for creating events)', function (assert) {
+ assert.expect(1);
+
+ var calendar = createView({
+ View: CalendarView,
+ model: 'event',
+ data: this.data,
+ arch: '<calendar class="o_calendar_test" '+
+ 'date_start="start" '+
+ 'date_stop="stop" '+
+ 'mode="month" '+
+ 'form_view_id="42">'+
+ '<field name="name"/>'+
+ '</calendar>',
+ archs: archs,
+ viewOptions: {
+ initialDate: initialDate,
+ },
+ mockRPC: function (route, args) {
+ if (args.method === "create") {
+ // we simulate here the case where a create call with just
+ // the field name fails. This is a normal flow, the server
+ // reject the create rpc (quick create), then the web client
+ // fall back to a form view. This happens typically when a
+ // model has required fields
+ return $.Deferred().reject('None shall pass!');
+ }
+ return this._super(route, args);
+ },
+ intercepts: {
+ do_action: function (event) {
+ assert.strictEqual(event.data.action.views[0][0], 42,
+ "should do a do_action with view id 42");
+ },
+ },
+ });
+
+ var $cell = calendar.$('.fc-day-grid .fc-row:eq(2) .fc-day:eq(2)');
+ testUtils.triggerMouseEvent($cell, "mousedown");
+ testUtils.triggerMouseEvent($cell, "mouseup");
+ var $input = $('.modal-body input:first');
+ $input.val("It's just a fleshwound").trigger('input');
+ $('.modal button.btn:contains(Create)').trigger('click');
+
+ calendar.destroy();
+ });
+
+ QUnit.test('calendar fallback to form view id in action if necessary', function (assert) {
+ assert.expect(1);
+
+ var calendar = createView({
+ View: CalendarView,
+ model: 'event',
+ data: this.data,
+ arch: '<calendar class="o_calendar_test" '+
+ 'date_start="start" '+
+ 'date_stop="stop" '+
+ 'mode="month"> '+
+ '<field name="name"/>'+
+ '</calendar>',
+ archs: archs,
+ viewOptions: {
+ initialDate: initialDate,
+ action: {views: [[1, 'kanban'], [43, 'form']]}
+ },
+ mockRPC: function (route, args) {
+ if (args.method === "create") {
+ // we simulate here the case where a create call with just
+ // the field name fails. This is a normal flow, the server
+ // reject the create rpc (quick create), then the web client
+ // fall back to a form view. This happens typically when a
+ // model has required fields
+ return $.Deferred().reject('None shall pass!');
+ }
+ return this._super(route, args);
+ },
+ intercepts: {
+ do_action: function (event) {
+ assert.strictEqual(event.data.action.views[0][0], 43,
+ "should do a do_action with view id 43");
+ },
+ },
+ });
+
+ var $cell = calendar.$('.fc-day-grid .fc-row:eq(2) .fc-day:eq(2)');
+ testUtils.triggerMouseEvent($cell, "mousedown");
+ testUtils.triggerMouseEvent($cell, "mouseup");
+ var $input = $('.modal-body input:first');
+ $input.val("It's just a fleshwound").trigger('input');
+ $('.modal button.btn:contains(Create)').trigger('click');
+
+ calendar.destroy();
+ });
+
});
});
diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js
index 859a3b29ee9..902bb5c8cd8 100644
--- a/addons/web/static/tests/views/kanban_tests.js
+++ b/addons/web/static/tests/views/kanban_tests.js
@@ -3222,6 +3222,47 @@ QUnit.module('Views', {
kanban.destroy();
});
+ QUnit.test('column progressbars on archiving records update counter', function (assert) {
+ assert.expect(4);
+
+ // add active field on partner model and make all records active
+ this.data.partner.fields.active = {string: 'Active', type: 'char', default: true};
+
+ var kanban = createView({
+ View: KanbanView,
+ model: 'partner',
+ data: this.data,
+ arch:
+ '<kanban>' +
+ '<field name="active"/>' +
+ '<field name="bar"/>' +
+ '<field name="int_field"/>' +
+ '<progressbar field="foo" colors=\'{"yop": "success", "gnap": "warning", "blip": "danger"}\' sum_field="int_field"/>' +
+ '<templates><t t-name="kanban-box">' +
+ '<div>' +
+ '<field name="name"/>' +
+ '</div>' +
+ '</t></templates>' +
+ '</kanban>',
+ groupBy: ['bar'],
+ });
+
+ assert.strictEqual(kanban.$('.o_kanban_group:eq(1) .o_kanban_counter_side').text(), "36",
+ "counter should contain the correct value");
+ assert.strictEqual(kanban.$('.o_kanban_group:eq(1) .o_kanban_counter_progress > .progress-bar:first').data('originalTitle'), "1 yop",
+ "the counter progressbars should be correctly displayed");
+
+ // archive all records of the second columns
+ kanban.$('.o_kanban_group:eq(1) .o_column_archive').click();
+
+ assert.strictEqual(kanban.$('.o_kanban_group:eq(1) .o_kanban_counter_side').text(), "0",
+ "counter should contain the correct value");
+ assert.strictEqual(kanban.$('.o_kanban_group:eq(1) .o_kanban_counter_progress > .progress-bar:first').data('originalTitle'), "0 yop",
+ "the counter progressbars should have been correctly updated");
+
+ kanban.destroy();
+ });
+
QUnit.test('drag & drop records grouped by m2o with progressbar', function (assert) {
assert.expect(4);
diff --git a/addons/web/static/tests/views/pivot_tests.js b/addons/web/static/tests/views/pivot_tests.js
index 9c27e2eeb35..fc20e3b6869 100644
--- a/addons/web/static/tests/views/pivot_tests.js
+++ b/addons/web/static/tests/views/pivot_tests.js
@@ -1006,4 +1006,37 @@ QUnit.module('Views', {
pivot.destroy();
});
+
+ QUnit.test('parallel data loading should discard all but the last one', function (assert) {
+ assert.expect(2);
+
+ var def;
+
+ var pivot = createView({
+ View: PivotView,
+ model: "partner",
+ data: this.data,
+ arch: '<pivot>' +
+ '<field name="foo" type="measure"/>' +
+ '</pivot>',
+ mockRPC: function (route, args) {
+ var result = this._super.apply(this, arguments);
+ if (args.method === 'read_group') {
+ return $.when(def).then(_.constant(result));
+ }
+ return result;
+ },
+ });
+
+ def = $.Deferred();
+ pivot.update({groupBy: ['product_id']});
+ pivot.update({groupBy: ['product_id', 'customer']});
+ def.resolve();
+
+ assert.strictEqual(pivot.$('.o_pivot_cell_value').length, 6,
+ "should have 6 cells");
+ assert.strictEqual(pivot.$('tbody tr').length, 6,
+ "should have 6 rows");
+ pivot.destroy();
+ });
});});
diff --git a/addons/web/tests/test_js.py b/addons/web/tests/test_js.py
index f903fa704c5..04df8be91c1 100644
--- a/addons/web/tests/test_js.py
+++ b/addons/web/tests/test_js.py
@@ -32,6 +32,6 @@ class WebSuite(odoo.tests.HttpCase):
filename = asset['filename']
if not filename or asset['atype'] != 'text/javascript':
continue
- with open(filename, 'r') as fp:
- if RE_ONLY.search(fp.read()):
+ with open(filename, 'rb') as fp:
+ if RE_ONLY.search(fp.read().decode('utf-8')):
self.fail("`QUnit.only()` used in file %r" % asset['url'])
diff --git a/addons/web_editor/static/lib/summernote/src/js/module/Clipboard.js b/addons/web_editor/static/lib/summernote/src/js/module/Clipboard.js
index 955b49437a8..4cd9088da75 100644
--- a/addons/web_editor/static/lib/summernote/src/js/module/Clipboard.js
+++ b/addons/web_editor/static/lib/summernote/src/js/module/Clipboard.js
@@ -1,256 +1,41 @@
define([
- 'summernote/core/list',
- 'summernote/core/dom',
- 'summernote/core/key',
- 'summernote/core/agent',
- 'summernote/core/range'
+ 'summernote/core/list',
+ 'summernote/core/dom',
+ 'summernote/core/key',
+ 'summernote/core/agent',
+ 'summernote/core/range'
], function (list, dom, key, agent, range) {
- var Clipboard = function (handler) {
- var $paste;
-
- this.attach = function (layoutInfo) {
- // [workaround] getting image from clipboard
- // - IE11 and Firefox: CTRL+v hook
- // - Webkit: event.clipboardData
- if (agent.isMSIE && agent.browserVersion > 10) {
- $paste = $('<div />').attr('contenteditable', true).css({
- position : 'absolute',
- left : -100000,
- opacity : 0
- });
-
- layoutInfo.editable().on('keydown', function (e) {
- if (e.ctrlKey && e.keyCode === key.code.V) {
- handler.invoke('saveRange', layoutInfo.editable());
- $paste.focus();
-
- setTimeout(function () {
- pasteByHook(layoutInfo);
- }, 0);
- }
- });
-
- layoutInfo.editable().before($paste);
- } else {
- layoutInfo.editable().on('paste', pasteByEvent);
- }
- };
-
- var pasteByHook = function (layoutInfo) {
- var $editable = layoutInfo.editable();
- var node = $paste[0].firstChild;
-
- if (dom.isImg(node)) {
- var dataURI = node.src;
- var decodedData = atob(dataURI.split(',')[1]);
- var array = new Uint8Array(decodedData.length);
- for (var i = 0; i < decodedData.length; i++) {
- array[i] = decodedData.charCodeAt(i);
- }
-
- var blob = new Blob([array], { type : 'image/png' });
- blob.name = 'clipboard.png';
-
- handler.invoke('restoreRange', $editable);
- handler.invoke('focus', $editable);
- handler.insertImages(layoutInfo, [blob]);
- } else {
- var pasteContent = $('<div />').html($paste.html()).html();
- handler.invoke('restoreRange', $editable);
- handler.invoke('focus', $editable);
-
- if (pasteContent) {
- handler.invoke('pasteHTML', $editable, pasteContent);
- }
- }
-
- $paste.empty();
- };
-
- /**
- * paste by clipboard event
- *
- * @param {Event} event
- */
- var pasteByEvent = function (event) {
- var clipboardData = event.originalEvent.clipboardData;
- var layoutInfo = dom.makeLayoutInfo(event.currentTarget || event.target);
- var $editable = layoutInfo.editable();
-
- if (["INPUT", "TEXTAREA"].indexOf(event.target.tagName) !== -1) {
- return;
- }
-
- if (clipboardData && clipboardData.items && clipboardData.items.length) {
- var item = list.head(clipboardData.items);
- if (item.kind === 'file' && item.type.indexOf('image/') !== -1) {
- handler.insertImages(layoutInfo, [item.getAsFile()]);
- }
- handler.invoke('editor.afterCommand', $editable);
- }
-
- event.preventDefault();
-
- var html = clipboardData.getData("text/html");
- var $node = $('<div/>').html(html);
- // if copying source did not provide html, default to plain text
- if(!html) {
- $node.text(clipboardData.getData("text/plain")).html(function(_, html){
- return html.replace(/\r?\n/g,'<br>');
- });
- }
- pasteContent($node, layoutInfo, $editable);
- };
-
- /*
- remove undesirable tag
- filter classes and style attributes
- remove undesirable attributes
- */
- var filter_tag = function ($nodes, $editable) {
- return $nodes.each(function() {
- var $node = $(this);
-
- if ($node.attr('style')) {
- var style = _.filter(_.compact($node.attr('style').split(/\s*;\s*/)), function (style) {
- style = style.split(/\s*:\s*/);
- return /width|height|color|background-color|font-weight|text-align|font-style|text-decoration/i.test(style[0]) &&
- !(style[1] === 'initial' || style[1] === 'inherit' || $node.css(style[0]) === $editable.css(style[0]) ||
- (style[0] === 'background-color' && style[1] === 'rgb(255, 255, 255)') ||
- (style[0] === 'color' && style[1] === 'rgb(0, 0, 0)'));
- }).join(';');
- if (style.length) {
- $node.attr('style', style);
- } else {
- $node.removeAttr('style');
- }
- }
-
- if ($node.attr('class')) {
- var classes = _.filter($node.attr('class').split(/\s+/), function (style) {
- return /(^|\s)(fa|pull|text|bg)(\s|-|$)/.test(style);
- }).join(' ');
- if (classes.length) {
- $node.attr('class', classes);
- } else {
- $node.removeAttr('class');
- }
- }
- });
- };
-
- var pasteContent = function ($node, layoutInfo, $editable) {
- $node.find('meta, script, style').remove();
- filter_tag($node.find('*'), $editable).removeAttr('title', 'alt', 'id', 'contenteditable');
-
- /*
- remove unless span and unwant font
- */
- $node.find('span, font').filter(':not([class]):not([style])').each(function () {
- $(this).replaceWith($(this).contents());
- });
- $node.find('span + span').each(function () {
-
- if (dom.isText(this.previousSibling)) {
- if (dom.isVisibleText(this.previousSibling)) {
- return;
- } else { // keep space between 2 tags, but can merge the both tags
- $(this).prev().append(this.previousSibling);
- }
- }
- if ($(this).attr('class') === $(this).prev().attr('class') && $(this).attr('style') === $(this).prev().attr('style')) {
- $(this).prev().append($(this).contents());
- $(this).remove();
- }
- });
-
- // remove empty table row and td
- var $tdr;
- while(($tdr = $node.find('tr:empty, td:empty, th:empty, tbody:empty, t-head:empty, table:empty')) && $tdr.length) {
- $tdr.remove();
- }
-
- /*
- reset architecture HTML node and add <p> tag
- */
- var $arch = $('<div/>');
- var $last = $arch;
- $node.contents().each(function () {
- if (dom.isBR(this)) {
- $(this).remove();
- $last = $('<p/>');
- $arch.append($last);
- } else if (/h[0-9]+|li|table|p/i.test(this.tagName)) {
- $last = $('<p/>');
- $arch.append(this).append($last);
- } else if ($arch.is(':empty') && dom.isText(this)) {
- $last = $('<p/>').append(this);
- $arch.append($last);
- } else if (this.nodeType !== Node.COMMENT_NODE) {
- $last.append(this);
- }
- });
- $arch.find(':not([class]):not([style]):empty, p:empty').remove();
-
- /*
- history
- */
- $editable.data('NoteHistory').recordUndo($editable, "paste");
-
- /*
- remove selected content
- */
- var r = range.create();
- if (!r.isCollapsed()) {
- r = r.deleteContents();
- r.select();
- }
-
- // If only pasting a <p/> element in an unique <p/> element, only paste
- // the <p/> element text
- var $p = $arch.children('p');
- var onlyAP = ($p.length === 1 && $arch.children().length === 1);
- if (onlyAP) {
- var $p1 = $(r.sc).closest('p');
- var $p2 = $(r.ec).closest('p');
- if ($p1.length && $p2.length && $p1[0] === $p2[0]) {
- $arch.html($p.text());
- }
- }
-
- /*
- insert content
- */
- var $nodes = $();
- $editable.on('DOMNodeInserted', function (event) {
- $nodes = $nodes.add(event.originalEvent.target);
- });
- window.document.execCommand('insertHTML', false, $arch.html());
- $editable.off('DOMNodeInserted');
-
- /*
- clean insterted content
- */
- var $span = $nodes.filter('span');
- $span = $span.first().add($span.last());
- $span = $span.add($span.prev('span'));
- $span = $span.add($span.next('span'));
- filter_tag($span, $editable);
- $span.not('[span], [style]').each(function () {
- _.each(this.childNodes, function (node) {
- $(node.parentNode).after(node);
- });
- $(this).remove();
- });
- r = range.create();
- if (!dom.isText(r.ec)) {
- r = range.create(r.sc.childNodes[r.so], dom.nodeLength(r.sc.childNodes[r.so]));
- }
- r.clean().select();
-
- $editable.trigger('content_changed');
+ // ODOO override: use 0.8.10 version of this, adapted for the old summernote
+ // version odoo is using
+ var Clipboard = function (handler) {
+ /**
+ * paste by clipboard event
+ *
+ * @param {Event} event
+ */
+ var pasteByEvent = function (event) {
+ if (["INPUT", "TEXTAREA"].indexOf(event.target.tagName) !== -1) {
+ // ODOO override: from old summernote version
+ return;
+ }
+
+ var clipboardData = event.originalEvent.clipboardData;
+ var layoutInfo = dom.makeLayoutInfo(event.currentTarget || event.target);
+ var $editable = layoutInfo.editable();
+
+ if (clipboardData && clipboardData.items && clipboardData.items.length) {
+ var item = list.head(clipboardData.items);
+ if (item.kind === 'file' && item.type.indexOf('image/') !== -1) {
+ handler.insertImages(layoutInfo, [item.getAsFile()]);
+ }
+ handler.invoke('editor.afterCommand', $editable);
+ }
+ };
+
+ this.attach = function (layoutInfo) {
+ layoutInfo.editable().on('paste', pasteByEvent);
+ };
};
- };
- return Clipboard;
+ return Clipboard;
});
diff --git a/addons/web_editor/static/src/js/editor/rte.summernote.js b/addons/web_editor/static/src/js/editor/rte.summernote.js
index ddf588eb569..969b9c060b2 100644
--- a/addons/web_editor/static/src/js/editor/rte.summernote.js
+++ b/addons/web_editor/static/src/js/editor/rte.summernote.js
@@ -675,7 +675,7 @@ function summernote_mousedown(event) {
return;
}
var editables = $(".o_editable[contenteditable], .note-editable[contenteditable]");
- var r_editable = editables.has((r||{}).sc);
+ var r_editable = editables.has((r||{}).sc).addBack(editables.filter((r||{}).sc));
if (!r_editable.closest('.note-editor').is($editable) && !r_editable.filter('.o_editable').is(editables)) {
var saved_editable = editables.has((remember_selection||{}).sc);
if ($editable.length && !saved_editable.closest('.o_editable, .note-editor').is($editable)) {
diff --git a/addons/website_quote/controllers/main.py b/addons/website_quote/controllers/main.py
index f795de5f4e6..434750c9250 100644
--- a/addons/website_quote/controllers/main.py
+++ b/addons/website_quote/controllers/main.py
@@ -8,6 +8,7 @@ from odoo.http import request
from odoo.addons.portal.controllers.portal import get_records_pager
from odoo.addons.sale.controllers.portal import CustomerPortal
from odoo.addons.portal.controllers.mail import _message_post_helper
+from odoo.osv import expression
class CustomerPortal(CustomerPortal):
@@ -49,7 +50,7 @@ class sale_quote(http.Controller):
if Order and request.session.get('view_quote_%s' % Order.id) != now and request.env.user.share:
request.session['view_quote_%s' % Order.id] = now
body = _('Quotation viewed by customer')
- _message_post_helper(res_model='sale.order', res_id=Order.id, message=body, token=token, message_type='notification', subtype="mail.mt_note", partner_ids=Order.user_id.sudo().partner_id.ids)
+ _message_post_helper(res_model='sale.order', res_id=Order.id, message=body, token=Order.access_token, message_type='notification', subtype="mail.mt_note", partner_ids=Order.user_id.sudo().partner_id.ids)
if not Order:
return request.render('website.404')
@@ -89,7 +90,11 @@ class sale_quote(http.Controller):
}
if order_sudo.require_payment or values['need_payment']:
- acquirers = request.env['payment.acquirer'].sudo().search([('website_published', '=', True), ('company_id', '=', order_sudo.company_id.id)])
+ domain = expression.AND([
+ ['&', ('website_published', '=', True), ('company_id', '=', order_sudo.company_id.id)],
+ ['|', ('specific_countries', '=', False), ('country_ids', 'in', [order_sudo.partner_id.country_id.id])]
+ ])
+ acquirers = request.env['payment.acquirer'].sudo().search(domain)
values['form_acquirers'] = [acq for acq in acquirers if acq.payment_flow == 'form' and acq.view_template_id]
values['s2s_acquirers'] = [acq for acq in acquirers if acq.payment_flow == 's2s' and acq.registration_view_template_id]
diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py
index 448b2f1c77d..a0f136ce79c 100644
--- a/addons/website_sale/controllers/main.py
+++ b/addons/website_sale/controllers/main.py
@@ -12,6 +12,7 @@ from odoo.addons.website.controllers.main import QueryURL
from odoo.exceptions import ValidationError
from odoo.addons.website.controllers.main import Website
from odoo.addons.website_form.controllers.main import WebsiteForm
+from odoo.osv import expression
_logger = logging.getLogger(__name__)
@@ -756,9 +757,11 @@ class WebsiteSale(http.Controller):
bootstrap_formatting= True
)
- acquirers = request.env['payment.acquirer'].search(
- [('website_published', '=', True), ('company_id', '=', order.company_id.id)]
- )
+ domain = expression.AND([
+ ['&', ('website_published', '=', True), ('company_id', '=', order.company_id.id)],
+ ['|', ('specific_countries', '=', False), ('country_ids', 'in', [order.partner_id.country_id.id])]
+ ])
+ acquirers = request.env['payment.acquirer'].search(domain)
values['access_token'] = order.access_token
values['form_acquirers'] = [acq for acq in acquirers if acq.payment_flow == 'form' and acq.view_template_id]
diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py
index ba0b1305946..2ef722104b5 100644
--- a/addons/website_slides/controllers/main.py
+++ b/addons/website_slides/controllers/main.py
@@ -179,8 +179,9 @@ class WebsiteSlides(http.Controller):
response.mimetype = 'application/pdf'
return response
- @http.route('''/slides/slide/<model("slide.slide"):slide>/download''', type='http', auth="public", website=True)
- def slide_download(self, slide, sitemap=False):
+ @http.route('''/slides/slide/<model("slide.slide"):slide>/download''', type='http', auth="public", website=True, sitemap=False)
+ def slide_download(self, slide, **kw):
+ slide = slide.sudo()
if slide.download_security == 'public' or (slide.download_security == 'user' and request.session.uid):
filecontent = base64.b64decode(slide.datas)
disposition = 'attachment; filename=%s.pdf' % werkzeug.urls.url_quote(slide.name)
@@ -190,7 +191,7 @@ class WebsiteSlides(http.Controller):
('Content-Length', len(filecontent)),
('Content-Disposition', disposition)])
elif not request.session.uid and slide.download_security == 'user':
- return werkzeug.utils.redirect('/web?redirect=/slides/slide/%s' % (slide.id))
+ return request.redirect('/web/login?redirect=/slides/slide/%s' % (slide.id))
return request.render("website.403")
@http.route('''/slides/slide/<model("slide.slide"):slide>/promote''', type='http', auth='user', website=True)
diff --git a/addons/website_slides/models/slides.py b/addons/website_slides/models/slides.py
index 764d8acfa6a..1689e8070c9 100644
--- a/addons/website_slides/models/slides.py
+++ b/addons/website_slides/models/slides.py
@@ -16,6 +16,8 @@ from odoo.addons.http_routing.models.ir_http import slug
from odoo.tools import image
from odoo.tools.translate import html_translate
from odoo.exceptions import Warning
+from odoo.http import request
+from odoo.addons.http_routing.models.ir_http import url_for
class Channel(models.Model):
@@ -345,10 +347,11 @@ class Slide(models.Model):
embed_code = fields.Text('Embed Code', readonly=True, compute='_get_embed_code')
def _get_embed_code(self):
- base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
+ base_url = request and request.httprequest.url_root or self.env['ir.config_parameter'].sudo().get_param('web.base.url')
for record in self:
if record.datas and (not record.document_id or record.slide_type in ['document', 'presentation']):
- record.embed_code = '<iframe src="%s/slides/embed/%s?page=1" class="o_wslides_iframe_viewer" allowFullScreen="true" height="%s" width="%s" frameborder="0"></iframe>' % (base_url, record.id, 315, 420)
+ slide_url = base_url + url_for('/slides/embed/%s?page=1' % record.id)
+ record.embed_code = '<iframe src="%s" class="o_wslides_iframe_viewer" allowFullScreen="true" height="%s" width="%s" frameborder="0"></iframe>' % (slide_url, 315, 420)
elif record.slide_type == 'video' and record.document_id:
if not record.mime_type:
# embed youtube video
diff --git a/doc/cla/individual/nomadic-coding.md b/doc/cla/individual/nomadic-coding.md
new file mode 100644
index 00000000000..4ac7e62b77c
--- /dev/null
+++ b/doc/cla/individual/nomadic-coding.md
@@ -0,0 +1,11 @@
+Panama, 2018-05-01
+
+I hereby agree to the terms of the Odoo Individual Contributor License
+Agreement v1.0.
+
+I declare that I am authorized and able to make this agreement and sign this
+declaration.
+
+Signed,
+
+Kumar Aberer hello@nomadic-coding.com https://github.com/nomadic-coding
diff --git a/doc/reference/views.rst b/doc/reference/views.rst
index 03dbdcd4816..8845e7806c3 100644
--- a/doc/reference/views.rst
+++ b/doc/reference/views.rst
@@ -954,7 +954,9 @@ calendar view are:
``readonly_form_view_id``
view to open in readonly mode
``form_view_id``
- view to open when the user create or edit an event
+ view to open when the user create or edit an event. Note that if this attribute
+ is not set, the calendar view will fall back to the id of the form view in the
+ current action, if any.
``event_open_popup``
If the option 'event_open_popup' is set to true, then the calendar view will
open events (or records) in a FormViewDialog. Otherwise, it will open events
diff --git a/odoo/addons/base/models/res_currency.py b/odoo/addons/base/models/res_currency.py
index 509bb548ecc..96d6af00ae4 100644
--- a/odoo/addons/base/models/res_currency.py
+++ b/odoo/addons/base/models/res_currency.py
@@ -44,6 +44,7 @@ class Currency(models.Model):
]
@api.multi
+ @api.depends('rate_ids.rate')
def _compute_current_rate(self):
date = self._context.get('date') or fields.Date.today()
company_id = self._context.get('company_id') or self.env['res.users']._get_company().id