[IMP] account: optimized the account invoice analysis report to lower the response time. Removed the fields due_delay and delay_to_pay that were the reasons of the bad performances besides being a bit useless and having wrong values computed
bzr revid: qdp-launchpad@openerp.com-20121129101228-6cxv07svxnbabfr0
This commit is contained in:
@@ -1381,8 +1381,8 @@ class account_invoice_line(osv.osv):
|
||||
'origin': fields.char('Source Document', size=256, help="Reference of the document that produced this invoice."),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence of this line when displaying the invoice."),
|
||||
'invoice_id': fields.many2one('account.invoice', 'Invoice Reference', ondelete='cascade', select=True),
|
||||
'uos_id': fields.many2one('product.uom', 'Unit of Measure', ondelete='set null'),
|
||||
'product_id': fields.many2one('product.product', 'Product', ondelete='set null'),
|
||||
'uos_id': fields.many2one('product.uom', 'Unit of Measure', ondelete='set null', select=True),
|
||||
'product_id': fields.many2one('product.product', 'Product', ondelete='set null', select=True),
|
||||
'account_id': fields.many2one('account.account', 'Account', required=True, domain=[('type','<>','view'), ('type', '<>', 'closed')], help="The income or expense account related to the selected product."),
|
||||
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')),
|
||||
'price_subtotal': fields.function(_amount_line, string='Subtotal', type="float",
|
||||
|
||||
@@ -98,150 +98,109 @@ class account_invoice_report(osv.osv):
|
||||
'partner_bank_id': fields.many2one('res.partner.bank', 'Bank Account',readonly=True),
|
||||
'residual': fields.float('Total Residual', readonly=True),
|
||||
'user_currency_residual': fields.function(_compute_amounts_in_user_currency, string="Total Residual", type='float', digits_compute=dp.get_precision('Account'), multi="_compute_amounts"),
|
||||
'delay_to_pay': fields.float('Avg. Delay To Pay', readonly=True, group_operator="avg"),
|
||||
'due_delay': fields.float('Avg. Due Delay', readonly=True, group_operator="avg"),
|
||||
}
|
||||
_order = 'date desc'
|
||||
|
||||
|
||||
def _select(self):
|
||||
select_str = """
|
||||
SELECT min(ail.id) as id,
|
||||
ai.date_invoice as date,
|
||||
to_char(ai.date_invoice, 'YYYY') as year,
|
||||
to_char(ai.date_invoice, 'MM') as month,
|
||||
to_char(ai.date_invoice, 'YYYY-MM-DD') as day,
|
||||
ail.product_id,
|
||||
ai.partner_id as partner_id,
|
||||
ai.payment_term as payment_term,
|
||||
ai.period_id as period_id,
|
||||
(case when u.uom_type not in ('reference') then
|
||||
(select name from product_uom where uom_type='reference' and active and category_id=u.category_id LIMIT 1)
|
||||
else
|
||||
u.name
|
||||
end) as uom_name,
|
||||
ai.currency_id as currency_id,
|
||||
ai.journal_id as journal_id,
|
||||
ai.fiscal_position as fiscal_position,
|
||||
ai.user_id as user_id,
|
||||
ai.company_id as company_id,
|
||||
count(ail.*) as nbr,
|
||||
ai.type as type,
|
||||
ai.state,
|
||||
pt.categ_id,
|
||||
ai.date_due as date_due,
|
||||
ai.account_id as account_id,
|
||||
ail.account_id as account_line_id,
|
||||
ai.partner_bank_id as partner_bank_id,
|
||||
sum(case when ai.type in ('out_refund','in_invoice') then
|
||||
-ail.quantity / u.factor
|
||||
else
|
||||
ail.quantity / u.factor
|
||||
end) as product_qty,
|
||||
|
||||
sum(case when ai.type in ('out_refund','in_invoice') then
|
||||
-ail.price_subtotal
|
||||
else
|
||||
ail.price_subtotal
|
||||
end) / cr.rate as price_total,
|
||||
|
||||
(case when ai.type in ('out_refund','in_invoice') then
|
||||
sum(-ail.price_subtotal)
|
||||
else
|
||||
sum(ail.price_subtotal)
|
||||
end) / (CASE WHEN sum(ail.quantity/u.factor) <> 0
|
||||
THEN
|
||||
(case when ai.type in ('out_refund','in_invoice')
|
||||
then sum(-ail.quantity/u.factor)
|
||||
else sum(ail.quantity/u.factor) end)
|
||||
ELSE 1
|
||||
END)
|
||||
/ cr.rate as price_average,
|
||||
|
||||
cr.rate as currency_rate,
|
||||
sum((select extract(epoch from avg(date_trunc('day',aml.date_created)-date_trunc('day',l.create_date)))/(24*60*60)::decimal(16,2)
|
||||
from account_move_line as aml
|
||||
left join account_invoice as a ON (a.move_id=aml.move_id)
|
||||
left join account_invoice_line as l ON (a.id=l.invoice_id)
|
||||
where a.id=ai.id)) as delay_to_pay,
|
||||
sum((select extract(epoch from avg(date_trunc('day',a.date_due)-date_trunc('day',a.date_invoice)))/(24*60*60)::decimal(16,2)
|
||||
from account_move_line as aml
|
||||
left join account_invoice as a ON (a.move_id=aml.move_id)
|
||||
left join account_invoice_line as l ON (a.id=l.invoice_id)
|
||||
where a.id=ai.id)) as due_delay,
|
||||
(case when ai.type in ('out_refund','in_invoice') then
|
||||
-ai.residual
|
||||
else
|
||||
ai.residual
|
||||
end)/ (CASE WHEN
|
||||
(select count(l.id) from account_invoice_line as l
|
||||
left join account_invoice as a ON (a.id=l.invoice_id)
|
||||
where a.id=ai.id) <> 0
|
||||
THEN
|
||||
(select count(l.id) from account_invoice_line as l
|
||||
left join account_invoice as a ON (a.id=l.invoice_id)
|
||||
where a.id=ai.id)
|
||||
ELSE 1
|
||||
END) / cr.rate as residual
|
||||
SELECT sub.id, sub.date, sub.year, sub.month, sub.day, sub.product_id, sub.partner_id,
|
||||
sub.payment_term, sub.period_id, sub.uom_name, sub.currency_id, sub.journal_id,
|
||||
sub.fiscal_position, sub.user_id, sub.company_id, sub.nbr, sub.type, sub.state,
|
||||
sub.categ_id, sub.date_due, sub.account_id, sub.account_line_id, sub.partner_bank_id,
|
||||
sub.product_qty, sub.price_total / cr.rate as price_total, sub.price_average /cr.rate as price_average,
|
||||
cr.rate as currency_rate, sub.residual / cr.rate as residual, sub.section_id
|
||||
FROM (
|
||||
SELECT min(ail.id) AS id,
|
||||
ai.date_invoice AS date,
|
||||
to_char(ai.date_invoice::timestamp with time zone, 'YYYY'::text) AS year,
|
||||
to_char(ai.date_invoice::timestamp with time zone, 'MM'::text) AS month,
|
||||
to_char(ai.date_invoice::timestamp with time zone, 'YYYY-MM-DD'::text) AS day,
|
||||
ail.product_id, ai.partner_id, ai.payment_term, ai.period_id,
|
||||
CASE
|
||||
WHEN u.uom_type::text <> 'reference'::text
|
||||
THEN ( SELECT product_uom.name
|
||||
FROM product_uom
|
||||
WHERE product_uom.uom_type::text = 'reference'::text
|
||||
AND product_uom.active
|
||||
AND product_uom.category_id = u.category_id LIMIT 1)
|
||||
ELSE u.name
|
||||
END AS uom_name,
|
||||
ai.currency_id, ai.journal_id, ai.fiscal_position, ai.user_id, ai.company_id,
|
||||
count(ail.*) AS nbr,
|
||||
ai.type, ai.state, pt.categ_id, ai.date_due, ai.account_id, ail.account_id AS account_line_id,
|
||||
ai.partner_bank_id,
|
||||
SUM(CASE
|
||||
WHEN ai.type::text = ANY (ARRAY['out_refund'::character varying::text, 'in_invoice'::character varying::text])
|
||||
THEN (- ail.quantity) / u.factor
|
||||
ELSE ail.quantity / u.factor
|
||||
END) AS product_qty,
|
||||
SUM(CASE
|
||||
WHEN ai.type::text = ANY (ARRAY['out_refund'::character varying::text, 'in_invoice'::character varying::text])
|
||||
THEN - ail.price_subtotal
|
||||
ELSE ail.price_subtotal
|
||||
END) AS price_total,
|
||||
CASE
|
||||
WHEN ai.type::text = ANY (ARRAY['out_refund'::character varying::text, 'in_invoice'::character varying::text])
|
||||
THEN SUM(- ail.price_subtotal)
|
||||
ELSE SUM(ail.price_subtotal)
|
||||
END / CASE
|
||||
WHEN SUM(ail.quantity / u.factor) <> 0::numeric
|
||||
THEN CASE
|
||||
WHEN ai.type::text = ANY (ARRAY['out_refund'::character varying::text, 'in_invoice'::character varying::text])
|
||||
THEN SUM((- ail.quantity) / u.factor)
|
||||
ELSE SUM(ail.quantity / u.factor)
|
||||
END
|
||||
ELSE 1::numeric
|
||||
END AS price_average,
|
||||
CASE
|
||||
WHEN ai.type::text = ANY (ARRAY['out_refund'::character varying::text, 'in_invoice'::character varying::text])
|
||||
THEN - ai.residual
|
||||
ELSE ai.residual
|
||||
END / CASE
|
||||
WHEN (( SELECT count(l.id) AS count
|
||||
FROM account_invoice_line l
|
||||
LEFT JOIN account_invoice a ON a.id = l.invoice_id
|
||||
WHERE a.id = ai.id)) <> 0
|
||||
THEN ( SELECT count(l.id) AS count
|
||||
FROM account_invoice_line l
|
||||
LEFT JOIN account_invoice a ON a.id = l.invoice_id
|
||||
WHERE a.id = ai.id)
|
||||
ELSE 1::bigint
|
||||
END::numeric AS residual,
|
||||
ai.section_id
|
||||
FROM account_invoice_line ail
|
||||
JOIN account_invoice ai ON ai.id = ail.invoice_id
|
||||
LEFT JOIN product_product pr ON pr.id = ail.product_id
|
||||
left JOIN product_template pt ON pt.id = pr.product_tmpl_id
|
||||
LEFT JOIN product_uom u ON u.id = ail.uos_id
|
||||
GROUP BY ail.product_id, ai.date_invoice, ai.id,
|
||||
to_char(ai.date_invoice::timestamp with time zone, 'YYYY'::text),
|
||||
to_char(ai.date_invoice::timestamp with time zone, 'MM'::text),
|
||||
to_char(ai.date_invoice::timestamp with time zone, 'YYYY-MM-DD'::text),
|
||||
ai.partner_id, ai.payment_term, ai.period_id, u.name, ai.currency_id, ai.journal_id,
|
||||
ai.fiscal_position, ai.user_id, ai.company_id, ai.type, ai.state, pt.categ_id,
|
||||
ai.date_due, ai.account_id, ail.account_id, ai.partner_bank_id, ai.residual,
|
||||
ai.amount_total, u.uom_type, u.category_id, ai.section_id
|
||||
) AS sub
|
||||
JOIN res_currency_rate cr ON (cr.currency_id = sub.currency_id)
|
||||
WHERE
|
||||
cr.id IN (SELECT id
|
||||
FROM res_currency_rate cr2
|
||||
WHERE (cr2.currency_id = sub.currency_id)
|
||||
AND ((sub.date IS NOT NULL AND cr.name <= sub.date)
|
||||
OR (sub.date IS NULL AND cr.name <= NOW()))
|
||||
ORDER BY name DESC LIMIT 1);
|
||||
"""
|
||||
return select_str
|
||||
|
||||
def _where(self):
|
||||
where_str = """
|
||||
WHERE cr.id in (select id from res_currency_rate cr2 where (cr2.currency_id = ai.currency_id)
|
||||
and ((ai.date_invoice is not null and cr.name <= ai.date_invoice) or (ai.date_invoice is null and cr.name <= NOW())) order by name desc limit 1)
|
||||
"""
|
||||
return where_str
|
||||
|
||||
def _from(self):
|
||||
from_str = """
|
||||
FROM account_invoice_line as ail
|
||||
left join account_invoice as ai ON (ai.id=ail.invoice_id)
|
||||
left join product_product pr on (pr.id=ail.product_id)
|
||||
left join product_template pt on (pt.id=pr.product_tmpl_id)
|
||||
left join product_uom u on (u.id=ail.uos_id),
|
||||
res_currency_rate cr
|
||||
"""
|
||||
return from_str
|
||||
|
||||
def _group_by(self):
|
||||
group_by_str = """
|
||||
GROUP BY ail.product_id,
|
||||
ai.date_invoice,
|
||||
ai.id,
|
||||
cr.rate,
|
||||
to_char(ai.date_invoice, 'YYYY'),
|
||||
to_char(ai.date_invoice, 'MM'),
|
||||
to_char(ai.date_invoice, 'YYYY-MM-DD'),
|
||||
ai.partner_id,
|
||||
ai.payment_term,
|
||||
ai.period_id,
|
||||
u.name,
|
||||
ai.currency_id,
|
||||
ai.journal_id,
|
||||
ai.fiscal_position,
|
||||
ai.user_id,
|
||||
ai.company_id,
|
||||
ai.type,
|
||||
ai.state,
|
||||
pt.categ_id,
|
||||
ai.date_due,
|
||||
ai.account_id,
|
||||
ail.account_id,
|
||||
ai.partner_bank_id,
|
||||
ai.residual,
|
||||
ai.amount_total,
|
||||
u.uom_type,
|
||||
u.category_id
|
||||
"""
|
||||
return group_by_str
|
||||
|
||||
def init(self, cr):
|
||||
# self._table = account_invoice_report
|
||||
tools.drop_view_if_exists(cr, self._table)
|
||||
cr.execute("CREATE or REPLACE VIEW %s as (%s %s %s %s)" % (
|
||||
cr.execute("CREATE or REPLACE VIEW %s as (%s %s)" % (
|
||||
self._table,
|
||||
self._select(), self._from(), self._where(), self._group_by()))
|
||||
self._select()))
|
||||
|
||||
account_invoice_report()
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
<!-- <field name="reconciled" sum="# Reconciled"/> -->
|
||||
<field name="user_currency_price_total" sum="Total Without Tax"/>
|
||||
<field name="user_currency_residual" sum="Total Residual" invisible="context.get('residual_invisible',False)"/>
|
||||
<field name="due_delay" sum="Avg. Due Delay" invisible="context.get('residual_invisible',False)"/>
|
||||
<field name="delay_to_pay" sum="Avg. Delay To Pay" invisible="context.get('residual_invisible',False)"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -93,7 +91,7 @@
|
||||
<field name="view_mode">tree,graph</field>
|
||||
<field name="context">{'search_default_period':1,'search_default_current':1, 'search_default_year': 1, 'search_default_category_product':1, 'search_default_customer':1, 'group_by':[], 'group_by_no_leaf':1,}</field>
|
||||
<field name="search_view_id" ref="view_account_invoice_report_search"/>
|
||||
<field name="help">From this report, you can have an overview of the amount invoiced to your customer as well as payment delays. The tool search can also be used to personalise your Invoices reports and so, match this analysis to your needs.</field>
|
||||
<field name="help">From this report, you can have an overview of the amount invoiced to your customer. The tool search can also be used to personalise your Invoices reports and so, match this analysis to your needs.</field>
|
||||
|
||||
</record>
|
||||
|
||||
|
||||
@@ -546,7 +546,7 @@ class product_product(osv.osv):
|
||||
'default_code' : fields.char('Internal Reference', size=64, select=True),
|
||||
'active': fields.boolean('Active', help="If unchecked, it will allow you to hide the product without removing it."),
|
||||
'variants': fields.char('Variants', size=64),
|
||||
'product_tmpl_id': fields.many2one('product.template', 'Product Template', required=True, ondelete="cascade"),
|
||||
'product_tmpl_id': fields.many2one('product.template', 'Product Template', required=True, ondelete="cascade", select=True),
|
||||
'ean13': fields.char('EAN13 Barcode', size=13, help="International Article Number used for product identification."),
|
||||
'packaging' : fields.one2many('product.packaging', 'product_id', 'Logistical Units', help="Gives the different ways to package the same product. This has no impact on the picking order and is mainly used if you use the EDI module."),
|
||||
'price_extra': fields.float('Variant Price Extra', digits_compute=dp.get_precision('Product Price')),
|
||||
|
||||
Reference in New Issue
Block a user