Using Buildfire Navgation's navigateTo to plugins that require user purchase - buildfire

I have been using Buildfire's internal navigation.navigateTo method and recently noticed it's not working for plugins that require a customer to have purchased the feature.
It opens the plugin but the query string is not getting processed. Console logging the window.location.search value from the plugin that is navigated TO shows that the query string passed in the navigateTo method is not carrying over to the opened plugin, resulting in the plugin simply opening to its main page, whereas the purpose of what I'm attempting to do is to drill down to a specific item within the plugin and display that.
When navigating to a plugin that does not require purchase, the function works as desired, and the window.location.search value does include the query string I passed from the previous plugin. For context, this is how the method is formatted. I've verified that the variables are all correct by logging them from the function that fires this navigation method.
buildfire.navigation.navigateTo({
pluginId: pluginId,
instanceId: recipe.instanceId,
queryString: `recipeId=${recipe.recipeId}`,
});
This was working previously within my plugin, and I have not changed anything related to its navigation.
Is there something I'm missing in regards to paid plugins that might interfere with the location.search parameter?

Related

Reading a NetSuite Item Fulfillment's shipcarrier field using suitescript 2.x

I have a script which loads an item fulfillment record and from there I am trying to read the "shipcarrier" field. This is a field that is shown on the IF page and if I put the &xml=t in the browser URL I can also see the value (such as Fed Ex or whatever). The issue is, I am struggling with how to get that with the script I am writing. I have noticed it does not appear to be in the schema browser but given that the UI shows it (and the help text shows 'shipcarrier'. I would think there is some kind of way to read it even if it is not as simple as using getText() on the fulfillment record. I have also seen some mention on other posts about it being set but again I don't seem to be able to read it and also .getFields() does not give it back either.
You can get that value using the search module and the lookupfields method.
var fieldLookUp = search.lookupFields({
type: search.Type.ITEM_FULFILLMENT,
id: param_itemful_id,
columns: ['shipcarrier']
});

Office document settings

I am currently storing a key value pair in Office.context.documents.settings using the following function:
Office.context.document.settings.set(name, value);
Once the key-value pair is stored , I am relaunching the add-in and trying to fetch the value using the following function -
Office.context.document.settings.get(name);
But the function is returning null instead of the proper value. Does the value stored in document settings persist across multiple sessions of an application or does it get refreshed once we close the application?
Your question doesn't have a lot of detail but there are two common errors when working with settings:
Failure to Load Settings
Prior to reading a given setting, you need to populate the settings object. This is done using refreshAsync():
Office.context.document.settings.refreshAsync(function(){
Office.context.document.settings.get(name);
});
Side-loaded Add-ins
When you side-load an add-in, Office generates a random ID and assigns it to your add-in. If you remove and re-side-load the add-in, it will generate a new ID. You'll also get two distinct IDs if you side-load the same add-on on two different machines.
This will affect how settings function since settings are keyed by the Add-in ID when they are stored or recalled from a document. For details on how this works (and how to get around it), see Issue with Office.context.document.settings.get.
The setting isn't being saved because you did not call saveAsync. The set method only saves the setting in memory, not to the file. To save to the file you must first call set, then call:
Office.context.document.settings.saveAsync(callback);
Then when you reload the add-in you will be able to retrieve the settings with get. Here's the documentation page for the saveAsync method: https://dev.office.com/reference/add-ins/shared/settings.saveasync
-Michael, PM for add-ins

'Migrate Routes' fail when upgrading from Orchard 1.3.9 to Orchard 1.7

I'm in the process of upgrading an Orchard site from 1.3.9 to 1.7.
I'm using the Upgrade module, and when attempting to upgrade Routes (last tab) the code fails, at the point where it attempts to access a newly created AutoroutePart.
Specifically, inside RouteController.IndexPOST() :
// migrating parts
_contentDefinitionManager.AlterTypeDefinition(contentType,
builder => builder
.WithPart("AutoroutePart")
.WithPart("TitlePart"));
// force the first object to be reloaded in order to get a valid AutoroutePart
_orchardServices.ContentManager.Clear();
This code snippet is supposed to assign an AutoroutePart and a TitlePart to the type at hand (let's say it's a Page but obviously any other type in the checkbox list of the Routes tab). But it fails to do so. Because later on the assignment
var autoroutePart = ((ContentItem)content).As<AutoroutePart>();
fails and autoroutePart is null, and then further down the code fails with an Object reference not set... error when it attempts to access autoroutePart.ContentItem.Id.
Eventually I was able to bypass it by manually entering a record in table Settings_ContentTypePartDefinitionRecord that maps a Page (ContentType ID 2) to Autoroute and Title part IDs but that seems awkward and error-prone, and I must have missed something (not to mention having to apply this hack to the rest of the content types).
What can cause AlterTypeDefinition to not apply these records in the database?
I was able to get this to work by using the new transaction system.
The idea is that ITransactionManager.RequireNew() is called before and after each piece of code that needs to be committed to the database. A few of the calls in my code example are redundant but I figure this code is only going to be used once so rather than try to optimize unneeded calls away, I would leave them in to indicate where transactions start and end.
Providing a diff as a gist.
https://gist.github.com/harmony7/10621982

What does the filtering attributes on the CRM 2011 plugin registration tool do?

I assumed that for an Update plugin, it specified a list of attributes, that if are changed, cause the plugin to fire.
So if I register a plugin against Foo, with only one filtering attribute specified against Bar, every time a Foo entity is updated, CRM performs a check to see if Bar has been updated, if it has, it runs my plugin. So with the code below, I would expect my plugin to execute once.
Foo foo = new Foo();
foo.Bar = 0;
foo.Id = service.Create(foo);
foo.Bar = 1;
service.Update(foo.Bar); // My plugin would execute
service.Update(foo.Bar); // Bar hasn't changed, I would assume the plugin will not execute
Am I right in this assumption?
While your initial analysis is loosely correct (i.e. filtering attributes cause the plugin to fire only if one or more filtering attributes have changed) this is not fully accurate.
When an entity is changed, e.g. the email address on a contact, the platform (and therefore your plugin) only receives the delta. In my example there would be an Entity in the Target InputParameter which only contains a single attribute (email). This is the case even if the contact record contains much more data - only that which is changed is sent to the platform. (as an aside, this is where Pre and Post entity Images come in as they allow you to access values on the entity that weren't changed, without having to issue a Retrieve).
So with this in mind it is instead correct to say that filtering attributes mean that the plugin will only fire if one or more of the filtering attributes are present in the request. The CRM ui doesn't usually send a value unless it has changed (forcesubmit overrides this behaviour). In your example Daryl the plugin will fire twice as the filtering attribute is present in both requests.
This is to narrow down the execution of the plugin.
The plugin fires only if one or more of the registered attributes changed.

Deleting a record in javascript

I need to delete some records related to the current record when it is deactivated. I can get the the event when the record is deactivated but I have looked around for some time on Google and this site for the code to delete records in javascript but I can't find any, though I know there must be some out there.
Can anyone help?
Thanks
I would be alright with doing this with a plugin, all I would need to know is how to pick up that the record has been deactivated
You can register a plugin on the SetState and SetStateDynamic messages (recommend the Pre event in your scenario). Each of these messages will pass an EntityMoniker in the InputParameters property bag which refers to the record that is being deactivated.
In your code you will need to:
Check that the new state in the SetState request is deactivated (since of course a record can usually be reactivated and you don't want to try deleting things then too, presumably)
Pick up the EntityMoniker from IPluginExecutionContext.InputParameters
Run your query to identify and delete related records
Exit the plugin to allow the SetState transaction to complete
If you really want to delete a record with JavaScript there is a sample on the MSDN.
Its a little long winded (its a CRUD example - create, retrieve, update & delete). But it should contain the information you need.
Note there is also an example on that page which doesnt use jQuery (if using jQuery is a problem).
That said I think for this operation would will find it easier to implement, test and maintain with a plugin (so I would go for Greg's answer).
Additionally a plugin will apply in all contexts, e.g. if you deactivate the record in a workflow your JavaScript will not run, but a plugin will.

Resources