diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py
index 56f1e9c910e..f4fe6810f44 100644
--- a/addons/account/models/account_invoice.py
+++ b/addons/account/models/account_invoice.py
@@ -302,6 +302,7 @@ class AccountInvoice(models.Model):
readonly=True, index=True, ondelete='restrict', copy=False,
help="Link to the automatically generated Journal Items.")
+ amount_by_group = fields.Binary(string="Taxe amount by group", compute='_amount_by_group', help="type: [(name, amount, base, formated amount, formated base)]")
amount_untaxed = fields.Monetary(string='Untaxed Amount',
store=True, readonly=True, compute='_compute_amount', track_visibility='always')
amount_untaxed_signed = fields.Monetary(string='Untaxed Amount in Company Currency', currency_field='company_currency_id',
@@ -1488,22 +1489,21 @@ class AccountInvoice(models.Model):
return 'account.mt_invoice_created'
return super(AccountInvoice, self)._track_subtype(init_values)
- @api.multi
- def _get_tax_amount_by_group(self):
- self.ensure_one()
- currency = self.currency_id or self.company_id.currency_id
- fmt = partial(formatLang, self.with_context(lang=self.partner_id.lang).env, currency_obj=currency)
- res = {}
- for line in self.tax_line_ids:
- res.setdefault(line.tax_id.tax_group_id, {'base': 0.0, 'amount': 0.0})
- res[line.tax_id.tax_group_id]['amount'] += line.amount
- res[line.tax_id.tax_group_id]['base'] += line.base
- res = sorted(res.items(), key=lambda l: l[0].sequence)
- res = [(
- r[0].name, r[1]['amount'], r[1]['base'],
- fmt(r[1]['amount']), fmt(r[1]['base']),
- ) for r in res]
- return res
+ def _amount_by_group(self):
+ for invoice in self:
+ currency = invoice.currency_id or invoice.company_id.currency_id
+ fmt = partial(formatLang, invoice.with_context(lang=invoice.partner_id.lang).env, currency_obj=currency)
+ res = {}
+ for line in invoice.tax_line_ids:
+ res.setdefault(line.tax_id.tax_group_id, {'base': 0.0, 'amount': 0.0})
+ res[line.tax_id.tax_group_id]['amount'] += line.amount
+ res[line.tax_id.tax_group_id]['base'] += line.base
+ res = sorted(res.items(), key=lambda l: l[0].sequence)
+ invoice.amount_by_group = [(
+ r[0].name, r[1]['amount'], r[1]['base'],
+ fmt(r[1]['amount']), fmt(r[1]['base']),
+ len(res),
+ ) for r in res]
class AccountInvoiceLine(models.Model):
@@ -1538,6 +1538,10 @@ class AccountInvoiceLine(models.Model):
return journal.default_credit_account_id.id
return journal.default_debit_account_id.id
+ def _get_price_tax(self):
+ for l in self:
+ l.price_tax = l.price_total - l.price_subtotal
+
name = fields.Text(string='Description', required=True)
origin = fields.Char(string='Source Document',
help="Reference of the document that produced this invoice.")
@@ -1561,6 +1565,7 @@ class AccountInvoiceLine(models.Model):
price_subtotal_signed = fields.Monetary(string='Amount Signed', currency_field='company_currency_id',
store=True, readonly=True, compute='_compute_price',
help="Total amount in the currency of the company, negative for credit note.")
+ price_tax = fields.Monetary(string='Tax Amount', compute='_get_price_tax', store=False)
quantity = fields.Float(string='Quantity', digits=dp.get_precision('Product Unit of Measure'),
required=True, default=1)
discount = fields.Float(string='Discount (%)', digits=dp.get_precision('Discount'),
diff --git a/addons/account/views/report_invoice.xml b/addons/account/views/report_invoice.xml
index 31e0417b5a2..fae65fc1c29 100644
--- a/addons/account/views/report_invoice.xml
+++ b/addons/account/views/report_invoice.xml
@@ -107,11 +107,7 @@
-
-
-
+
|
|
-
+
|
diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py
index d3ac169e17b..2d6fa9e9cb1 100644
--- a/addons/sale/models/sale.py
+++ b/addons/sale/models/sale.py
@@ -4,9 +4,12 @@
import uuid
from datetime import datetime, timedelta
+from functools import partial
+from itertools import groupby
from odoo import api, fields, models, _
from odoo.exceptions import UserError, AccessError
+from odoo.tools.misc import formatLang
from odoo.osv import expression
from odoo.tools import float_is_zero, float_compare
@@ -146,6 +149,7 @@ class SaleOrder(models.Model):
note = fields.Text('Terms and conditions', default=_default_note)
amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, readonly=True, compute='_amount_all', track_visibility='onchange', track_sequence=5)
+ amount_by_group = fields.Binary(string="Taxe amount by group", compute='_amount_by_group', help="type: [(name, amount, base, formated amount, formated base)]")
amount_tax = fields.Monetary(string='Taxes', store=True, readonly=True, compute='_amount_all')
amount_total = fields.Monetary(string='Total', store=True, readonly=True, compute='_amount_all', track_visibility='always', track_sequence=6)
@@ -617,23 +621,48 @@ class SaleOrder(models.Model):
})
order.analytic_account_id = analytic
- @api.multi
- def _get_tax_amount_by_group(self):
+ def _amount_by_group(self):
+ for order in self:
+ currency = order.currency_id or order.company_id.currency_id
+ fmt = partial(formatLang, self.with_context(lang=order.partner_id.lang).env, currency_obj=currency)
+ res = {}
+ for line in self.order_line:
+ price_reduce = line.price_unit * (1.0 - line.discount / 100.0)
+ taxes = line.tax_id.compute_all(price_reduce, quantity=line.product_uom_qty, product=line.product_id, partner=self.partner_shipping_id)['taxes']
+ for tax in line.tax_id:
+ group = tax.tax_group_id
+ res.setdefault(group, {'amount': 0.0, 'base': 0.0})
+ for t in taxes:
+ if t['id'] == tax.id or t['id'] in tax.children_tax_ids.ids:
+ res[group]['amount'] += t['amount']
+ res[group]['base'] += t['base']
+ res = sorted(res.items(), key=lambda l: l[0].sequence)
+ order.amount_by_group = [(
+ l[0].name, l[1]['amount'], l[1]['base'],
+ fmt(l[1]['amount']), fmt(l[1]['base']),
+ len(res),
+ ) for l in res]
+
+ def order_lines_layouted(self):
+ """
+ Returns this order lines classified by sale_layout_category and separated in
+ pages according to the category pagebreaks. Used to render the report.
+ """
self.ensure_one()
- res = {}
- for line in self.order_line:
- price_reduce = line.price_unit * (1.0 - line.discount / 100.0)
- taxes = line.tax_id.compute_all(price_reduce, quantity=line.product_uom_qty, product=line.product_id, partner=self.partner_shipping_id)['taxes']
- for tax in line.tax_id:
- group = tax.tax_group_id
- res.setdefault(group, {'amount': 0.0, 'base': 0.0})
- for t in taxes:
- if t['id'] == tax.id or t['id'] in tax.children_tax_ids.ids:
- res[group]['amount'] += t['amount']
- res[group]['base'] += t['base']
- res = sorted(res.items(), key=lambda l: l[0].sequence)
- res = [(l[0].name, l[1]['amount'], l[1]['base'], len(res)) for l in res]
- return res
+ report_pages = [[]]
+ for category, lines in groupby(self.order_line, lambda l: l.layout_category_id):
+ # If last added category induced a pagebreak, this one will be on a new page
+ if report_pages[-1] and report_pages[-1][-1]['pagebreak']:
+ report_pages.append([])
+ # Append category to current report page
+ report_pages[-1].append({
+ 'name': category and category.name or _('Uncategorized'),
+ 'subtotal': category and category.subtotal,
+ 'pagebreak': category and category.pagebreak,
+ 'lines': list(lines)
+ })
+
+ return report_pages
def get_portal_confirmation_action(self):
if self.company_id.portal_confirmation_sign and not self.signature:
diff --git a/addons/sale/report/sale_report_templates.xml b/addons/sale/report/sale_report_templates.xml
index ef7916213fb..23ec95c586d 100644
--- a/addons/sale/report/sale_report_templates.xml
+++ b/addons/sale/report/sale_report_templates.xml
@@ -175,7 +175,7 @@
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
|
-
+
diff --git a/addons/sale/views/sale_portal_templates.xml b/addons/sale/views/sale_portal_templates.xml
index a48cfe4bdf5..b71f4ae9711 100644
--- a/addons/sale/views/sale_portal_templates.xml
+++ b/addons/sale/views/sale_portal_templates.xml
@@ -326,7 +326,7 @@
-
+
diff --git a/addons/website_quote/views/website_quote_templates.xml b/addons/website_quote/views/website_quote_templates.xml
index 9b73aaf69f4..28851eb32de 100644
--- a/addons/website_quote/views/website_quote_templates.xml
+++ b/addons/website_quote/views/website_quote_templates.xml
@@ -140,7 +140,7 @@
/>
|
-
+
|
|