jueves, 14 de noviembre de 2013

Minimum Level in Sales Order

1) Add new column in the table AD_Role

alter table ad_role add aplica_minimo_almacenado char default 'N';

2) In iDempiere, add column for AD_Role in the screen "Table and Columns", then add field in the screen "Windows, Tabs and Fields".

3) Add code in the following classes and apply customization:

package org.compiere.model;
...
public class CalloutOrder extends CalloutEngine
{
...
public String product (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value)
{
...
if (Env.isSOTrx(ctx, WindowNo))
        {
            MProduct product = MProduct.get (ctx, M_Product_ID.intValue());
            if (product.isStocked())
            {
                BigDecimal QtyOrdered = (BigDecimal)mTab.getValue("QtyOrdered");
                int M_Warehouse_ID = Env.getContextAsInt(ctx, WindowNo, "M_Warehouse_ID");
                int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID");
               
                BigDecimal nivel_minimo = DB.getSQLValueBD(null, "select coalesce(r.level_min, 0) from m_replenish r" +
                    " where r.m_product_id = " + M_Product_ID + ";");
                   
                if(nivel_minimo == null)
                    nivel_minimo = BigDecimal.ZERO;
                   
                BigDecimal available = MStorage.getQtyAvailable
                    (M_Warehouse_ID, M_Product_ID.intValue(), M_AttributeSetInstance_ID, null);
                       
                BigDecimal reservado = new BigDecimal(0.00);
                   
                if(available.doubleValue() >= nivel_minimo.doubleValue())
                    reservado = available.subtract(nivel_minimo);
               
                if(Aplica_Minimo_Almacenado() == 1)
                    reservado = available;

               
                if (available == null)
                    available = Env.ZERO;
                if (available.signum() == 0)
                    mTab.fireDataStatusEEvent ("NoQtyAvailable", "0", false);
                // else if (available.compareTo(QtyOrdered) < 0)
                else if (reservado.compareTo(QtyOrdered) < 0)
                    if(Aplica_Minimo_Almacenado() == 1)
                        mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", available.toString(), false);
                    else
                        mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", "Total=" + available.setScale(2).toString() + ", Nivel Minimo=" + nivel_minimo.setScale(2).toString() + ", Disponible=" + reservado.setScale(2).toString(), false);

                    //mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", available.toString(), false);
                else
                {
                    Integer C_OrderLine_ID = (Integer)mTab.getValue("C_OrderLine_ID");
                    if (C_OrderLine_ID == null)
                        C_OrderLine_ID = new Integer(0);
                    BigDecimal notReserved = MOrderLine.getNotReserved(ctx,
                        M_Warehouse_ID, M_Product_ID, M_AttributeSetInstance_ID,
                        C_OrderLine_ID.intValue());
                    if (notReserved == null)
                        notReserved = Env.ZERO;
...
}

}
public String qty (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value)
{
...
//    Storage
        if (M_Product_ID != 0
            && Env.isSOTrx(ctx, WindowNo)
            && QtyOrdered.signum() > 0)        //    no negative (returns)
        {
            MProduct product = MProduct.get (ctx, M_Product_ID);
            if (product.isStocked())
            {
                int M_Warehouse_ID = Env.getContextAsInt(ctx, WindowNo, "M_Warehouse_ID");
                int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID");
               
                BigDecimal nivel_minimo = DB.getSQLValueBD(null, "select coalesce(r.level_min, 0) from m_replenish r" +
                        " where r.m_product_id = " + M_Product_ID + ";");
                   
                if(nivel_minimo == null)
                    nivel_minimo = BigDecimal.ZERO;
                   
                BigDecimal available = MStorage.getQtyAvailable
                    (M_Warehouse_ID, M_Product_ID, M_AttributeSetInstance_ID, null);
                   
                BigDecimal reservado = new BigDecimal(0.00);
                   
                if(available.doubleValue() >= nivel_minimo.doubleValue())
                    reservado = available.subtract(nivel_minimo);
               
                if(Aplica_Minimo_Almacenado() == 1)
                    reservado = available;

               
                if (available == null)
                    available = Env.ZERO;
                if (available.signum() == 0)
                    mTab.fireDataStatusEEvent ("NoQtyAvailable", "0", false);
               
                // else if (available.compareTo(QtyOrdered) < 0)
                else if (reservado.compareTo(QtyOrdered) < 0)
                    if(Aplica_Minimo_Almacenado() == 1)
                        mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", available.toString(), false);
                    else
                        mTab.fireDataStatusEEvent ("InsufficientQtyAvailable", "Total=" + available.setScale(2).toString() + ", Nivel Minimo=" + nivel_minimo.setScale(2).toString() + ", Disponible=" + reservado.setScale(2).toString(), false);

                else
                {
                    Integer C_OrderLine_ID = (Integer)mTab.getValue("C_OrderLine_ID");
                    if (C_OrderLine_ID == null)
                        C_OrderLine_ID = new Integer(0);
...
}
...
public int Aplica_Minimo_Almacenado()
    {
        int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx());
        int AD_Role_ID = Env.getAD_Role_ID(Env.getCtx());
        int b = 0;
       
        b = DB.getSQLValue(null, "select coalesce((select 1 from ad_role r " +
                " where r.ad_client_id = " + AD_Client_ID +
                " and r.aplica_minimo_almacenado = 'Y'" +
                " and r.ad_role_id = " + AD_Role_ID + "), 0);");
       
        return b;
    }

}

package org.compiere.model;
...
public class MOrderLine extends X_C_OrderLine
{

protected boolean beforeSave (boolean newRecord)
{
...
MProduct product = getProduct();
            if (product.isStocked())
            {
                int M_AttributeSet_ID = product.getM_AttributeSet_ID();
                boolean isInstance = M_AttributeSet_ID != 0;
                if (isInstance)
                {
                    MAttributeSet mas = MAttributeSet.get(getCtx(), M_AttributeSet_ID);
                    isInstance = mas.isInstanceAttribute();
                }
                //    Max
                if (isInstance)
                {
                    MStorage[] storages = MStorage.getWarehouse(getCtx(),
                        getM_Warehouse_ID(), getM_Product_ID(), getM_AttributeSetInstance_ID(),
                        M_AttributeSet_ID, false, null, true, get_TrxName());
                   
                    BigDecimal qty = Env.ZERO;
                   
                    for (int i = 0; i < storages.length; i++)
                    {
                        if (storages[i].getM_AttributeSetInstance_ID() == getM_AttributeSetInstance_ID())
                            qty = qty.add(storages[i].getQtyOnHand());
                    }
                   
                    BigDecimal nivel_minimo = DB.getSQLValueBD(null, "select coalesce(r.level_min, 0) from m_replenish r" +
                            " where r.m_product_id = " + getM_Product_ID() + ";");
                   
                    if(nivel_minimo == null)
                        nivel_minimo = BigDecimal.ZERO;
                       
                    BigDecimal reservado = new BigDecimal(0.00);
                   
                    if(qty.doubleValue() >= nivel_minimo.doubleValue())
                        reservado = qty.subtract(nivel_minimo);
                   
                    if(Aplica_Minimo_Almacenado() == 1)
                        reservado = qty;

                   
                    if (getQtyOrdered().compareTo(reservado) > 0)
                    {
                        //log.warning("Qty - Stock=" + qty + ", Ordered=" + getQtyOrdered());
                        //log.saveError("QtyInsufficient", "=" + qty);
                       
                        if(Aplica_Minimo_Almacenado() == 1)
                        {
                            //log.warning("Qty - Stock=" + qty + ", Ordered=" + getQtyOrdered());
                            log.saveError("QtyInsufficient", "=" + qty);
                        }
                        else
                        {
                            //log.warning("Total=" + qty.setScale(2).toString() + ", Nivel Minimo=" + nivel_minimo.setScale(2).toString() + ", Disponible=" + reservado.setScale(2).toString());
                            log.saveError("QtyInsufficient", "Total=" + qty.setScale(2).toString() + ", Nivel Minimo=" + nivel_minimo.setScale(2).toString() + ", Disponible=" + reservado.setScale(2).toString());
                        }
...
}
...
public int Aplica_Minimo_Almacenado()
    {
        int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx());
        int AD_Role_ID = Env.getAD_Role_ID(Env.getCtx());
        int b = 0;
       
        b = DB.getSQLValue(null, "select coalesce((select 1 from ad_role r " +
                " where r.ad_client_id = " + AD_Client_ID +
                " and r.aplica_minimo_almacenado = 'Y'" +
                " and r.ad_role_id = " + AD_Role_ID + "), 0);");
       
        return b;
    }

}

1 comentario:

  1. Que codigo tan util, lo estamos utilizando en nuestra empresa, nos ha resuelto la vida!!!! Gracias!!!

    ResponderEliminar