NetSuite: Calling an API in real time as field values get updated - netsuite

I'm looking for a way (using SuiteScript 2.0) to handle real-time persistent (stored) field updates, where a field might have changed in NetSuite (for example a lead time was just updated), and it doesn't matter if a user saved the change, or some other automated process changed that field. I just want to be able to pick up on that change:
The moment that it's done, and
Without regard for who or what kicked it off (e.g. it could be a person, but it could also be an automated change from a workflow, or a formula on the field itself which pulls values from another field)
Doing some research I found some options that looked somewhat promising at first. One being the afterSubmit event in a client script, and the other being the fieldChanged event. My issue however is, from what I understood those only really seem to be triggered by a user manually going in and making those changes, but this is only one part of the puzzle and doesn't seem to cover changes made outside of the scope of the user making those changes. Is that correct however? Or would one of those events still be able to capture changes done to that field regardless of who (or what) initiated or triggered the change, and right at the moment the change was saved/ persisted to the database?

UserEvents are basically triggers. In their deployment records you can set the context in which they fire so you can get them to fire in all circumstances (called contexts in Netsuite) but one.
That circumstance is User Events are not fired for record saves made in User Event scripts. i.e., if an AfterSubmit UserEvent script loads, changes and saves your record a fresh user event will not be fired.

Related

Updating data on rows deleted event

I have a custom page with a form and a grid. When a row from a grid is deleted, I want to update some other rows. I am therefore handling the rowdeleted event. I confirmed (through debugging) that the event is firing correctly and that the data is being updated correctly.
The only issue I have is that the screen still shows the old values. My delete row correctly disappears but the other rows do not get updated.
For each row that I change, I am calling the Update method of the Data View. However, this still does not refresh the user interface.
Interesting, if I save, all my changes get correctly updated to the database. Which confirms that this is a UI isssue.
Is there any additional step that I need to perform to refresh the user interface? Or should I just avoid doing updates in Row Deleted event?
To guarantee constant optimal performance level, in the end of a roundtrip grids in Acumatica only update currently selected record. This behavior is by default. In case you insert/update/delete other records in the same grid within an event handler or an action delegate, it's always necessary to call View.RequestRefresh() to force the grid to update its entire content instead of only the selected record.
I managed to solve the issue by calling View.RequestRefresh(). However, I am not sure whether this is a standard practice. But I did find it used in several places in the Acumatica code

How can I trigger a NetSuite workflow on a Form Event (Client side event)

I want to trigger a NetSuite workflow when the user sets the value of a field, but I don't want to have them submit first. The Workflow state builder looks like it has useful options but I can't get it to work.
There's some useful looking blog posts around but a lot of them seem out of date.
Update - more info
My primary issue is this one: Restrict what customers an employee can see (NetSuite)
The hack I'm currently looking at is populating a custom Transaction Column Field that I've added to a custom Time Recording form. The idea is to load this field on the UI with only valid projects (not customers as well), and this I have been able to do.
The problem is I still (as far as I can tell) still need to populate the "Customer" field, which is mandatory; I'm also assuming that if I don't do that then any time that is recorded won't go against the project. I had thought that if the user selects the project they want then I can populate the customer field with that value. I hate this as an approach but I can't see how else to do it. I do have coding experience (including JavaScript) but haven't made the leap into SuiteScript yet.
You won't be able to do this in a Workflow, as they are currently limited to only work with body level fields and cannot modify Transaction Column Fields (aka sublists).
You should be able to achieve this with a Client Side Script though.
Source (Netsuite login required).
Sublist changes will be available for transactions in the 2018.1 release sometime in Feb/Mar.

In PyQt, I need to handle both itemClicked and itemSelectionChanged, but not both at the same time

