Browse Source

In the *Reporting* menu, add a new entry *POS + Sale Orders Analysis* that show sale statistics per products that aggregate sale orders and pos orders. add filtro y campo user_id

SEBAS 1 year ago
commit
cdfe202795
8 changed files with 277 additions and 0 deletions
  1. 2 0
      .gitignore
  2. 3 0
      __init__.py
  3. 23 0
      __openerp__.py
  4. 29 0
      product_view.xml
  5. 23 0
      report/__init__.py
  6. 137 0
      report/pos_sale_report.py
  7. 57 0
      report/pos_sale_report_view.xml
  8. 3 0
      security/ir.model.access.csv

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+*.pyc
+.scannerwork

+ 3 - 0
__init__.py

@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+from . import report

+ 23 - 0
__openerp__.py

@@ -0,0 +1,23 @@
+# -*- encoding: utf-8 -*-
+
+{
+    'name': 'POS Sale Report',
+    'version': '0.1',
+    'category': 'Point Of Sale',
+    'license': 'AGPL-3',
+    'summary': 'Add a graph via on that aggregate sale orders and pos orders',
+    'description': """
+In the *Reporting* menu, add a new entry *POS + Sale Orders Analysis* that show sale statistics per products that aggregate sale orders and pos orders.
+
+Also add direct access to Sales statistics on the Product form view and Product Variants form view (Menu entry *Sales Statistics* in the *More* drop down list).
+    """,
+    'author': 'Akretion - EIRU',
+    'website': 'https://www.eiru.com.py',
+    'depends': ['point_of_sale', 'sale'],
+    'data': [
+        'report/pos_sale_report_view.xml',
+        'product_view.xml',
+        'security/ir.model.access.csv',
+        ],
+    'installable': True,
+}

+ 29 - 0
product_view.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<openerp>
+<data>
+
+<!-- Add entry in the "More" drop down list in form view -->
+<act_window id="product_product_pos_sale_report_action"
+    key2="client_action_multi"
+    name="Sales Statistics"
+    res_model="pos.sale.report"
+    src_model="product.product"
+    view_mode="graph"
+    domain="[('product_id', 'in', active_ids)]"
+    context="{'search_default_product_groupby': 1}"
+    />
+
+<act_window id="product_template_pos_sale_report_action"
+    key2="client_action_multi"
+    name="Sales Statistics"
+    res_model="pos.sale.report"
+    src_model="product.template"
+    view_mode="graph"
+    domain="[('product_tmpl_id', 'in', active_ids)]"
+    context="{'search_default_product_tmpl_groupby': 1}"
+    />
+
+
+</data>
+</openerp>

+ 23 - 0
report/__init__.py

@@ -0,0 +1,23 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    POS Sale Report module for Odoo
+#    Copyright (C) 2015 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@akretion.com>
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from . import pos_sale_report

+ 137 - 0
report/pos_sale_report.py

@@ -0,0 +1,137 @@
+# -*- encoding: utf-8 -*-
+from openerp import models, fields
+from openerp import tools
+
+
+class pos_sale_report(models.Model):
+    _name = 'pos.sale.report'
+    _description = 'POS orders and Sale orders aggregated report'
+    _auto = False
+    _rec_name = 'date'
+    _order = 'date desc'
+
+    date = fields.Date(string='Order Date', readonly=True)
+    product_id = fields.Many2one(
+        'product.product', string='Variantes', readonly=True)
+    product_tmpl_id = fields.Many2one(
+        'product.template', string='Producto', readonly=True)
+    user_id = fields.Many2one(
+        'res.users', string='User', readonly=True)  # Add this line for user_id
+    # company_id = fields.Many2one(
+    #     'res.company', string='Company', readonly=True)
+    origin = fields.Char(string='Origin', readonly=True)
+    qty = fields.Float(string='Cantidad', readonly=True)
+
+    number = fields.Char(string='Venta', readonly=True)
+    store_id = fields.Many2one(
+        'res.store', string='Sucursal', readonly=True)
+    subtotal_taxed = fields.Float(string='total', readonly=True)
+    standard_price = fields.Float(string='Costo', readonly=True)
+    utility = fields.Float(string='Utilidad', readonly=True)
+    categ_id = fields.Many2one(
+        'product.category', string='Categoría', readonly=True)
+
+    # WARNING : this code doesn't handle uom conversion for the moment
+    def _sale_order_select(self):
+        select = """
+            SELECT
+                --min(invoice_line.id)*-1 AS id,
+                invoice_line.id*-1 AS id,
+                invoice.number AS number,
+                invoice.date_invoice AS date,
+                invoice_line.product_id AS product_id,
+                product.product_tmpl_id AS product_tmpl_id,
+                invoice.user_id AS user_id,
+                invoice.company_id AS company_id,
+                'Pedido de Venta' AS origin,
+                --sum(invoice_line.quantity) AS qty,
+                invoice_line.quantity AS qty,
+                journal.store_id AS store_id,
+                invoice_line.price_subtotal AS subtotal_untaxed,
+                --invoice_line.discount,
+                --((invoice_line.quantity * invoice_line.price_unit) * invoice_line.discount) / 100 AS amount_discount,
+                (invoice_line.quantity * invoice_line.price_unit) - (((invoice_line.quantity * invoice_line.price_unit) * invoice_line.discount) / 100) AS subtotal_taxed,
+                (array_agg(history.cost ORDER BY history.id DESC))[1] * invoice_line.quantity AS standard_price,
+                ((invoice_line.quantity * invoice_line.price_unit) - (((invoice_line.quantity * invoice_line.price_unit) * invoice_line.discount) / 100) - ((array_agg(history.cost ORDER BY history.id DESC))[1] * invoice_line.quantity)) AS utility,
+                template.categ_id
+            FROM account_invoice_line AS invoice_line
+            LEFT JOIN account_invoice AS invoice
+            ON invoice.id = invoice_line.invoice_id
+            LEFT JOIN res_users AS users
+            ON users.id = invoice.user_id
+            LEFT JOIN product_product AS product
+            ON product.id = invoice_line.product_id
+            LEFT JOIN product_template AS template
+            ON template.id = product.product_tmpl_id
+            LEFT JOIN res_store_journal_rel as journal
+            ON journal.journal_id = invoice.journal_id
+            LEFT JOIN product_price_history AS history
+            ON history.product_template_id = product.product_tmpl_id
+            WHERE invoice.state IN ('open','paid')
+            AND invoice.type = 'out_invoice'
+            GROUP BY
+                invoice_line.id,
+                invoice.date_invoice,
+                invoice.number,
+                invoice_line.product_id,
+                product.product_tmpl_id,
+                invoice.user_id,
+                invoice.company_id,
+                journal.store_id,
+                invoice_line.price_subtotal,
+                template.categ_id
+        """
+        return select
+
+    def _pos_order_select(self):
+        select = """
+            SELECT
+                --min(pol.id) AS id,
+                pol.id AS id,
+                po.name AS number,
+                po.date_order::date AS date,
+                pol.product_id AS product_id,
+                product.product_tmpl_id AS product_tmpl_id,
+                po.user_id AS user_id,
+                po.company_id AS company_id,
+                'TPV' AS origin,
+                --sum(pol.qty) AS qty,
+                pol.qty AS qty,
+                journal.store_id AS store_id,
+                pol.price_subtotal_incl AS subtotal_untaxed,
+                pol.price_subtotal_incl AS subtotal_taxed,
+                (array_agg(history.cost ORDER BY history.id DESC))[1] * pol.qty AS standard_price,
+                (pol.price_subtotal_incl - ((array_agg(history.cost ORDER BY history.id DESC))[1] * pol.qty)) AS utility,
+                template.categ_id
+            FROM pos_order_line AS pol
+            LEFT JOIN pos_order AS po
+            ON po.id = pol.order_id
+            LEFT JOIN res_users AS users
+            ON users.id = po.user_id
+            LEFT JOIN product_product AS product
+            ON product.id = pol.product_id
+            LEFT JOIN product_template AS template
+            ON template.id = product.product_tmpl_id
+            LEFT JOIN res_store_journal_rel as journal
+            ON journal.journal_id = po.sale_journal
+            LEFT JOIN product_price_history AS history
+            ON history.product_template_id = product.product_tmpl_id
+            WHERE po.state IN ('paid', 'done', 'invoiced')
+            GROUP BY
+                pol.id,
+                po.name,
+                po.date_order,
+                pol.product_id,
+                product.product_tmpl_id,
+                po.user_id,
+                po.company_id,
+                journal.store_id,
+                pol.price_subtotal_incl,
+                template.categ_id
+        """
+        return select
+
+    def init(self, cr):
+        tools.drop_view_if_exists(cr, self._table)
+        cr.execute("CREATE OR REPLACE VIEW %s AS (%s UNION %s)" % (
+            self._table, self._sale_order_select(), self._pos_order_select()))

+ 57 - 0
report/pos_sale_report_view.xml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<openerp>
+<data>
+
+<record id="pos_sale_report_search" model="ir.ui.view">
+    <field name="name">pos.sale.report.search</field>
+    <field name="model">pos.sale.report</field>
+    <field name="arch"  type="xml">
+        <search string="POS orders and Sale orders aggregated report">
+            <field name="product_tmpl_id"/>
+            <field name="product_id"/>
+            <filter name="today" string="Hoy"
+                domain="[('date', '=', context_today().strftime('%Y-%m-%d'))]"/>
+            <filter name="yesterday" string="Ayer"
+                domain="[('date', '=', (context_today() + datetime.timedelta(days=-1)).strftime('%Y-%m-%d'))]"/>
+            <group string="Agrupado por" name="groupby">
+                <filter name="date_groupby" string="Fecha" context="{'group_by': 'date'}"/>
+                <filter name="product_tmpl_groupby" string="Producto" context="{'group_by': 'product_tmpl_id'}"/>
+                <filter name="user_groupby" string="Comercial" context="{'group_by': 'user_id'}"/>
+                <filter name="product_groupby" string="Variantes" context="{'group_by': 'product_id'}"/>
+                <filter name="origin_groupby" string="Origen" context="{'group_by': 'origin'}"/>
+            </group>
+        </search>
+    </field>
+</record>
+
+<record id="pos_sale_report_graph" model="ir.ui.view">
+    <field name="name">pos.sale.report.graph</field>
+    <field name="model">pos.sale.report</field>
+    <field name="arch"  type="xml">
+        <graph string="POS orders and Sale Orders aggregated report" type="pivot">
+            <field name="origin" type="col"/>
+            <field name="store_id" type="row"/>
+            <!-- <field name="date" type="row" interval="month"/> -->
+            <field name="standard_price" type="measure"/>
+            <field name="qty" type="measure"/>
+            <field name="subtotal_taxed" type="measure"/>
+            <!-- <field name="utility" type="measure"/> -->
+        </graph>
+    </field>
+</record>
+
+<record id="pos_sale_report_action" model="ir.actions.act_window">
+    <field name="name">Análisis Detallado de Ventas</field>
+    <field name="res_model">pos.sale.report</field>
+    <field name="view_mode">graph</field>
+</record>
+
+<!-- <menuitem id="pos_sale_report_title_menu" parent="base.menu_reporting"
+    name="POS + Sales" sequence="9"/> -->
+
+<menuitem id="pos_sale_report_menu" action="pos_sale_report_action"
+    parent="eiru_reports.sale_parent_menu" sequence="10"/>
+
+</data>
+</openerp>

+ 3 - 0
security/ir.model.access.csv

@@ -0,0 +1,3 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_pos_sale_report_pos_user,Full access on pos.sale.report to POS User,model_pos_sale_report,point_of_sale.group_pos_user,1,1,1,1
+access_pos_sale_report_sale_user,Full access on pos.sale.report to Sale User,model_pos_sale_report,base.group_sale_salesman,1,1,1,1