Pages

Wednesday, May 2, 2018

Need to work with or add system defined buttons on forms?

You can change the behavior of system defined buttons form, or add buttons, by subscribing to delegates from the SysSystemDefinedButons class.

The class AlertFormExtender has an example of how a button is added to the Options action pane tab.

Monday, April 30, 2018

Why you can't setup sharing of customers and vendors in 8.0

The release notes for 8.0 says that you can now share customers and vendors with the data sharing feature. But it also says: "To enable this functionality, contact your Solution Architect, who will verify that your business requirements and data volumes will be acceptable for data sharing, and then enable the sharing policies in your environment".

So what does that mean?

Microsoft has started using a "flighting" concept where they add features on a release, but keep them turned of until activated for the tenant by Microsoft. This is something you can see Microsoft check in their code.

A new isFlightEnabled method on the Global class does the work of checking if a feature is enabled or not.

If you want to cheat a bit, you could probably add an event handler to this method and return true for the feature you want to enable. I haven't tried that though.

In class SysDataSharingValidation, method validateTableCanBeSharedWithPolicy, you can see an example of how this is called:



Thursday, March 15, 2018

Lifecycle Service companion app

Here is a cool tool for LCS environment managers, written by Tomek Melissa from Microsoft.

The tool is unofficial and comes AS-IS.


https://github.com/Microsoft/2LCS/releases

Saturday, March 10, 2018

Generic function for switching line numbers on records

Tried to write a generic routine for switching line numbers on records, to help with functions that move records up or down according to a line number sequence.

Comments are welcome and I'll update the post according to the bugs you can find. However I only spent 10 minutes on this and it's provided to you for free, so please bear that in mind before you send me death threats in the comments.

public static void switchLineNumbers(
    Common      _currentTopRecord,
    Common      _currentBottomRecord,
    FieldName   _lineNumberFieldName)
{
    #define.RetryNum(5)
    Common      currentTopRecordUpdate;
    Common      currentBottomRecordUpdate;
    LineNumber  topLineNumber;
    LineNumber  bottomLineNumber;
    FieldId     lineNumberFieldFieldId = fieldName2id(_currentTopRecord.TableId, _lineNumberFieldname);

    try
    {
        ttsBegin;

        // Initialize correct table id on common
        currentTopRecordUpdate = new DictTable(_currentTopRecord.TableId).makeRecord();
        currentBottomRecordUpdate  = new DictTable(_currentBottomRecord.TableId).makeRecord();

        select firstOnly forUpdate currentTopRecordUpdate
            where currentTopRecordUpdate.RecId == _currentTopRecord.RecId;

        // Make a temporary line value, in case there is a unique index with line number,
        // making a free spot to update the currect bottom record with
        topLineNumber = currentTopRecordUpdate.(lineNumberFieldFieldId);

        currentTopRecordUpdate.(lineNumberFieldFieldId) = maxInt();
        currentTopRecordUpdate.update();

        select firstOnly forUpdate currentBottomRecordUpdate
            where currentBottomRecordUpdate.RecId == _currentBottomRecord.RecId;

        bottomLineNumber = currentBottomRecordUpdate.(lineNumberFieldFieldId);

        currentBottomRecordUpdate.(lineNumberFieldFieldId) = topLineNumber;
        currentBottomRecordUpdate.update();

        currentTopRecordUpdate.(lineNumberFieldFieldId) = bottomLineNumber;
        currentTopRecordUpdate.update();

        ttsCommit;
    }

    catch (Exception::DuplicateKeyException)
    {
        if (appl.ttsLevel() == 0)
        {
            if (xSession::currentRetryCount() >= #RetryNum)
            {
                throw Exception::DuplicateKeyExceptionNotRecovered;
            }
            else
            {
                retry;
            }
        }
        else
        {
            throw Exception::DuplicateKeyException;
        }
    }
}

Use at your own risk.