Uncategorized

Show if data is synchronized

The post is related to the masterdata synchronization.

I wanted to give end-users an explanation why they cannot change some of the fields in a synchronized records.  I  decided to create a generic way of alerting the end-user, like you see in the screenshot below, and also to lock any fields that is synchronized.

image

So if a record is originating from another master-company, then the following yellow text will be visible. Doing this on a single form is surely easy, but I wanted to create a generic solution that has Zero footprint, and NOT making any changes to any standard form. 

Can it be done ?  Yes 🙂

So what I did, was to create a event handler on the info.formNotify():

image

Then the code looks like this (the code contains some ColSync* references, but you see the idea:

public static void colSyncEnableFields(XppPrePostArgs _args)
{
    FormRun                 formRun;
    FormDesign              formDesign;
    FormNotify              event;
    FormNotifyEventArgs     eventArgs;
    ColSyncCache            colSyncCache;
    Common                  common;
    ColSyncLine             colSyncLine;
    ColSyncTable            colSyncTable;
    ColSyncDefinition       colSyncDefinition;
    ColSyncDestinations     colSyncDestinations;
    FormGroupControl        actionBarGroup;
    FormActionPaneControl   actionPane;
    FormGroupControl        firstGroup;
    int                     defaultBackgroundColor;
    FormStaticTextControl   actionBarMessageText;
    int                     i;

    #define.SyncActionBarGroup('SyncActionBarGroup')
    #define.SyncActionBarMessageText('SyncBarMessageText')

    event     = _args.getArg('event');
    eventArgs = _args.getArg('eventArgs');

    switch (event)
    {
        case FormNotify::RecordChange:
            if ((eventArgs != null) &&
                (eventArgs.formDataSource()))
            {
                formRun   = _args.getArg('formRun');
                colSyncCache = ColSyncCache::construct();
                common = eventArgs.formDataSource().getFirst(true) ? eventArgs.formDataSource().getFirst(true) : eventArgs.formDataSource().cursor();
                if (common.RecId &&
                    colSyncCache.isSyncEnabledDestination(common))
                {
                    formDesign = formrun.design();
                    for (i=1; i<=formDesign.controlCount(); i++)
                    {
                        if ((formDesign.controlNum(i).handle() == classNum(FormActionPaneControl)))
                        {
                            actionPane = formDesign.controlNum(i);
                            break;
                        }
                    }
                    formRun.lock();

                    if (actionPane != null)
                    {
                        for (i=1; i<=formDesign.controlCount(); i++)
                        {
                            if ((formDesign.controlNum(i).handle() == classNum(FormGroupControl) &&
                                 formDesign.controlNum(i).name() == #SyncActionBarGroup ))
                            {
                                actionBarGroup = formDesign.controlNum(i);
                                break;
                            }
                        }

                        if (!actionBarGroup)
                            actionBarGroup = formDesign.addControl(FormControlType::Group, #SyncActionBarGroup, actionPane);
                    }
                    // add directly to top of form design
                    else
                    {
                        for (i=1; i<=formDesign.controlCount(); i++)
                        {
                            if ((formDesign.controlNum(i).handle() == classNum(FormGroupControl) &&
                                 formDesign.controlNum(i).name() == #SyncActionBarGroup ))
                            {
                                actionBarGroup = formDesign.controlNum(i);
                                break;
                            }
                        }

                        if (!actionBarGroup)
                        {
                            // find the first group control on form (if one exists)
                            for (i=1; i<=formDesign.controlCount(); i++)
                            {
                                if ((formDesign.controlNum(i).handle() == classNum(FormGroupControl)))
                                {
                                    firstGroup = formDesign.controlNum(i);
                                    break;
                                }
                            }
                            if(firstGroup)
                            {
                                actionBarGroup = firstGroup.addControl(FormControlType::Group, #SyncActionBarGroup);
                                actionBarGroup.top(FormTop::Auto);
                            }
                            else
                            {
                                actionBarGroup = formDesign.addControl(FormControlType::Group,#SyncActionBarGroup);
                                actionBarGroup.top(1, FormTop::Auto);
                            }
                        }
                    }

                    defaultBackgroundColor = formDesign.backgroundColor();
                    actionBarGroup.frameType(FormFrameType::None);
                    actionBarGroup.height(27);
                    actionBarGroup.hideIfEmpty(false);
                    actionBarGroup.topMargin(1);
                    actionBarGroup.bottomMargin(1);
                    actionBarGroup.widthMode(FormWidth::ColumnWidth);
                    actionBarGroup.colorScheme(FormColorScheme::RGB);
                    actionBarGroup.verticalSpacingValue(0);
                    if (System.Windows.SystemParameters::get_HighContrast())
                    {
                        actionBarGroup.colorScheme(FormColorScheme::WindowsPalette);
                        actionBarGroup.backgroundColor(WindowsPalette::TooltipBackground);
                    }
                    else
                    {
                        actionBarGroup.colorScheme(FormColorScheme::RGB);
                        actionBarGroup.backgroundColor(WinAPI::RGB2int(255,255,153));
                    }
                    // don't reserve space for details forms
                    if (formDesign.style() == FormStyle::DetailsFormMaster || formDesign.style() == FormStyle::DetailsFormTransaction)
                    {
                        actionBarGroup.visible(false);
                    }

                    for (i=1; i<=actionBarGroup.controlCount(); i++)
                    {
                        if ((actionBarGroup.controlNum(i).handle() == classNum(FormStaticTextControl)))
                        {
                            actionBarMessageText = actionBarGroup.controlNum(i);
                            if (actionBarMessageText && actionBarMessageText.name() == #SyncActionBarMessageText)
                                break;
                        }
                    }

                    if (!actionBarMessageText)
                    {
                        actionBarMessageText = actionBarGroup.addControl(FormControlType::StaticText, #SyncActionBarMessageText, actionBarGroup);
                    }
                    actionBarMessageText.backStyle(FormBackStyle::Opaque);
                    actionBarMessageText.colorScheme(FormColorScheme::RGB);
                    actionBarMessageText.backgroundColor(WinAPI::RGB2int(255,255,153));
                    actionBarMessageText.widthMode(FormWidth::ColumnWidth);
                    actionBarMessageText.text(strFmt("@SYN112"));
                    actionBarMessageText.visible(true);
                    formRun.unLock();

                    while select  SyncFieldId from  colSyncLine group by SyncFieldId
                            where   colSyncLine.SyncTableId == eventArgs.formDataSource().table()
                                &&  colSyncLine.SyncType == ColSyncType::SynchronizeField
                        exists join colSyncTable
                            where   colSyncTable.SyncId == colSyncLine.SyncId
                                &&  colSyncTable.SyncTableId == colSyncLine.SyncTableId
                                &&  colSyncTable.SyncActive == NoYes::Yes
                        exists join colSyncDefinition
                            where   colSyncDefinition.SyncId == colSyncLine.SyncId
                                &&  colSyncDefinition.SyncActive == NoYes::Yes
                        exists join colSyncDestinations
                            where   colSyncDestinations.SyncId == colSyncLine.SyncId
                                &&  colSyncDestinations.ToDataAreaId == common.dataAreaId
                                &&  colSyncDestinations.LockSyncFields == true
                    {
                        eventArgs.formDataSource().object(colSyncLine.SyncFieldId).allowEdit(false);
                    }
                    eventArgs.formDataSource().allowCreate(false);
                    eventArgs.formDataSource().allowDelete(false);
                }
                else if (common.RecId &&
                         colSyncCache.isGlobalTableEnabled(common))
                {
                    eventArgs.formDataSource().allowCreate(false);
                    eventArgs.formDataSource().allowEdit(false);
                    eventArgs.formDataSource().allowDelete(false);
                }
            }
        break;
    }
}

I appreciate that I can be a part of this worldwide blog community—as a consultant working from Norway, the blog lets me share more than 20 years of experience with Microsoft Dynamics 365. Along the way, I participated in developing retail, PDA/RF, barcoding, master data, kitting and WMS-solutions for Dynamics. My blog focuses on my deepest interests and expertise: along with a 360 degree view of digital transformation topics, I welcome opportunities to dive into retail and intercompany supply chain automation, logistics, and production—everything that is moving around in a truly connected enterprise. As Enterprise Architect on Dynamics 365, I specialize in strategic development and planning for corporate vertical solutions and works to build international networks that increase knowledge and understanding for Dynamics 365. As an advocate for both providers and customers, I'm committed to ensure that customers constantly changing needs are meet, and I see community as key for increasing expertise. I welcome you to connect with me.

0 comments on “Show if data is synchronized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: