diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/account/report/account_invoice_report.py | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/account/report/account_invoice_report.py')
| -rw-r--r-- | addons/account/report/account_invoice_report.py | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/addons/account/report/account_invoice_report.py b/addons/account/report/account_invoice_report.py new file mode 100644 index 00000000..05be7856 --- /dev/null +++ b/addons/account/report/account_invoice_report.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api + +from functools import lru_cache + + +class AccountInvoiceReport(models.Model): + _name = "account.invoice.report" + _description = "Invoices Statistics" + _auto = False + _rec_name = 'invoice_date' + _order = 'invoice_date desc' + + # ==== Invoice fields ==== + move_id = fields.Many2one('account.move', readonly=True) + journal_id = fields.Many2one('account.journal', string='Journal', readonly=True) + company_id = fields.Many2one('res.company', string='Company', readonly=True) + company_currency_id = fields.Many2one('res.currency', string='Company Currency', readonly=True) + partner_id = fields.Many2one('res.partner', string='Partner', readonly=True) + commercial_partner_id = fields.Many2one('res.partner', string='Partner Company', help="Commercial Entity") + country_id = fields.Many2one('res.country', string="Country") + invoice_user_id = fields.Many2one('res.users', string='Salesperson', readonly=True) + move_type = fields.Selection([ + ('out_invoice', 'Customer Invoice'), + ('in_invoice', 'Vendor Bill'), + ('out_refund', 'Customer Credit Note'), + ('in_refund', 'Vendor Credit Note'), + ], readonly=True) + state = fields.Selection([ + ('draft', 'Draft'), + ('posted', 'Open'), + ('cancel', 'Cancelled') + ], string='Invoice Status', readonly=True) + payment_state = fields.Selection(selection=[ + ('not_paid', 'Not Paid'), + ('in_payment', 'In Payment'), + ('paid', 'paid') + ], string='Payment Status', readonly=True) + fiscal_position_id = fields.Many2one('account.fiscal.position', string='Fiscal Position', readonly=True) + invoice_date = fields.Date(readonly=True, string="Invoice Date") + + # ==== 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_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)]) + analytic_account_id = fields.Many2one('account.analytic.account', string='Analytic Account', groups="analytic.group_analytic_accounting") + price_subtotal = fields.Float(string='Untaxed Total', readonly=True) + price_average = fields.Float(string='Average Price', readonly=True, group_operator="avg") + + _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', + ], + 'account.move.line': [ + 'quantity', 'price_subtotal', 'amount_residual', 'balance', 'amount_currency', + 'move_id', 'product_id', 'product_uom_id', 'account_id', 'analytic_account_id', + 'journal_id', 'company_id', 'currency_id', 'partner_id', + ], + 'product.product': ['product_tmpl_id'], + 'product.template': ['categ_id'], + 'uom.uom': ['category_id', 'factor', 'name', 'uom_type'], + '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()) + + @api.model + def _select(self): + return ''' + SELECT + line.id, + line.move_id, + line.product_id, + line.account_id, + line.analytic_account_id, + line.journal_id, + line.company_id, + line.company_currency_id, + line.partner_id AS commercial_partner_id, + move.state, + move.move_type, + move.partner_id, + move.invoice_user_id, + move.fiscal_position_id, + move.payment_state, + move.invoice_date, + 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) + AS quantity, + -line.balance * currency_table.rate AS price_subtotal, + -COALESCE( + -- Average line price + (line.balance / NULLIF(line.quantity, 0.0)) + -- 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, + COALESCE(partner.country_id, commercial_partner.country_id) AS country_id + ''' + + @api.model + def _from(self): + return ''' + 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 + LEFT JOIN account_account account ON account.id = line.account_id + LEFT JOIN account_account_type user_type ON user_type.id = account.user_type_id + LEFT JOIN product_template template ON template.id = product.product_tmpl_id + LEFT JOIN uom_uom uom_line ON uom_line.id = line.product_uom_id + 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()}}), + ) + + @api.model + def _where(self): + return ''' + 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 NOT line.exclude_from_invoice_tab + ''' + + +class ReportInvoiceWithoutPayment(models.AbstractModel): + _name = 'report.account.report_invoice' + _description = 'Account report without payment lines' + + @api.model + def _get_report_values(self, docids, data=None): + docs = self.env['account.move'].browse(docids) + + qr_code_urls = {} + for invoice in docs: + if invoice.display_qr_code: + new_code_url = invoice.generate_qr_code() + if new_code_url: + qr_code_urls[invoice.id] = new_code_url + + return { + 'doc_ids': docids, + 'doc_model': 'account.move', + 'docs': docs, + 'qr_code_urls': qr_code_urls, + } + +class ReportInvoiceWithPayment(models.AbstractModel): + _name = 'report.account.report_invoice_with_payments' + _description = 'Account report with payment lines' + _inherit = 'report.account.report_invoice' + + @api.model + def _get_report_values(self, docids, data=None): + rslt = super()._get_report_values(docids, data) + rslt['report_type'] = data.get('report_type') if data else '' + return rslt |
