Understanding how an extension is wired up in SAP Commerce - sap-commerce-cloud

I am working on the SAP Commerce (formally known as Hybris) ecommerice system.
The Warehousing extension is being added to a B2B site. Upon adding it, On the Stock Level item the Invoice Event collection is visable on the admin tab. An ATP Formula has been set on the Base Store. The stock is now displayed on the PDP. In an OTB site I have seen an OTB instance adjust the stock levels accordingly upon completing an order, but that is not happening on the local dev instance. The question is why?
Is the impression correct that some facade within the warehousing extension is called during the order-processing process? If so, how exactly is that wired up? There doesn't seem to be any relationship to the warehousing extension and any other code.
UPDATE 1:
Here is an example of the question: After adding a new product populator to the custom facade, a few entries are added to the *-spring.xml file, one of them being adding the populator to the configurablePopulatorModification. Finally the option needs to be added to the ProductOptions list in the controller. Then the populator is called when that controller is called.
In this example the connection between the controller and the popular is clear, once it is understood how things are wired up. There is a connection to the ProductOptions in the custom core extension, custom facade extension, and custom accelerator. Once someone knows how this is "wired up" it can be easily duplicated.
What I am trying to understand is this: The warehousing extension has been added to the localextensions.xml, but there is NO reference to any aspect of that anywhere else in the system, AT ALL. Somehow some extension between the storefront accelerator and the platform code has to know about the new functionality found in the warehousing extension so that it is called. How?????
UPDATE 2:
After adding the warehousing extension, there are new attributes added to existing itemTypes that show up in Backoffice. It is my understanding that this is the concept which Modifying Lists and Maps in Spring Context explains.
The issue I am having problems understanding is how the business logic within the warehousing extension is being called to modify the stock levels. My best guess is that the function doing the change is WarehousingStockLevelFacade.createStockLevelAdjustements(...). I have searched high and low for where createStockLevelAdjustements(...) is called and it is ONLY called in the warehousingwebservices.
I am at a total loss on how exactly any of the facades wihtin warehousingfacades or warehousingwebservices is being called by

Hmmm, your text contains more than one question I think. So I try to answer each part of them separately.
In an OTB site I have seen an OTB instance adjust the stock levels accordingly upon completing an order, but that is not happening on the local dev instance
There should be no difference on the systems. You should always look, that you have the same configuration on each system. Normally the 'config' folder here is the part where you define the configuration. From system to system there can be small difference. But for example, the 'localextensions.xml' shold always be the same.
Is the impression correct that some facade within the warehousing extension is called during the order-processing process?
No. You define your extensions in the 'localextensions.xml' and than the new parts are on any system. Have you done an 'UPDATE' on each system, so that the new types are also imported in the type system and the database?
So overall. You define your extensions. And than hybris includes all needed extensions automatically. You can see this, when you start the server, which extensions are loaded.
UPDATE 1
I think, now I got your point. I try to stay in common and not to specify on the 'warehouse' extension. Hybris has some funtionalities how to modify code 'afterwards'. Here are some useful links
Modifying Spring beans afterwards
Extension Dependency
Also have a look left in the navigation about the 'Extnsion Concept'. Maybe some points will than be clear.
So in your example, think what happens is: first new attributes in the *-items.xml, than there will be a 'modifiyPopulatorList' bean somewhere.
UPDATE 2
I don't know the 'warehousing' extension. But I think there must be a part that overwrites the 'normal' beans with the 'warehousing' beans. Something like:
<bean id="stockLevelBean" ...>
<property name="normalProvider" ref="normalProvider"/>
</bean>
<bean id="stockLevelBean" ...>
<property name="warehousingProvider" ref="warehousingProvider"/>
</bean>

Related

How can I make Content Items without a CommonPart appear in the content list?

I created a custom Type that has a UserPart attached to it.
According to this issue on GitHub you can't add a CommonPart to content that also has a UserPart because it causes a StackOverflowException but I would still like items of my custom Type to show up in the content list. I already store CreatedUtc and PublishedUtc in the custom PartRecord, can I manually plug these in somewhere?
EDIT: For clarification, my specific scenario is that I am building a public facing Orchard website based on existing data that was used in a private application up to this point. I have a legacy table with user accounts that need to be mapped to Orchard Users but they also represent travel agencies that visitors should be able to browse and that Orchard admins should easily be able to edit and create through the Dashboard. I got the idea to create a TravelAgency type with a UserPart from Sipke's webshop tutorial
Content Types do not require to have a CommonPart to show in the Content List. If i remember properly its done by triggering the Creatable() in your migrations.
Also if you have a UserPart, you could Lazy loaded or just reference it via Foreign Key.
Why would you like something like that to be part of the Content List? I usually keep my business-specific Content Types tucked away in a nice section, so there are easier to visualise and use for users.
There is definitely a bug but as they comment you could extend taxonomies to accomplish your task and keep in mind sometimes changing the Orchard Codebase might fit your purposes, you only have to keep track of your changes when you upgrade next time. I have done it a couple of occasions to fit my projects.
If i remember properly, its been a while.. If you look in the core code where the Content List is created it looks for Creatable() Types. digging even more inside the code, chances are the Query in charge will join the CommonPart, hence your problem. You could easily add another query in the controller and add whatever you are after. The problem though, will be refactoring the rest of actions to accommodate your your type too. Way easier isolating your new Type. had to look at it for you, check this baby: Orchard.Core.Contents.Controllers.AdminController

