src-db/database/model/triggers/C_INVOICELINE_BEFORE_TRG.xml
author Alvaro Ferraz <alvaro.ferraz@openbravo.com>
Tue, 01 Dec 2015 19:06:20 +0100
changeset 28093 e867bcaa1cc6
parent 27202 dd85e72e7847
child 29762 9b517e1b61bc
permissions -rw-r--r--
Fixes issue 31550: Net Unit Price is changed after saving the invoice line

Update call to C_GET_NET_PRICE_FROM_GROSS from C_ORDERLINE_TRG and C_INVOICELINE_BEFORE_TRG to do it with gross_unit_price * qtyinvoiced and taxbaseamt.
adrianromero@27178
     1
<?xml version="1.0"?>
adrianromero@27178
     2
  <database name="TRIGGER C_INVOICELINE_BEFORE_TRG">
adrianromero@27178
     3
    <trigger name="C_INVOICELINE_BEFORE_TRG" table="C_INVOICELINE" fires="before" insert="true" update="true" delete="false" foreach="row">
adrianromero@27178
     4
      <body><![CDATA[
adrianromero@27178
     5
/*************************************************************************
adrianromero@27178
     6
* The contents of this file are subject to the Openbravo  Public  License
adrianromero@27178
     7
* Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
adrianromero@27178
     8
* Version 1.1  with a permitted attribution clause; you may not  use this
adrianromero@27178
     9
* file except in compliance with the License. You  may  obtain  a copy of
adrianromero@27178
    10
* the License at http://www.openbravo.com/legal/license.html
adrianromero@27178
    11
* Software distributed under the License  is  distributed  on  an "AS IS"
adrianromero@27178
    12
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
adrianromero@27178
    13
* License for the specific  language  governing  rights  and  limitations
adrianromero@27178
    14
* under the License.
adrianromero@27178
    15
* The Original Code is Openbravo ERP.
adrianromero@27178
    16
* The Initial Developer of the Original Code is Openbravo SLU
adrianromero@27202
    17
* All portions are Copyright (C) 2015 Openbravo SLU
adrianromero@27178
    18
* All Rights Reserved.
adrianromero@27178
    19
* Contributor(s):  ______________________________________.
adrianromero@27178
    20
************************************************************************/
adrianromero@27178
    21
adrianromero@27178
    22
  v_std_prec NUMBER:=2;
adrianromero@27178
    23
  v_price_prec NUMBER:=2;
adrianromero@27178
    24
  v_invoiceline_id VARCHAR2(32);
adrianromero@27178
    25
  v_invoice_id VARCHAR2(32);
adrianromero@27178
    26
  v_istaxincluded CHAR(1);
adrianromero@27178
    27
  v_PriceActual NUMBER;
adrianromero@27178
    28
  
adrianromero@27178
    29
  v_IsSOTrx CHAR(1);
adrianromero@27178
    30
  v_Warehouse_ID VARCHAR2(32);
adrianromero@27178
    31
  v_BPartner_Location_ID VARCHAR2(32);
adrianromero@27178
    32
  v_Project_ID VARCHAR2(32);  
adrianromero@27178
    33
  v_AsBOM CHAR(1);  
adrianromero@27178
    34
  v_TotalRatio NUMBER;
adrianromero@27178
    35
  v_TotalProducts NUMBER;
adrianromero@27178
    36
  
adrianromero@27178
    37
  v_BaseLine NUMBER;
adrianromero@27178
    38
  v_Line NUMBER;
adrianromero@27178
    39
  v_LineAcum NUMBER;   
adrianromero@27178
    40
  v_NetActual NUMBER;
adrianromero@27178
    41
  v_PriceLine NUMBER;
adrianromero@27178
    42
  v_CalcLine NUMBER;
adrianromero@27178
    43
  v_execute CHAR(1):='N';
adrianromero@27178
    44
          
adrianromero@27178
    45
  TYPE RECORD IS REF CURSOR;
adrianromero@27178
    46
  Cur_BOM RECORD;  
adrianromero@27178
    47
BEGIN
adrianromero@27178
    48
  IF AD_isTriggerEnabled()='N' THEN RETURN;
adrianromero@27178
    49
  END IF;
adrianromero@27178
    50
adrianromero@27178
    51
  IF (:new.c_orderline_id IS NULL) THEN
adrianromero@27178
    52
    v_Warehouse_ID := NULL;
adrianromero@27178
    53
  ELSE
adrianromero@27178
    54
    SELECT o.m_warehouse_id into v_Warehouse_ID 
adrianromero@27178
    55
    FROM c_orderline ol, c_order o 
adrianromero@27178
    56
    WHERE o.c_order_id = ol.c_order_id and ol.c_orderline_id = :new.c_orderline_id;
adrianromero@27178
    57
  END IF;
adrianromero@27178
    58
  
adrianromero@27178
    59
  v_invoice_id := :new.c_invoice_id;
adrianromero@27178
    60
  SELECT stdPrecision, m_pricelist.istaxincluded, priceprecision, i.C_BPARTNER_LOCATION_ID, i.C_PROJECT_ID, i.ISSOTRX
adrianromero@27178
    61
    INTO v_std_prec, v_istaxincluded, v_price_prec, v_Bpartner_Location_ID, v_Project_ID, v_IsSOTRX
adrianromero@27178
    62
  FROM c_invoice i
adrianromero@27178
    63
    JOIN c_currency ON i.c_currency_id = c_currency.c_currency_id
adrianromero@27178
    64
    JOIN m_pricelist ON i.m_pricelist_id = m_pricelist.m_pricelist_id
adrianromero@27178
    65
  WHERE i.c_invoice_id = v_invoice_id;
adrianromero@27178
    66
adrianromero@27178
    67
  IF (v_istaxincluded = 'Y') THEN
adrianromero@27178
    68
    IF (INSERTING) THEN
adrianromero@27178
    69
          v_execute:='Y';
adrianromero@27178
    70
    ELSIF(UPDATING) THEN
adrianromero@27178
    71
        IF(:old.LineNetAmt <> :new.LineNetAmt
adrianromero@27178
    72
          OR :old.gross_unit_price <> :new.gross_unit_price
adrianromero@27178
    73
          OR :old.c_tax_id <> :new.c_tax_id
adrianromero@27178
    74
          OR :old.qtyinvoiced <> :new.qtyinvoiced) THEN
adrianromero@27178
    75
          v_execute:='Y';
adrianromero@27178
    76
        END IF;
adrianromero@27178
    77
    END IF;
adrianromero@27178
    78
    IF (v_execute='Y') THEN
adrianromero@27178
    79
  
adrianromero@27178
    80
      -- If tax included taxes recalculate net price / amounts
adrianromero@27178
    81
      :new.line_gross_amount := ROUND(:new.gross_unit_price * :new.Qtyinvoiced, v_std_prec);
adrianromero@27178
    82
      
adrianromero@27178
    83
      SELECT tc.ASBOM INTO v_AsBOM FROM C_TAXCATEGORY tc, C_tax t WHERE tc.C_TAXCATEGORY_ID = t.C_TAXCATEGORY_ID AND t.C_TAX_ID = :new.C_Tax_ID;
adrianromero@27178
    84
      IF (v_AsBOM = 'Y') THEN
adrianromero@27178
    85
        -- BOM taxes
adrianromero@27178
    86
        -- Calculate the base for ratios.
adrianromero@27178
    87
        v_BaseLine := :new.line_gross_amount;
adrianromero@27178
    88
        -- Calculate total ratio and number of products
adrianromero@27178
    89
        v_TotalRatio := 0;
adrianromero@27178
    90
        v_TotalProducts := 0;      
adrianromero@27178
    91
        FOR Cur_BOM IN (
adrianromero@27178
    92
          SELECT C_GETTAX(m_productbom_id, :new.UPDATED, :new.AD_Org_ID, v_Warehouse_ID, v_Bpartner_Location_ID, v_Bpartner_Location_ID, v_Project_ID, v_IsSOTRX) AS TAX,
adrianromero@27178
    93
          SUM(ROUND(BOMQTY * BOMPRICE, v_std_Prec)) AS RATIO FROM m_product_bom WHERE m_product_id = :NEW.M_PRODUCT_ID
adrianromero@27178
    94
          GROUP BY C_GETTAX(m_productbom_id, :new.UPDATED, :new.AD_Org_ID, v_Warehouse_ID, v_Bpartner_Location_ID, v_Bpartner_Location_ID, v_Project_ID, v_IsSOTRX)
adrianromero@27178
    95
          ORDER BY RATIO ASC )
adrianromero@27178
    96
        LOOP
adrianromero@27178
    97
          v_TotalRatio := v_TotalRatio + Cur_BOM.RATIO;
adrianromero@27178
    98
          v_TotalProducts := v_TotalProducts + 1;
adrianromero@27178
    99
        END LOOP;
adrianromero@27178
   100
        
adrianromero@27178
   101
        -- Calculate taxes based on BOM of products  
adrianromero@27178
   102
        v_LineAcum := 0;
adrianromero@27178
   103
        v_NetActual := 0;
adrianromero@27178
   104
        FOR Cur_BOM IN (
adrianromero@27178
   105
          SELECT C_GETTAX(m_productbom_id, :new.UPDATED, :new.AD_Org_ID, v_Warehouse_ID, v_Bpartner_Location_ID, v_Bpartner_Location_ID, v_Project_ID, v_IsSOTRX) AS TAX,
adrianromero@27178
   106
          SUM(ROUND(BOMQTY * BOMPRICE, v_std_Prec)) AS RATIO FROM m_product_bom WHERE m_product_id = :NEW.M_PRODUCT_ID
adrianromero@27178
   107
          GROUP BY C_GETTAX(m_productbom_id, :new.UPDATED, :new.AD_Org_ID, v_Warehouse_ID, v_Bpartner_Location_ID, v_Bpartner_Location_ID, v_Project_ID, v_IsSOTRX)
adrianromero@27178
   108
          ORDER BY RATIO ASC )
adrianromero@27178
   109
        LOOP
adrianromero@27178
   110
          v_TotalProducts := v_TotalProducts - 1;
adrianromero@27178
   111
          IF (v_TotalProducts > 0) THEN
adrianromero@27178
   112
            v_Line := ROUND(v_BaseLine * Cur_BOM.RATIO / v_TotalRatio , v_std_Prec);
adrianromero@27178
   113
            v_LineAcum := v_LineAcum + v_Line;
adrianromero@27178
   114
          ELSE -- The last willaccummulate rounding
adrianromero@27178
   115
            v_Line := v_BaseLine - v_LineAcum;
adrianromero@27178
   116
          END IF;
adrianromero@27178
   117
adrianromero@27178
   118
          v_PriceLine := C_GET_NET_PRICE_FROM_GROSS(Cur_BOM.TAX, v_Line, v_Line, v_price_prec, :new.qtyinvoiced);
adrianromero@27178
   119
          v_CalcLine := ROUND(:new.qtyinvoiced * v_PriceLine, v_std_Prec); -- In price including taxes the net and net alternate are equals.
adrianromero@27178
   120
adrianromero@27178
   121
          v_NetActual := v_NetActual + v_CalcLine; -- Acum the net
adrianromero@27178
   122
        END LOOP;    
adrianromero@27178
   123
        v_PriceActual := v_NetActual / :new.qtyinvoiced;     
adrianromero@27178
   124
      ELSE
adrianromero@27178
   125
        -- Regular taxes
alvaro@28093
   126
        v_PriceActual := C_GET_NET_PRICE_FROM_GROSS(:new.c_tax_id, :new.gross_unit_price * :new.qtyinvoiced, :new.taxbaseamt, v_price_prec, :new.qtyinvoiced);
adrianromero@27178
   127
        v_NetActual := ROUND(:new.Qtyinvoiced * v_PriceActual, v_std_Prec);
adrianromero@27178
   128
      END IF;      
adrianromero@27178
   129
      
adrianromero@27178
   130
      :NEW.pricestd := v_priceactual;
adrianromero@27178
   131
      :NEW.pricelist := v_priceactual;
adrianromero@27178
   132
      :NEW.pricelimit := v_priceactual;
adrianromero@27178
   133
      :NEW.priceactual := v_priceactual;
adrianromero@27178
   134
      :new.taxbaseamt := v_NetActual;
adrianromero@27178
   135
      :new.LineNetAmt := v_NetActual;
adrianromero@27178
   136
    END IF;
adrianromero@27178
   137
  END IF;
adrianromero@27178
   138
adrianromero@27178
   139
END C_INVOICELINE_BEFORE_TRG
adrianromero@27178
   140
]]></body>
adrianromero@27178
   141
    </trigger>
adrianromero@27178
   142
  </database>