Problem in complex consultation Postgresql (Odoo)

0

I have a problem with a complex query. It's about seeing all sales orders. The query is for an ERP called Odoo:

    CREATE OR REPLACE VIEW public.ordenes_de_venta AS
    WITH tabla as (
    SELECT
       po.id pos_id,
       sp_fecha(to_char(po.create_date, 'D')) AS "día de la semana",
       to_char(po.create_date, 'FMDD')::integer AS día,
       to_char(po.create_date, 'FMMM')::integer AS mes,
       to_char(po.create_date, 'YYYY')::integer AS año,
       to_char(po.create_date, 'HH24:MI:SS')::time AS hora,
       po.create_date fechor,
       po.pos_reference pedido,
       pol.product_id AS "id producto",
       pt.name AS "nombre producto",
       pol.price_unit::numeric(10,2) AS "precio unidad",
       pol.qty AS cantidad,
       pol.discount AS descuento,
       (pol.qty::NUMERIC(10,2) * (pol.price_unit::NUMERIC(10,2) -(pol.discount::NUMERIC(10,2)*
       pol.price_unit::NUMERIC(10,2)/100::NUMERIC(10,2))))::NUMERIC(10,2) AS subtotal,
       pol.purchase_price::numeric(10,2) AS coste,
       pol.margin::numeric(10,2) AS margen,
       substring(pol.name, 1, strpos((pol.name)::text, '/')-1) AS "localización",
       bn.name AS marca,
       sbn.name AS submarca,
       pol.product_description AS "descripción producto",
       pc.name AS "categoría",
       pse.name temporada,
       pa.name ||': '|| pav.name atributo,
       pp.default_code AS "referencia interna",
       rp.name AS proveedor,
       round((pol.margin/NULLIF((pol.qty * pol.price_unit * (100::numeric(10,4) - pol.discount) / 100::numeric(10,4))::numeric(10,2),0))::numeric,2) "margen%"
   FROM pos_order po
       LEFT JOIN pos_order_line pol ON pol.order_id = po.id
       LEFT JOIN product_product pp ON pp.id = pol.product_id
       LEFT JOIN product_template pt ON pt.id = pp.product_tmpl_id
       LEFT JOIN brand_name bn ON bn.id = pol.brand_id
       LEFT JOIN subbrand_name sbn ON sbn.id = pol.subbrand_id
       LEFT JOIN product_category pc ON pc.id = pt.categ_id
       LEFT JOIN product_supplierinfo ps ON ps.product_tmpl_id = pp.product_tmpl_id
       LEFT JOIN res_partner rp ON rp.id = ps.name
       LEFT JOIN product_season pse ON pse.id = pt.season
       LEFT JOIN product_attribute_value_product_product_rel pavppr ON pavppr.product_product_id = pol.product_id
       LEFT JOIN product_attribute_value pav ON pav.id = pavppr.product_attribute_value_id
       LEFT JOIN product_attribute pa ON pa.id = pav.attribute_id
   ORDER BY atributo)

   SELECT  "día de la semana", "día", mes, año, hora, fechor, pedido, "id producto", "nombre producto", "precio unidad", pos_id
cantidad, descuento, subtotal, margen, coste, localización, marca, submarca, "descripción producto", categoría, temporada, string_agg(atributo,',') atributos, 
"referencia interna", string_agg(proveedor,','), "margen%"

   FROM tabla
   GROUP BY "día de la semana", "día", mes, año, hora, fechor, "id producto", "nombre producto", "precio unidad", pos_id,
cantidad, descuento, subtotal, coste, localización, marca, submarca, "descripción producto", categoría, temporada,
"referencia interna", margen, "margen%", pedido
   ORDER BY fechor DESC;

The table po (pos_order) saves the purchase orders, but does not show all the data that is necessary, that's why I created this view. I can not put the data I'm analyzing because they are from a company.

The problem with this query is that when a cashier picks up a product and passes it through the barcode reader, then another passes and passes the first if I do select * from ordenes_de_venta where pedido = 'Pedido 12323' will not tell me (among many other fields ):

    pos_id    pedido producto cantidad precio descuento subtotal
    1         12323  Gafas    1        15,90  0         15,90
    1         12323  Collar   2        4,95   0         9,90
    1         12323  Gafas    1        15.90  0         15.90

But:

    pos_id pedido producto cantidad precio descuento subtotal
    1      12323  Gafas    1        15,90  0         15,90
    1      12323  Collar   2        4,95   0         9,90

If I look in the table po (pos_order) I will find that the 3 lines are there, but when joins are done, one of them is deleted, as if doing distinct .

With the query select * from pos_order_line pol join pos_order po on po.id = pol.order_id where po.pos_reference= 'Pedido 12323'; it shows everything I'm looking for.

Thank you.

    
asked by Joshua 16.11.2017 в 00:31
source

1 answer

0

Well, I've managed to make it work. Unbalance a couple of cents, but nothing of importance. I'll see soon in what orders it happens.

CREATE OR REPLACE FUNCTION sp_fecha(n_dia char)
RETURNS varchar
AS $$
DECLARE
    dia_semana varchar;   
BEGIN
    dia_semana = 
        (SELECT
            CASE n_dia
                WHEN '2' THEN 'Lunes'
                WHEN '3' THEN 'Martes'
                WHEN '4' THEN 'Miércoles'
                WHEN '5' THEN 'Jueves'
                WHEN '6' THEN 'Viernes'
                WHEN '7' THEN 'Sábado'
                WHEN '1' THEN 'Domingo'
            END);

    RETURN dia_semana;
END;
$$ LANGUAGE plpgsql;

DROP VIEW public.ordenes_de_venta;
DROP SEQUENCE proxima_fila_id;
CREATE SEQUENCE proxima_fila_id;
CREATE OR REPLACE VIEW public.ordenes_de_venta AS
WITH lineas_de_ventas as (
SELECT
    sp_fecha(to_char(po.create_date, 'D')) AS "día de la semana",
    to_char(po.create_date, 'FMDD')::integer AS día,
    to_char(po.create_date, 'FMMM')::integer AS mes,
    to_char(po.create_date, 'YYYY')::integer AS año,
    to_char(po.create_date, 'HH24:MI:SS')::time AS hora,
    po.create_date fechor,
    po.pos_reference pedido,
    pol.product_id AS "id producto",
    pol.price_unit::numeric(10,2) AS "precio unidad",
    pol.qty AS cantidad,
    pol.discount AS descuento,
    pol.brand_id,
    pol.subbrand_id,
    (pol.qty::NUMERIC(10,2) * (pol.price_unit::NUMERIC(10,2) - (pol.discount::NUMERIC(10,2)*pol.price_unit::NUMERIC(10,2)/100::NUMERIC(10,2))))::NUMERIC(10,2) AS subtotal,
    pol.purchase_price::numeric(10,2) AS coste,
    pol.margin::numeric(10,2) AS margen,
    substring(pol.name, 1, strpos((pol.name)::text, '/')-1) AS "localización",
    pol.product_description AS "descripción producto",
    round((pol.margin/NULLIF((pol.qty * pol.price_unit * (100::numeric(10,4) - pol.discount) / 100::numeric(10,4))::numeric(10,2),0))::numeric,2) "margen%"
FROM pos_order po
     LEFT JOIN pos_order_line pol ON pol.order_id = po.id

ORDER BY po.id),

nombres as (
SELECT "día de la semana", "día", mes, año, hora, fechor, pedido, "precio unidad", descuento, subtotal, coste, margen, localización, "descripción producto", "margen%", "id producto", brand_id, subbrand_id,
    pp.product_tmpl_id ptemplate, cantidad,
    pt.name AS "nombre producto",
    pt.season,
    pt.default_code as "referencia interna",
    nextval('proxima_fila_id') as fila,
    pc.name AS "categoría"

FROM lineas_de_ventas
    LEFT JOIN product_product pp ON pp.id = "id producto"
    LEFT JOIN product_template pt ON pt.id = pp.product_tmpl_id
    LEFT JOIN product_category pc ON pc.id = pt.categ_id
    ),

marcas as(
SELECT distinct "día de la semana", "día", mes, año, hora, fechor, pedido, "precio unidad", descuento, subtotal, coste, margen, localización, "descripción producto", "margen%", "id producto",
    "nombre producto", categoría, fila, ptemplate, season, cantidad, "referencia interna",
    bn.name AS marca,
    sbn.name AS submarca
FROM nombres
    LEFT JOIN brand_name bn ON bn.id = brand_id
    LEFT JOIN subbrand_name sbn ON sbn.id = subbrand_id
    LEFT JOIN product_supplierinfo ps ON ps.product_tmpl_id = ptemplate),

proveedores as(
SELECT distinct pp.id,
    pp.product_tmpl_id,
    rp.name prv
FROM product_product AS pp
    LEFT JOIN product_supplierinfo ps ON ps.product_tmpl_id = pp.product_tmpl_id
    LEFT JOIN res_partner rp ON rp.id = ps.name
),

proveedor_linea_de_ventas as(
    SELECT "día de la semana", "día", mes, año, hora, fechor, pedido, "precio unidad", descuento, subtotal, coste, margen, localización, "descripción producto", "margen%", "id producto", 
    "nombre producto", categoría, fila, marca, submarca, product_tmpl_id, season, cantidad, "referencia interna",
    string_agg(prv,',') AS "proveedor/es"
    FROM marcas
    LEFT JOIN proveedores p ON p.id = "id producto"

    GROUP BY "día de la semana", "día", mes, año, hora, fechor, pedido,"precio unidad", descuento, subtotal, coste, margen, localización, "descripción producto", "margen%", "id producto", 
    "nombre producto", categoría, fila, marca, submarca, product_tmpl_id,season, cantidad, "referencia interna"
),

atributos_y_temporada as (
SELECT "día de la semana", "día", mes, año, hora, fechor, pedido, "precio unidad", descuento, subtotal, coste, margen, localización, "descripción producto", "margen%", "id producto", 
    "nombre producto", categoría, fila, marca, submarca, product_tmpl_id, "proveedor/es",cantidad, "referencia interna",
    pse.name temporada,
    pa.name ||': '|| pav.name atributo
    FROM proveedor_linea_de_ventas
    LEFT JOIN product_season pse ON pse.id = season
    LEFT JOIN product_attribute_value_product_product_rel pavppr ON pavppr.product_product_id = "id producto"
    LEFT JOIN product_attribute_value pav ON pav.id = pavppr.product_attribute_value_id
    LEFT JOIN product_attribute pa ON pa.id = pav.attribute_id
    order by pa.name, pav.name
)

SELECT 
    "día de la semana", "día", mes, año, hora, fechor, pedido, "id producto", "nombre producto", "referencia interna", "precio unidad", 
    cantidad, descuento, subtotal, margen, coste, localización, marca, submarca, "descripción producto", categoría, temporada, string_agg(atributo,',') atributos, 
    "proveedor/es", "margen%"
    FROM atributos_y_temporada

    GROUP BY 
    "día de la semana", "día", mes, año, hora, fechor, "id producto", pedido, "id producto", "nombre producto", "precio unidad", 
    cantidad, descuento, subtotal, margen, coste, localización, marca, submarca, "descripción producto", categoría, temporada,
    "margen%", fila, "proveedor/es", cantidad, "referencia interna"
    ORDER BY fechor DESC;
    
answered by 16.11.2017 в 23:16