MDGP October 2019 Release Feature of the Day: Security Role and Task Workflows

Microsoft Dynamics GPThe Inside Microsoft Dynamics GP blog has started a series Feature of the Day posts for Microsoft Dynamics GP “October 2019” Release on which I am following and adding commentary. The index for this series of posts is here.

The third Feature of the Day is new workflows for Security Role and Task approval.

The last two new workflows are Security Task Approval and Security Roles Approval:

  1. Security Task Approval lets you edit the operations that are assigned to a task or create a new task; and if the workflow is active, the workflow actions will display on Security Task Setup.
  2. Security Roles Approval lets you edit the operations that are assigned to a role or create a new role; and if the workflow is active, the workflow actions will display on Security Role Setup.

With these Security Approval workflows, you can require that any changes made in these windows be submitted for review and approval:

Security Role Setup window

No changes made for Security Tasks or Security Roles will be implemented until the workflow task has been final approved.

I’ve fielded lots of questions over the years from clients asking how they can find out who has changed a role or task. These workflows will allow them to control changes with only a limited number of users able to approve a change and make it live.

Internationalizing a ClassicPress plugin: Localizing a string

ClassicPress PluginsThis post is part of the sub-series on Internationalizing a ClassicPress plugin which is part of the Internationalizing a ClassicPress plugin series.

Over the previous posts I’ve discussed adding text domains and which functions are available to use, it’s time to look at a practical application.

To return a translated string we’d use the esc_html__ function with the string which can be localized as the first parameter and the text domain as the second:

$str = esc_html__('This is the string to translate', 'plugin-text-domain');

If we wanted to echo the translated string rather than return it, we’d use the esc_html_e function:

esc_html_e('This is the string to translate', 'plugin-text-domain');

Translating a ClassicPress plugin

Translating a ClassicPress plugin
What is Internationalization and Localization?
Why is Internationalization and Localization important?
When should a plugin be internationalized?
Internationalizing a ClassicPress plugin: How does internationalization work?
Internationalizing a ClassicPress plugin: What is a Text Domain and how is it specified?
Internationalizing a ClassicPress plugin: Localization functions
Internationalizing a ClassicPress plugin: Which localization functions to use?
Internationalizing a ClassicPress plugin: Localizing a string
Internationalizing a ClassicPress plugin: Don't paramaterize your text domain
Internationalizing a ClassicPress plugin: Localizing a string containing a parameter
Internationalizing a ClassicPress plugin: Localizing a string including plurals
Internationalizing a ClassicPress plugin: Localizing a string including notes for the translator
Internationalizing a ClassicPress plugin: Don't include HTML markup in localization
Internationalizing a ClassicPress plugin: Don't localize URLs
Internationalizing a ClassicPress plugin: Localizing a string including line breaks
Internationalizing a ClassicPress plugin: Load plugin translations
Translating a ClassicPress plugin with Poedit: What is Poedit?
Translating a ClassicPress plugin with Poedit: Download Poedit
Translating a ClassicPress plugin with Poedit: Install Poedit
Translating a ClassicPress plugin with Poedit: Create New Translation Template
Translating a ClassicPress plugin with Poedit: Create Translations
Translating a ClassicPress plugin with GlotPress: What is GlotPress?
Translating a ClassicPress plugin with GlotPress: Download and install GlotPress
Translating a ClassicPress plugin with GlotPress: Creating administrators
Translating a ClassicPress plugin with GlotPress: Create a project
Translating a ClassicPress plugin with GlotPress: Import translation template
Translating a ClassicPress plugin with GlotPress: Import translations
Translating a ClassicPress plugin with GlotPress: Create new translation set
Translating a ClassicPress plugin with GlotPress: Export translations
Internationalizing a ClassicPress plugin
How does internationalization work?
What is a Text Domain and how is it specified?
Localization functions
Which localization functions to use?
Localizing a string
Don't paramaterize your text domain
Localizing a string containing a parameter
Localizing a string including plurals
Localizing a string including notes for the translator
Don't include HTML markup in localization
Don't localize URLs
Localizing a string including line breaks
Load plugin translations

MDGP October 2019 Release Feature of the Day: User Security Workflow

Microsoft Dynamics GPThe Inside Microsoft Dynamics GP blog has started a series Feature of the Day posts for Microsoft Dynamics GP “October 2019” Release on which I am following and adding commentary. The index for this series of posts is here.

The second Feature of the Day is another new User Security Workflow to complement the one covered in the previous post of this series.

