mirror of
https://github.com/bringout/oca-ocb-accounting.git
synced 2026-04-25 06:42:03 +02:00
19.0 vanilla
This commit is contained in:
parent
ba20ce7443
commit
768b70e05e
2357 changed files with 1057103 additions and 712486 deletions
|
|
@ -1,13 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import models, fields, api
|
||||
from odoo.tools import SQL
|
||||
from odoo.tools.query import Query
|
||||
from odoo.addons.account.models.account_move import PAYMENT_STATE_SELECTION
|
||||
|
||||
from functools import lru_cache
|
||||
|
||||
|
||||
class AccountInvoiceReport(models.Model):
|
||||
_name = "account.invoice.report"
|
||||
_name = 'account.invoice.report'
|
||||
_description = "Invoices Statistics"
|
||||
_auto = False
|
||||
_rec_name = 'invoice_date'
|
||||
|
|
@ -40,39 +42,44 @@ class AccountInvoiceReport(models.Model):
|
|||
# ==== Invoice line fields ====
|
||||
quantity = fields.Float(string='Product Quantity', readonly=True)
|
||||
product_id = fields.Many2one('product.product', string='Product', readonly=True)
|
||||
product_uom_id = fields.Many2one('uom.uom', string='Unit of Measure', readonly=True)
|
||||
product_uom_id = fields.Many2one('uom.uom', string='Unit', readonly=True)
|
||||
product_categ_id = fields.Many2one('product.category', string='Product Category', readonly=True)
|
||||
invoice_date_due = fields.Date(string='Due Date', readonly=True)
|
||||
account_id = fields.Many2one('account.account', string='Revenue/Expense Account', readonly=True, domain=[('deprecated', '=', False)])
|
||||
price_subtotal = fields.Float(string='Untaxed Total', readonly=True)
|
||||
price_total = fields.Float(string='Total in Currency', readonly=True)
|
||||
price_average = fields.Float(string='Average Price', readonly=True, group_operator="avg")
|
||||
account_id = fields.Many2one('account.account', string='Revenue/Expense Account', readonly=True)
|
||||
price_subtotal_currency = fields.Float(string='Untaxed Amount in Currency', readonly=True)
|
||||
price_subtotal = fields.Float(string='Untaxed Amount', readonly=True)
|
||||
price_total = fields.Float(string='Total', readonly=True)
|
||||
price_total_currency = fields.Float(string='Total in Currency', readonly=True)
|
||||
price_average = fields.Float(string='Average Price', readonly=True, aggregator="avg")
|
||||
price_margin = fields.Float(string='Margin', readonly=True)
|
||||
inventory_value = fields.Float(string='Inventory Value', readonly=True)
|
||||
currency_id = fields.Many2one('res.currency', string='Currency', readonly=True)
|
||||
|
||||
_depends = {
|
||||
'account.move': [
|
||||
'name', 'state', 'move_type', 'partner_id', 'invoice_user_id', 'fiscal_position_id',
|
||||
'invoice_date', 'invoice_date_due', 'invoice_payment_term_id', 'partner_bank_id',
|
||||
'invoice_date', 'invoice_date_due', 'invoice_payment_term_id', 'partner_bank_id', 'invoice_currency_rate',
|
||||
],
|
||||
'account.move.line': [
|
||||
'quantity', 'price_subtotal', 'price_total', 'amount_residual', 'balance', 'amount_currency',
|
||||
'move_id', 'product_id', 'product_uom_id', 'account_id',
|
||||
'journal_id', 'company_id', 'currency_id', 'partner_id',
|
||||
],
|
||||
'product.product': ['product_tmpl_id'],
|
||||
'product.product': ['product_tmpl_id', 'standard_price'],
|
||||
'product.template': ['categ_id'],
|
||||
'uom.uom': ['category_id', 'factor', 'name', 'uom_type'],
|
||||
'uom.uom': ['factor', 'name'],
|
||||
'res.currency.rate': ['currency_id', 'name'],
|
||||
'res.partner': ['country_id'],
|
||||
}
|
||||
|
||||
@property
|
||||
def _table_query(self):
|
||||
return '%s %s %s' % (self._select(), self._from(), self._where())
|
||||
def _table_query(self) -> SQL:
|
||||
return SQL('%s %s %s', self._select(), self._from(), self._where())
|
||||
|
||||
@api.model
|
||||
def _select(self):
|
||||
return '''
|
||||
def _select(self) -> SQL:
|
||||
return SQL(
|
||||
'''
|
||||
SELECT
|
||||
line.id,
|
||||
line.move_id,
|
||||
|
|
@ -93,24 +100,39 @@ class AccountInvoiceReport(models.Model):
|
|||
move.invoice_date_due,
|
||||
uom_template.id AS product_uom_id,
|
||||
template.categ_id AS product_categ_id,
|
||||
line.quantity / NULLIF(COALESCE(uom_line.factor, 1) / COALESCE(uom_template.factor, 1), 0.0) * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END)
|
||||
line.quantity * COALESCE(uom_line.factor, 1) / NULLIF(COALESCE(uom_template.factor, 1), 0.0) * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END)
|
||||
AS quantity,
|
||||
-line.balance * currency_table.rate AS price_subtotal,
|
||||
line.price_subtotal * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END)
|
||||
AS price_subtotal_currency,
|
||||
-line.balance * account_currency_table.rate AS price_subtotal,
|
||||
line.price_total * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END)
|
||||
/ move.invoice_currency_rate
|
||||
AS price_total,
|
||||
line.price_total * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END)
|
||||
AS price_total_currency,
|
||||
-COALESCE(
|
||||
-- Average line price
|
||||
(line.balance / NULLIF(line.quantity, 0.0)) * (CASE WHEN move.move_type IN ('in_invoice','out_refund','in_receipt') THEN -1 ELSE 1 END)
|
||||
-- convert to template uom
|
||||
* (NULLIF(COALESCE(uom_line.factor, 1), 0.0) / NULLIF(COALESCE(uom_template.factor, 1), 0.0)),
|
||||
0.0) * currency_table.rate AS price_average,
|
||||
/ NULLIF(COALESCE(uom_line.factor, 1), 0.0) * COALESCE(uom_template.factor, 1),
|
||||
0.0) * account_currency_table.rate AS price_average,
|
||||
CASE
|
||||
WHEN move.move_type NOT IN ('out_invoice', 'out_receipt', 'out_refund') THEN 0.0
|
||||
WHEN move.move_type = 'out_refund' THEN account_currency_table.rate * (-line.balance + (line.quantity * COALESCE(uom_line.factor, 1) / NULLIF(COALESCE(uom_template.factor, 1), 0.0)) * COALESCE(product.standard_price -> line.company_id::text, to_jsonb(0.0))::float)
|
||||
ELSE account_currency_table.rate * (-line.balance - (line.quantity * COALESCE(uom_line.factor, 1) / NULLIF(COALESCE(uom_template.factor, 1), 0.0)) * COALESCE(product.standard_price -> line.company_id::text, to_jsonb(0.0))::float)
|
||||
END
|
||||
AS price_margin,
|
||||
account_currency_table.rate * line.quantity * COALESCE(uom_line.factor, 1) / NULLIF(COALESCE(uom_template.factor, 1), 0.0) * (CASE WHEN move.move_type IN ('out_invoice','in_refund','out_receipt') THEN -1 ELSE 1 END)
|
||||
* COALESCE(product.standard_price -> line.company_id::text, to_jsonb(0.0))::float AS inventory_value,
|
||||
COALESCE(partner.country_id, commercial_partner.country_id) AS country_id,
|
||||
line.currency_id AS currency_id
|
||||
'''
|
||||
''',
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _from(self):
|
||||
return '''
|
||||
def _from(self) -> SQL:
|
||||
return SQL(
|
||||
'''
|
||||
FROM account_move_line line
|
||||
LEFT JOIN res_partner partner ON partner.id = line.partner_id
|
||||
LEFT JOIN product_product product ON product.id = line.product_id
|
||||
|
|
@ -120,45 +142,33 @@ class AccountInvoiceReport(models.Model):
|
|||
LEFT JOIN uom_uom uom_template ON uom_template.id = template.uom_id
|
||||
INNER JOIN account_move move ON move.id = line.move_id
|
||||
LEFT JOIN res_partner commercial_partner ON commercial_partner.id = move.commercial_partner_id
|
||||
JOIN {currency_table} ON currency_table.company_id = line.company_id
|
||||
'''.format(
|
||||
currency_table=self.env['res.currency']._get_query_currency_table({'multi_company': True, 'date': {'date_to': fields.Date.today()}}),
|
||||
JOIN %(currency_table)s ON account_currency_table.company_id = line.company_id
|
||||
''',
|
||||
currency_table=self.env['res.currency']._get_simple_currency_table(self.env.companies),
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _where(self):
|
||||
return '''
|
||||
def _where(self) -> SQL:
|
||||
return SQL(
|
||||
'''
|
||||
WHERE move.move_type IN ('out_invoice', 'out_refund', 'in_invoice', 'in_refund', 'out_receipt', 'in_receipt')
|
||||
AND line.account_id IS NOT NULL
|
||||
AND line.display_type = 'product'
|
||||
'''
|
||||
''',
|
||||
)
|
||||
|
||||
@api.model
|
||||
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
|
||||
"""
|
||||
This is a hack to allow us to correctly calculate the average price.
|
||||
"""
|
||||
set_fields = set(fields)
|
||||
|
||||
if 'price_average:avg' in fields:
|
||||
set_fields.add('quantity:sum')
|
||||
set_fields.add('price_subtotal:sum')
|
||||
|
||||
res = super().read_group(domain, list(set_fields), groupby, offset, limit, orderby, lazy)
|
||||
|
||||
if 'price_average:avg' in fields:
|
||||
for data in res:
|
||||
data['price_average'] = data['price_subtotal'] / data['quantity'] if data['quantity'] else 0
|
||||
|
||||
if 'quantity:sum' not in fields:
|
||||
del data['quantity']
|
||||
if 'price_subtotal:sum' not in fields:
|
||||
del data['price_subtotal']
|
||||
|
||||
return res
|
||||
def _read_group_select(self, aggregate_spec: str, query: Query) -> SQL:
|
||||
""" This override allows us to correctly calculate the average price of products. """
|
||||
if aggregate_spec != 'price_average:avg':
|
||||
return super()._read_group_select(aggregate_spec, query)
|
||||
return SQL(
|
||||
'COALESCE(SUM(%(f_price)s) / NULLIF(SUM(%(f_qty)s), 0.0), 0)',
|
||||
f_qty=self._field_to_sql(self._table, 'quantity', query),
|
||||
f_price=self._field_to_sql(self._table, 'price_subtotal', query),
|
||||
)
|
||||
|
||||
|
||||
class ReportInvoiceWithoutPayment(models.AbstractModel):
|
||||
class ReportAccountReport_Invoice(models.AbstractModel):
|
||||
_name = 'report.account.report_invoice'
|
||||
_description = 'Account report without payment lines'
|
||||
|
||||
|
|
@ -180,10 +190,11 @@ class ReportInvoiceWithoutPayment(models.AbstractModel):
|
|||
'qr_code_urls': qr_code_urls,
|
||||
}
|
||||
|
||||
class ReportInvoiceWithPayment(models.AbstractModel):
|
||||
|
||||
class ReportAccountReport_Invoice_With_Payments(models.AbstractModel):
|
||||
_name = 'report.account.report_invoice_with_payments'
|
||||
_description = 'Account report with payment lines'
|
||||
_inherit = 'report.account.report_invoice'
|
||||
_inherit = ['report.account.report_invoice']
|
||||
|
||||
@api.model
|
||||
def _get_report_values(self, docids, data=None):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue