SQL view for rolling 12 months of sales by item by site in Dynamics GP


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:

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 DYNGRP

Disclaimer: 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.

12 Responses to “SQL view for rolling 12 months of sales by item by site in Dynamics GP”

  1. 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.

    Like

    • 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

      Like

      • 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.

        Like

        • 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

          Like

  2. 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?

    Like

    • 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

      Like

      • 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.

        Like

        • 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

          Like

  3. 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

    Like

  4. Another awesome view! I just used it as part of a data set in Power BI worked great.
    Thank you.

    Like

  5. Stephane Jodouin Reply April 20, 2017 at 3:58 pm

    It works perfectly, thank you so much for this update!
    This will drastically improve our forecast tracking

    Like

  6. Blair Christensen Reply April 20, 2017 at 1:37 pm

    Just tried this out using SSRS and am going to post it for internal comments. Thanks!

    Like

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 )

Facebook photo

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

Connecting to %s

%d bloggers like this: