[MERGE] forward port branch saas-14 up to 6fd092e131
This commit is contained in:
@@ -5,7 +5,8 @@
|
|||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-5 col-xs-offset-7">
|
<div class="col-xs-5 col-xs-offset-7">
|
||||||
<span t-field="o.name"/><br/>
|
<!-- When partner is a company, its name is included in contact_address -->
|
||||||
|
<span t-if="not o.is_company"><span t-field="o.name"/><br/></span>
|
||||||
<span t-raw="o.contact_address.replace('\n\n', '\n').replace('\n', '<br>')"/>
|
<span t-raw="o.contact_address.replace('\n\n', '\n').replace('\n', '<br>')"/>
|
||||||
<span t-field="o.vat"/>
|
<span t-field="o.vat"/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class AuthSignupHome(Home):
|
|||||||
if 'error' not in qcontext and request.httprequest.method == 'POST':
|
if 'error' not in qcontext and request.httprequest.method == 'POST':
|
||||||
try:
|
try:
|
||||||
self.do_signup(qcontext)
|
self.do_signup(qcontext)
|
||||||
return super(AuthSignupHome, self).web_login(*args, **kw)
|
return self.web_login(*args, **kw)
|
||||||
except (SignupError, AssertionError), e:
|
except (SignupError, AssertionError), e:
|
||||||
if request.env["res.users"].sudo().search([("login", "=", qcontext.get("login"))]):
|
if request.env["res.users"].sudo().search([("login", "=", qcontext.get("login"))]):
|
||||||
qcontext["error"] = _("Another user is already registered using this email address.")
|
qcontext["error"] = _("Another user is already registered using this email address.")
|
||||||
@@ -55,7 +55,7 @@ class AuthSignupHome(Home):
|
|||||||
try:
|
try:
|
||||||
if qcontext.get('token'):
|
if qcontext.get('token'):
|
||||||
self.do_signup(qcontext)
|
self.do_signup(qcontext)
|
||||||
return super(AuthSignupHome, self).web_login(*args, **kw)
|
return self.web_login(*args, **kw)
|
||||||
else:
|
else:
|
||||||
login = qcontext.get('login')
|
login = qcontext.get('login')
|
||||||
assert login, "No login provided."
|
assert login, "No login provided."
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ class IrModule(models.Model):
|
|||||||
installed_mods = [m.name for m in known_mods if m.state == 'installed']
|
installed_mods = [m.name for m in known_mods if m.state == 'installed']
|
||||||
|
|
||||||
terp = load_information_from_description_file(module, mod_path=path)
|
terp = load_information_from_description_file(module, mod_path=path)
|
||||||
|
if not terp:
|
||||||
|
return False
|
||||||
values = self.get_values_from_terp(terp)
|
values = self.get_values_from_terp(terp)
|
||||||
|
|
||||||
unmet_dependencies = set(terp['depends']).difference(installed_mods)
|
unmet_dependencies = set(terp['depends']).difference(installed_mods)
|
||||||
@@ -110,8 +112,8 @@ class IrModule(models.Model):
|
|||||||
try:
|
try:
|
||||||
# assert mod_name.startswith('theme_')
|
# assert mod_name.startswith('theme_')
|
||||||
path = opj(module_dir, mod_name)
|
path = opj(module_dir, mod_name)
|
||||||
self.import_module(mod_name, path, force=force)
|
if self.import_module(mod_name, path, force=force):
|
||||||
success.append(mod_name)
|
success.append(mod_name)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
_logger.exception('Error while importing module')
|
_logger.exception('Error while importing module')
|
||||||
errors[mod_name] = exception_to_unicode(e)
|
errors[mod_name] = exception_to_unicode(e)
|
||||||
|
|||||||
@@ -66,6 +66,11 @@ msgstr ""
|
|||||||
msgid "Corrupted data on point of sale order with id %s."
|
msgid "Corrupted data on point of sale order with id %s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: l10n_fr_pos_cert
|
||||||
|
#: model:ir.model,name:l10n_fr_pos_cert.model_account_fiscal_position
|
||||||
|
msgid "Fiscal Position"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. module: l10n_fr_pos_cert
|
#. module: l10n_fr_pos_cert
|
||||||
#: model:ir.ui.menu,name:l10n_fr_pos_cert.pos_fr_statements_menu
|
#: model:ir.ui.menu,name:l10n_fr_pos_cert.pos_fr_statements_menu
|
||||||
msgid "French Statements"
|
msgid "French Statements"
|
||||||
@@ -137,7 +142,13 @@ msgid "This session has been opened another day. To comply with the French law,
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. module: l10n_fr_pos_cert
|
#. module: l10n_fr_pos_cert
|
||||||
#: code:addons/l10n_fr_pos_cert/models/account_bank_statement.py:11
|
#: code:addons/l10n_fr_pos_cert/models/account_fiscal_position.py:14
|
||||||
|
#, python-format
|
||||||
|
msgid "You cannot modify a fiscal position used in a POS order. You should archive it and create a new one."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: l10n_fr_pos_cert
|
||||||
|
#: code:addons/l10n_fr_pos_cert/models/account_bank_statement.py:12
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "You cannot modify anything on a bank statement (name: %s) that was created by point of sale operations."
|
msgid "You cannot modify anything on a bank statement (name: %s) that was created by point of sale operations."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
import account_bank_statement
|
import account_bank_statement
|
||||||
|
from . import account_fiscal_position
|
||||||
import res_company
|
import res_company
|
||||||
import pos
|
import pos
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from odoo import _, models
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
|
||||||
|
class AccountFiscalPosition(models.Model):
|
||||||
|
_inherit = "account.fiscal.position"
|
||||||
|
|
||||||
|
def write(self, vals):
|
||||||
|
if "tax_ids" in vals:
|
||||||
|
if self.env["pos.order"].sudo().search_count([("fiscal_position_id", "in", self.ids)]):
|
||||||
|
raise UserError(
|
||||||
|
_(
|
||||||
|
"You cannot modify a fiscal position used in a POS order. "
|
||||||
|
+ "You should archive it and create a new one."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return super(AccountFiscalPosition, self).write(vals)
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<data noupdate="0">
|
<data noupdate="1">
|
||||||
<record id="seq_picking_type_posout" model="ir.sequence">
|
<record id="seq_picking_type_posout" model="ir.sequence">
|
||||||
<field name="name">Picking POS</field>
|
<field name="name">Picking POS</field>
|
||||||
<field name="prefix">POS</field>
|
<field name="prefix">POS</field>
|
||||||
<field name="padding">5</field>
|
<field name="padding">5</field>
|
||||||
<field name="company_id" eval="False"/>
|
<field name="company_id" eval="False"/>
|
||||||
</record>
|
</record>
|
||||||
|
</data>
|
||||||
|
<data noupdate="0">
|
||||||
<record id="picking_type_posout" model="stock.picking.type">
|
<record id="picking_type_posout" model="stock.picking.type">
|
||||||
<field name="name">PoS Orders</field>
|
<field name="name">PoS Orders</field>
|
||||||
<field name="sequence_id" ref="seq_picking_type_posout"/>
|
<field name="sequence_id" ref="seq_picking_type_posout"/>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class SaleOrder(models.Model):
|
|||||||
values['product_id'] = ticket.product_id.id
|
values['product_id'] = ticket.product_id.id
|
||||||
values['event_id'] = ticket.event_id.id
|
values['event_id'] = ticket.event_id.id
|
||||||
values['event_ticket_id'] = ticket.id
|
values['event_ticket_id'] = ticket.id
|
||||||
values['price_unit'] = ticket.price_reduce or ticket.price
|
values['price_unit'] = ticket.price_reduce
|
||||||
values['name'] = "%s\n%s" % (ticket.event_id.display_name, ticket.name)
|
values['name'] = "%s\n%s" % (ticket.event_id.display_name, ticket.name)
|
||||||
|
|
||||||
# avoid writing related values that end up locking the product record
|
# avoid writing related values that end up locking the product record
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
import werkzeug
|
import werkzeug
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
from odoo import fields, http, _
|
from odoo import fields, http, _
|
||||||
|
from odoo.tools import formatLang
|
||||||
from odoo.http import request
|
from odoo.http import request
|
||||||
from odoo.addons.website_mail.controllers.main import _message_post_helper
|
from odoo.addons.website_mail.controllers.main import _message_post_helper
|
||||||
from odoo.addons.website_portal.controllers.main import get_records_pager
|
from odoo.addons.website_portal.controllers.main import get_records_pager
|
||||||
@@ -107,8 +109,17 @@ class sale_quote(http.Controller):
|
|||||||
_message_post_helper(message=message, res_id=order_id, res_model='sale.order', **{'token': token, 'token_field': 'access_token'} if token else {})
|
_message_post_helper(message=message, res_id=order_id, res_model='sale.order', **{'token': token, 'token_field': 'access_token'} if token else {})
|
||||||
return werkzeug.utils.redirect("/quote/%s/%s?message=2" % (order_id, token))
|
return werkzeug.utils.redirect("/quote/%s/%s?message=2" % (order_id, token))
|
||||||
|
|
||||||
|
# Deprecated because override opportunities are **really** limited
|
||||||
|
# In fact it should be removed in master ASAP
|
||||||
@http.route(['/quote/update_line'], type='json', auth="public", website=True)
|
@http.route(['/quote/update_line'], type='json', auth="public", website=True)
|
||||||
def update(self, line_id, remove=False, unlink=False, order_id=None, token=None, **post):
|
def update(self, line_id, remove=False, unlink=False, order_id=None, token=None, **post):
|
||||||
|
values = self.update_line_dict(line_id, remove, unlink, order_id, token, **post)
|
||||||
|
if values:
|
||||||
|
return [values['order_line_product_uom_qty'], values['order_amount_total']]
|
||||||
|
return values
|
||||||
|
|
||||||
|
@http.route(['/quote/update_line_dict'], type='json', auth="public", website=True)
|
||||||
|
def update_line_dict(self, line_id, remove=False, unlink=False, order_id=None, token=None, input_quantity=False, **kwargs):
|
||||||
Order = request.env['sale.order'].sudo().browse(int(order_id))
|
Order = request.env['sale.order'].sudo().browse(int(order_id))
|
||||||
if token != Order.access_token:
|
if token != Order.access_token:
|
||||||
return request.render('website.404')
|
return request.render('website.404')
|
||||||
@@ -118,10 +129,27 @@ class sale_quote(http.Controller):
|
|||||||
if unlink:
|
if unlink:
|
||||||
OrderLine.unlink()
|
OrderLine.unlink()
|
||||||
return False
|
return False
|
||||||
number = -1 if remove else 1
|
|
||||||
quantity = OrderLine.product_uom_qty + number
|
if input_quantity is not False:
|
||||||
|
quantity = input_quantity
|
||||||
|
else:
|
||||||
|
number = -1 if remove else 1
|
||||||
|
quantity = OrderLine.product_uom_qty + number
|
||||||
|
|
||||||
|
if quantity < 0:
|
||||||
|
quantity = 0.0
|
||||||
OrderLine.write({'product_uom_qty': quantity})
|
OrderLine.write({'product_uom_qty': quantity})
|
||||||
return [str(quantity), str(Order.amount_total)]
|
currency = Order.currency_id
|
||||||
|
format_price = partial(formatLang, request.env, digits=currency.decimal_places)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'order_line_product_uom_qty': str(quantity),
|
||||||
|
'order_line_price_total': format_price(OrderLine.price_total),
|
||||||
|
'order_line_price_subtotal': format_price(OrderLine.price_subtotal),
|
||||||
|
'order_amount_total': format_price(Order.amount_total),
|
||||||
|
'order_amount_untaxed': format_price(Order.amount_untaxed),
|
||||||
|
'order_amount_tax': format_price(Order.amount_tax),
|
||||||
|
}
|
||||||
|
|
||||||
@http.route(["/quote/template/<model('sale.quote.template'):quote>"], type='http', auth="user", website=True)
|
@http.route(["/quote/template/<model('sale.quote.template'):quote>"], type='http', auth="user", website=True)
|
||||||
def template_view(self, quote, **post):
|
def template_view(self, quote, **post):
|
||||||
|
|||||||
@@ -15,28 +15,160 @@ if(!$('.o_website_quote').length) {
|
|||||||
events: {
|
events: {
|
||||||
'click' : 'onClick',
|
'click' : 'onClick',
|
||||||
},
|
},
|
||||||
onClick: function(ev){
|
/**
|
||||||
ev.preventDefault();
|
* @override
|
||||||
|
*/
|
||||||
|
start: function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
var href = this.$el.attr("href");
|
return this._super.apply(this, arguments).then(function () {
|
||||||
var order_id = href.match(/order_id=([0-9]+)/);
|
self.elems = self._getUpdatableElements();
|
||||||
var line_id = href.match(/update_line\/([0-9]+)/);
|
self.elems.$lineQuantity.change(function (ev) {
|
||||||
var token = href.match(/token=(.*)/);
|
var quantity = parseInt(this.value);
|
||||||
ajax.jsonRpc("/quote/update_line", 'call', {
|
self._onChangeQuantity(quantity);
|
||||||
'line_id': line_id[1],
|
});
|
||||||
'order_id': parseInt(order_id[1]),
|
|
||||||
'token': token[1],
|
|
||||||
'remove': self.$el.is('[href*="remove"]'),
|
|
||||||
'unlink': self.$el.is('[href*="unlink"]')
|
|
||||||
}).then(function (data) {
|
|
||||||
if(!data){
|
|
||||||
location.reload();
|
|
||||||
}
|
|
||||||
self.$el.parents('.input-group:first').find('.js_quantity').val(data[0]);
|
|
||||||
$('[data-id="total_amount"]>span').html(data[1]);
|
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Process the change in line quantity
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Int} quantity, the new quantity of the line
|
||||||
|
* If not present it will increment/decrement the existing quantity
|
||||||
|
*/
|
||||||
|
_onChangeQuantity: function (quantity) {
|
||||||
|
var href = this.$el.attr("href");
|
||||||
|
var order_id = href.match(/order_id=([0-9]+)/)[1];
|
||||||
|
var line_id = href.match(/update_line(_dict)?\/([0-9]+)/)[2];
|
||||||
|
var token = href.match(/token=([\w\d-]*)/)[1];
|
||||||
|
|
||||||
|
var callParams = {
|
||||||
|
'line_id': parseInt(line_id),
|
||||||
|
'order_id': parseInt(order_id),
|
||||||
|
'token': token,
|
||||||
|
'remove': this.$el.is('[href*="remove"]'),
|
||||||
|
'unlink': this.$el.is('[href*="unlink"]'),
|
||||||
|
'input_quantity': quantity >= 0 ? quantity : false,
|
||||||
|
};
|
||||||
|
this._callUpdateLineRoute(callParams).then(this._updateOrderValues.bind(this));
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Reacts to the click on the -/+ buttons
|
||||||
|
*
|
||||||
|
* @param {Event} ev
|
||||||
|
*/
|
||||||
|
onClick: function (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
return this._onChangeQuantity();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Calls the route to get updated values of the line and order
|
||||||
|
* when the quantity of a product has changed
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} params
|
||||||
|
* @return {Deferred}
|
||||||
|
*/
|
||||||
|
_callUpdateLineRoute: function (params) {
|
||||||
|
var def = new $.Deferred();
|
||||||
|
ajax.jsonRpc("/quote/update_line_dict", 'call', params)
|
||||||
|
.then(def.resolve.bind(def))
|
||||||
|
.fail(function () {
|
||||||
|
// Compatibility: the server may not have been restarted
|
||||||
|
// So the real route may not exist
|
||||||
|
delete params.input_quantity;
|
||||||
|
ajax.jsonRpc("/quote/update_line", 'call', params)
|
||||||
|
.fail(def.reject.bind(def))
|
||||||
|
.then(function (data) {
|
||||||
|
// Data is an array, convert it to a dict
|
||||||
|
var actualData = data;
|
||||||
|
if (data) {
|
||||||
|
actualData = {
|
||||||
|
order_amount_total: data[1],
|
||||||
|
order_line_product_uom_qty: data[0],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
def.resolve(actualData);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return def;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Processes data from the server to update the UI
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} data: contains order and line updated values
|
||||||
|
*/
|
||||||
|
_updateOrderValues: function (data) {
|
||||||
|
if (!data) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
var orderAmountTotal = data.order_amount_total;
|
||||||
|
var orderAmountUntaxed = data.order_amount_untaxed;
|
||||||
|
var orderAmountTax = data.order_amount_tax;
|
||||||
|
|
||||||
|
var lineProductUomQty = data.order_line_product_uom_qty;
|
||||||
|
var linePriceTotal = data.order_line_price_total;
|
||||||
|
var linePriceSubTotal = data.order_line_price_subtotal;
|
||||||
|
|
||||||
|
this.elems.$lineQuantity.val(lineProductUomQty)
|
||||||
|
|
||||||
|
if (this.elems.$linePriceTotal.length && linePriceTotal !== undefined) {
|
||||||
|
this.elems.$linePriceTotal.text(linePriceTotal);
|
||||||
|
}
|
||||||
|
if (this.elems.$linePriceSubTotal.length && linePriceSubTotal !== undefined) {
|
||||||
|
this.elems.$linePriceSubTotal.text(linePriceSubTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orderAmountUntaxed !== undefined) {
|
||||||
|
this.elems.$orderAmountUntaxed.text(orderAmountUntaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orderAmountTax !== undefined) {
|
||||||
|
this.elems.$orderAmountTax.text(orderAmountTax);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orderAmountTotal !== undefined) {
|
||||||
|
this.elems.$orderAmountTotal.text(orderAmountTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Locate in the DOM the elements to update
|
||||||
|
* Mostly for compatibility, when the module has not been upgraded
|
||||||
|
* In that case, we need to fall back to some other elements
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @return {Object}: Jquery elements to update
|
||||||
|
*/
|
||||||
|
_getUpdatableElements: function () {
|
||||||
|
var $parentTr = this.$el.parents('tr:first');
|
||||||
|
var $linePriceTotal = $parentTr.find('.oe_order_line_price_total .oe_currency_value');
|
||||||
|
var $linePriceSubTotal = $parentTr.find('.oe_order_line_price_subtotal .oe_currency_value');
|
||||||
|
|
||||||
|
if (!$linePriceTotal.length && !$linePriceSubTotal.length) {
|
||||||
|
$linePriceTotal = $linePriceSubTotal = $parentTr.find('.oe_currency_value').last();
|
||||||
|
}
|
||||||
|
|
||||||
|
var $orderAmountUntaxed = $('[data-id="total_untaxed"]>span');
|
||||||
|
var $orderAmountTax = $('[data-id="total_taxes"]>span');
|
||||||
|
var $orderAmountTotal = $('[data-id="total_amount"]>span');
|
||||||
|
|
||||||
|
if (!$orderAmountUntaxed.length && !$orderAmountTax.length) {
|
||||||
|
$orderAmountUntaxed = $orderAmountTotal.eq(1);
|
||||||
|
$orderAmountTax = $orderAmountTotal.eq(2);
|
||||||
|
$orderAmountTotal = $orderAmountTotal.eq(0).add($orderAmountTotal.eq(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
$lineQuantity: this.$el.parents('.input-group:first').find('.js_quantity'),
|
||||||
|
$linePriceSubTotal: $linePriceSubTotal,
|
||||||
|
$linePriceTotal: $linePriceTotal,
|
||||||
|
$orderAmountUntaxed: $orderAmountUntaxed,
|
||||||
|
$orderAmountTax: $orderAmountTax,
|
||||||
|
$orderAmountTotal: $orderAmountTotal,
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var update_button_list = [];
|
var update_button_list = [];
|
||||||
|
|||||||
@@ -10,6 +10,12 @@
|
|||||||
class="o_open_quotation" string="Preview"
|
class="o_open_quotation" string="Preview"
|
||||||
attrs="{'invisible': [('template_id', '=', False)]}"/>
|
attrs="{'invisible': [('template_id', '=', False)]}"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
<xpath expr="//page/field[@name='order_line']/tree/field[@name='name']" position="after">
|
||||||
|
<field name="website_description" invisible="1" readonly="1"/>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//page/field[@name='order_line']/form/field[@name='name']" position="after">
|
||||||
|
<field name="website_description" invisible="1" readonly="1"/>
|
||||||
|
</xpath>
|
||||||
<xpath expr="//page/field[@name='order_line']/.." position="after">
|
<xpath expr="//page/field[@name='order_line']/.." position="after">
|
||||||
<page string="Suggested Products">
|
<page string="Suggested Products">
|
||||||
<field name="quote_viewed" invisible="1"/>
|
<field name="quote_viewed" invisible="1"/>
|
||||||
|
|||||||
@@ -74,11 +74,11 @@
|
|||||||
<t t-esc="(1-line.discount / 100.0) * line.price_unit" t-options='{"widget": "monetary", "display_currency": quotation.pricelist_id.currency_id}'/>
|
<t t-esc="(1-line.discount / 100.0) * line.price_unit" t-options='{"widget": "monetary", "display_currency": quotation.pricelist_id.currency_id}'/>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right" groups="sale.group_show_price_subtotal">
|
<td class="text-right oe_order_line_price_subtotal" groups="sale.group_show_price_subtotal">
|
||||||
<span t-field="line.price_subtotal"
|
<span t-field="line.price_subtotal"
|
||||||
t-options='{"widget": "monetary", "display_currency": quotation.pricelist_id.currency_id}'/>
|
t-options='{"widget": "monetary", "display_currency": quotation.pricelist_id.currency_id}'/>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right" groups="sale.group_show_price_total">
|
<td class="text-right oe_order_line_price_total" groups="sale.group_show_price_total">
|
||||||
<span t-field="line.price_total"
|
<span t-field="line.price_total"
|
||||||
t-options='{"widget": "monetary", "display_currency": quotation.pricelist_id.currency_id}'/>
|
t-options='{"widget": "monetary", "display_currency": quotation.pricelist_id.currency_id}'/>
|
||||||
</td>
|
</td>
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
<td></td><td></td><td></td><td></td>
|
<td></td><td></td><td></td><td></td>
|
||||||
<td class="text-right"><strong>Subtotal:</strong></td>
|
<td class="text-right"><strong>Subtotal:</strong></td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<strong data-id="total_amount" t-field="quotation.amount_untaxed" t-options='{"widget": "monetary","display_currency": quotation.pricelist_id.currency_id}'/>
|
<strong data-id="total_untaxed" t-field="quotation.amount_untaxed" t-options='{"widget": "monetary","display_currency": quotation.pricelist_id.currency_id}'/>
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
<td></td><td></td><td></td><td></td>
|
<td></td><td></td><td></td><td></td>
|
||||||
<td class="text-right">Taxes:</td>
|
<td class="text-right">Taxes:</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<span data-id="total_amount" t-field="quotation.amount_tax" t-options='{"widget": "monetary","display_currency": quotation.pricelist_id.currency_id}'/>
|
<span data-id="total_taxes" t-field="quotation.amount_tax" t-options='{"widget": "monetary","display_currency": quotation.pricelist_id.currency_id}'/>
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
Reference in New Issue
Block a user