SQL View to Return Prior Day Logins

Microsoft Dynamics GPMicrosoft Dynamics GP is licensed, for full users, on a concurrent user basis. This means that you can create more users than can be logged in at the same time; unfortunately, this means that if users don;t log out correctly, that the license remains in use.

The below script can be plugged into a SmartList Designer to give easy visibility of who logged in before the current day.

CREATE VIEW uv_AZRCRV_GetPriorDayLogins AS
/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 2.0 UK: England & Wales (CC BY-NC-SA 2.0 UK).
*/
SELECT
	['User Activity'].USERID AS 'User ID'
	,ISNULL(['Users Master'].USERNAME, 'User Master record not found') AS 'User Name'
	,ISNULL(['Company Master'].INTERID, 'Company Master record not found') AS 'Inter ID'
	,['User Activity'].CMPNYNAM AS 'Company Name'
	,FORMAT(['User Activity'].LOGINDAT, 'yyyy-MM-dd') AS 'Login Date'
	,FORMAT(['User Activity'].LOGINTIM, 'hh:mm:ss') AS 'Login Time'
FROM
	ACTIVITY AS ['User Activity']
LEFT JOIN
	SY01400 AS ['Users Master']
		ON
			['User Activity'].USERID = ['Users Master'].USERID
LEFT JOIN
	SY01500 AS ['Company Master']
		ON
			['User Activity'].CMPNYNAM = ['Company Master'].CMPNYNAM
WHERE
	['User Activity'].LOGINDAT <= DATEADD(DAY, -1, GETDATE())
GO
GRANT SELECT ON uv_AZRCRV_GetPriorDayLogins TO DYNGRP
GO

Update Year on Budgets in Fabrikam Sample Company

Microsoft Dynamics GPI’ve written a few scripts to update data in the Fabrikam sample company (I will be posting a series index to link them all together in the near future).

The sample company ships with a few budgets preloaded, but they are not named very well. For example, the budget for 2027 (the year in which Fabrikam is operating) is named BUDGET 4 and the budget for 2025 is named BUDGET 2005.

Continue reading “Update Year on Budgets in Fabrikam Sample Company”

Scripts to Remove Analytical Accounting

Microsoft Dynamics GPBack in February 2017, I posted about a Microsoft Knowledge Base article on removing Analytical Accounting (AA) from Microsoft Dynamics GP. At the time, the KB article was unavailable, but the download links still worked (if you knew what they are).

I was contacted by someone recently asking if I had a copy of the scripts as the download links no longer work (the KB article itself is available).

This was unusual timing as I had just been onsite with a client where we encountered issues upgrading their system from 2016 RTM to 2018 RTM. In that case, the solution was to remove AA from the system as they had the module used, but never implemented it.

To remove AA, I dipped into my script library for the AA removal scripts from KB915903. After being alerted at the scripts were no longer available, I thought it might be useful to others to post them here.