Should Change Tracking Proxies work if I use a Database First model?

Should Change Tracking Proxies work if I use a Database First model?
After creating the model with the database first designer, though navigational properties are marked virtual, other properties are not.
If I edit the classes so that the properties are virtual (and of course public, not sealed, use ICollection where needed and remove initializing of navigators from the classes constructor), this will get overwritten if I ever update the model from the database while within the designer.
And, if I make all (what I believe are) the necessary changes to allow for Change Tracking Proxies, when I test with "x is IEntityWithChangeTracker" it still returns false.
So, either I'm really doing something wrong or I'm doing something that wasn't meant to be. I hope it's the former.
EF6.x uses System.Data.Entity.Core.Objects.DataClasses for its IEntityWithChangeTracker. If you use this version of IEntityWithChangeTracker, it will work. Using System.Data.Objects.DataClasses.IEntityWithChangeTracker was my problem here.

Adding new section in control panel of Liferay

I want to add a new section in control panel of liferay and within that section I want to have my custom-portlet. I did it using ext. However I want to do it with hook . Is it possible ?
I don't think it would be that easy with a hook, because of the following reasons:
You can't modify in a Hook - the class com.liferay.portal.util.PortletCategoryKeys which contains the keys for displaying the different sections. The different sections are hard-coded in this class in a String array ALL.
You can't modify the logic of PortalImpl#isControlPanelPortlet() which uses the PortletCategoryKeys#ALL to determine if the request in question is for a control panel portlet.
Then you also have another method which you can't modify with a Hook and is used extensively PortalImpl#getControlPanelCategory()
Doing it with a hook:
I have not tried this but I think if you need to do it with a hook you would have to change all those JSPs which make use of PortletCategoryKeys#ALL and the methods of PortalImpl as stated above, and provide your custom implementation for all these methods in the JSP.
I would really like to know how you implemented it with an EXT may be just the steps or the methods you have overridden. So that I can try to convert those in terms of a hook.
This is as far as my understanding goes. Hope this helps.
With the advent of Marketplace, ControlPanel has a new category named "Marketplace" and that section is introduced in a plugin. However, I never checked if 6.1 GA2 introduced a new section that this plugin just fills. Check the marketplace plugin if you can find a trace of this section implemented there.
On the other hand, nobody has yet named any section that definitely required a new section (though some have asked me how to solve the same problem). For this reason, you might want to re-think the requirement and choose one of the existing sections. If you don't, at least I'd be interested in the name and purpose of the new section - I might find a first one actually justifying this kind of implementation...

Best Practices for Content Types in SharePoint

