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 |
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 > |
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 >> |
Yea great detail on how you handled it.
I know for myself I moved all my code to hot-deploy project. Not sure it will help that much for new versions, but I try to avoid messing with the original code unless I copy it into my hot-deploy.
Joel Fradkin
|
Joel, That was the whole point here, not to mess with the main line
code, but to make my modifications in my custom component in the hot-deploy directory. You'll see that I don't touch any of the order code in the applications directory. Todd, I'm happy to write something up on the wiki, please let me know where to put it and I'll make it happen. I am curious what people's thoughts are in making a modification to the existing code to accomplish this though, as I explain in my previous mail. I could make a patch to the Java code, and include a new setting in the supplier screens to control whether shipping and handling charges are passed to the PO. If people are interested in this of course... -Forrest On 11/4/2014 9:32 AM, [hidden email] wrote: > Yea great detail on how you handled it. > I know for myself I moved all my code to hot-deploy project. > Not sure it will help that much for new versions, but I try to avoid messing > with the original code unless I copy it into my hot-deploy. |
Sorry, Forrest, I'm still pretty clueless about OFBiz and can't begin to
help anyone with the project's wiki accessibility. I was actually kicking myself in that message for not yet being able to help the project by turning someone else's generous mailing list contribution (e.g. your instructions) into a small-scope tutorial (I'm a tech writer in search of a SME or three). Perhaps someone more in-the-know can help you get started on transposing your instructions to the wiki. On 14-11-05 11:28 AM, Forrest Rae wrote: > Joel, That was the whole point here, not to mess with the main line > code, but to make my modifications in my custom component in the > hot-deploy directory. You'll see that I don't touch any of the order > code in the applications directory. > > Todd, I'm happy to write something up on the wiki, please let me know > where to put it and I'll make it happen. > > I am curious what people's thoughts are in making a modification to the > existing code to accomplish this though, as I explain in my previous > mail. I could make a patch to the Java code, and include a new setting > in the supplier screens to control whether shipping and handling charges > are passed to the PO. If people are interested in this of course... > > -Forrest > > On 11/4/2014 9:32 AM, [hidden email] wrote: >> Yea great detail on how you handled it. >> I know for myself I moved all my code to hot-deploy project. >> Not sure it will help that much for new versions, but I try to avoid messing >> with the original code unless I copy it into my hot-deploy. |
Administrator
|
In reply to this post by Forrest Rae
Yes please create a Jira issue and attach a patch. Remember that new feature are only applied on trunk so your patch must be created against trunk HEAD
In case of doubts always refer to https://cwiki.apache.org/confluence/display/OFBADMIN/OFBiz+Contributors+Best+Practices Thanks Jacques Le 05/11/2014 20:28, Forrest Rae a écrit : > Joel, That was the whole point here, not to mess with the main line > code, but to make my modifications in my custom component in the > hot-deploy directory. You'll see that I don't touch any of the order > code in the applications directory. > > Todd, I'm happy to write something up on the wiki, please let me know > where to put it and I'll make it happen. > > I am curious what people's thoughts are in making a modification to the > existing code to accomplish this though, as I explain in my previous > mail. I could make a patch to the Java code, and include a new setting > in the supplier screens to control whether shipping and handling charges > are passed to the PO. If people are interested in this of course... > > -Forrest > > On 11/4/2014 9:32 AM, [hidden email] wrote: >> Yea great detail on how you handled it. >> I know for myself I moved all my code to hot-deploy project. >> Not sure it will help that much for new versions, but I try to avoid messing >> with the original code unless I copy it into my hot-deploy. |
Free forum by Nabble | Edit this page |