Recent ISC Software Webinar: Lesser Used Modules In Microsoft Dynamics GP

ISC Software SolutionsIn our most recent webinar, we took a look at Lesser Used Modules In Microsoft Dynamics GP. In this webinar, we took a look at some of the lesser known, but very useful modules in Microsoft Dynamics GP. If you want to catch up on this, or any other, webinar, you can do so here.

  1. Introduction
  2. Licensing
  3. Available Modules
  4. Lesser User Modules
  5. Conclusion

Introduction ^

Microsoft Dynamics GP is a mature enterprise resource planning (ERP) system which has lot of functionality available. I find when working with client that many of them are familiar with the core modules such as General, Purchase and Sales Ledgers as well as Purchase and Sales Order Processing and Fixed Asset Management, but don’t know much of what is available outside of these modules. this is why in this webinar, we took a look at some of the lesser used modules in Microsoft Dynamics GP so we can give people an insight into the functionality available to them within the licensing they already own.

Much of the focus was on modules in the a href=’#lesser-used-starter-pack’>Starter Pack as all clients on Dynamics GP 2013 or later have access to this, but we did also take a look at some of the functionality in the Extended Pack.

Continue reading “Recent ISC Software Webinar: Lesser Used Modules In Microsoft Dynamics GP”

New ClassicPress Documentation Hub Now Live

ClassicPressThe new ClassicPress Documentation Hub is now live with user and developer guides as well as the Plugins Guidelines for the ClassicPress Plugin Directory, but the big addition is the ClassicPress Code Reference.

The bulk of the work done to build the new site was done by Beda Schmid who also wrote the announcement post on the ClassicPress blog.

The code reference means that developers can now look up any of the 2,814 methods, 2,874 functions, 280 classes and 2,063 hooks from the ClassicPress code instead of having to use the old WordPress code reference which would include all of the Gutenberg additions.

Full details on what has been added to the ClassicPress Documentation Hub can be read in the announcement.

ClassicPress Plugin Development: Load Multilevel Options with Defaults

ClassicPress PluginsThis post is part of the ClassicPress Plugin Development series in which I am going to look at both best practice for developing plugins and how I approach some requirements as well as some of the functions I commonly use.

Over the last couple of posts, I’ve taken a look at saving and loading options and how to load options with defaults. The defaults in the last post was a single dimension array, but you can also do the same with multi dimensional arrays using a ustom recursive parse of the arrays.

The below is an example of loading options with multi dimensional defaults from my Widget Announcements plugin:

/**
 * Get options including defaults.
 *
 * @since 1.1.0
 *
 */
function azrcrv_wa_get_option($option_name){
 
	$defaults = array(
						'widget' => array(
											'width' => 300,
											'height' => 300,
										),
						'to-twitter' => array(
												'integrate' => 0,
												'tweet' => 0,
												'retweet' => 0,
												'retweet-prefix' => 'ICYMI:',
												'tweet-format' => '%t %h',
												'tweet-time' => '10:00',
												'retweet-time' => '16:00',
												'use-featured-image' => 1,
											),
						'toggle-showhide' => array(
												'integrate' => 0,
											),
					);

	$options = get_option($option_name, $defaults);

	$options = azrcrv_wa_recursive_parse_args($options, $defaults);

	return $options;

}

/**
 * Recursively parse options to merge with defaults.
 *
 * @since 1.1.0
 *
 */
function azrcrv_wa_recursive_parse_args( $args, $defaults ) {
	$new_args = (array) $defaults;

	foreach ( $args as $key => $value ) {
		if ( is_array( $value ) && isset( $new_args[ $key ] ) ) {
			$new_args[ $key ] = azrcrv_wa_recursive_parse_args( $value, $new_args[ $key ] );
		}
		else {
			$new_args[ $key ] = $value;
		}
	}

	return $new_args;
}

Click to show/hide the ClassicPress Plugin Development Series Index

Error Purchasing Requisition in Microsoft Dynamics GP

Microsoft Dynamics GPI’ve been working with a client to create a new standalone Microsoft Dynamics GP test system. We copied the databases to the new SQL Server and were progressing through several tasks making sure everything was aligned and working correctly as they have a number of add-ins which needed to be installed.

One user testing the purchasing module encountered an error when trying to transfer a purchase requisition to purchase order:

Error produced when purchasing a purchase requisition

The request failed with HTTP status 404: Not Found.

The error was produced because the details for the Reporting Services Reports in Reporting Tools Setup had not been updated and the reports deployed; the links were still to the live server SSRS implementation which was inaccessible to the new sandboxed test environment.

Once the links were updated and redeployed the error went away.

Microsoft Dynamics GP 2016 Now Out of Mainstream Support

Microsoft Dynamics GPA couple of days ago, I posted about the updated Microsoft Dynamics GP roadmap which goes through 2028. One item which is worth noting, is that Microsoft Dynamics GP 2016 RTM and 2016 R2 are both out of mainstream support as of yesterday and those versions are now in extended support.

This means that critical security issues found will be fixed, but no feature enhancements or other bugs will be added or fixed. This does of course include changes to the VAT Daybook module which are very important to users in the UK with the ever changing requirements from HMRC for MTD.

If you are using Dynamics GP 2016, I would recommend contacting your partner to discuss an upgrade to a version under mainstream support. If you are in the UK it is important you do this as you will only get updates to the MTD functionality if you are on the latest build of Microsoft Dynamics GP and under the Modern Lifecycle policy.

For those clients with MTD requirements, but who, for whatever reason cannot upgrade at the moment, ISC have an add-on available for all versions of Microsoft Dynamics GP which will support the MTD submissions to HMRC. If you’d like to discuss requirements in this area, please use the contact form below.

Microsoft Dynamics GP Roadmap to 2028 and Beyond

Microsoft Dynamics GPTerry Heley on the Dynamics GP Support and Services Blog posted an article on Friday on the exciting future of Microsoft Dynamics GP and giving a Lifecycle Update. As part of the article she inked to the published Lifecycle (Roadmap) for Microsoft Dynamics GP which extends to 2028 and beyond for Microsoft Dynamics GP.

The published roadmap also shows the end of mainstream and extended support for versions older versions of the product which predate the Modern Lifecycle:

Microsoft Dynamics GP Roadmap through to 2028

In brief:

  • 2013 and 2013 R2 are out of mainstream support and in extended support until 11/4/2023.
  • 2015 and 2015 R2 are out of mainstream support and in extended support until 14/4/2025.
  • 2016 and 2016 R2 are out of mainstream support on 13/7/2021 and in extended support until 7/4/2026.
  • 2018 and 2018 R2 in mainstream support until 10/1/2023 and in extended support until 7/4/2026.

Microsoft Dynamics GP is now under the Modern Lifecycle and has the same commitment from Microsoft as Dynamics 365. The Modern Lifecycle means there should be more frequent updates to Microsoft Dynamics GP with at least three updates a year in January, June/July and October.

Microsoft will continue to keep adding new features and improving it based on direct feedback from users. The best way to make sure you continue to benefit from the improvements is to keep up-to-date on upgrades and use the latest version of Microsoft Dynamics GP.

The key takeaway from the published Lifecycle is that Microsoft Dynamics GP is not going anywhere and development will continue under the Modern Lifecycle policy with multiple releases each year.

ClassicPress Plugin Development: Load Options with Defaults

ClassicPress PluginsThis post is part of the ClassicPress Plugin Development series in which I am going to look at both best practice for developing plugins and how I approach some requirements as well as some of the functions I commonly use.

In the last post I covered saving and loading options in a ClassicPress plugin. When you create a plugin with options you will want to provide defaults to be used before the user makes any changes to the settings; this both allows for basic operation of the plugin and avoids unset option errors.

The get_option function does allow for defaults to be passed, but this will only work if there are no options; it will not work effectively if new options are added to the plugin. This can be handled using the wp_parse_args function which merges user defined arguments into defaults array.

wp_parse_args( string|array|object $args, array $defaults = array() )

Parameters

$args (string|array|object) (Required) Value to merge with $defaults. $defaults (array) (Optional) Array that serves as the defaults. Default value: array()

Return

(array) Merged user defined values with defaults.

The below is an example of loading options with defaults from my Comment Validator plugin:

/**
 * Get options including defaults.
 *
 * @since 1.2.0
 *
 */
function azrcrv_cv_get_option($option_name){
 
	$defaults = array(
						'min_length' => 10,
						'max_length' => 500,
						'mod_length' => 250,
						'prevent_unreg_using_reg_name' => 1,
						'use_network' => 1,
					);

	$options = get_option($option_name, $defaults);

	$options = wp_parse_args($options, $defaults);

	return $options;

}

The above example works when the default options is single level. If the options are multilevel, these need to be handled differently; I will cover this in the next post in this series.

Click to show/hide the ClassicPress Plugin Development Series Index

ClassicPress Plugin Development: Load and Save Options

ClassicPress PluginsThis post is part of the ClassicPress Plugin Development series in which I am going to look at both best practice for developing plugins and how I approach some requirements as well as some of the functions I commonly use.

When developing a plugin, most of them will have settings which need to be saved ad recalled. There are functions available in ClassicPress which you can use to do this:

    get_option

    update_option

If your plugin contains multiple options, then best practice would be to store these in an array within one option rather than each option stored individually.

The get_option is used to load options from the database:

get_option( string $option, mixed $default = false )

Parameters

$option (string) (Required) Name of option to retrieve. Expected to not be SQL-escaped. $default (mixed) (Optional) Default value to return if the option does not exist. Default value: false

Return

(mixed) Value set for the option.

The below is an example of loading options from my SMTP plugin:

$options = get_option( 'azrcrv-smtp' );

The update_option function is used to save options:

update_option( string $option, mixed $value, string|bool $autoload = null )

Parameters

$option (string) (Required) Option name. Expected to not be SQL-escaped. $value (mixed) (Required) Option value. Must be serializable if non-scalar. Expected to not be SQL-escaped. $autoload (string|bool) (Optional) Whether to load the option when ClassicPress starts up. For existing options, $autoload can only be updated using update_option() if $value is also changed. Accepts 'yes'|true to enable or 'no'|false to disable. For non-existent options, the default value is 'yes'. Default value: null

Return

(bool) False if value was not updated and true if value was updated.

The below is an example of saving options from my SMTP plugin:

update_option( 'azrcrv-smtp', $options );

Click to show/hide the ClassicPress Plugin Development Series Index

Excel Snippets: Generate Row Numbers

MicrosoftI might not post many Excel snippets, but I’m collecting them into a small Excel Snippets series to make them easy to find.

A while ago, I posted an article on generating row umbers in a SQL script; I fielded a question from someone recently on doing the same thing Excel where the row number changes based on two columns of data. Basically when either of the columns were different, the row number should reset back to 1.

The following formula uses an IF combined with an OR to check if either column of data is different to the row above and if so sets the row number to 1 otherwise it increments by 1:

=IF(OR(A2<>A3,B2<>B3),1,C2+1)

SQL Snippets: Manage Data Containing an Apostrophe

Microsoft SQL ServerThis post is part of the series on SQL Snippets.

I was doing some work with a client recently and they had an issue with some data in SQL Server which they needed change, but weren’t able to do it through the application.

The issue was that they had some names in a column marked as a key field which contained an apostrophe and it was causing them problems; the data should not have had an apostrophe, but they a user had managed to do it and they wanted to do an update to remove it.

There SQL was a little more limited than mine so they asked for assistance. I created the following SQL as an example for them on how data with apostrophe in can be managed.

The example shows how to insert data containing an apostrophe as well as two ways of changing data; one was doing it globally an the other just changing a specific record.

The key to this is that in Microsoft SQL Server you can use one apostrophe to escape another.

-- CREATE TEMP TABLE
CREATE TABLE #Temp(
	USERNAME VARCHAR(15)
)
GO

-- INSERT DATA INTO TEMP TABLE
INSERT INTO #Temp (USERNAME) VALUES ('AJ''ones')
GO

-- SELECT DATA TO CHECK
SELECT * FROM #Temp
GO

-- RUN ONE OF THE TWO UPDATE STATEMENTS
-- remove single quote FROM one record
UPDATE #Temp SET USERNAME = REPLACE(USERNAME, '''', '') WHERE USERNAME = 'AJ''ones'

-- remove single quote FROM all records
UPDATE #Temp SET USERNAME = REPLACE(USERNAME, '''', '') WHERE USERNAME LIKE '%''%'
GO

-- SELECT DATA TO CHECK
SELECT * FROM #Temp
GO

-- DROP TEMP TABLE
DROP TABLE #Temp
GO