Recently, we came across a severe problem in production farm with the Content Types. I would like to explain the background of this problem first.
We have nice working feature for Content Types installation in production and test farms. We developed and deployed (using wsps) this SharePoint feature in Visual studio. We are using the publishing pages using page layouts and Content Types to help content editors to quickly publish the web pages. Unfortunately, some Content Types and site columns have been manually updated/added by some people in the production, so whenever I (developer) make some changes to the existing Content Types (using Visual Studio and feature activation/deactivation) , SharePoint removes one or two columns (during feature activation/deactivation) from Content Types; or the columns which have not been added in a best practice way. I think the best practice is to update Content Types using Visual Studio.
Now, I wish to ensure that site columns shouldn't get removed from Content Types upon feature activation/deactivation.
Note: Our feature for Content Type activation/deactivation doesn't hold any activation dependencies in the feature.xml
Recommended Approach
Based on all these factors, my suggestion would be to:
• Create two Features: one for the original markup and one for making changes. (Or you can put them in the same Feature; I just want to differentiate between where you do what.)
• The original Feature should contain the CAML for Site Columns and Content Types. This ensures the IDs have been assigned ahead of type and remain constant.
• If you want to update a Site Column by changing nearly anything about it except its Field type, do it using a Feature Receiver. By doing this, you can call the Update method and pass in a boolean indicating if you want all the existing assets in the site that inherit from this to update to, (something you couldn't do via the CAML.)
• You can also add an existing Site Column (that you provisioned via the CAML feature) to an existing Content Type (that was provisioned via the CAML feature). This is helpful if the Column was not part of that Content Type before, etc.
• In a scenario like the one I just mentioned in the last bullet point, it's necessary to deactivate and reactive the CAML feature (to provision the new assets) before calling your Feature Receiver. What will this mean for the site? Since all the Site Columns and Content Types in the lists in the site are using the same ID's as the ones provisioned in the Site Collection root, removing its parent from the Site Collection won't change that. It might leave it orphaned temporarily, (i.e. there will be no relationship between that item and an item in the Site Collection root, but it will function the same way it always has, since it's really a fully-functioning copy of the original item) until you reactivate the Feature that puts the item back in the Site Collection. It's like the parents are going on vacation when you deactivate the Feature, and are coming back home when you activate the Feature again.
You have a choice when it comes to how you maintain the CAML and the Feature Receiver, since you have two scenarios: existing Site Collections and new ones.
• You could make a policy that every time you write code in your Feature Receiver to update a Site Column or Content Type, you have to make the change in your CAML as well. That would mean that every time you activated the CAML Feature in a "fresh" Site Collection, the CAML would be up-to-date and accurate; there would be no need to run the "updater" feature. (In your Feature Receiver, you should make sure you do some extra checking to make sure a Site Column doesn't already belong to a Content Type before adding it, etc. in case that change is already in place before the code executes.) This approach means you only have to execute one Feature when creating a new Site Collection, but it also means you're maintaining changes in two places: in your Feature Receiver for making changes to existing sites, and in your CAML for new sites. It's a cleaner approach, but also contains an element of redundancy, which always leaves room for human error.
• The other approach is to simply assume that every time the base CAML feature is activated, you're always going to execute the Feature Receiver. This approach says the only time you'd change the CAML is to add a new Site Column or new Content Type; otherwise, all the changes happen in the Feature Receiver. This approach reduces redundancy, but also means your Feature Receiver code could get quite large with all your changes over time, and it could leave your CAML as very much "legacy" over time.
Src: http://blog.beckybertram.com/Lists/Posts/Post.aspx?List=eb3e1762%2Dbab0%2D4e96%2D8bc5%2Dd67d6e6bfd44&ID=18
Updating Content Types is still one of the underdeveloped portions of Sharepoint which sometimes causes trouble, especially in Content Deployment scenarios.
The best thing in your case would be to always avoid making any changes to content types by hand (using UI)
Whenever you are installing the content type, make sure that you remove the previous one and then install the new one. (Sometimes its not possible due to pages being already created out of it).
My current approach to deploying content types is to do as much as possible using code rather than CAML. That way it is easy to fully control the logic of updates, including ensuring that changes made manually don't cause conflicts. I have the structure defined as attributes on an interface I also use for strongly typed list access, but there are several other ways you could do it.
The only piece that isn't available in the API is setting a specific content type ID, so you need to have a caml file for that, but it's a small/simple file, doesn't try to make updates and is only referenced from a feature that will also run the update code.

Determine the property name in a SharePoint Webpart for XML

I'm employing a custom webpart that is made by an unaffiliated third party. I've created a feature which adds this webpart to a page. It's working mostly fine, except that I can't figure out the name of a specific property that needs to be defined. I tried obvious ones that match the display name on the tool pane view, adding the company's name in front of said display name, and many similar permutations. All of which to no avail. I would much prefer to include the property to the feature, as this will be necessary to deploy across multiple sites in the future. Manually configuring it every time will be a pain for my client.
The short, obvious answer is "Ask the third party". This can potentially work, particularly for this specific one (it is a CodePlex webpart and the author has posted a comment as recent as last week). But my experience with previous third party solutions has been less than optimal, usually even getting no response until they ask me three weeks later if I still like their product. So, since this is not always a reliable method to obtain this information, I was thinking the best option is to find out a way to figure out the name of properties in a webpart that I can use not just with this particular one, but in all future situations.
I did check out this earlier question which addresses a similar topic. However, I don't have access to the class for the webpart so I can't just find a convenient property in the code to modify. Or, at least, if I do have access to it in some fashion, I'm certainly unaware of it.
Thank you in advance!
From what I understand, you are trying to set a certain webpart property for which you do not know the corresponding XML attribute name.
Did you try to export the web part? One possible check might be to try to export the webpart to see what properties come up in the webpart XML. If it is a common property, chances are the webpart XML will have that property already defined with no value e.g.
<data>
<properties>
<property name="Your property Name" type="yourType"></property>
<properties>
</data>
To export the webpart, go to Edit Page mode, click the down arrow on the webpart and choose Export.
Also, if you have the webpart code in a dll, can you use reflector to open it and see what properties are being set in code?
Hope this helps.

Resources