In User Security, you can make changes to the access for a user, what security role they are assigned or what modified reports they can access. With User Security Approval workflow, you can require that these changes be submitted for review and approval. This workflow is available in Workflow Maintenance (Administration area page » Setup » Company » Workflow » Workflow Maintenance):

Workflow Maintenance window showing User Security approval workflow

Continue reading “MDGP October 2019 Release Feature of the Day: User Security Workflow”

Internationalizing a ClassicPress plugin: Which localization functions to use?

ClassicPress PluginsThis post is part of the sub-series on Internationalizing a ClassicPress plugin which is part of the Internationalizing a ClassicPress plugin series.

In the previous post, of this series, I explained what functions were available for use in internationalizing a plugin, but there is something you need to consider when deciding which one to use.

With security at the forefront, it is important to remember that you cannot trust translators as you do not know who the translator will be. As you don’t know them, you can’t be sure that they won’t add something malicious to the translated string. To protect against this, you need to treat the localized strings as you would any other untrusted input: by escaping them.

So instead of using the plugins at the top of the previous post, you should be using the ones at the bottom which escape the returned or echoed strings.

Translating a ClassicPress plugin

Translating a ClassicPress plugin
What is Internationalization and Localization?
Why is Internationalization and Localization important?
When should a plugin be internationalized?
Internationalizing a ClassicPress plugin: How does internationalization work?
Internationalizing a ClassicPress plugin: What is a Text Domain and how is it specified?
Internationalizing a ClassicPress plugin: Localization functions
Internationalizing a ClassicPress plugin: Which localization functions to use?
Internationalizing a ClassicPress plugin: Localizing a string
Internationalizing a ClassicPress plugin: Don't paramaterize your text domain
Internationalizing a ClassicPress plugin: Localizing a string containing a parameter
Internationalizing a ClassicPress plugin: Localizing a string including plurals
Internationalizing a ClassicPress plugin: Localizing a string including notes for the translator
Internationalizing a ClassicPress plugin: Don't include HTML markup in localization
Internationalizing a ClassicPress plugin: Don't localize URLs
Internationalizing a ClassicPress plugin: Localizing a string including line breaks
Internationalizing a ClassicPress plugin: Load plugin translations
Translating a ClassicPress plugin with Poedit: What is Poedit?
Translating a ClassicPress plugin with Poedit: Download Poedit
Translating a ClassicPress plugin with Poedit: Install Poedit
Translating a ClassicPress plugin with Poedit: Create New Translation Template
Translating a ClassicPress plugin with Poedit: Create Translations
Translating a ClassicPress plugin with GlotPress: What is GlotPress?
Translating a ClassicPress plugin with GlotPress: Download and install GlotPress
Translating a ClassicPress plugin with GlotPress: Creating administrators
Translating a ClassicPress plugin with GlotPress: Create a project
Translating a ClassicPress plugin with GlotPress: Import translation template
Translating a ClassicPress plugin with GlotPress: Import translations
Translating a ClassicPress plugin with GlotPress: Create new translation set
Translating a ClassicPress plugin with GlotPress: Export translations
Internationalizing a ClassicPress plugin
How does internationalization work?
What is a Text Domain and how is it specified?
Localization functions
Which localization functions to use?
Localizing a string
Don't paramaterize your text domain
Localizing a string containing a parameter
Localizing a string including plurals
Localizing a string including notes for the translator
Don't include HTML markup in localization
Don't localize URLs
Localizing a string including line breaks
Load plugin translations

MDGP October 2019 Release Feature of the Day: User Approval Workflow

Microsoft Dynamics GPThe Inside Microsoft Dynamics GP blog has started a series Feature of the Day posts for Microsoft Dynamics GP “October 2019” Release on which I am following and adding commentary. The index for this series of posts is here.

The first Feature of the Day is a new User Approval workflow. Maintained with the rest of the workflows in Workflow Maintenance (Administration area page » Setup » Company » Workflow » Workflow Maintenance), this workflow forces approval of new or changed user:

Workflow Maintenance window showing User approval workflow

The workflow status bar and buttons will show on the User window when a workflow is active.

The new workflows around security, such as this one, could be very useful. Security is becoming more prominent for a number of clients and this will allow them control over which users have access to what and

Internationalizing a ClassicPress plugin: Localization functions

ClassicPress PluginsThis post is part of the sub-series on Internationalizing a ClassicPress plugin which is part of the Internationalizing a ClassicPress plugin series.

There is a number of functions available in ClassicPress which can be used in localising code:

  • __() – this function takes a string and returns the translation if it exists.
  • _e() – this function takes a string and echos the translation if it exists.
  • _n() – this function allows plurals to be handled. It takes 4 parameters: the single form, the plural form, the number based on which one or the other will be displayed and the text domain.
  • _x() – this function is to prevent collisions of similar words. If you plugin uses pair in the sense of a couple of people and pair in the sense of pairing a device via bluetooth as well, collisions could arise. A foreign language might well use very different words for the two.
  • _ex() – this function is the same as the above, but echos the result rather than returning it.
  • _nx() – this function is a combination of pairs and plurals.

There are also six functions which allow us to escape the value for safe usage in attributes and HTML. Considering the above functions, the names are very descriptive:

  • esc_attr__()
  • esc_attr_e()
  • esc_attr_x()
  • esc_html__()
  • esc_html_e()
  • esc_html_x()

Translating a ClassicPress plugin

Translating a ClassicPress plugin
What is Internationalization and Localization?
Why is Internationalization and Localization important?
When should a plugin be internationalized?
Internationalizing a ClassicPress plugin: How does internationalization work?
Internationalizing a ClassicPress plugin: What is a Text Domain and how is it specified?
Internationalizing a ClassicPress plugin: Localization functions
Internationalizing a ClassicPress plugin: Which localization functions to use?
Internationalizing a ClassicPress plugin: Localizing a string
Internationalizing a ClassicPress plugin: Don't paramaterize your text domain
Internationalizing a ClassicPress plugin: Localizing a string containing a parameter
Internationalizing a ClassicPress plugin: Localizing a string including plurals
Internationalizing a ClassicPress plugin: Localizing a string including notes for the translator
Internationalizing a ClassicPress plugin: Don't include HTML markup in localization
Internationalizing a ClassicPress plugin: Don't localize URLs
Internationalizing a ClassicPress plugin: Localizing a string including line breaks
Internationalizing a ClassicPress plugin: Load plugin translations
Translating a ClassicPress plugin with Poedit: What is Poedit?
Translating a ClassicPress plugin with Poedit: Download Poedit
Translating a ClassicPress plugin with Poedit: Install Poedit
Translating a ClassicPress plugin with Poedit: Create New Translation Template
Translating a ClassicPress plugin with Poedit: Create Translations
Translating a ClassicPress plugin with GlotPress: What is GlotPress?
Translating a ClassicPress plugin with GlotPress: Download and install GlotPress
Translating a ClassicPress plugin with GlotPress: Creating administrators
Translating a ClassicPress plugin with GlotPress: Create a project
Translating a ClassicPress plugin with GlotPress: Import translation template
Translating a ClassicPress plugin with GlotPress: Import translations
Translating a ClassicPress plugin with GlotPress: Create new translation set
Translating a ClassicPress plugin with GlotPress: Export translations
Internationalizing a ClassicPress plugin
How does internationalization work?
What is a Text Domain and how is it specified?
Localization functions
Which localization functions to use?
Localizing a string
Don't paramaterize your text domain
Localizing a string containing a parameter
Localizing a string including plurals
Localizing a string including notes for the translator
Don't include HTML markup in localization
Don't localize URLs
Localizing a string including line breaks
Load plugin translations

MDGP October 2019 Release Feature of the Day: Series Index

Microsoft Dynamics GPThe Inside Microsoft Dynamics GP blog has started a series Feature of the Day posts for Microsoft Dynamics GP “October 2019” Release on which I am following and adding commentary. This post is the series index which will automatically update as each post goes live (if you are reading the original MDGP October 2019 Release Feature of the Day post).

There are four key areas in which ehancements can be grouped:

  1. Top Feature Requests by our customers
  2. Financial Enhancements
  3. System Enhancements
  4. Workflow Functionality

Continue reading “MDGP October 2019 Release Feature of the Day: Series Index”

Internationalizing a ClassicPress plugin: What is a Text Domain and how is it specified?

ClassicPress PluginsThis post is part of the sub-series on Internationalizing a ClassicPress plugin which is part of the Internationalizing a ClassicPress plugin series.

A text domain is a unique identifier which makes sure ClassicPress can distinguish between all loaded translations and apply the correct one.

The text domain should be a unique string, not used by any other translation (which would include plugins and themes) and so is recommended to match the plugin slug. So if you have a plugin with the slug of my-classicpress-plugin the text domain should be the same.

If the text domain matches the plugin slug, ClassicPress does not require the text domain to be defined in th plugin header (although it is very much recommended that it does i order to avoid collisions with other plugins or themes), but if the text domain is different to the plugin slug, then you need to include the following highlighted line in the header:

