[IMP] account, sale: convert template python logic into computed field

Make simpler report edition in studio

* 'amount_by_group' for account.invoice and sale.order
* 'price_tax' for account.invoice.line
This commit is contained in:
Christophe Matthieu
2018-08-13 17:09:28 +02:00
parent 19106533d3
commit 149eb38b07
6 changed files with 71 additions and 41 deletions
+21 -16
View File
@@ -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'),
+2 -6
View File
@@ -107,11 +107,7 @@
<span t-esc="', '.join(map(lambda x: (x.description or x.name), line.invoice_line_tax_ids))"/>
</td>
<td t-if="display_taxamount and type_is_out" class="text-right d-none d-md-table-cell">
<t t-set="taxes"
t-value="line.invoice_line_tax_ids.compute_all(line.price_unit, line.currency_id, line.quantity)"/>
<t t-set="tax_amount"
t-value="taxes and (taxes['total_included'] - taxes['base']) or 0.0"/>
<span t-esc="tax_amount" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
<span t-esc="line.price_tax" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
</td>
<td class="text-right">
<span
@@ -164,7 +160,7 @@
<span t-field="o.amount_untaxed" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
</td>
</tr>
<t t-foreach="o._get_tax_amount_by_group()" t-as="amount_by_group">
<t t-foreach="o.amount_by_group" t-as="amount_by_group">
<tr style="border-bottom:1px solid #dddddd;">
<t t-if="len(o.tax_line_ids) == 1 and o.amount_untaxed == amount_by_group[2]">
<td>
+45 -16
View File
@@ -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:
+1 -1
View File
@@ -175,7 +175,7 @@
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
</td>
</tr>
<t t-foreach="doc._get_tax_amount_by_group()" t-as="amount_by_group">
<t t-foreach="doc.amount_by_group" t-as="amount_by_group">
<tr style="border-bottom:1px solid #dddddd;">
<t t-if="amount_by_group[3] == 1 and doc.amount_untaxed == amount_by_group[2]">
<td>
+1 -1
View File
@@ -326,7 +326,7 @@
</div>
</div>
<div class="row mb4">
<t t-set="tax_groups" t-value="order._get_tax_amount_by_group()"/>
<t t-set="tax_groups" t-value="order.amount_by_group"/>
<t t-foreach="tax_groups" t-as="amount_by_group">
<t t-if="len(tax_groups) == 1 and order.amount_untaxed == amount_by_group[2]">
<div class="col-lg-9 col-8 text-right"><span t-esc="amount_by_group[0]"/></div>
@@ -140,7 +140,7 @@
/>
</td>
</tr>
<t t-foreach="quotation._get_tax_amount_by_group()" t-as="amount_by_group">
<t t-foreach="quotation.amount_by_group" t-as="amount_by_group">
<tr style="border-bottom:1px solid #dddddd;">
<t t-if="amount_by_group[3] == 1 and quotation.amount_untaxed == amount_by_group[2]">
<td>