src-db/database/model/triggers/C_ORDERLINE_TRG.xml
author Juan Pablo Aroztegi <juanpablo.aroztegi@openbravo.com>
Wed, 03 Sep 2008 17:55:37 +0000
changeset 1605 8a0fe0193bef
parent 1240 d7790e722976
child 2078 cf88ca44cdd2
permissions -rw-r--r--
Merge r2.5x intro trunk
<?xml version="1.0"?>
  <database name="TRIGGER C_ORDERLINE_TRG">
    <trigger name="C_ORDERLINE_TRG" table="C_ORDERLINE" fires="before" insert="true" update="true" delete="true" foreach="row">
      <body><![CDATA[
/*************************************************************************
  * The contents of this file are subject to the Compiere Public
  * License 1.1 ("License"); You may not use this file except in
  * compliance with the License. You may obtain a copy of the License in
  * the legal folder of your Openbravo installation.
  * Software distributed under the License is distributed on an
  * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  * implied. See the License for the specific language governing rights
  * and limitations under the License.
  * The Original Code is  Compiere  ERP &  Business Solution
  * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
  * Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke,
  * parts created by ComPiere are Copyright (C) ComPiere, Inc.;
  * All Rights Reserved.
  * Contributor(s): Openbravo SL
  * Contributions are Copyright (C) 2001-2008 Openbravo, S.L.
  *
  * Specifically, this derivative work is based upon the following Compiere
  * file and version.
  *************************************************************************/



  v_newTaxBaseAmt NUMBER;
  v_oldTaxBaseAmt NUMBER;
  v_oldLine NUMBER:= 0;
  v_newLine NUMBER:= 0;
  v_taxAmt NUMBER:= 0;
  v_HasTaxLine  BOOLEAN := FALSE;
  v_Prec   NUMBER;
  v_ID   VARCHAR2(32);
  v_Processed  CHAR(1);
  v_UOM_ID    VARCHAR2(32);
  v_IsSOTrx CHAR(1);
  v_Count NUMBER;
BEGIN
IF (UPDATING) THEN
  IF NOT(COALESCE(:old.M_Product_ID,'0') <> COALESCE(:NEW.M_Product_ID,'0')
  OR COALESCE(:old.LineNetAmt,0) <> COALESCE(:NEW.LineNetAmt,0)
  OR COALESCE(:old.FreightAmt,0) <> COALESCE(:NEW.FreightAmt,0)
  OR COALESCE(:old.ChargeAmt,0) <> COALESCE(:NEW.ChargeAmt,0)
  OR COALESCE(:old.C_Tax_ID,'0') <> COALESCE(:NEW.C_Tax_ID,'0')
  OR COALESCE(:old.C_Uom_ID,'0') <> COALESCE(:NEW.C_Uom_ID,'0'))
 THEN
  RETURN;
  END IF;
 END IF;
 /**
  * Check Product changes = not possible when reservation, invoice or delivery exists
  */
 IF (DELETING) THEN
  IF (:old.QtyReserved <> 0) THEN
   RAISE_APPLICATION_ERROR(-20200, 'Changed Product had Reservation=' || :old.QtyReserved);
  ELSIF (:old.QtyDelivered <> 0) THEN
   RAISE_APPLICATION_ERROR(-20201, 'Changed Product had Delieveries=' || :old.QtyDelivered);
  ELSIF (:old.QtyInvoiced <> 0) THEN
   RAISE_APPLICATION_ERROR(-20202, 'Changed Product was Invoiced=' || :old.QtyInvoiced);
  END IF;
 ELSIF (UPDATING) THEN
   SELECT issotrx INTO v_IsSOTrx
   FROM c_order
   WHERE c_order_id = :old.c_order_id;
   IF (:old.M_Product_ID <> :NEW.M_Product_ID) THEN
     IF (:old.QtyReserved <> 0) THEN
       RAISE_APPLICATION_ERROR(-20203, 'Changed Product had Reservation=' || :old.QtyReserved);
     ELSIF (:old.QtyDelivered <> 0) THEN
       RAISE_APPLICATION_ERROR(-20204, 'Changed Product had Delieveries=' || :old.QtyDelivered);
     ELSIF (:old.QtyInvoiced <> 0) THEN
       RAISE_APPLICATION_ERROR(-20205, 'Changed Product was Invoiced=' || :old.QtyInvoiced);
     ELSIF (v_IsSOTrx = 'N') THEN
       SELECT count(*) INTO v_Count
       FROM m_inoutline
       WHERE c_orderline_id = :old.c_orderline_id;
       IF (v_count > 0) THEN
         RAISE_APPLICATION_ERROR(-20206, 'Changed Product has good receipts');
       END IF;
     END IF;
   END IF;
 END IF;

 -- Get ID
 IF (UPDATING OR INSERTING) THEN
     IF (:NEW.M_PRODUCT_ID IS NOT NULL) THEN
       SELECT C_UOM_ID INTO v_UOM_ID FROM M_PRODUCT WHERE M_PRODUCT_ID=:NEW.M_PRODUCT_ID;
       IF (COALESCE(v_UOM_ID,'0') <> COALESCE(:NEW.C_UOM_ID,'0')) THEN
         RAISE_APPLICATION_ERROR(-20111, 'Unit of Measure mismatch (product/transaction)');
       END IF;
     END IF;
  v_ID := :new.C_Order_ID;
 ELSE
  v_ID := :old.C_Order_ID;
 END IF;

 SELECT processed
   INTO v_Processed
 FROM C_Order
 WHERE C_Order_ID=v_ID;


 /**
  * Round Base
  */
 v_Prec := 2;
 IF (INSERTING OR UPDATING) THEN
     -- Modified by I.Ciordia. Sometimes js fails calculting lineNet
  :new.LineNetAmt := ROUND(:new.QtyOrdered*:new.PriceActual, v_Prec);-- Modified by I.Ciordia
  :new.FreightAmt := ROUND(:new.FreightAmt, v_Prec);
  :new.ChargeAmt := ROUND(:new.ChargeAmt, v_Prec);
 END IF;


  /**************************************************************************
   * Calculate Tax, etc.
   */
 IF(v_Processed='N') THEN
  -- Subtract old Amount
  IF (DELETING OR UPDATING) THEN
   -- Get old Tax Info
   SELECT SUM(TaxBaseAmt)
     INTO v_oldTaxBaseAmt
   FROM C_OrderTax
   WHERE C_Order_ID=:old.C_Order_ID
     AND C_Tax_ID=:old.C_Tax_ID;
  -- DBMS_OUTPUT.PUT_LINE('Old TaxBaseAmt=' || v_oldTaxBaseAmt);
   --
   v_oldLine := COALESCE(:old.LineNetAmt,0) + COALESCE(:old.FreightAmt,0) + COALESCE(:old.ChargeAmt,0);
   IF (v_oldTaxBaseAmt IS NOT NULL) THEN
   -- DBMS_OUTPUT.PUT_LINE('Update NewLineAmt -= ' || v_oldLine);
    UPDATE C_OrderTax
      SET TaxBaseAmt = TaxBaseAmt - v_oldLine
    WHERE C_Order_ID=:old.C_Order_ID
      AND C_Tax_ID=:old.C_Tax_ID;
   END IF;

   -- Calculate old tax with 2 digits precision
   UPDATE C_OrderTax
     SET TaxAmt = (SELECT ROUND(C_OrderTax.TaxBaseAmt * t.Rate / 100, v_Prec)
       FROM C_Tax t WHERE C_OrderTax.C_Tax_ID=t.C_Tax_ID),
     Updated = now(),
     UpdatedBy = '0'
   WHERE C_Order_ID=:old.C_Order_ID
     AND C_Tax_ID=:old.C_Tax_ID;
  END IF;

  -- Add new Amount
  IF (INSERTING OR UPDATING) THEN
   -- Get new Tax Info
   SELECT SUM(TaxBaseAmt)
     INTO v_newTaxBaseAmt
   FROM C_OrderTax
   WHERE C_Order_ID=:new.C_Order_ID
     AND C_Tax_ID=:new.C_Tax_ID;
  -- DBMS_OUTPUT.PUT_LINE('New TaxBaseAmt=' || v_newTaxBaseAmt);
   --
   v_newLine := COALESCE(:new.LineNetAmt,0) + COALESCE(:new.FreightAmt,0) + COALESCE(:new.ChargeAmt,0);
   IF (v_newTaxBaseAmt IS NULL) THEN
   -- DBMS_OUTPUT.PUT_LINE('Insert NewLineAmt = ' || v_newLine);
    INSERT INTO C_OrderTax
     (c_OrderTax_ID, AD_Client_ID, AD_Org_ID, IsActive, Created, CreatedBy, Updated, UpdatedBy,
     C_Order_ID, C_Tax_ID, TaxBaseAmt, taxAmt)
    VALUES
     (get_uuid(), :new.AD_Client_ID, :new.AD_Org_ID, 'Y', now(), :new.UpdatedBy, now(), :new.UpdatedBy,
     :new.C_Order_ID, :new.C_Tax_ID, v_newLine, 0);
   ELSE
   -- DBMS_OUTPUT.PUT_LINE('Update NewLineAmt += ' || v_newLine);
    UPDATE C_OrderTax
      SET TaxBaseAmt = TaxBaseAmt + v_newLine
    WHERE C_Order_ID=:new.C_Order_ID
      AND C_Tax_ID=:new.C_Tax_ID;
   END IF;

   -- Calculate new tax with 2 digits precision
   UPDATE C_OrderTax
     SET TaxAmt = (SELECT ROUND(C_OrderTax.TaxBaseAmt * t.Rate / 100, v_Prec)
       FROM C_Tax t WHERE C_OrderTax.C_Tax_ID=t.C_Tax_ID),
     Updated = now(),
     UpdatedBy = :new.UpdatedBy
   WHERE C_Order_ID=:new.C_Order_ID
     AND C_Tax_ID=:new.C_Tax_ID;
  END IF;



  -- Get Total Tax Amt
  IF (INSERTING OR UPDATING) THEN
   SELECT SUM(TaxAmt)
     INTO v_taxAmt
   FROM C_OrderTax
   WHERE C_Order_ID=:new.C_Order_ID;
  -- DBMS_OUTPUT.PUT_LINE('TaxAmt = ' || v_taxAmt);
   -- Update Header
   UPDATE C_Order
     SET TotalLines = TotalLines - v_oldLine + v_newLine,
     GrandTotal = TotalLines - v_oldLine + v_newLine + COALESCE(v_taxAmt, 0)
   --  Updated = SysDate -- Don't update as otherwise it does not save changes
   WHERE C_Order_ID = :new.C_Order_ID;
  ELSE -- DELETING
   SELECT SUM(TaxAmt)
     INTO v_taxAmt
   FROM C_OrderTax
   WHERE C_Order_ID=:old.C_Order_ID;
  -- DBMS_OUTPUT.PUT_LINE('TaxAmt = ' || v_taxAmt);
   -- Update Header
   UPDATE C_Order
     SET TotalLines = TotalLines - v_oldLine + v_newLine,
     GrandTotal = TotalLines - v_oldLine + v_newLine + COALESCE(v_taxAmt, 0)
   --  Updated = SysDate -- Don't update as otherwise it does not save changes
   WHERE C_Order_ID=:old.C_Order_ID;
  END IF;
 END IF;

END C_ORDERLINE_TRG
]]></body>
    </trigger>
  </database>