Movimentação de Produto


#1

Ola,

Criei um tipo de documento “pos order x” que tem tipo de entrega indireta, por sua ver essa entrega é uma movimentação de material que tem um tipo de documento do mesmo nome “movimentação de material x” e um armazém de destino.

Resumindo a movimentação de material tem um armazém de destino já definido.
Quando faço uma venda com esse tipo de documento “pos order x” ele automaticamente gera uma expedição e essa expedição gera uma movimentação de material que tem como tem um armazém de origem informado na ordem de venda e um armazém de destino informado no tipo de documento “movimentação de material x”.

Perfeito isso, quando o produto não tem atributo, o adempiere faz todo esse processo, gera uma expedição, movimentação de material(sai de um armazém e entra em outro), fatura e uma nota fiscal.

Mas quando o produto tem atributo tanto de instância quanto de cadastro, a ordem de venda não completa e informa que não pode completar a remessa. Debugando, pelo eclipse verifiquei que o problema é o atributo que é obrigatório quando o produto o tem!

Isso ocorre na classe MMovementline tem um método beforesave, que busca o atributo, caso não tenha ele informa que é obrigatório.

Alguem pode me dizer algo sobre isso

obrigado desde então…


#2

Tentando resumir a pergunta para ver se sai alguma respota.

Estou tentando fazer uma expedição que crie um movimentação de material. Quando o produto movimentado tem algum atributo, não da certo concluir a expedição.


#3

ola,

estava vendo esse problema e resolvi. Na classe Minout o metodo completeIt() não passa o atributo do produto na movimentação. esta aqui somente o método corrigido e comentado.

