By popular request I have created a variation on my rolling 12 months of sales by item to show a rolling 12 months of sales by item and site ID in Dynamics GP. This view will return the last 12 months, not including the current month. So if you’re running this today – April 20, 2017 – it will show you April 2016 through March 2017. The names of the monthly columns are generic – if you’re using a reporting tool with this, you can use formulas to have more meaningful column names. Please check the view comments to see other assumptions I am making.
Related code and table information:
- Sales Order Processing (SOP) tables
- Inventory tables
- Sales Order Processing (SOP) SQL views
- Inventory SQL views
create view view_Rolling_12_Mo_Sales_by_Item_Site as -- ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ -- view_Rolling_12_Mo_Sales_by_Item_Site -- Created Apr 20, 2017 by Victoria Yudin, Flexible Solutions -- For updates see https://victoriayudin.com/gp-reports/ -- Returns total sales (invoices - returns) for each item for -- the last 12 months. Current month is not included, -- even if it is the last day of the month. -- Only posted invoices and returns are included. -- Voided transactions are excluded. -- Item Description is taken from Inventory Item Maintenance -- for all inventory items, and from SOP line items -- for non-inventory items. -- Document Date is used (not GL Posting Date). -- ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ select rtrim(d.ITEMNMBR) Item_Number, rtrim(d.ITEMDESC) Item_Description, rtrim(d.ITMGEDSC) Generic_Description, rtrim(d.ITMCLSCD) Item_Class, rtrim(d.USCATVLS_1) User_Category_1, rtrim(d.LOCNCODE) Site_ID, sum(case when month(d.DOCDATE) = month(dateadd(m, -12, getdate())) and year(d.DOCDATE) = year(dateadd(m, -12, getdate())) then d.SALES else 0 end) as [Sales_12_mo_ago], sum(case when month(d.DOCDATE) = month(dateadd(m, -11, getdate())) and year(d.DOCDATE) = year(dateadd(m, -11, getdate())) then d.SALES else 0 end) as [Sales_11_mo_ago], sum(case when month(d.DOCDATE) = month(dateadd(m, -10, getdate())) and year(d.DOCDATE) = year(dateadd(m, -10, getdate())) then d.SALES else 0 end) as [Sales_10_mo_ago], sum(case when month(d.DOCDATE) = month(dateadd(m, -9, getdate())) and year(d.DOCDATE) = year(dateadd(m, -9, getdate())) then d.SALES else 0 end) as [Sales_9_mo_ago], sum(case when month(d.DOCDATE) = month(dateadd(m, -8, getdate())) and year(d.DOCDATE) = year(dateadd(m, -8, getdate())) then d.SALES else 0 end) as [Sales_8_mo_ago], sum(case when month(d.DOCDATE) = month(dateadd(m, -7, getdate())) and year(d.DOCDATE) = year(dateadd(m, -7, getdate())) then d.SALES else 0 end) as [Sales_7_mo_ago], sum(case when month(d.DOCDATE) = month(dateadd(m, -6, getdate())) and year(d.DOCDATE) = year(dateadd(m, -6, getdate())) then d.SALES else 0 end) as [Sales_6_mo_ago], sum(case when month(d.DOCDATE) = month(dateadd(m, -5, getdate())) and year(d.DOCDATE) = year(dateadd(m, -5, getdate())) then d.SALES else 0 end) as [Sales_5_mo_ago], sum(case when month(d.DOCDATE) = month(dateadd(m, -4, getdate())) and year(d.DOCDATE) = year(dateadd(m, -4, getdate())) then d.SALES else 0 end) as [Sales_4_mo_ago], sum(case when month(d.DOCDATE) = month(dateadd(m, -3, getdate())) and year(d.DOCDATE) = year(dateadd(m, -3, getdate())) then d.SALES else 0 end) as [Sales_3_mo_ago], sum(case when month(d.DOCDATE) = month(dateadd(m, -2, getdate())) and year(d.DOCDATE) = year(dateadd(m, -2, getdate())) then d.SALES else 0 end) as [Sales_2_mo_ago], sum(case when month(d.DOCDATE) = month(dateadd(m, -1, getdate())) and YEAR(d.DOCDATE) = year(dateadd(m, -1, getdate())) then d.SALES else 0 end) as [Sales_1_mo_ago] from (select sh.DOCDATE, sd.ITEMNMBR, sd.LOCNCODE, coalesce(i.ITEMDESC, sd.ITEMDESC) ITEMDESC, coalesce(i.ITMGEDSC, '') ITMGEDSC, coalesce(i.ITMCLSCD,'') ITMCLSCD, coalesce(i.USCATVLS_1,'') USCATVLS_1, case sd.SOPTYPE when 3 then sd.XTNDPRCE when 4 then sd.XTNDPRCE*-1 end SALES from SOP30200 sh -- SOP header inner join SOP30300 sd -- SOP lines on sd.SOPNUMBE = sh.SOPNUMBE and sd.SOPTYPE = sh.SOPTYPE left outer join IV00101 i -- item master on i.ITEMNMBR = sd.ITEMNMBR where sh.VOIDSTTS = 0 -- not voided and sh.SOPTYPE IN (3,4) -- only invoices and returns and sd.XTNDPRCE <> 0 -- excludes zero price and sd.ITEMNMBR not like 'XXXXXXXXXXXXXXX%' and sh.DOCDATE > dateadd(d, -1, dateadd(m, datediff(m, 0, dateadd(m, -12, getdate())), 0)) ) d group by d.ITEMNMBR, d.ITEMDESC, d.ITMGEDSC, d.ITMCLSCD, d.USCATVLS_1, d.LOCNCODE -- add permissions for DYNGRP go grant select on view_Rolling_12_Mo_Sales_by_Item_Site to DYNGRPDisclaimer: I tested this on limited data, if you find an issue or have a suggestion for improvement, please let me know and I will post the update here for everyone.
Victoria,
I have a question. We are on GP2010 and I was wondering if there is a SQL or Smartlist for Deferred Revenue. What we want to do is confirm the “contract” = Quarterly, Yearly, etc. with the invoices that are generated via that contract. We have found some example of invoices that were created but were not being deferred which we then had to do manually to the GL.
LikeLike
Hi Joanna,
Are you using the Revenue and Expense Deferrals module in GP? If so, unfortunately, there are no SmartLists for that data. There should be a report and inquiry window for Deferrals. I know they are in my GP 2016 and I am pretty certain they are also in GP 2010, but I don’t have any easy way of confirming that. Not sure if those will give you what you need, though.
I’ve done some custom reporting on this in the past, but it’s typically pretty specific to the data and report needed, as people use this module in different ways. If that is what you need, let me know if you are interested in pursuing this as a consulting engagement.
-Victoria
LikeLike
Thanks Victoria for the quick response.
I will look into the Deferred Expense Module and see if this will work for what we are looking for.
LikeLike
Hi Joanna,
Sorry if I misunderstood your question – I thought you were already using that module. If you’re not and you need deferrals – it’s perfect for many situations. But since you’re on GP 2010 you might need to check into your GP licensing to see if you have it already and if not, what your options are.
-Victoria
LikeLike
Victoria, First of all.. thank you for creating this site. I can’t tell you how many times I’ve come here to find translations for fields like RMDTYPL, DISTTYPE and the like.
I’m working on a GP 2015 project. (My experience dates back to Dynamics 3.15… how old am I??) Anyway, I need to create a report the “reassembles” allocation entries from the GL20000 and 30000 tables. Unfortunately, I can’t find anything in the tables that clearly and unambiguously indicates that these were enter using a Fixed or Variable allocation account.
Do you know of either any table that stores the original allocation entry OR any way to identify GL Entries that were entered using an allocation account?
LikeLike
Hi Tom,
Thank you for your kind words. I have worked with GP since it was on DOS, so I guess I am old, too. 🙂
My understanding of how allocations work in GP is that it’s a temporary place holder. As soon as the transaction is posted, the allocation accounts get “translated” into the actual posting accounts and there is nothing stored anywhere to let you know that there was an allocation done.
Why do you need to report on this? Perhaps if I knew what the ultimate goal was I could think of something else to recommend.
-Victoria
LikeLike
One of our VP’s is trying to get a list of expenses for a particular office. The office expenses are posted to allocation accounts then split to various cost centers. Of course, the accounts in the cost centers also include expenses that have nothing to do with the office expenses. (This means a trial balance wouldn’t be sufficient.)
This would be easy if the allocated expenses went through AP. PM30600 still has the allocation account’s DISTINDX. Trouble is than many of those AP vouchers debit a prepaid account (prepaid rent for example). We use a gl entry to credit prepaid and debit allocation. Those entries, like you say, seem to be temporary.
LikeLike
Tom,
The only thing I can think of is this is something that needs to be tracked is tracking it in some other way. For example on all transactions that belong to the office that you need to track, enter something else, maybe using MDA or Extender. Then report off that. However that would require additional entry for people that are entering the transactions and them remembering to do this. I don’t think it’s a lot of additional work, but more the change and the remembering that would be important. 😦
-Victoria
LikeLike
Victoria, you do such great work and your scripts have been helpful to me so often.
I wanted to share a template I use for creating Views and such.
— this first section checks to see if the view exists and if so drops it before creating the view
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = N’Your_View_Name_Here’
AND type = ‘V’) — note the type is V for view, P for Stored Proc, U for Table
DROP view Your_View_Name_Here
GO
create view Your_View_Name_Here
as
–…place body of the view here and end with a ‘Go’ statement……………
go
— this will grant select rights to the view.
grant select on Your_View_Name_Here to DYNGRP
Go
LikeLike
Another awesome view! I just used it as part of a data set in Power BI worked great.
Thank you.
LikeLike
It works perfectly, thank you so much for this update!
This will drastically improve our forecast tracking
LikeLike
Just tried this out using SSRS and am going to post it for internal comments. Thanks!
LikeLike