Hello Emad,
We are simply getting "billItems"(List) value from the service context map.
Here is the service definition of createInvoiceForOrder(Please refer file:
services_invoice.xml):
<service name="createInvoiceForOrder" engine="java"
location="org.apache.ofbiz.accounting.invoice.InvoiceServices"
invoke="createInvoiceForOrder">
<description>
Create an invoice from existing order
orderId = The orderId to associate the invoice with
billItems = List of ItemIssuance records to use for creating
the invoice
</description>
<attribute name="orderId" type="String" mode="IN" optional="false"/>
<attribute name="billItems" type="List" mode="IN" optional="false"/>
<attribute name="eventDate" type="Timestamp" mode="IN"
optional="true"/>
<attribute name="invoiceId" type="String" mode="INOUT"
optional="true"/>
<attribute name="invoiceTypeId" type="String" mode="OUT"
optional="true"/>
</service>
Now you can check from where this service is being called:
One example from where "createInvoiceForOrder" is being called is from
OrderServices.java(There can be other references as well)-
Please refer following service implementation:
public static Map<String, Object> invoiceServiceItems(
And then read the code of this service and see the following code snippet:
// find any service items
List<GenericValue> serviceItems = new LinkedList<>();
if (UtilValidate.isNotEmpty(orderItems)) {
for (GenericValue item : orderItems) {
GenericValue product = null;
try {
product = item.getRelatedOne("Product", false);
} catch (GenericEntityException e) {
Debug.logError(e, "ERROR: Unable to get Product from
OrderItem", module);
}
if (product != null) {
// check for service goods
if ("SERVICE".equals(product.get("productTypeId"))) {
serviceItems.add(item);
}
}
}
}
// now process the service items
if (UtilValidate.isNotEmpty(serviceItems)) {
// Make sure there is actually something needing invoicing
because createInvoiceForOrder doesn't check
List<GenericValue> billItems = new LinkedList<>();
for (GenericValue item : serviceItems) {
BigDecimal orderQuantity =
OrderReadHelper.getOrderItemQuantity(item);
BigDecimal invoiceQuantity =
OrderReadHelper.getOrderItemInvoicedQuantity(item);
BigDecimal outstandingQuantity =
orderQuantity.subtract(invoiceQuantity);
if (outstandingQuantity.compareTo(ZERO) > 0) {
billItems.add(item);
}
}
// do something tricky here: run as a different user that can
actually create an invoice, post transaction, etc
Map<String, Object> invoiceResult = null;
try {
GenericValue permUserLogin = ServiceUtil.getUserLogin(dctx,
context, "system");
Map<String, Object> invoiceContext =
UtilMisc.toMap("orderId", orderId, "billItems", billItems, "userLogin",
permUserLogin);
invoiceResult = dispatcher.runSync("createInvoiceForOrder",
invoiceContext);
if (ServiceUtil.isError(invoiceResult)) {
return
ServiceUtil.returnError(ServiceUtil.getErrorMessage(invoiceResult));
}
} catch (GenericServiceException e) {
Debug.logError(e, "ERROR: Unable to invoice service items",
module);
return
ServiceUtil.returnError(UtilProperties.getMessage(resource_error,
"OrderProblemWithInvoiceCreationServiceItems",
locale));
}
If you find it difficult to understand the control flow and learn how to do
application development in Apache OFBiz framework then you can refer to the
following document:
https://cwiki.apache.org/confluence/x/1gsBCw
Above document will help you to understand the following topics from Apache
OFBiz:
- Control Flow
- Form/Screen Widget
- Events
- Services
- Groovy
- FTL
And many more things that we can't learn from a random exploration
Please let me know if you need further help from my side.
--
Kind Regards,
Ashish Vijaywargiya
Vice President of Operations
*HotWax Systems*
*Enterprise open source experts*
http://www.hotwaxsystems.com
On Sat, Oct 1, 2022 at 6:22 PM Emad Radwan <[email protected]> wrote:
> Hello Ashish,
>
> One more thing please on the 'createInvoiceForOrder' service, how
> 'billItems'
> in line 163 are being retrieved and identified?
>
> Regards,
> Emad
>
> On Thu, Sep 1, 2022 at 8:58 AM Ashish Vijaywargiya <
> [email protected]> wrote:
>
> > Hello Emad,
> >
> > Please read the code of the service/method:
> > File: InvoiceServices.java
> >
> >
> https://github.com/apache/ofbiz-framework/blob/trunk/applications/accounting/src/main/java/org/apache/ofbiz/accounting/invoice/InvoiceServices.java
> > Method: createInvoiceForOrder
> >
> > See the line #461
> > createInvoiceItemContext.put("invoiceItemTypeId",
> > getInvoiceItemType(delegator, orderItem.getString("orderItemTypeId"),
> > product == null ? null :
> > product.getString("productTypeId"), invoiceType, "INV_FPROD_ITEM"));
> >
> > Then see the method present inside line # 1941:
> > private static String getInvoiceItemType(Delegator delegator, String
> key1,
> > String key2, String invoiceTypeId, String defaultValue) {
> > }
> >
> > Hopefully it's self explanatory, Please let me know if you need
> > further assistance on this.
> >
> > --
> > Kind Regards,
> > Ashish Vijaywargiya
> > Vice President of Operations
> > *HotWax Systems*
> > *Enterprise open source experts*
> > http://www.hotwaxsystems.com
> >
> >
> >
> > On Wed, Aug 31, 2022 at 5:31 PM Emad Radwan <[email protected]>
> wrote:
> >
> > > Hello Ashis,
> > >
> > > Many thanks for the usual help! One issue please that I don't
> understand
> > in
> > > the data itself, I noticed that for products - finished good - an
> > > invoice_item_type_id is 'INV_FPROD_ITEM' while order_item_type_id is '
> > > PRODUCT_ORDER_ITEM'
> > > but the key for 'INV_FPROD_ITEM' is 'FINISHED_GOOD' however, so how the
> > > mapping is happening? What am I missing here?
> > >
> > > For other mappings like adjustments, mappings looks fine.
> > >
> > > Please shed some light on this.
> > >
> > > Regards,
> > > Emad
> > >
> > > On Wed, Aug 31, 2022 at 6:53 AM Ashish Vijaywargiya <
> > > [email protected]> wrote:
> > >
> > > > Hello Emad,
> > > >
> > > > A very good question. Please refer to the records present inside
> > > > InvoiceItemTypeMap entity:
> > > >
> > > >
> > >
> >
> https://demo-stable.ofbiz.apache.org/webtools/control/FindGeneric?entityName=InvoiceItemTypeMap
> > > >
> > > > Hopefully it's self explanatory.
> > > >
> > > > --
> > > > Kind Regards,
> > > > Ashish Vijaywargiya
> > > > Vice President of Operations
> > > > *HotWax Systems*
> > > > *Enterprise open source experts*
> > > > http://www.hotwaxsystems.com
> > > >
> > > >
> > > >
> > > > On Wed, Aug 31, 2022 at 1:16 AM Emad Radwan <[email protected]>
> > > wrote:
> > > >
> > > > > Hello Community,
> > > > >
> > > > > Let me explain my query with this when I create an order with items
> > and
> > > > > possible adjustments, the auto-created invoice when the order gets
> > > > > completed we get a list of invoice items that is almost a match
> with
> > > both
> > > > > order items plus adjustments. My question what decides the
> > > > > invoice_item_type for each invoice item?
> > > > >
> > > > > I understand that an invoice can be not only for order; e.g. work
> > > effort,
> > > > > but I used order item vs invoice item as an example.
> > > > >
> > > > > Is it mapped somehow and is configurable, or pre-determined and
> > > > hard-coded?
> > > > >
> > > > >
> > > > > Regards,
> > > > > Emad
> > > >
> > >
> >
>