You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ofbiz.apache.org by Forrest Rae <fb...@14x.net> on 2014/11/04 05:50:25 UTC

Re: ShipmentCostEstimate is the Supplier Shipping Price

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
> 

Re: ShipmentCostEstimate is the Supplier Shipping Price

Posted by Todd Thorner <tt...@infotinuum.com>.
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, joelfradkin@gmail.com 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.

Re: ShipmentCostEstimate is the Supplier Shipping Price

Posted by Jacques Le Roux <ja...@les7arts.com>.
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, joelfradkin@gmail.com 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.

Re: ShipmentCostEstimate is the Supplier Shipping Price

Posted by Forrest Rae <fb...@14x.net>.
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, joelfradkin@gmail.com 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.

Re: ShipmentCostEstimate is the Supplier Shipping Price

Posted by "joelfradkin@gmail.com" <jo...@gmail.com>.
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
--
View this message in context: http://ofbiz.135035.n4.nabble.com/ShipmentCostEstimate-is-the-Supplier-Shipping-Price-tp4656851p4657828.html
Sent from the OFBiz - User mailing list archive at Nabble.com.

Re: ShipmentCostEstimate is the Supplier Shipping Price

Posted by Todd Thorner <tt...@infotinuum.com>.
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
>>