[code] public String completeIt()
{
// Re-Check
if (!m_justPrepared)
{
String status = prepareIt();
if (!DocAction.STATUS_InProgress.equals(status))
return status;
}

	m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE);
	if (m_processMsg != null)
		return DocAction.STATUS_Invalid;
	
    /**    Criar movimentação de estoque    **/
    MDocType docTypeInOut = new MDocType(p_ctx, getC_DocType_ID(), get_TrxName());
	boolean lbr_IsReturn = POLBR.get_ValueAsBoolean(docTypeInOut.get_Value("lbr_IsReturn"));
	
    if(POLBR.get_ValueAsBoolean(docTypeInOut.get_Value("lbr_GenerateMovement")))
    {
		MMovement movement = new MMovement(p_ctx, 0, get_TrxName());
		movement.setMovementDate(getDateAcct());
		
		Integer C_DocType_ID = null;
		C_DocType_ID = (Integer)docTypeInOut.get_Value("LBR_DocTypeMovement_ID");
		if (C_DocType_ID == null || C_DocType_ID.intValue() == 0){
			log.log(Level.SEVERE,"C_DocType_ID = " + C_DocType_ID);
			return DocAction.STATUS_Invalid;
		}
		
		movement.setC_DocType_ID(C_DocType_ID);
		movement.setIsApproved(true);
		movement.save(get_TrxName());
		   
		//For all lines
		MInOutLine[] lines = getLines(false);
		for(MInOutLine line : lines)
		{
			Integer M_Warehouse_ID = null;
			M_Warehouse_ID = (Integer)docTypeInOut.get_Value("M_Warehouse_ID");
			if (M_Warehouse_ID == null || M_Warehouse_ID.intValue() == 0){
				log.log(Level.SEVERE,"M_Warehouse_ID = " + M_Warehouse_ID);
				return DocAction.STATUS_Invalid;
			}
			
			Integer M_OrderLineLocator_ID = null;
			MOrderLine ordLine = new MOrderLine(Env.getCtx(),line.getC_OrderLine_ID(),get_TrxName());
			
			/** Edilson Neto Grupo LCR
			   problema de entregar produto com atributo **/
			
			Integer M_AttributeSetInstance_ID = null;
			M_AttributeSetInstance_ID = (Integer)ordLine.get_Value("M_AttributeSetInstance_ID");			
			/** fim **/ 
			
			
			
			M_OrderLineLocator_ID = (Integer)ordLine.get_Value("M_Locator_ID");
			
			MMovementLine mLine = new MMovementLine(movement);
			mLine.setM_Product_ID(line.getM_Product_ID());
			
			
			
			mLine.setLine(line.getLine());
			mLine.setDescription(line.getDescription());
			
			
			/** Edilson Neto Grupo LCR
			   problema de entregar produto com atributo **/
			
			mLine.setM_AttributeSetInstance_ID(M_AttributeSetInstance_ID);
			/** fim **/
			
			mLine.setMovementQty(line.getMovementQty());
			if(lbr_IsReturn)
				mLine.setM_LocatorTo_ID(M_OrderLineLocator_ID);
			else
				mLine.setM_Locator_ID(line.getM_Locator_ID());
			
			int locatorTo = POLBR.getM_Locator_ID(M_Warehouse_ID, getBPartner(), get_TrxName());
			
			if(locatorTo <= 0){ 
				log.log(Level.SEVERE,"M_LocatorTo_ID = " + locatorTo);
				return DocAction.STATUS_Invalid;
			}	
			
			if(lbr_IsReturn)
				mLine.setM_Locator_ID(locatorTo);
			else
				mLine.setM_LocatorTo_ID(locatorTo);
			
			mLine.save(get_TrxName());
			
			line.setProcessed(true);
			line.save(get_TrxName());
			
			//	Update Storage
			if (!MStorage.add(getCtx(), getM_Warehouse_ID(),
				line.getM_Locator_ID(),
				line.getM_Product_ID(), 
				line.getM_AttributeSetInstance_ID(), line.getM_AttributeSetInstance_ID(), 
				null, line.getMovementQty().negate(), null, get_TrxName()))
			{
				m_processMsg = "Cannot correct Inventory";
				return DocAction.STATUS_Invalid;
			}
			 
            //      Correct Order Line 	 
            int M_Product_ID   = line.getM_Product_ID(); 	 
            int C_OrderLine_ID = line.getC_OrderLine_ID(); 	 
            if (M_Product_ID != 0 && C_OrderLine_ID != 0){ 	 
                    MOrderLine oLine = new MOrderLine(getCtx(),C_OrderLine_ID,get_TrxName()); 	 
                    if (line.getMovementQty().signum() != 1) 	 
                            oLine.setQtyReserved(Env.ZERO); 	 
                    else 	 
                            oLine.setQtyReserved(oLine.getQtyReserved().subtract(line.getMovementQty())); 	 
                    oLine.save(get_TrxName()); 	 
                    log.info("OrderLine QtyReserved = " + oLine.getQtyReserved()); 	 
            }
			
		}
		
        movement.processIt(DocAction.ACTION_Complete);
        movement.set_Value("M_InOut_ID", getM_InOut_ID());
        movement.save(get_TrxName());
       
        if(movement.getDocStatus().equalsIgnoreCase(DocAction.STATUS_Completed))
        {
        	setProcessed(true);
        	setDocAction(DocAction.ACTION_Close);
        	movement.setDocAction(DocAction.ACTION_None);
        	movement.setDocStatus(DocAction.STATUS_Closed);
        	movement.save();

        	//User Validation
    		String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);
    		if (valid != null)
    		{
    			m_processMsg = valid;
    			return DocAction.STATUS_Invalid;
    		}
        	return DocAction.STATUS_Completed;
        }
        else
        	return DocAction.STATUS_Invalid;
    }
	
	//	Outstanding (not processed) Incoming Confirmations ?
	MInOutConfirm[] confirmations = getConfirmations(true);
	for (int i = 0; i < confirmations.length; i++)
	{
		MInOutConfirm confirm = confirmations[i];
		if (!confirm.isProcessed())
		{
			if (MInOutConfirm.CONFIRMTYPE_CustomerConfirmation.equals(confirm.getConfirmType()))
				continue;
			//
			m_processMsg = "Open @M_InOutConfirm_ID@: " + 
				confirm.getConfirmTypeName() + " - " + confirm.getDocumentNo();
			return DocAction.STATUS_InProgress;
		}
	}
	
	//	Implicit Approval
	if (!isApproved())
		approveIt();
	log.info(toString());
	StringBuffer info = new StringBuffer();
	
	//	For all lines
	MInOutLine[] lines = getLines(false);
	for (int lineIndex = 0; lineIndex < lines.length; lineIndex++)
	{
		MInOutLine sLine = lines[lineIndex];
		MProduct product = sLine.getProduct();

		//	Qty & Type
		String MovementType = getMovementType();
		BigDecimal Qty = sLine.getMovementQty();
		if (MovementType.charAt(1) == '-')	//	C- Customer Shipment - V- Vendor Return
			Qty = Qty.negate();
		BigDecimal QtySO = Env.ZERO;
		BigDecimal QtyPO = Env.ZERO;
		
		//	Update Order Line
		MOrderLine oLine = null;
		if (sLine.getC_OrderLine_ID() != 0)
		{
			oLine = new MOrderLine (getCtx(), sLine.getC_OrderLine_ID(), get_TrxName());
			log.fine("OrderLine - Reserved=" + oLine.getQtyReserved() 
				+ ", Delivered=" + oLine.getQtyDelivered());
			if (isSOTrx())
				QtySO = sLine.getMovementQty();
			else
				QtyPO = sLine.getMovementQty();
		}
        
                   
        // Load RMA Line
        MRMALine rmaLine = null;
        
        if (sLine.getM_RMALine_ID() != 0)
        {
            rmaLine = new MRMALine(getCtx(), sLine.getM_RMALine_ID(), get_TrxName());
        }
		
		log.info("Line=" + sLine.getLine() + " - Qty=" + sLine.getMovementQty());

		//	Stock Movement - Counterpart MOrder.reserveStock
		if (product != null 
			&& product.isStocked() )
		{
			//Ignore the Material Policy when is Reverse Correction
			if(!isReversal())
				checkMaterialPolicy(sLine);
			
			log.fine("Material Transaction");
			MTransaction mtrx = null; 

			//same warehouse in order and receipt?
			boolean sameWarehouse = true;

			//	Reservation ASI - assume none
			int reservationAttributeSetInstance_ID = 0; // sLine.getM_AttributeSetInstance_ID();

			if (oLine != null) {
				reservationAttributeSetInstance_ID = oLine.getM_AttributeSetInstance_ID();
				sameWarehouse = oLine.getM_Warehouse_ID()==getM_Warehouse_ID();
			}

			//

			if (sLine.getM_AttributeSetInstance_ID() == 0)

			{
				MInOutLineMA mas[] = MInOutLineMA.get(getCtx(),
					sLine.getM_InOutLine_ID(), get_TrxName());

				for (int j = 0; j < mas.length; j++)
				{
					MInOutLineMA ma = mas[j];
					BigDecimal QtyMA = ma.getMovementQty();

					if (MovementType.charAt(1) == '-')	//	C- Customer Shipment - V- Vendor Return
						QtyMA = QtyMA.negate();

					BigDecimal reservedDiff = Env.ZERO;
					BigDecimal orderedDiff = Env.ZERO;

					if (sLine.getC_OrderLine_ID() != 0)
					{
						if (isSOTrx())
							reservedDiff = ma.getMovementQty().negate();
						else
							orderedDiff = ma.getMovementQty().negate();
					}

					//	Update Storage - see also VMatch.createMatchRecord
					if (!MStorage.add(getCtx(), getM_Warehouse_ID(),
						sLine.getM_Locator_ID(),
						sLine.getM_Product_ID(), 
						ma.getM_AttributeSetInstance_ID(), reservationAttributeSetInstance_ID, 
						QtyMA,
						sameWarehouse ? reservedDiff : Env.ZERO,
						sameWarehouse ? orderedDiff : Env.ZERO,
						get_TrxName()))

					{
						m_processMsg = "Cannot correct Inventory (MA)";
						return DocAction.STATUS_Invalid;
					}

					if (!sameWarehouse) {
						//correct qtyOrdered in warehouse of order
						MWarehouse wh = MWarehouse.get(getCtx(), oLine.getM_Warehouse_ID());

						if (!MStorage.add(getCtx(), oLine.getM_Warehouse_ID(),
								wh.getDefaultLocator().getM_Locator_ID(),
								sLine.getM_Product_ID(), 
								ma.getM_AttributeSetInstance_ID(), reservationAttributeSetInstance_ID, 
								Env.ZERO, reservedDiff, orderedDiff, get_TrxName()))
							{
								m_processMsg = "Cannot correct Inventory (MA) in order warehouse";
								return DocAction.STATUS_Invalid;
							}
					}

					//	Create Transaction
					mtrx = new MTransaction (getCtx(), sLine.getAD_Org_ID(), 
						MovementType, sLine.getM_Locator_ID(),
						sLine.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), 
						QtyMA, getMovementDate(), get_TrxName());
					mtrx.setM_InOutLine_ID(sLine.getM_InOutLine_ID());

					if (!mtrx.save())
					{
						m_processMsg = "Could not create Material Transaction (MA)";
						return DocAction.STATUS_Invalid;
					}
				}
			}

			//	sLine.getM_AttributeSetInstance_ID() != 0

			if (mtrx == null)
			{
				BigDecimal reservedDiff = sameWarehouse ? QtySO.negate() : Env.ZERO;
				BigDecimal orderedDiff = sameWarehouse ? QtyPO.negate(): Env.ZERO;

				//	Fallback: Update Storage - see also VMatch.createMatchRecord
				if (!MStorage.add(getCtx(), getM_Warehouse_ID(), 
					sLine.getM_Locator_ID(),
					sLine.getM_Product_ID(), 
					sLine.getM_AttributeSetInstance_ID(), reservationAttributeSetInstance_ID, 
					Qty, reservedDiff, orderedDiff, get_TrxName()))

				{
					m_processMsg = "Cannot correct Inventory";
					return DocAction.STATUS_Invalid;
				}

				if (!sameWarehouse) {
					//correct qtyOrdered in warehouse of order
					MWarehouse wh = MWarehouse.get(getCtx(), oLine.getM_Warehouse_ID());
					if (!MStorage.add(getCtx(), oLine.getM_Warehouse_ID(), 
							wh.getDefaultLocator().getM_Locator_ID(),
							sLine.getM_Product_ID(), 
							sLine.getM_AttributeSetInstance_ID(), reservationAttributeSetInstance_ID, 
							Env.ZERO, QtySO.negate(), QtyPO.negate(), get_TrxName()))
						{
							m_processMsg = "Cannot correct Inventory";
							return DocAction.STATUS_Invalid;
						}
				}

				//	FallBack: Create Transaction

				mtrx = new MTransaction (getCtx(), sLine.getAD_Org_ID(),
					MovementType, sLine.getM_Locator_ID(),
					sLine.getM_Product_ID(), sLine.getM_AttributeSetInstance_ID(), 
					Qty, getMovementDate(), get_TrxName());

				mtrx.setM_InOutLine_ID(sLine.getM_InOutLine_ID());

				if (!mtrx.save())
				{
					m_processMsg = CLogger.retrieveErrorString("Could not create Material Transaction");
					return DocAction.STATUS_Invalid;
				}
			}
		}	//	stock movement
		
		//	Correct Order Line
		if (product != null && oLine != null)		//	other in VMatch.createMatchRecord
			oLine.setQtyReserved(oLine.getQtyReserved().subtract(sLine.getMovementQty()));
		
		//	Update Sales Order Line
		if (oLine != null)
		{
			if (isSOTrx()							//	PO is done by Matching
				|| sLine.getM_Product_ID() == 0)	//	PO Charges, empty lines
			{
				if (isSOTrx())
					oLine.setQtyDelivered(oLine.getQtyDelivered().subtract(Qty));
				else
					oLine.setQtyDelivered(oLine.getQtyDelivered().add(Qty));
				oLine.setDateDelivered(getMovementDate());	//	overwrite=last
			}
			if (!oLine.save())
			{
				m_processMsg = "Could not update Order Line";
				return DocAction.STATUS_Invalid;
			}
			else
				log.fine("OrderLine -> Reserved=" + oLine.getQtyReserved() 
					+ ", Delivered=" + oLine.getQtyReserved());
		}
        //  Update RMA Line Qty Delivered
        else if (rmaLine != null)
        {
            if (isSOTrx())
            {
                rmaLine.setQtyDelivered(rmaLine.getQtyDelivered().add(Qty));
            }
            else
            {
                rmaLine.setQtyDelivered(rmaLine.getQtyDelivered().subtract(Qty));
            }
            if (!rmaLine.save())
            {
                m_processMsg = "Could not update RMA Line";
                return DocAction.STATUS_Invalid;
            }
        }

		//	Create Asset for SO
		if (product != null 
			&& isSOTrx() 
			&& product.isCreateAsset()
			&& sLine.getMovementQty().signum() > 0
			&& !isReversal())
		{
			log.fine("Asset");
			info.append("@A_Asset_ID@: ");
			int noAssets = sLine.getMovementQty().intValue();
			if (!product.isOneAssetPerUOM())
				noAssets = 1;
			for (int i = 0; i < noAssets; i++)
			{
				if (i > 0)
					info.append(" - ");
				int deliveryCount = i+1;
				if (!product.isOneAssetPerUOM())
					deliveryCount = 0;
				MAsset asset = new MAsset (this, sLine, deliveryCount);
				if (!asset.save(get_TrxName()))
				{
					m_processMsg = "Could not create Asset";
					return DocAction.STATUS_Invalid;
				}
				info.append(asset.getValue());
			}
		}	//	Asset


		//	Matching
		if (!isSOTrx() 
			&& sLine.getM_Product_ID() != 0
			&& !isReversal())
		{
			BigDecimal matchQty = sLine.getMovementQty();
			//	Invoice - Receipt Match (requires Product)
			MInvoiceLine iLine = MInvoiceLine.getOfInOutLine (sLine);
			if (iLine != null && iLine.getM_Product_ID() != 0)
			{
				if (matchQty.compareTo(iLine.getQtyInvoiced())>0)
					matchQty = iLine.getQtyInvoiced();

				MMatchInv[] matches = MMatchInv.get(getCtx(), 
					sLine.getM_InOutLine_ID(), iLine.getC_InvoiceLine_ID(), get_TrxName());
				if (matches == null || matches.length == 0)
				{
					MMatchInv inv = new MMatchInv (iLine, getMovementDate(), matchQty);
					if (sLine.getM_AttributeSetInstance_ID() != iLine.getM_AttributeSetInstance_ID())
					{
						iLine.setM_AttributeSetInstance_ID(sLine.getM_AttributeSetInstance_ID());
						iLine.save();	//	update matched invoice with ASI
						inv.setM_AttributeSetInstance_ID(sLine.getM_AttributeSetInstance_ID());
					}
					if (!inv.save(get_TrxName()))
					{
						m_processMsg = "Could not create Inv Matching";
						return DocAction.STATUS_Invalid;
					}
				}
			}	

			//	Link to Order
			if (sLine.getC_OrderLine_ID() != 0)
			{
				log.fine("PO Matching");
				//	Ship - PO
				MMatchPO po = MMatchPO.create (null, sLine, getMovementDate(), matchQty);
				if (!po.save(get_TrxName()))
				{
					m_processMsg = "Could not create PO Matching";
					return DocAction.STATUS_Invalid;
				}
				//	Update PO with ASI
				if (   oLine != null && oLine.getM_AttributeSetInstance_ID() == 0
					&& sLine.getMovementQty().compareTo(oLine.getQtyOrdered()) == 0) //  just if full match [ 1876965 ]
				{
					oLine.setM_AttributeSetInstance_ID(sLine.getM_AttributeSetInstance_ID());
					oLine.save(get_TrxName());
				}
			}
			else	//	No Order - Try finding links via Invoice
			{
				//	Invoice has an Order Link
				if (iLine != null && iLine.getC_OrderLine_ID() != 0)
				{
					//	Invoice is created before  Shipment
					log.fine("PO(Inv) Matching");
					//	Ship - Invoice
					MMatchPO po = MMatchPO.create (iLine, sLine,  
						getMovementDate(), matchQty);
					if (!po.save(get_TrxName()))
					{
						m_processMsg = "Could not create PO(Inv) Matching";
						return DocAction.STATUS_Invalid;
					}
					//	Update PO with ASI
					oLine = new MOrderLine (getCtx(), po.getC_OrderLine_ID(), get_TrxName());
					if (   oLine != null && oLine.getM_AttributeSetInstance_ID() == 0 
						&& sLine.getMovementQty().compareTo(oLine.getQtyOrdered()) == 0) //  just if full match [ 1876965 ]
					{
						oLine.setM_AttributeSetInstance_ID(sLine.getM_AttributeSetInstance_ID());
						oLine.save(get_TrxName());
					}						
				}
			}	//	No Order
		}	//	PO Matching
		
	}	//	for all lines
	
	//	Counter Documents
	MInOut counter = createCounterDoc();
	if (counter != null)
		info.append(" - @CounterDoc@: @M_InOut_ID@=").append(counter.getDocumentNo());
	//	User Validation
	String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);
	if (valid != null)
	{
		m_processMsg = valid;
		return DocAction.STATUS_Invalid;
	}

	// Set the definite document number after completed (if needed)
	setDefiniteDocumentNo();

	m_processMsg = info.toString();
	setProcessed(true);
	setDocAction(DOCACTION_Close);
	return DocAction.STATUS_Completed;
}	//	completeIt

[/code]