/*
 * Plugin Name: My ClassicPress Plugin
 * Author: Ian Grieve
 * Text Domain: my-classicpress-plugin
 */

One important point to remember, is that a text domain cannot include underscores.

Translating a ClassicPress plugin

Translating a ClassicPress plugin
What is Internationalization and Localization?
Why is Internationalization and Localization important?
When should a plugin be internationalized?
Internationalizing a ClassicPress plugin: How does internationalization work?
Internationalizing a ClassicPress plugin: What is a Text Domain and how is it specified?
Internationalizing a ClassicPress plugin: Localization functions
Internationalizing a ClassicPress plugin: Which localization functions to use?
Internationalizing a ClassicPress plugin: Localizing a string
Internationalizing a ClassicPress plugin: Don't paramaterize your text domain
Internationalizing a ClassicPress plugin: Localizing a string containing a parameter
Internationalizing a ClassicPress plugin: Localizing a string including plurals
Internationalizing a ClassicPress plugin: Localizing a string including notes for the translator
Internationalizing a ClassicPress plugin: Don't include HTML markup in localization
Internationalizing a ClassicPress plugin: Don't localize URLs
Internationalizing a ClassicPress plugin: Localizing a string including line breaks
Internationalizing a ClassicPress plugin: Load plugin translations
Translating a ClassicPress plugin with Poedit: What is Poedit?
Translating a ClassicPress plugin with Poedit: Download Poedit
Translating a ClassicPress plugin with Poedit: Install Poedit
Translating a ClassicPress plugin with Poedit: Create New Translation Template
Translating a ClassicPress plugin with Poedit: Create Translations
Translating a ClassicPress plugin with GlotPress: What is GlotPress?
Translating a ClassicPress plugin with GlotPress: Download and install GlotPress
Translating a ClassicPress plugin with GlotPress: Creating administrators
Translating a ClassicPress plugin with GlotPress: Create a project
Translating a ClassicPress plugin with GlotPress: Import translation template
Translating a ClassicPress plugin with GlotPress: Import translations
Translating a ClassicPress plugin with GlotPress: Create new translation set
Translating a ClassicPress plugin with GlotPress: Export translations
Internationalizing a ClassicPress plugin
How does internationalization work?
What is a Text Domain and how is it specified?
Localization functions
Which localization functions to use?
Localizing a string
Don't paramaterize your text domain
Localizing a string containing a parameter
Localizing a string including plurals
Localizing a string including notes for the translator
Don't include HTML markup in localization
Don't localize URLs
Localizing a string including line breaks
Load plugin translations

Microsoft Dynamics GP “October 2019” Release now available for download

Microsoft Dynamics GPThe download for the Microsoft Dynamics GP “October 2019” Release is now available for download from CustomerSource as either a full install or service pack release to upgrade Microsoft Dynamics GP 2018:

This is the first release of Microsoft Dynamics GP on the Modern Lifecycle. There is a series of feature of the day posts being released by the Inside Microsoft Dynamics GP, but I have been on holiday and am behind on posting them.

I will be starting that series tomorrow and will then move onto a series of posts installing the new version. These posts will go-live over the coming days and weeks.

Microsoft Dynamics GP Naming And Modern Lifecycle

Microsoft Dynamics GPWith the release of Microsoft Dynamics GP in October 2019, it is moving to the Modern Lifecycle. This means the new version won’t be called Microsoft Dynamics GP 2019 as thought, but will instead be the Microsoft Dynamics GP “October 2019” Release.

The Modern Policy offers continuous support and servicing, including bug fixes, new features and the latest tax updates. Customers can stay current by taking at least one of the three yearly planned Dynamics GP releases.

Before the October 2019 release, any older release will continue to follow their existing Lifecycle timelines under the Fixed Policy which you can see here.

Microsoft are committing to three updates per year with additional updates as needed (which would include changes like regulatory requirements such as the UK’s Making Tax Digital).

You can see the planned update schedule for Microsoft Dynamics GP, beginning with the October 2019 release, on the Microsoft Docs website.

Microsoft MVP Jen Kuntz shared her thoughts on the change and I largely agree with her. Microsoft Dynamics GP is a mature product which doesn’t undergo the large architectural changes a much less mature product, such as Dynamics 365 Business Central undergoes, as it already has the core functionality and the basic structure doesn’t need to change as much. This means updates and upgrades are much simpler to undertake. A simpler upgrade once per year is a lot less work and a lot less disruptive than a major upgrade every two or three years.