KonaKart Community Forum

Installation / Configuration => Programming of KonaKart => Topic started by: Kim.Zeevaarders on May 26, 2011, 07:36:08 am

Title: Overriding the client-side productmanager (External product catalog)
Post by: Kim.Zeevaarders on May 26, 2011, 07:36:08 am
Hello,

We are going to rebuild the old webshop of a University in the Netherlands with Konakart.

On of the complications is that the products of the University (courses, etc.) are persisted in 2 different legacy databases (Oracle).

Right now we are thinking about the architecture of the solution and are considering two options:

1. The first option is periodically synchronizing these legacy databases with the konakart database usin the xml_io tool or by creating some custom interface using the Konakart API's.
2. Another option is that we only registrate a reference to the products in Konakart (id in products_table), so we can use alle functionality of konakart, but if the content of the product needs to be used we get this data from the legacy database. Our initial thought was to subclass the client-side productmanager and override the relevant methods where necessary.

I saw in the API examples that you can create your own custom product manager and register this new manager in the konakart.properties file. There is only one problem: this concerns the server-side product manager. We need to subclass the client-side product manager because this is returned by the KKAppEng.

My question is therefore as follows:
- Is option 2 a viable one? If not could you please explain where it will go wrong?
- If it is viable, is it possible to subclass the client-side product manager and let the KKAppEng use this? Is it, for example, possible to subclass the KKappEng and let the engine return our custom product manager when the method getKKAppEngine is invoked?

I would like to hear your thoughts about the conceptual idea and, if it's possible, receive some guidelines for doing this.

Many thx in advance,

Kim Zeevaarders







Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: trevor on May 26, 2011, 08:07:05 am
I recommend building a small utility using the KK admin APIs that synchronizes the KK database with the legacy databases at regular intervals or whenever the legacy data changes. In this way you'll have all of the data within KK and will be able to use all of the available product search and sort functionality. i.e. If you use the enterprise version of KK you'll be able to take advantage of the SOLR search engine and the suggested search functionality.
Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: Kim.Zeevaarders on May 26, 2011, 08:21:55 am
Hi Trevor,

First of all, thanks for the quick response.

I know from other posts about external product catalogs that you guys recommend synchronization over customization, so in that aspect I inderstand your answer.

But the problem here is that we don't want to replicate productdata and want the legacy systems to remain master of the data.

So it basically comes down to this: which of the 2 options will be the least complex and will be more future proof? Is my second option even possible?

Could you point out what functionallity we will be missing when we only store a reference to the products in konakart (whereas the content is coming from the legacy systems)? Does this only mean we cannot use the search engine (we are using the enterprise edition) or are there other farstretching limitations?

Don't get me wrong, if u guys say it's better to synchronize we are definitely going to do this. But we would like to make a well-judged decision about this when defending this decision to our customer.

Regards,

Kim





Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: trevor on May 26, 2011, 08:34:18 am
A lot depends on how your store front application works and the user experience you want to give to your customers. i.e. If you want to allow them to search for products, sort them by various attributes, use product tags to categorize them etc. then we need the data within our database in order to be able to query it.

Another problem that often comes up with just storing a reference, is performance, so you have to be careful to store enough descriptive data in the KK database in order to be able to display a list of products, and only look up from the legacy database if a customer asks for more details.

If you were to take the reference approach, I think that a good way of doing it would be to use our custom engine and to customize the getProduct* API calls to fill the product objects with external data before returning them to the client engine .
Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: Kim.Zeevaarders on May 26, 2011, 08:44:50 am
Trevor,

Again thank for the quick response.

I just read the "Customization of the KonaKart Engines" part in the user guide and I think this is exactly what you mean.

I'm going to try to make a proof of concept to see how difficult this is and what limitations arise when using this approach.

My opinion is that we indeed should synchronize, but I will check this option also to come to a well-judged decision...

I will output my results in this topic so that it might be of some use for the community.

Regards,

Kim
Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: trevor on May 26, 2011, 09:22:23 am
Yes, the custom engine is a good way of adding functionality since the API calls tend to be very stable between releases so you should have no problems upgrading.

I look forward to reading about your results.
Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: Kim.Zeevaarders on May 26, 2011, 10:49:33 am
Trevor,

Could you please enlighten me on the following:

Does the productmanager (kkAppEng.getProdMgr()) invoke the kkEngApp methods (like getProduct()) to get his work done? If not, then how to modify the behaviour of the product manager? Say, for example, that I would like to intervene in the fetchNewProductsArray method of the productmanager that is called when you login to Konakart. In that case I would like to fetch the productreferences from the kk database and then add the legacy data to them before storing the products in the newProductsArray of the productmanager.

Is this possible? The reason why I am asking this is that I don't know when the kkEngApp methods will be called. I am now customizing the getProduct method of the custom engine but I have no clue when it will be called. I know that i can call the methode getProducts on the engine directly where I need it but i've got a feeling that is not the idea. Am I Right?

Regards,

Kim
Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: Kim.Zeevaarders on May 26, 2011, 10:54:17 am
I just found out one minute after posting this thread that there is a difference between the kkEng and the kkAppEng. So my assumption is that the kkAppEng delegates call to the kkEng. Is this right?

If not could you please tell me how the differenct engines work together?

Thx,

Kim
Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: Kim.Zeevaarders on May 26, 2011, 10:57:45 am
Trevor,

Sorry for the multiple posts i've posted. It seems you cannot edit a post.

I found out that you can get the kkEng by calling kkAppEng.getEng() so please ignore my previous post.

Next time I will take a deeper look before posting stupid questions :)

Thx,

Kim

Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: trevor on May 26, 2011, 10:59:46 am
Take a look at http://www.konakart.com/product/technical-details .

The AppEng does invoke the Eng to get his work done. You will be customizing the Eng API calls. As long as the API calls keep on returning ProductIf objects the AppEng will continue working as is.  You customization code should just fill in the attributes of the Product objects from your external sources. You should customize all API calls that return Products.

Not everyone uses the AppEng since it is quite specific to a certain type of eCommerce application. For example, many customers that integrate KK into CMS applications, make calls directly to the engine.
Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: Kim.Zeevaarders on May 26, 2011, 12:40:11 pm
Trevor,

It makes total sense now.

The kkAppEng delegates to the kkEng. This also means that the Productmanager uses the kkEng.

So modifying the kkEng changes the behaviour of the kkAppEng, including the behaviour of the different managers (basketmanager, productmanager, etc)

I'll come back to you on this as soon as I get my proof of concept up and running.


Thx for taking the time to reply,

Kim
Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: Kim.Zeevaarders on May 27, 2011, 10:02:18 am
Trevor,

I've started with overriding some of the methods in the kkCustomEng. Furthermor I've added a System.out.println(<methodname>) statement in all methods of the kkCustomEng class to see which methods are called during execution.

In my simple testcase I have a product stored in Konakart with only the not-null fields filled. My intention is to get all content for this product from another system.

So I overrode the getProduct and getProductWithOptions using the customEngine Framework. In these methods I simply add (hardcoded) information to the otherwise nearly empty product in the kk database.

When I press AddToCart (on this product) on the mainpage and start debugging I indeed see that a call to kkAppEng.getProductMgr().fetchSelectedProduct(new Integer(prodId).intValue()) is delegated to the getProductWithOptions method of the custom engine (this happends in the action AddToCartFromProdIdAction). The product is then retrieved with kkAppEng.getProductMgr().getSelectedProduct() and does indeed contain the added properties I programmed in getProductWithSelectedOptions.

However now comes the problem that I was already expecting. Further in the code the selectedProduct is added to a BasketIf object and added to the customerbasket (kkAppEng.getBasketMgr().addToBasket(b, /* refresh */false)). Only the id and quantity (1) of the product are set as a property of the basket object.

In the following action, ShowCartItemsAction, the basketitems are again updated and retrieved for showing on the page:

BasketIf[] items = kkAppEng.getEng().updateBasketWithStockInfoWithOptions(
                        kkAppEng.getCustomerMgr().getCurrentCustomer().getBasketItems(),
                        kkAppEng.getBasketMgr().getAddToBasketOptions());


However, the product seems to be reloaded from the database and has lost all of the added properties I added in getSelectedProductWithOptions. Looking back at the creation of the basket and the adding by the basketMgr I tried to do two things to prohibite this:
- I set not only the productId of the basketIf object, but also the entire product object (b.setProduct(selectedProd))
- I set the property true to false when calling the basketMgr.addToBasket(b, false) in the hope there wil no reload.

Both options do not work and the product is always reloaded from the database.

So the only thing I can do now is desig a custom BaksetMgr so that I can override the relevant methods like kkAppEng.getEng().updateBasketWithStockInfoWithOptions and  kkAppEng.getCustomerMgr().getCurrentCustomer().getBasketItems(). This is not difficult since both methods return an array of BasketIf objects which contain the products I need to fill with legcy data.

