I a sorry I have not explained myself well.
I have assumed you have seen how VBA of excel works.
however make work in the current environment of ofbiz.
the Business user will not know about minilang, ECA, SECA, and Services as ofbiz implements them but will have a free flow language that they can talk in a comfortable terms. I have a rough proof of concept I will try to put on my demo server shortly that will show more what I am talking about.





Marek Mosiewicz sent the following on 8/2/2010 1:10 AM:
I'do not think ECA implementation would work in way is needed.
When we operate on macros (documents), what is important is dependency
graph and
old values tracking.
we can have conditions like this in pseudo code:

on Order o
when
grandTotal>$200 and o.noPromotionsAdded
then
invoke addSomePromotion(o)

on
OrderItem oi
when
changed(oi.quantity) or
changed(oi.price)
then
invoke recalulateLineTotal(oi)

on
Order o
when
changed or added or deleted (o.items[].lineTotal)
then
invoke recalculateGrandTotal(o)

Now if we order >200 then we add some stuff and recalulate line total
and later need to fire rule which
will recaulate Order grand total. It must be like speadsheet where you can
show what depends on what. Of course we can always do calcuations in
services to avoid these kind of problems
but it will not be flexible or manually know (as in your ECA example)
that e.g. service updateOrderItems changes
line total so we need to invoke reset grand total. But there are many
services which change line total (adding, deleteing, updating item)
and we will need to always say it manually, so saying that ECA depends
on field is much more useful.

Of course the best thing would be to have triggers for complicated stuff
but also
calculation rules for simpler things like GrandTotal. For rules it can
be automatically determined what they are depend on , we just say:
grandTotal =from items select sum(lineTotal)

There are several problems with more advanced appoach:
need for change notification mechanism to know what to fire next (let
imagine rule which operates on order but changes order line - in case of
db services we have no way to detect that line has changed - and we need
another rule to fire)
probably need in memory macros for performance reasons. In memory macros
can be much more faster (e.g. recalulation of grand total after change
of line total) and futher optimized (can be in "invalid" status until
acctually required or stored in db e.g. no need to recaulate grand total
after adding new line)
rules would need some kind of language



W dniu 2010-07-31 23:34, BJ Freeman pisze:
in line


Marek Mosiewicz sent the following on 7/30/2010 12:50 AM:

W dniu 2010-07-29 20:18, BJ Freeman pisze:
Thanks that looks like beanshell or Groovy type of code.
this goes along with the openoffice macro code flexibility.
It has a little different usage. Each rule is fired only when assertions
for rule are true. That means that facts can be fired incrementally when
new facts appear. But it also means that you have to supply facts.
Drools does not opperate on data model but on facts.
Each statement (e.g. OrderLine) must be inserted into so called working
memory as a fact. In example blow the only facts are entities (fact that
they exists), but in more advanced scenario fact can be that some field
changed. That would make possible to
fire some expensive rules only when given field change, but it makes
rules definitions more complicated. It would need braimstorming,
probably with appropriate people in field what is better: RETE rule
engine(aka drools) or functional reactive programming (FRP)
(something like this http://lambda-the-ultimate.org/node/1918 or this
http://www.flapjax-lang.org/tutorial/ ). Functional reactive programming
seems to be more declarative way of things for me.

and ECA works this way.
<eca service="updateOrderItems" event="commit">
<action service="resetGrandTotal" mode="sync"/>
<action service="sendOrderChangeNotification" mode="async"
persist="true"/>
</eca>
OR
<eca service="changeOrderStatus" event="commit" run-on-error="false">
<condition field-name="statusId" operator="equals"
value="ORDER_APPROVED"/>
<condition field-name="orderTypeId" operator="equals"
value="SALES_ORDER"/>
<condition-field field-name="statusId" operator="not-equals"
to-field-name="oldStatusId"/>
<action service="updateContentSubscriptionByOrder" mode="sync"/>
<action service="processExtendSubscriptionByOrder" mode="sync"/>
</eca>


.
At a business level would like to follow that macro type of
formulation but expose ofbiz services like the Artifacts (webtools)
OfBiz services are stateless. What I think is possible is (optional)
stateful services. I think it is possible to have "live" documents. For
example when we create order we do not go with services to database, but
operate only in memory. Drools or FRP would recalculate document on
change of facts. What is good is that you can have temporary facts (e.g.
line X is discount for line Y). Facts can also retract (be removed) when
condition is no longer valid, so discount line probably could be removed
if condition for it is no longer valid.
Live documets would have folowing advantages:
no problems with temporary documents between saves
much imporved scalabilty (go to database only when save whole document)
possiblity to have one logic to serve UI and for batch/webservices
mode ?

in the macro mode the business man can use predfined macro(services)
once a macro the new macro is define it can be called but another macro.
Part of my spec, pulls all the current services and SECA into this
Macro enviorment. Then the business man has access to them.
from what you describe the Macro is a Document.


At this point I am aiming this for business person that has little or
no programming knowlege.
Curent DSL for Drools would genereate some noise, I think. There is a
lot of tricks. One I said before, that you must order rules manualy.
Another thing is you have to divide logic into agenda groups (In case
below one agenda group caulcates item and another order summary). Yet
another thing is that you have to say that fact was modified with
modify() statement.

I believe macro environment I am describing will fill those
requirements but be native to ofbiz.
I related Agenda Group as components in ofbiz.

I will use you supplied example to show how the Business Macros will
work.
You are welcome.
Marek Mosiewicz sent the following on 7/29/2010 7:10 AM:
W dniu 2010-07-29 15:14, chris snow pisze:
Hi BJ, I was responding to your comment:

"I like the design of Drool but think we need to go one step higher
and see this as how to run a business."

Guvnor has an abstraction on top of drools that is aimed at the
business user. I don't know enough about drools to comment on how it
would be integrated with the business model. I still have a lot more
learning to do around the subject...


I made some attempts with Drools as engine for future (probably open
source) ERP. But it not like excel. You can write calculation rules
but
Drools would not order them automatically based on dependencies. (e.g.
calc line total before sum of order). But in many ways it is very
powerful tool.


There are example rules for simple Order (I could send whole project):

package com.sample

import com.sample.Order;
import com.sample.OrderItem
import com.sample.OrderTaxLine;
import com.sample.OrderTaxSummary;
import com.sample.OrderDiscount;
import com.sample.Product;
import com.sample.Tax;
import com.sample.TaxCalculator;
import com.sample.Discount;
import com.sample.DiscountCalculator;

dialect "java"

function Tax calcTax(int customerId,int productId) {
return TaxCalculator.calculateTax(customerId,productId);
}

rule "order item price"
dialect "mvel"
agenda-group "Items"
lock-on-active true
salience 9
when
$item : OrderItem();
then
modify($item){
setPrice($item.product.price);
}
end

rule "order item amountNetto"
dialect "mvel"
lock-on-active true
agenda-group "Items"
salience 8
when
$item : OrderItem();
then
modify($item){
setAmountNetto($item.price * $item.quantity);
}
end

rule "order item tax"
dialect "mvel"
lock-on-active true
agenda-group "Items"
salience 7
when
$item : OrderItem();
then
modify($item){
setTaxes(calcTax($item.order.partyDelivery.partyId.intValue(),$item.product.productId.intValue()));



}
end

rule "order item amountTax"
dialect "mvel"
lock-on-active true
agenda-group "Items"
salience 6
when
$item : OrderItem();
then
modify($item){
setAmountTax($item.tax.rateTax * $item.amountNetto);
}
end

rule "order item amountBrutto"
dialect "mvel"
lock-on-active true
agenda-group "Items"
salience 5
when
$item : OrderItem();
then
modify($item){
setAmountBrutto($item.amountNetto + $item.amountTax);
}
end

rule "Switch to Order"
dialect "mvel"
lock-on-active true
agenda-group "Items"
salience -100000
when
$item : OrderItem();
then
drools.setFocus("Order");
end

rule "order calucations"
dialect "mvel"
lock-on-active true
agenda-group "Order"
salience 4
when
$order : Order();
$amountTax : Number() from accumulate (OrderItem( order==$order,
amountTax!=null,$amount:amountTax), sum($amount));
then
$order.amountTax = $amountTax;
end

rule "order calucations 2"
dialect "mvel"
lock-on-active true
agenda-group "Order"
salience 3
when
$order : Order();
$amountNetto : Number() from accumulate (OrderItem( order==$order,
amountNetto!=null, $amount:amountNetto), sum($amount));
then
$order.amountNetto = $amountNetto;
end


rule "order calucations 3"
dialect "mvel"
lock-on-active true
agenda-group "Order"
salience 2
when
$order : Order(amountTax !=null,amountNetto!=null);
then
$order.amountBrutto = ($order.amountTax + $order.amountNetto);
end



Maybe facts assertions should not be like above "OrderLine exists" but
e.g. "quantity of order line changed"












Reply via email to