Thanks, Forrest, for making time to add valuable information that benefits future MarkMail answer-hunters. Such details would make a good tutorial for beginners to OFBiz services.
On 14-11-03 08:50 PM, Forrest Rae wrote: > Hi Again, > > First, apologies for the length of this mail, but I learned quite a bit > in the last couple weeks of working on this in my spare time and I don't > want these lessons to be applicable to only myself. > > I wanted to get back and answer my own post now that I've figured it out > for mailing list archival purposes. For anyone else that is struggling > to learn OFBiz, and not sure how something works, the best method I've > found is to set a break point via Java debugging and step through the > code. Find a service you're particularly interested in, for me it was > storeOrder, find the associated routing that is invoked by inspecting > the XML configuration for the service, and step through the code in the > debugger line by line. > > For my purposes, I wanted to see how the associated purchase orders were > generated when a sales order was created for dropship products. It was > pretty easy to find a service that was called via an SECA in > applications/order/servicedef/secas.xml called > checkCreateDropShipPurchaseOrders. Setting a break point here and > stepping through the code showed me how purchase orders were created. > > If you read below, you see that I was trying to ensure the amount I was > trying to charge for shipping was passed to the supplier, from sales > order to purchase order. I was hoping there was an easy way of doing > this, but it turns out there wasn't. If you look at the Java code for > checkCreateDropShipPurchaseOrders, you can see that it doesn't do > anything with OrderAdjustment entity. > > It took me a while to figure out that Shipping and Handling charges were > tracked via OrderAdjustment. I determined this by tracing the code in > the Order view back to where it pulls the data from. > > Once I had all the information together, I had enough information to > write a service that would be triggered via an SECA that given a sales > order id, could find the associated purchase order, and create an > OrderAdjustment for that purchase order. (I also had to learn MiniLang > in the process). > > My code has some limitations, especially when mixing orders from > different suppliers where not all items are dropship. Also, it might be > nice if you could configure this to happen per product, rather than per > purchase order. Additionally, I feel like this functionality belongs in > Java closer to checkCreateDropShipPurchaseOrders, rather than as a SECA. > > Feedback is definitely appreciated! My apologies for the line wrapping > in email, let me know if there was a better way to present this kind of > thing. > > ===================================================================== > First, I had to overload the ordermgr in my ofbiz-component.xml: > ===================================================================== > > <?xml version="1.0" encoding="UTF-8"?> > <ofbiz-component name="dropShipPOAdjustment" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > > xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-component.xsd"> > <!-- define resource loaders; most common is to use the component > resource loader --> > <resource-loader name="main" type="component"/> > > <service-resource type="model" loader="main" > location="servicedef/services.xml"/> > <service-resource type="eca" loader="main" > location="servicedef/secas.xml"/> > > <webapp name="dropShipPOAdjustment" > title="DropShipPOAdjustment" > server="default-server" > location="webapp/dropShipPOAdjustment" > base-permission="OFBTOOLS,ORDERMGR" > mount-point="/dropShipPOAdjustment" > app-bar-display="true"/> > > <webapp name="order" > title="Order-Customized" > description="OrderComponentDescription" > server="default-server" > location="webapp/ordermgr" > base-permission="OFBTOOLS,ORDERMGR" > mount-point="/ordermgr"/> > </ofbiz-component> > > ===================================================================== > Next, create a service that is triggered by SECA in my services.xml: > ===================================================================== > > <?xml version="1.0" encoding="UTF-8"?> > <services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/services.xsd"> > <description>DropShipPOAdjustment Services</description> > <vendor></vendor> > <version>1.0</version> > <service name="dropShipPOAdjustmentSimple" engine="simple" > location="component://dropShipPOAdjustment/script/com/fidelissd/order/dropShipPOAdjustmentSimple.xml" > invoke="dropShipPOAdjustmentSimple"> > <description>For each Purchase Order related to a Sales Order, > associate those adjustments to the Purchase Orders</description> > <attribute name="orderId" type="String" mode="IN" > optional="false" /> > <attribute name="toOrderId" type="String" mode="IN" > optional="false" /> > </service> > </services> > > The actual SECA is next, in secas.xml: > > <?xml version="1.0" encoding="UTF-8"?> > <service-eca xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/service-eca.xsd"> > <eca service="checkCreateDropShipPurchaseOrders" event="return"> > <action service="dropShipPOAdjustmentSimple" mode="sync" > run-as-user="system" /> > </eca> > </service-eca> > > ===================================================================== > Finally, the code of my service in dropShipPOAdjustmentSimple.xml: > ===================================================================== > > <?xml version="1.0" encoding="UTF-8"?> > <simple-methods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/simple-methods-v2.xsd"> > > <simple-method method-name="dropShipPOAdjustmentSimple" > short-description="Service for the searching for adjustments on Sales > Orders, and associating those adjustments to the Purchase Orders"> > <check-permission permission="ORDERMGR" > action="_UPDATE"><fail-property resource="OrderErrorUiLabels" > property="OrderSecurityErrorToRunUpdateOrderAdjustement"/></check-permission> > <check-errors/> > > <!-- Find Associated Drop Ship Orders --> > <entity-and entity-name="OrderItemAssoc" list="orderAssociations"> > <field-map field-name="orderId" > from-field="parameters.orderId"/> > <field-map field-name="orderItemAssocTypeId" > value="DROP_SHIPMENT"/> > </entity-and> > > <iterate entry="orderAssoc" list="orderAssociations"> > <log message="Found Order Association > ${orderAssoc.orderId} to > ${orderAssoc.toOrderId}" level="info"/> > > <!-- Save off order IDs for later use --> > <set from-field="orderAssoc.orderId" field="salesOrderId"/> > <set from-field="orderAssoc.toOrderId" field="purchaseOrderId"/> > > <!-- Find our Sales Order Header --> > <entity-one entity-name="OrderHeader" value-field="orderHeader"> > <field-map field-name="orderId" > from-field="salesOrderId"/> > </entity-one> > <log message="Found order ${orderHeader.orderName} with an id > of ${orderHeader.orderId}" level="info"/> > > <!-- Find the related order adjustments, filtering with > SHIPPING_CHARGES and the Shipping Group Sequence ID --> > <set field="searchMap.orderAdjustmentTypeId" type="String" > value="SHIPPING_CHARGES"/> > <set field="searchMap.shipGroupSeqId" > from="orderAssoc.shipGroupSeqId"/> > <get-related relation-name="OrderAdjustment" > value-field="orderHeader" list="orderAdjustments" map="searchMap"/> > <!-- There should only be one order adjustment of type shipping > charges, for this shipGroup --> > <log message="Found Order Adjustment in the amount of > ${orderAdjustments[0].amount}" level="info"/> > > <!-- Setup the parameters required for the call to > createOrderAdjustment --> > <set from-field="purchaseOrderId" field="orderId"/> > <set from-field="orderAdjustments[0].orderAdjustmentTypeId" > field="orderAdjustmentTypeId"/> > <set from-field="orderAdjustments[0].orderItemSeqId" > field="orderItemSeqId"/> > <set from-field="orderAdjustments[0].shipGroupSeqId" > field="shipGroupSeqId"/> > <set from-field="orderAdjustments[0].amount" field="amount"/> > > <!-- Call createOrderAdjustment --> > <call-simple-method > xml-resource="component://order/script/org/ofbiz/order/order/OrderSimpleMethods.xml" > method-name="createOrderAdjustment" scope="function"/> > </iterate> > </simple-method> > </simple-methods> > > > > > > On 10/16/2014 4:34 PM, Forrest Rae wrote: >> Hi Guys, >> >> I have a dropship product supplier who has some crazy shipping prices. >> I was able to model them accurately after about two days of reverse >> engineering how ShipmentCostEstimate and calcShipmentCostEstimate() work >> via Eclipse Java Debugging. Was actually kind of fun and learned a ton >> about how OFBiz works. >> >> My question is, how do I pass the "Shipping and Handling" cost from the >> sales order (that is generated via my elaborate set of >> ShipmentCostEstimate), to the purchase order. It seems like that would >> be a standard thing that would need to be done, so I'm wondering if I've >> just missed an option somewhere? >> >> -Forrest >>