The scripts are available from the following links:

  1. KB915903_AA_Remove_AACompete_DYNAMICS_10 – this script needs to be run against the system database (typically called DYNAMICS.
  2. KB915903_10 – this script should be run against all of the company databases.
  3. KB915903_DYNAMICS_Remove_DB_Upgrade_10 – this script is run against the system database.

Microsoft Dynamics GP Macros: Macro By SQL

Microsoft Dynamics GPIn this series I am taking a look at how macros can be used to update data in Microsoft Dynamics GP.

In the last post in this series, I showed how to merge the data into the macro template; another approach I have used a few times is to write a SQL query which returns the data already in the macro. This is done by embedding the macro file into the SQL Query:

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 2.0 UK: England & Wales (CC BY-NC-SA 2.0 UK).
*/
SELECT '# DEXVERSION=16.00.0034.000 2 2
CheckActiveWin dictionary ''default''  form ''Enter_User_Names'' window ''Enter_User_Names'' 
  TypeTo field ''User ID'' , ''' + RTRIM(USERID) +'''
  MoveTo field ''User Name'' 
  MoveTo field Password 
  TypeTo field Password , ''' + LEFT(RTRIM(REPLACE(USERNAME,' ','')),14) + '1' + '''
  MoveTo field ''(L) Confirm Password'' 
  TypeTo field ''(L) Confirm Password'' , ''' + LEFT(RTRIM(REPLACE(USERNAME,' ','')),14) + '1' + '''
  CommandExec dictionary ''default''  form ''Enter_User_Names'' command ''Save Button_w_Enter_User_Names_f_Enter_User_Names'' 
NewActiveWin dictionary ''default''  form ''Enter_User_Names'' window ''Enter_User_Names'' 
ActivateWindow dictionary ''default''  form ''Enter_User_Names'' window ''Enter_User_Names'''
FROM
	DYNAMICS..SY01400
WHERE
	USERID <> 'sa'
AND
	USERID <> 'DYNSA'
AND
	USERID NOT LIKE 'LESSON%'

Continue reading “Microsoft Dynamics GP Macros: Macro By SQL”

SQL Script to Set EFT Output Locations When Copying Live To Test

Microsoft Dynamics GPAs mentioned in the last post I’ve had a couple of scripts recently which I needed to create in order to facilitate clients easily making live to test copies without issues arising.

The script, below, can be used to set the EFT file locations in Checkbook Master. For the client I was working with, we only needed to set the file location of the Domestic Payments File Location field, but I am including all of the file location fields in the script.

Simply change the highlighted path locations to the required paths and set the Checkbook ID at the bottom:

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
UPDATE
	CM00101
SET
	DomPmtsFile = '{path}'
	,ForeignPmtsFile = '{path}'
	,DomDirDbtCollectFile = '{path}'
	,DomDirDbtRefundFile = '{path}'
	,EFTPMPrenoteFile = '{path}'
	,EFTRMPrenoteFile = '{path}'
	,EFTCommunicationFile = '{path}'
WHERE
	CHEKBKID = '{chequebook id}'

As always with scripts, please make sure you have a good backup before using the script.

SQL Script to Update Web Services Server in Workflow Setup When Copying Live To Test

Microsoft Dynamics GPAll clients will at some point copy their live company into a test one, whether or not the test system is on the same server or a different one. If on the same machine, they will usually use an automated process to perform the backup and restore.

There is usually other tasks which will need to be undertaken such as changing the output location of the EFT Payment Register Report or prefixing email message subjects with “TEST” or setting all email addresses to internal ones.

I’ve recently encountered a couple more fields which need to be reset to avoid problems when copying live to test. The one prompting this script, was when the live company was copied to the standalone test system, the Web Services server needed to be changed to a different value:

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
UPDATE WF00100
	SET
		Web_Service_Server = '{servername}'
WHERE
	SETUPKEY = 0
GO

The highlighted section, above, needs to be changed to your Web Services server.

In addition, a repair needed to be run using the Web Services Configuration Wizard, but at least the script removes one manual step.

As always with scripts, please make sure you have a good backup before using the script.

SQL Script to Remove Purchase Requisition Workflow Status

Microsoft Dynamics GPA client recently had some hardware issues causing problems with the submission of purchases requisitions into a Workflow approval process. The hardware issues were causing some speed issues which resulted in the workflow timing out and the approval status becoming corrupt.

Instead of the PR being approved and going to a status of Final Approved, it was going to Approved, even though there was only one level of approval required by the workflow.

When the hardware issues were resolved, the error stopped occurring, but a number of corrupt PRs were remaining.

The way to correct the data is to reset the workflow status. I produced a small script which does this by resetting the Workflow_Status on the Purchasing Requisition Work (POP10200) table and removing the entries from the following tables:

  1. Workflow Step Instance Table (WFI10003)
  2. Workflow Tasks Table (WFI10004)
  3. Workflow Instance Master (WFI10002)

The list of PRs to be reset are entered in the highlighted part of the script:

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
CREATE TABLE #POPRequisitions(
	POPRequisitionNumber VARCHAR(21)
)
GO

INSERT INTO
	#POPRequisitions
VALUES
	('REQ00000000000017')
GO

UPDATE POP10200 SET Workflow_Status = 1 WHERE POPRequisitionNumber IN (SELECT POPRequisitionNumber FROM #POPRequisitions)

DELETE FROM WFI10003 WHERE WorkflowInstanceID IN 
	(SELECT WorkflowInstanceID FROM WFI10002 WHERE Workflow_Type_Name='Purchase Requisition Approval' AND WfBusObjKey IN (SELECT POPRequisitionNumber FROM #POPRequisitions))

DELETE FROM WFI10004 WHERE WorkflowInstanceID IN 
	(SELECT WorkflowInstanceID FROM WFI10002 WHERE Workflow_Type_Name='Purchase Requisition Approval' AND WfBusObjKey IN (SELECT POPRequisitionNumber FROM #POPRequisitions))

DELETE FROM WFI10002 WHERE Workflow_Type_Name='Purchase Requisition Approval' AND WfBusObjKey IN
	(SELECT POPRequisitionNumber FROM #POPRequisitions)
GO

DROP TABLE #POPRequisitions
GO

As always before running a script on live, make sure you have a good backup and test the script in a test company.

Copy Posting Report Configuration Between Companies

Microsoft Dynamics GPI wrote the first version of this script a long time ago, but recently had cause to return to it. A client I am working with has configured the posting reports in one company and wanted to copy the same configuration to the other companies.

This script allows you to do this, on a one by one basis. Set the first highlighted parameter to the source company, and the second to the destination company.

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
DECLARE @SQLStatement VARCHAR(8000)
DECLARE @SourceCompany VARCHAR(5) = 'T16R2'
DECLARE @DestinationCompany VARCHAR(5) = 'P16R2'

SET @SQLStatement = 'UPDATE
				['Destination Posting Journal Destinations']
			SET
				PRNTJRNL = ['Source Posting Journal Destinations'].PRNTJRNL
				,ASECTMNT = ['Source Posting Journal Destinations'].ASECTMNT
				,PRTOPRNT = ['Source Posting Journal Destinations'].PRTOPRNT
				,PRTOFLNT = ['Source Posting Journal Destinations'].PRTOFLNT
			FROM
				' + @DestinationCompany + '.dbo.SY02200 AS ['Destination Posting Journal Destinations']
			INNER JOIN
				' + @SourceCompany + '.dbo.SY02200 AS ['Source Posting Journal Destinations'] ON ['Source Posting Journal Destinations'].SERIES = ['Destination Posting Journal Destinations'].SERIES
					AND ['Source Posting Journal Destinations'].TRXSOURC = ['Destination Posting Journal Destinations'].TRXSOURC
					AND ['Source Posting Journal Destinations'].PTGRPTNM = ['Destination Posting Journal Destinations'].PTGRPTNM'
EXEC (@SQLStatement)

As always with an SQL script, please make sure you have a good backup before running it.

SQL View to Return Sales By Customer By Year

Microsoft Dynamics GPThe last post was a SQL view to return purchases by vendor by year; in this one I am posting a similar view, but for the Sales series.

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
IF OBJECT_ID (N'uv_AZRCRV_SalesByCustomerByYear', N'V') IS NOT NULL
	DROP VIEW uv_AZRCRV_SalesByCustomerByYear
GO
CREATE VIEW uv_AZRCRV_SalesByCustomerByYear AS
SELECT
	['Receivables Transactions'].CUSTNMBR AS 'Customer ID'
	,['RM Debtor MSTR'].CUSTNAME AS 'Customer Name'
	,['RM Debtor MSTR'].CUSTCLAS AS 'Class ID'
	,FORMAT(['Receivables Transactions'].DOCDATE, 'yyyy') AS 'Year'
	,CASE WHEN ['RM Debtor MSTR'].INACTIVE = 1 THEN
		'Inactive'
	ELSE
		'Active'
	END AS 'Status'
	,SUM(CASE WHEN ['Receivables Transactions'].RMDTYPAL <= 3 THEN ['Receivables Transactions'].SLSAMNT ELSE ['Receivables Transactions'].SLSAMNT * -1 END) AS 'Purchases Amount'
	,SUM(CASE WHEN ['Receivables Transactions'].RMDTYPAL <= 3 THEN ['Receivables Transactions'].TRDISAMT * -1 ELSE ['Receivables Transactions'].TRDISAMT END) AS 'Trade Discount'
	,SUM(CASE WHEN ['Receivables Transactions'].RMDTYPAL <= 3 THEN ['Receivables Transactions'].FRTAMNT ELSE ['Receivables Transactions'].FRTAMNT * -1 END) AS 'Freight'
	,SUM(CASE WHEN ['Receivables Transactions'].RMDTYPAL <= 3 THEN ['Receivables Transactions'].MISCAMNT ELSE ['Receivables Transactions'].MISCAMNT * -1 END) AS 'Miscalleneous'
	,SUM(CASE WHEN ['Receivables Transactions'].RMDTYPAL <= 3 THEN ['Receivables Transactions'].TAXAMNT ELSE ['Receivables Transactions'].TAXAMNT * -1 END) AS 'Tax Amount'
	,SUM(CASE WHEN ['Receivables Transactions'].RMDTYPAL <= 3 THEN ['Receivables Transactions'].DOCAMNT ELSE ['Receivables Transactions'].DOCAMNT * -1 END) AS 'Total Amount'
FROM
	(SELECT
		CUSTNMBR
		,DOCDATE
		,GLPOSTDT
		,DOCNUMBR
		,RMDTYPAL
		,SLSAMNT
		,TRDISAMT
		,FRTAMNT
		,MISCAMNT
		,TAXAMNT
		,SLSAMNT - TRDISAMT + FRTAMNT + MISCAMNT + TAXAMNT AS DOCAMNT
	FROM
		RM20101
	WHERE
		VOIDSTTS >= 0
	AND
		RMDTYPAL IN (1,3,4,7,8)
	UNION ALL
		SELECT
			CUSTNMBR
			,DOCDATE
			,GLPOSTDT
			,DOCNUMBR
			,RMDTYPAL
			,SLSAMNT
			,TRDISAMT
			,FRTAMNT
			,MISCAMNT
			,TAXAMNT
			,SLSAMNT - TRDISAMT + FRTAMNT + MISCAMNT + TAXAMNT AS DOCAMNT
		FROM
			RM30101
		WHERE
			VOIDSTTS >= 0
		AND
			RMDTYPAL IN (1,3,4,7,8)
	) AS ['Receivables Transactions']
LEFT JOIN
	RM00101 AS ['RM Debtor MSTR']
		ON
			['Receivables Transactions'].CUSTNMBR >= ['RM Debtor MSTR'].CUSTNMBR
GROUP BY
	['Receivables Transactions'].CUSTNMBR
	,['RM Debtor MSTR'].CUSTNAME
	,['RM Debtor MSTR'].CUSTCLAS
	,['RM Debtor MSTR'].INACTIVE
	,FORMAT(['Receivables Transactions'].DocDate, 'yyyy')
GO
GRANT SELECT ON uv_AZRCRV_SalesByCustomerByYear TO DYNGRP
GO

The view can easily be plugged into SmartList Designer, SmartList Builder, a refreshable Excel Report, a SQL Server Reporting Services report or any other type of reporting tool.

SQL Script to Prefix Email Message Subjects with Test

Microsoft Dynamics GPI had an issue reported with purchase requisitions the other day. I logged on and did a little testing and then, a short wile later, got an email from the client asking about some workflow approval emails some managers had received.

The email to the approvers did not contain the word “test” anywhere in either the subject or body. This lead to me having a horrible moment when I thought I might have done my testing on live; I was able to confirm quickly that I had not.

After this I decided I had better knock a quick script together which the client could incorporate into their live to test copy.

The script is more engineered than it might otherwise need to be as I have included code to only do the update when it is running against a test company (flagged with <TEST> at the end of the Company Name) and where the email subject isn’t already prefixed with the word TEST:

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
UPDATE
	['Email Messages']
SET
	EmailMessageSubject = LEFT('TEST: ' + CAST(['Email Messages'].EmailMessageSubject AS CHAR(150)), 150)
FROM
	SY04901 AS ['Email Messages']
INNER JOIN
	DYNAMICS..SY01500 AS ['Company Master']
		ON
			['Company Master'].INTERID = DB_NAME()
WHERE
	['Company Master'].CMPNYNAM LIKE '%<TEST>'
AND
	LEFT(['Email Messages'].EmailMessageSubject, 4) <> 'TEST'
GO

As always, before running a script against a database, make sure you understand the scirpt and have a good backup of the database.