I've created a QTreeWidget that displays data that's pulled from 3rd party API calls.
I want the data to be fresh when the user either clicks on or uses the arrow keys to navigate to any QTreeWidgetItem. This means making an API call each time the user clicks or uses an arrow key. Importantly: If the user clicks on the same item a second time, I would like the item to display fresh data (in other words, make another API call and populate with new data, aka refresh)
So far, I've tried:
connecting both itemSelectionChanged and itemClicked to the same update function. This works, but it means that for every click on a new QTreeWidgetItem, I get two calls to the update function (one from itemClicked and the other from itemSelectionChanged), and therefore two API calls that do the exact same thing. Not ideal.
Only handling itemClicked, but then using an event filter to look for Key_Up or Key_Down and then manually emitting an itemClicked. The problem with this is that the key event is handled before the selection is changed, so when using the arrow keys, I'm always getting data for the last QTreeWidgetItem selected, not the current QTreeWidgetItem.
I thought about creating a very short timer or a flag and starting/setting at the start of the update function. If the timer is running or the flag is set, don't run the function (the idea being that the first slot would run, but the second would not because the flag is set/timer is running), but that seems both sloppy and prone to race conditions.
Unfortunately, using a QTreeView with a QAbstractItemModel is not an option.
With that, is there any way to handle both a repeated click on the same item and arrow keys to select new items without double-calling the same update function?
As #ekhumoro pointed out, this can be done by handling both itemClicked and itemSelectionChanged, but introducing some logic so that both functions don't run at the same time.
When a user clicks on the widget, an itemClicked signal is fired. When the user changes selection, the itemSelectionChanged signal is fired. In my case, then, I've created two slots (functions): update (a slot for itemSelectionChanged) and updateFromClick (a slot for itemClicked). updateFromClick checks to see if the selection has changed (this means you always have to store and keep track of the current selection). If, in updateFromClick, I see that the selection has changed, then I do nothing, as update will have been called from itemSelectionChanged. If, in updateFromClick, I see that the selection has not changed, I know that itemSelectionChanged has not been fired, so I call the update function explicitly from updateFromClick.
Again, this is just a long-winded version of #ekhumoro's comment that I'm putting here so the question doesn't go unanswered.

Breaking down 1 calendar event into smaller events in SharePoint

I'm trying to create some sort of reservation system in SharePoint using a calendar list. It's been recommend to me to create events and add a column which allows a user to claim it. From there, claimed events would change color and only those who've claimed the event would have permission to unclaim the event.
This is what it would look like (see alternative option):
What I'd like to be able to do though, is instead of having to create three events like shown in the alternative option, creating 1 event (see original) and have that be broken down into 3 events or more, maybe using some form of drop down asking for intervals (ie. 15m, 30m, 1h). Based on the selected interval, it'd break the event accordingly.
A possible solution is in your main event you add another field named Interval.
The you design a workflow when you create the event that creates new events according to the interval specified using a while loop while incrementing the start time with your interval.
Those new events have a content type with a field named UserClaimed. you then associate another workflow to those new events that checks for that field and changes permissions on the event to only allow modifications of that event to the user specified.
This is the general idea, the implementation should not be that hard
just a thought -
I mean, the reason i think you want the events to pre-exist is so that users can easily create them in the correct time slot (rather than clicking the new item menu, which throws them away from the calendar view/context). Is that right?
If so, allow me to offer you this scenario:
If you are using KWizCom's Calendar Plus web part (yeah, I work for KWizCom...) it allows you to type in the event in the calendar itself directly.
Something simple like: "1pm-2:30pm Training meeting with Josh"
check the demo video here: http://www.kwizcom.com/sharepoint-add-ons/sharepoint-calendar-plus-web-part/overview/
Also, drag and drop events in the calendar to move them easily, and it also supports color coding events based on categories (meta data, views, sources, etc.).
The one thing you will need to develop is the unique meeting logic, and owner permissions.
meaning, an event handler that does not accept 2 meetings at the same time for the same room (define the unique resource field, if any), and the logic that allows only the person who created an event to edit or delete it.
ping me, I can help with the event handler - perhaps we can add this to our product, this is actually a cool idea. my work mail is shai at kwizcom dot com

Adding logging in Lotus Notes form

I want to add logging capabilities in my Lotus Notes application. Basically I want to be able to log who make the change, when the change is made, and what field(s) is/are changed in a document. What is the best way to do this? I am thinking to also add this at the end of each document so the user knows who make the changes.
OpenNTF has several tools for this purpose that you could use, including Open Audit and Audit Manager.
I've done this before using LotusScript. It's a bit of a pain, but the basic idea is to:
Create an array or new document object within the QueryOpen event, and store the values for all the items in the current document.
In your QuerySave event, compare the values of the current document to the in-memory copy you made, and then log any differences.
You can create a field on the form to write these changes to, and just append to it each time.
Watch out for other event handlers that make changes everytime the document opens, though. You may need to copy original values in the PostOpen event, for example, if you change some fields in the QueryOpen event each time the doc opens, otherwise you'd get false change logs.
Hope this helps!
A "brute force" approach can also work. Every time a document is saved, create a copy of that version to a (separate) database. This will build an audit trail of the documents. The documents can be compared to extract the changes.
There is quite some overhead in this approach, but in my experience it has been worth it. The implementation is simple and all changes are captured without affecting the actual document. All information that is needed is captured and available for (offline) processing.

Resources