Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo
I'm trying to figure out how the distribution order works, I spent a few days now, digging into the code, and at the moment I'm persuaded that the functionality has many bugs, I wonder if there is a more up to date version somewhere; this is where I took the code:
this is the list of bugs (and/or doubts) I've currently found:
1. Mandatory Transit Warehouse. I wonder why it's mandatory to have a transit warehouse, so there should always be two material movement one from the original locator to the transit warehouse, and one from the transit warehouse to the destination locator. What if there is no transit warehouse?
2. How to generate the Material Movement? Currently there are two ways, using a process (org.eevolution.process.MovementGenerate) or a custom form (org.eevolution.form.OrderDistribution) which in turn call the same process. It seems from the code that the quantity for the movement is taken from the ConfirmedQty of the DD_OrderLine, now even if it's possible to input this qty into the DO window there is a callout which control that it's never greater than the QtyDelivered but the QtyDelivered shoul be updated by the completion of the Material Movement so we have a chicken-egg problem here.
3. Wrong definition of m_movement.c_bpartner_location_id. The db constraint for this column is
CONSTRAINT cbpartnerlocation_mmovement FOREIGN KEY (c_bpartner_location_id)
REFERENCES c_location (c_location_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED
the definition inside the dictionary is also wrong, the reference is "Location (Address)".
I found this error after changing the process and managing to create the movement using the QtyOrdered instead of the ConfirmedQty, I got an integrity check violation because the method org.eevolution.process.MovementGenerate.createMovement(MDDOrder, Timestamp) do the following
MMovement move = new MMovement(order.getCtx(), 0, order.get_TrxName());
move.setC_BPartner_Location_ID (order.getC_BPartner_Location_ID()); // shipment address
which is right in my opinion, but the column reference another table so that's the problem.
In the end I wonder how is the status of this functionality, the problems I got are so basic that they lead me to think that nobody is using it, or maybe it's just me missing something.
I hope somebody will enlighten me
Victor Perez Juarez
I've been a little busy and so far I have a few minutes to help.
The transit warehouse is needed to identify the product you are traveling and update the quantity on hand. so to know which are the products, quantities and value of inventory in transit we must have a different warehouse source or destination.
The current Inventory Move does not allow management material in transit, as you complete a "Inventory Move" the quantity on hand is updated even when the inventory is still in transit.
The order of distribution are generated during the execution of MRP with DRP option is activated, MRP suggests a distribution orden for products with a network code rather than a Manufacturing Order or Requisition.
The Distribution Order also may be generated manually.
The cycle of an order of distribution is:
1 .-A Inventory Move is created from the source warehouse to warehouse in transit by the amount confirmed using the option Generate Movement Manual (the operation is similar to the shipments, the delivery rule is used to validate the inventory available).
2 .- When the material reaches its destination it is necessary to receive the material of the distribution order, so a Inventory Move is generated by receiving material from the warehouse in transit to warehouse target (the operation is similar to the receipt of a purchase order).
The confirmed quantity can be set using distribution lists or manually
The callout that validate that quantity confirmed must be greater than quantity to deliver, so the quantity to deliver = quantity ordered - quantity in transit - quantity delivered.
Note: please check that is not the same quantity to deliver that the quantity delivered.
about that location into the inventory move should be definite the same way that distribution order, so that you found a bug here, so as this column can be null and is not mandatory may be that not cause some issues, but you are in correct, I should fix this problem.
thank you very much for your reply, I'm still a bit confused about the use of the quantities, into MovementGenerate there is a first loop for every line with the following test:
271 //BigDecimal toDeliver = line.getQtyOrdered()
272 BigDecimal toDeliver = line.getConfirmedQty(); //.subtract(line.getQtyDelivered());
273 MProduct product = line.getProduct();
274 // Nothing to Deliver
275 if (product != null && toDeliver.signum() == 0)
so it just look at ConfirmedQty, if it's zero it loops to the next line.
Then if the delivery rule is CompleteOrder there is a second loop where quantity is calculated as
400 BigDecimal toDeliver = line.getQtyOrdered().subtract(line.getQtyDelivered());
So I don't understand why it use two different method.
About the Callout, you are right about QtyToDeliver it's equal to getQtyOrdered().subtract(getQtyInTransit()).subtract(getQtyDelivered());
The problem is inside the callout:
206 public String qtyConfirmed (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value)
208 I_DD_OrderLine line = GridTabWrapper.create(mTab, I_DD_OrderLine.class);
209 MDDOrderLine orderLine = new MDDOrderLine(ctx, line.getDD_OrderLine_ID(), null);
211 if (line.getConfirmedQty().compareTo(orderLine.getQtyToDeliver()) > 0)
If you are inserting a new record and still haven't save it, the line 209 return a new MDDOrderLine and so getQtyToDeliver() return zero. Even if you save the record the result is not reliable because you could change the QtyOrdered and then the ConfirmedQty without saving. I think we should replace the method getQtyToDeliver() with a local calculation, since we can't cast the interface to the M class.
another question about the Distribution Order, this one is about the callout
org.eevolution.model.CalloutDistributionOrder.qty(Properties, int, GridTab, GridField, Object)
near the end there is a check for quantity availability which start with the following code
if (M_Product_ID != 0
&& Env.isSOTrx(ctx, WindowNo)
&& QtyOrdered.signum() > 0) // no negative (returns)
it never fire, because Env.isSOTrx(ctx, WindowNo) is returning false. I saw that isSOTrx is not checked neither on the Window nor on the Menu. Is that intentional or it's just my DB which is wrong?