My question however is if you guys could tell me if this is the way to go when customizing the engine and if i'm on the right way using this approach. If not could you guys give me some of your insights on this matter and some of the best practices that should be followed? Perhaps a sort of strategy to follow?

Thx in advance,

Kim
Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: trevor on May 27, 2011, 10:13:24 am
Where are you seeing the reloaded product without the properties ? Maybe you haven't specialized the API call that was used to fetch it ? There are quite a few API calls that return products.
Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: Kim.Zeevaarders on May 27, 2011, 10:25:11 am
Trevor,

You're right. The method updateBasketWithStockInfoWithOptions is called on the engine and thus overridable by me. I thought it was a method of the basketMgr.

Is it true that if I customize ALL relevant productmethods of the engine that I don't have to create custom managers (because they rely on the engine methods)? For example will the call to  kkAppEng.getCustomerMgr().getCurrentCustomer().getBasketItems() return the legacy filled products I coded in the custom engine methods (on the condition I overrode all relevant product methods)?

Thx for the help.

Regards,

Kim





Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: trevor on May 27, 2011, 10:57:52 am
The managers do call each other. i.e. Various managers call the ProductManager to get product information so there may be some cases where you'll need to go to the ProductManager.

It's rather difficult to list all dependencies of all of the API calls so I suppose the safest bet could be to customize at the ProductManager level although we don't guarantee that these internal methods won't change between releases so there may be a bit more work to do when upgrading.
Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: Kim.Zeevaarders on May 27, 2011, 12:31:45 pm
Trevor,

I modified the engine so far that I can see the product (filled with legacy data) in the main page, add it to the cart (button AddToCart) and see it in the showcartitem page.

To realise this I needed to override 4 engine methods (following from first to last):
- GetProductsPerCategoryWithOptions
- GetProductWithOptions
- UpdateBasketWithStockInfoWithOptions
- CreateOrderWithOptions

It seems that the different managers indeed call these engine methods under water. Now I'm going to try to view the details of the product in the productdetails page and try to complete the order as far as possible (checkout). If this succeeeds i've got a (very limited) proof of concept that it can be done.

From what i've seen it's a trial and error method since there is no clear call hierarchy overview. Luckily I added the println statements in every customengine method so I can exactly see which methods are called over time and especially which methods are called by managers.

Regards,

Kim

Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: Kim.Zeevaarders on June 08, 2011, 02:22:09 pm
Trevor,

The customization of the engine is reasonbly working. I now only have a reference to a product in the kk db (id) and I enrich the product with external retrieved data. So that's exactly what we want :)

The problem I now face is that I want to modify the behaviour of the client-side productmanager.

for example, when the store front is started, in the left pane there is a "random new product" visible.

When you take a look in the jsp (RandomNewProductTile.jsp) it shows that the info for this product comes from the randomNewProp property of the al-productmgr:

<bean:define id="newProd" name="prodMgr" property="randomNewProd" type="com.konakart.appif.ProductIf"/>

The problem is that it shows kk-db values for the product (price=0.0, etc.) So the product in this property is not enriched with external data through my customized engine. I know for sure that I overrode all relevant methods in the engine since I added System.out.println statements to each and everyone of them and then debugged the code when loading the store front (CatalogMainPageAction). So I know exactly what is called when the Mainpage is loaded.

So, following our conversation and the info in the user guide of Konakart, I tried to implement my own bl-Productmanager and overrode all productmethods in this manager. My expectation was that the al-productmanager would delegate calls like getRandomNewProd()  to the bl-productmanager. But the methods of my custom manager are never called!

So my question is as follows:
- How does it come that the al-productmanager doesnt call the bl-productmanager?
- Is there a way to override the al-productmanager or to acces the properties of this manager like the randomNewProd property?

Could you please help me out on this because the go or no-go with Konakart depends on this.

Regards,

Kim


Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: trevor on June 08, 2011, 03:07:44 pm
Have you overriden getAllProductsWithOptions() ?
Title: Re: Overriding the client-side productmanager (External product catalog)
Post by: Kim.Zeevaarders on June 08, 2011, 03:25:39 pm
Trevor,

You're right. I missed this method because it is called when the Konakart store front is intializing/started on the Tomcat server. So I missed this procedure when debugging the code that is invoked when navigating to the main page of Konakart.

Thx for the help. I am glad that it was this because it shows that customizing the engine changes the behaviour of the various managers and it is very important for us to know this works properly.

Thx again!

Regards,

Kim