**This page is obsolete.** OfBiz is not part of current developments. ======Acquisitions/Serials - notes for developers====== OFBiz/opentaps is huge, but lots of organizations use it and there is a lot of material online. A particularly useful document is [[http://www.opensourcestrategies.com/ofbiz/ofbiz_debugging.txt|Zen and the Art of Debugging OFBiz]], especially the section on log files. The [[http://www.opensourcestrategies.com/ofbiz/hello_world1.php|Hello World]] example gives a good sense of how OFBiz works. David Jones' [[http://docs.ofbiz.org/display/OFBTECH/Framework+Introduction+Videos+and+Diagrams|introductory video]] is also very helpful. We have made some changes to the layout of OFBiz, nothing complex in a technical sense, but it is well worth touching base with us before embarking on a developer's journey. On the other hand, downloading it directly to see how it works is still a valid option. In general, the main objects of most changes do not require a restart: * [[http://freemarker.org/|Freemaker]] templates (see this [[http://www.javaworld.com/javaworld/jw-11-2007/jw-11-java-template-engines.html|comparison to Velocity]]) * [[http://www.beanshell.org/|Beanshell]] files * Screens XML files * Forms XML files * controller XML file There is a cache that often needs to be cleared in //Web Tools// when making modifications, but this is still a much faster and more convenient option than waiting for a tomcat restart. ====Up close: modifying the Purchase Order screen==== OFBiz applications are made up of many small pieces. Although some developers use OFBiz as a general purpose framework, its value is clearly far more as a ready source of financial functions and data models (see [[http://www.djangoproject.com/|Django]] or [[http://www.rubyonrails.org/|Ruby on Rails]] if you are looking for a framework to build something from scratch). The example that might be the most helpful is both intricate (in terms of layout) and trivial (in terms of actual code), and that is using [[http://open-ils.org/dokuwiki/doku.php?id=osrf-devel:primer|OpenSRF]] to bring records from the //Evergreen// catalogue into the Purchase Order screen: {{:acq:dev1.jpg|PO Screen}} As you may have guessed, the "Evergreen Bib Lookup" option has been a customized addition to this screen. In order to see how this was done, we go to the key to any interaction, which is the URL, in this case: https://localhost:8443/ordermgr/control/setOrderCurrencyAgreementShipDates We will ignore the hostname and port, and focus on the rest of the url: /ordermgr/control/setOrderCurrencyAgreementShipDates The first part of the address is the //mount-point//, and this is specified in the //ofbiz-component.xml// associated with the application. Since the application in this case is related to ordering, the ofbiz-component.xml file we want is in located in the subdirectory //applications/order//. {{:acq:dev2.jpg|ofbiz-component.xml}} And, sure enough, in this file, we find the entry point for //ordermgr//: This tells us that the building blocks of //ordermgr// are in the subdirectory //webapp/ordermgr//. {{:acq:dev3.jpg|ordermgr dir listing}} ====The Role of the Controller==== The file that represents the switchboard for URL requests is //controller.xml//, which is always located in the //WEB-INF// subdirectory. The //control// part of the URL identifies the servlet involved and confirms that this interaction is under a controller, and we look for the section that describes what happens when //setOrderCurrencyAgreementShipDates// is requested. Handles setting the currency, agreement and shipment dates of an order. This tells us a bit about what this request is responsible for, and what action should take place. In this case, a java action is invoked (//setOrderCurrencyAgreementShipDates//), and the action can either return a value indicating success or error. Generally speaking, this is how you would normally weave a java interaction into an application, and looking at the source of the //ShoppingCartEvents// class reveals the java contortions that can be mixed in. However, let's assume that the action is successful and skip to //orderentry//. This also maps to a request, and is specified in //controller.xml//. Again, more java plumbing is invoked, but this time there are 4 possible outcomes. It is possible to glean the jumping off point from the code, but the //runtime/logs/console.log// also gives a running update on what's happening. [ UtilXml.java:246:DEBUG] XML Read 0.061s: jndi:/0.0.0.0/ordermgr/WEB-INF/controller.xml [ConfigXMLReader.java:561:INFO ] ConfigMap Created: (4) records in 0.0030s [ConfigXMLReader.java:719:INFO ] HandlerMap Created: (4) view handlers and (6) request/event handlers in 0.0s [ConfigXMLReader.java:294:INFO ] RequestMap Created: (295) records in 0.016s [ConfigXMLReader.java:388:INFO ] ViewMap Created: (129) records in 0.0010s [ UtilXml.java:246:DEBUG] XML Read 0.046s: file:opentaps-1.0-dist/applications/order/widget/ordermgr/OrderViewScreens.xml [ ScreenFactory.java:121:INFO ] Got 19 screens in 0.084s from: file:opentaps-1.0-dist/applications/order/widget/ordermgr/OrderViewScreens.xml [ UtilXml.java:246:DEBUG] XML Read 0.03s: file:opentaps-1.0-dist/applications/order/widget/ordermgr/CommonScreens.xml [ ScreenFactory.java:121:INFO ] Got 4 screens in 0.036s from: file:opentaps-1.0-dist/applications/order/widget/ordermgr/CommonScreens.xml This is where things start getting interesting, and we can start to see how the //screen//, a snippet of HTML for display, is coming together. Each response in //controller.xml// has a //type//, and in this case, the type is //view//. Peeking inside //OrderViewScreens.xml//, for example, shows how screens can be defined.
In this case, //minicart.ftl// is an Freemaker template file, and the //component// designation indicates a directory relative to the //applications// directory, so that the source file can be found in //applications/order/webapp/ordermgr/entry/cart//. Freemaker is similar to other templating engines, and brings together what should normally be a thin layer of business logic with presentation options.
${uiLabelMap.EcommerceCartSummary}
<#if (shoppingCartSize > 0)> <#if hidetoplinks?default("N") != "Y">
${uiLabelMap.EcommerceViewCart}  ${uiLabelMap.EcommerceCheckout}
====Launching from a Button==== To add an Evergreen lookup, we modify the //showcart.ftl// file, which contains the layout of the portion of the screen we are targeting. ${uiLabelMap.OrderQuickEvergreenLookup} Note the use of //uiLabelMap//, it is a common mechanism for keeping labels and other textual content out of the templates. The button initiates a snippet of javascript: function quicklookupevergreen_popup(element) { target = element; var searchTerm = element.value; var obj_lookupwindow = window.open('/woodchip/control/ils_bib_search?foo=' + searchTerm,'FieldLookup', 'width=700,height=550,scrollbars=yes,status=no,resizable=yes,top='+my+', left='+mx+',dependent=yes,alwaysRaised=yes'); obj_lookupwindow.opener = window; obj_lookupwindow.focus(); } Once again, the URL invoked is the key construct in making something useful happen, in this case: /woodchip/control/ils_bib_search Thanks to the wizardry of [[http://esilibrary.com/esi/company.html|Bill Erickson]], this produces a search screen that retrieves records from the catalogue: {{:acq:dev4.jpg|PO Screen}} We would probably want to transfer much more information to //Desiderata//, but let's implement a very simple mechanism to add the //record id// and the //title//, and encapsulate this into the URL: /catalog/control/EditProduct?record_id=5&title=Harry%20Potter%20and%20the%20deathly%20hallows Once again, the ofbiz-component.xml file reveals the entry point for //catalog//: No surprises here, and the //WEB-INF/controller.xml// tells us that a //view// is produced when this request arrives: and, in turn, the view is contained inside an XML file called //ProductScreens.xml//: Note the syntax, this indicates that section we want in //ProductScreens.xml// is called //EditProduct//, and we can focus on that part of the screen definition: