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/sale/report/sale_report.py | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/sale/report/sale_report.py')
| -rw-r--r-- | addons/sale/report/sale_report.py | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/addons/sale/report/sale_report.py b/addons/sale/report/sale_report.py new file mode 100644 index 00000000..76ec1476 --- /dev/null +++ b/addons/sale/report/sale_report.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import tools +from odoo import api, fields, models + + +class SaleReport(models.Model): + _name = "sale.report" + _description = "Sales Analysis Report" + _auto = False + _rec_name = 'date' + _order = 'date desc' + + @api.model + def _get_done_states(self): + return ['sale', 'done', 'paid'] + + name = fields.Char('Order Reference', readonly=True) + date = fields.Datetime('Order Date', readonly=True) + product_id = fields.Many2one('product.product', 'Product Variant', readonly=True) + product_uom = fields.Many2one('uom.uom', 'Unit of Measure', readonly=True) + product_uom_qty = fields.Float('Qty Ordered', readonly=True) + qty_delivered = fields.Float('Qty Delivered', readonly=True) + qty_to_invoice = fields.Float('Qty To Invoice', readonly=True) + qty_invoiced = fields.Float('Qty Invoiced', readonly=True) + partner_id = fields.Many2one('res.partner', 'Customer', readonly=True) + company_id = fields.Many2one('res.company', 'Company', readonly=True) + user_id = fields.Many2one('res.users', 'Salesperson', readonly=True) + price_total = fields.Float('Total', readonly=True) + price_subtotal = fields.Float('Untaxed Total', readonly=True) + untaxed_amount_to_invoice = fields.Float('Untaxed Amount To Invoice', readonly=True) + untaxed_amount_invoiced = fields.Float('Untaxed Amount Invoiced', readonly=True) + product_tmpl_id = fields.Many2one('product.template', 'Product', readonly=True) + categ_id = fields.Many2one('product.category', 'Product Category', readonly=True) + nbr = fields.Integer('# of Lines', readonly=True) + pricelist_id = fields.Many2one('product.pricelist', 'Pricelist', readonly=True) + analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account', readonly=True) + team_id = fields.Many2one('crm.team', 'Sales Team', readonly=True) + country_id = fields.Many2one('res.country', 'Customer Country', readonly=True) + industry_id = fields.Many2one('res.partner.industry', 'Customer Industry', readonly=True) + commercial_partner_id = fields.Many2one('res.partner', 'Customer Entity', readonly=True) + state = fields.Selection([ + ('draft', 'Draft Quotation'), + ('sent', 'Quotation Sent'), + ('sale', 'Sales Order'), + ('done', 'Sales Done'), + ('cancel', 'Cancelled'), + ], string='Status', readonly=True) + weight = fields.Float('Gross Weight', readonly=True) + volume = fields.Float('Volume', readonly=True) + + discount = fields.Float('Discount %', readonly=True) + discount_amount = fields.Float('Discount Amount', readonly=True) + campaign_id = fields.Many2one('utm.campaign', 'Campaign') + medium_id = fields.Many2one('utm.medium', 'Medium') + source_id = fields.Many2one('utm.source', 'Source') + + order_id = fields.Many2one('sale.order', 'Order #', readonly=True) + + def _query(self, with_clause='', fields={}, groupby='', from_clause=''): + with_ = ("WITH %s" % with_clause) if with_clause else "" + + select_ = """ + coalesce(min(l.id), -s.id) as id, + l.product_id as product_id, + t.uom_id as product_uom, + CASE WHEN l.product_id IS NOT NULL THEN sum(l.product_uom_qty / u.factor * u2.factor) ELSE 0 END as product_uom_qty, + CASE WHEN l.product_id IS NOT NULL THEN sum(l.qty_delivered / u.factor * u2.factor) ELSE 0 END as qty_delivered, + CASE WHEN l.product_id IS NOT NULL THEN sum(l.qty_invoiced / u.factor * u2.factor) ELSE 0 END as qty_invoiced, + CASE WHEN l.product_id IS NOT NULL THEN sum(l.qty_to_invoice / u.factor * u2.factor) ELSE 0 END as qty_to_invoice, + CASE WHEN l.product_id IS NOT NULL THEN sum(l.price_total / CASE COALESCE(s.currency_rate, 0) WHEN 0 THEN 1.0 ELSE s.currency_rate END) ELSE 0 END as price_total, + CASE WHEN l.product_id IS NOT NULL THEN sum(l.price_subtotal / CASE COALESCE(s.currency_rate, 0) WHEN 0 THEN 1.0 ELSE s.currency_rate END) ELSE 0 END as price_subtotal, + CASE WHEN l.product_id IS NOT NULL THEN sum(l.untaxed_amount_to_invoice / CASE COALESCE(s.currency_rate, 0) WHEN 0 THEN 1.0 ELSE s.currency_rate END) ELSE 0 END as untaxed_amount_to_invoice, + CASE WHEN l.product_id IS NOT NULL THEN sum(l.untaxed_amount_invoiced / CASE COALESCE(s.currency_rate, 0) WHEN 0 THEN 1.0 ELSE s.currency_rate END) ELSE 0 END as untaxed_amount_invoiced, + count(*) as nbr, + s.name as name, + s.date_order as date, + s.state as state, + s.partner_id as partner_id, + s.user_id as user_id, + s.company_id as company_id, + s.campaign_id as campaign_id, + s.medium_id as medium_id, + s.source_id as source_id, + extract(epoch from avg(date_trunc('day',s.date_order)-date_trunc('day',s.create_date)))/(24*60*60)::decimal(16,2) as delay, + t.categ_id as categ_id, + s.pricelist_id as pricelist_id, + s.analytic_account_id as analytic_account_id, + s.team_id as team_id, + p.product_tmpl_id, + partner.country_id as country_id, + partner.industry_id as industry_id, + partner.commercial_partner_id as commercial_partner_id, + CASE WHEN l.product_id IS NOT NULL THEN sum(p.weight * l.product_uom_qty / u.factor * u2.factor) ELSE 0 END as weight, + CASE WHEN l.product_id IS NOT NULL THEN sum(p.volume * l.product_uom_qty / u.factor * u2.factor) ELSE 0 END as volume, + l.discount as discount, + CASE WHEN l.product_id IS NOT NULL THEN sum((l.price_unit * l.product_uom_qty * l.discount / 100.0 / CASE COALESCE(s.currency_rate, 0) WHEN 0 THEN 1.0 ELSE s.currency_rate END))ELSE 0 END as discount_amount, + s.id as order_id + """ + + for field in fields.values(): + select_ += field + + from_ = """ + sale_order_line l + right outer join sale_order s on (s.id=l.order_id) + join res_partner partner on s.partner_id = partner.id + left join product_product p on (l.product_id=p.id) + left join product_template t on (p.product_tmpl_id=t.id) + left join uom_uom u on (u.id=l.product_uom) + left join uom_uom u2 on (u2.id=t.uom_id) + left join product_pricelist pp on (s.pricelist_id = pp.id) + %s + """ % from_clause + + groupby_ = """ + l.product_id, + l.order_id, + t.uom_id, + t.categ_id, + s.name, + s.date_order, + s.partner_id, + s.user_id, + s.state, + s.company_id, + s.campaign_id, + s.medium_id, + s.source_id, + s.pricelist_id, + s.analytic_account_id, + s.team_id, + p.product_tmpl_id, + partner.country_id, + partner.industry_id, + partner.commercial_partner_id, + l.discount, + s.id %s + """ % (groupby) + + return '%s (SELECT %s FROM %s GROUP BY %s)' % (with_, select_, from_, groupby_) + + def init(self): + # self._table = sale_report + tools.drop_view_if_exists(self.env.cr, self._table) + self.env.cr.execute("""CREATE or REPLACE VIEW %s as (%s)""" % (self._table, self._query())) + +class SaleOrderReportProforma(models.AbstractModel): + _name = 'report.sale.report_saleproforma' + _description = 'Proforma Report' + + @api.model + def _get_report_values(self, docids, data=None): + docs = self.env['sale.order'].browse(docids) + return { + 'doc_ids': docs.ids, + 'doc_model': 'sale.order', + 'docs': docs, + 'proforma': True + } |
