Quantcast

Programming Auto-apply in Accounts Receivable

Get the WebProNews Newsletter:
[ Business]

Microsoft Great Plains is one of three Microsoft Business Solutions mid-market ERP products: Great Plains, Solomon, Navision.

Considering that Great Plains is now very good candidate for integration with POS application, such as Microsoft Retail Management System or RMS and Client Relation Systems, such as Microsoft CRM – there is common need in Great Plains customizations and integrations, especially on the level of MS SQL Server transact SQL queries and stored procedures. In this small article we’ll show you how to create auto-apply utility, when you integrate huge number of sales transactions and payments. We will be working with RM20101 – Receivables Open File and RM20201 – Receivables Apply Open File. Let’s see SQL code:

declare @curpmtamt numeric(19,5)
declare @curinvamt numeric(19,5)
declare @curpmtnum varchar(20)
declare @curinvnum varchar(20)
declare @curinvtype int
declare @curpmttype int
declare @maxid int
declare @counter int

-- Create a temporary table
create table #temp
(
&nbsp&nbsp&nbsp&nbsp [ID] int identity(1,1) primary key,
&nbsp&nbsp&nbsp&nbsp CUSTNMBR varchar(15),
&nbsp&nbsp&nbsp&nbsp INVNUM varchar(20),
&nbsp&nbsp&nbsp&nbsp INVTYPE int,
&nbsp&nbsp&nbsp&nbsp PMTNUM varchar(20),
&nbsp&nbsp&nbsp&nbsp PMTTYPE int,
&nbsp&nbsp&nbsp&nbsp INVAMT numeric(19,5),
&nbsp&nbsp&nbsp&nbsp PMTAMT numeric(19,5),
&nbsp&nbsp&nbsp&nbsp AMTAPPLIED numeric(19,5)
)

create index IDX_INVNUM on #temp (INVNUM)
create index IDX_PMTNUM on #temp (PMTNUM)

-- Insert unapplied invoices and payments
insert into #temp
&nbsp&nbsp&nbsp&nbsp (
&nbsp&nbsp&nbsp&nbsp CUSTNMBR,
&nbsp&nbsp&nbsp&nbsp INVNUM,
&nbsp&nbsp&nbsp&nbsp INVTYPE,
&nbsp&nbsp&nbsp&nbsp PMTNUM,
&nbsp&nbsp&nbsp&nbsp PMTTYPE&nbsp&nbsp&nbsp&nbsp,
&nbsp&nbsp&nbsp&nbsp INVAMT,
&nbsp&nbsp&nbsp&nbsp PMTAMT,
&nbsp&nbsp&nbsp&nbsp AMTAPPLIED
)
select
&nbsp&nbsp&nbsp&nbsp CUSTNMBR = a.CUSTNMBR,
&nbsp&nbsp&nbsp&nbsp INVNUM = b.DOCNUMBR,
&nbsp&nbsp&nbsp&nbsp INVTYPE = b.RMDTYPAL,
&nbsp&nbsp&nbsp&nbsp PMTNUM = a.DOCNUMBR,
&nbsp&nbsp&nbsp&nbsp PMTTYPE = a.RMDTYPAL,
&nbsp&nbsp&nbsp&nbsp INVAMT = b.CURTRXAM,
&nbsp&nbsp&nbsp&nbsp PMTAMT = a.CURTRXAM,
&nbsp&nbsp&nbsp&nbsp AMTAPPLIED = 0
from RM20101 a
&nbsp&nbsp&nbsp&nbsp join RM20101 b on (a.CUSTNMBR = b.CUSTNMBR)
&nbsp&nbsp&nbsp&nbsp join RM00101 c on (a.CUSTNMBR = c.CUSTNMBR)
where
&nbsp&nbsp&nbsp&nbsp a.RMDTYPAL in (7, 8, 9) and
&nbsp&nbsp&nbsp&nbsp b.RMDTYPAL in (1, 3) and
&nbsp&nbsp&nbsp&nbsp a.CURTRXAM <> 0 and
&nbsp&nbsp&nbsp&nbsp b.CURTRXAM <> 0
order by
&nbsp&nbsp&nbsp&nbsp a.custnmbr,
&nbsp&nbsp&nbsp&nbsp b.DOCDATE,
&nbsp&nbsp&nbsp&nbsp a.DOCDATE,
&nbsp&nbsp&nbsp&nbsp a.DOCNUMBR,
&nbsp&nbsp&nbsp&nbsp b.DOCNUMBR

-- Iterate through each record
select @maxid = max([ID])
from #temp

select @counter = 1

while @counter <= @maxid
begin
&nbsp&nbsp&nbsp&nbsp select
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp @curinvnum = INVNUM,
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp @curpmtnum = PMTNUM,
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp @curinvamt = INVAMT,
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp @curpmtamt = PMTAMT,
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp @curinvtype = INVTYPE,
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp @curpmttype = PMTTYPE
&nbsp&nbsp&nbsp&nbsp from
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp #temp
&nbsp&nbsp&nbsp&nbsp where
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [ID] = @counter

&nbsp&nbsp&nbsp&nbsp if (@curinvamt >= @curpmtamt) and (@curpmtamt>0) and (@curinvamt>0)-- if the invoice amount is greater or the same as the payment amount
&nbsp&nbsp&nbsp&nbsp begin
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp select @curinvamt = @curinvamt - @curpmtamt -- invoice amount remaining

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp -- update with the amount that is applied to the current invoice from
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp -- the current payment
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp update #temp
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp set
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp AMTAPPLIED = @curpmtamt
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp where
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [ID] = @counter

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp -- update with amount of invoice remaining
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp update #temp
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp set
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp INVAMT = @curinvamt
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp where
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp INVNUM = @curinvnum and
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp INVTYPE = @curinvtype

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp -- update with amount of payment remaining
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp update #temp
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp set
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PMTAMT = 0
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp where
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PMTNUM = @curpmtnum and
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PMTTYPE = @curpmttype
&nbsp&nbsp&nbsp&nbsp end
&nbsp&nbsp&nbsp&nbsp else if (@curinvamt <= @curpmtamt) and (@curpmtamt>0) and (@curinvamt>0)-- if the invoice amount is lesser to the payment amount
&nbsp&nbsp&nbsp&nbsp begin
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp select @curpmtamt = @curpmtamt - @curinvamt -- payment amount remaining

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp -- update with the amount that is applied to the current invoice from
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp -- the current payment
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp update #temp
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp set
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp AMTAPPLIED = @curinvamt
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp where
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp [ID] = @counter

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp -- update with amount of invoice remaining
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp update #temp
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp set
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp INVAMT = 0
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp where
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp INVNUM = @curinvnum and
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp INVTYPE = @curinvtype

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp -- update with amount of payment remaining
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp update #temp
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp set
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PMTAMT = @curpmtamt
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp where
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PMTNUM = @curpmtnum and
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PMTTYPE = @curpmttype
&nbsp&nbsp&nbsp&nbsp end

&nbsp&nbsp&nbsp&nbsp -- go to the next record
&nbsp&nbsp&nbsp&nbsp select @counter = @counter + 1
end

-- update the RM Open table with the correct amounts
update
&nbsp&nbsp&nbsp&nbsp RM20101
set
&nbsp&nbsp&nbsp&nbsp CURTRXAM = b.INVAMT
from
&nbsp&nbsp&nbsp&nbsp RM20101 a
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp join #temp b on (a.DOCNUMBR = b.INVNUM and a.RMDTYPAL = b.INVTYPE)

update
&nbsp&nbsp&nbsp&nbsp RM20101
set
&nbsp&nbsp&nbsp&nbsp CURTRXAM = b.PMTAMT
from
&nbsp&nbsp&nbsp&nbsp RM20101 a
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp join #temp b on (a.DOCNUMBR = b.PMTNUM and a.RMDTYPAL = b.PMTTYPE)

-- create the RM Apply record or update if records already exist
update
&nbsp&nbsp&nbsp&nbsp RM20201
set
&nbsp&nbsp&nbsp&nbsp DATE1 = convert(varchar(10), getdate(), 101),
&nbsp&nbsp&nbsp&nbsp GLPOSTDT = convert(varchar(10), getdate(), 101),
&nbsp&nbsp&nbsp&nbsp APPTOAMT = APPTOAMT + a.AMTAPPLIED,
&nbsp&nbsp&nbsp&nbsp ORAPTOAM = ORAPTOAM + a.AMTAPPLIED,
&nbsp&nbsp&nbsp&nbsp APFRMAPLYAMT = APFRMAPLYAMT + a.AMTAPPLIED,
&nbsp&nbsp ActualApplyToAmount = APFRMAPLYAMT + a.AMTAPPLIED
from
&nbsp&nbsp&nbsp&nbsp #temp a
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp join RM20101 b on (b.DOCNUMBR = a.INVNUM and b.RMDTYPAL = a.INVTYPE)
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp join RM20101 c on (c.DOCNUMBR = a.PMTNUM and c.RMDTYPAL = a.PMTTYPE)
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp join RM20201 d on (d.APFRDCTY = a.PMTTYPE and
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp d.APFRDCNM = a.PMTNUM and
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp d.APTODCTY = a.INVTYPE and
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp d.APTODCNM = a.INVNUM)
where
&nbsp&nbsp&nbsp&nbsp a.AMTAPPLIED <> 0

insert into RM20201
&nbsp&nbsp&nbsp&nbsp (CUSTNMBR,
&nbsp&nbsp&nbsp&nbsp DATE1,
&nbsp&nbsp&nbsp&nbsp GLPOSTDT,
&nbsp&nbsp&nbsp&nbsp POSTED, APTODCNM,
&nbsp&nbsp&nbsp&nbsp APTODCTY,
&nbsp&nbsp&nbsp&nbsp APTODCDT,
&nbsp&nbsp&nbsp&nbsp ApplyToGLPostDate,
&nbsp&nbsp&nbsp&nbsp CURNCYID,
&nbsp&nbsp&nbsp&nbsp CURRNIDX,
&nbsp&nbsp&nbsp&nbsp APPTOAMT,
&nbsp&nbsp&nbsp&nbsp ORAPTOAM,
&nbsp&nbsp&nbsp&nbsp APFRDCNM,
&nbsp&nbsp&nbsp&nbsp APFRDCTY,
&nbsp&nbsp&nbsp&nbsp APFRDCDT,
&nbsp&nbsp&nbsp&nbsp ApplyFromGLPostDate,
&nbsp&nbsp&nbsp&nbsp FROMCURR,
&nbsp&nbsp&nbsp&nbsp APFRMAPLYAMT,
&nbsp&nbsp&nbsp&nbsp ActualApplyToAmount)
select
&nbsp&nbsp&nbsp&nbsp CUSTNMBR = a.CUSTNMBR,
&nbsp&nbsp&nbsp&nbsp DATE1 = convert(varchar(10), getdate(), 101),
&nbsp&nbsp&nbsp&nbsp GLPOSTDT = convert(varchar(10), getdate(), 101),
&nbsp&nbsp&nbsp&nbsp POSTED = 1,
&nbsp&nbsp&nbsp&nbsp APTODCNM = a.INVNUM,
&nbsp&nbsp&nbsp&nbsp APTODCTY = a.INVTYPE,
&nbsp&nbsp&nbsp&nbsp APTODCDT = b.DOCDATE,
&nbsp&nbsp&nbsp&nbsp ApplyToGLPostDate = b.GLPOSTDT,
&nbsp&nbsp&nbsp&nbsp CURNCYID = b.CURNCYID,
&nbsp&nbsp&nbsp&nbsp CURRNIDX = '',
&nbsp&nbsp&nbsp&nbsp APPTOAMT = a.AMTAPPLIED,
&nbsp&nbsp&nbsp&nbsp ORAPTOAM = a.AMTAPPLIED,
&nbsp&nbsp&nbsp&nbsp APFRDCNM = a.PMTNUM,
&nbsp&nbsp&nbsp&nbsp APFRDCTY = a.PMTTYPE,
&nbsp&nbsp&nbsp&nbsp APFRDCDT = c.DOCDATE,
&nbsp&nbsp&nbsp&nbsp ApplyFromGLPostDate = c.GLPOSTDT,
&nbsp&nbsp&nbsp&nbsp FROMCURR = c.CURNCYID,
&nbsp&nbsp&nbsp&nbsp APFRMAPLYAMT = a.AMTAPPLIED,
&nbsp&nbsp&nbsp&nbsp ActualApplyToAmount = a.AMTAPPLIED
from
&nbsp&nbsp&nbsp&nbsp #temp a
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp join RM20101 b on (b.DOCNUMBR = a.INVNUM and b.RMDTYPAL = a.INVTYPE)
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp join RM20101 c on (c.DOCNUMBR = a.PMTNUM and c.RMDTYPAL = a.PMTTYPE)
where
&nbsp&nbsp&nbsp&nbsp a.AMTAPPLIED <> 0 and
&nbsp&nbsp&nbsp&nbsp not exists (select 1
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp from RM20201 d
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp where d.APFRDCTY = a.PMTTYPE and
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp d.APFRDCNM = a.PMTNUM and
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp d.APTODCTY = a.INVTYPE and
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp d.APTODCNM = a.INVNUM)

drop table #temp

Andrew Karasev is Chief Technology Officer in Alba Spectrum Technologies USA nationwide Microsoft CRM, Microsoft Great Plains customization company, based in Chicago, California, Texas, New York, Georgia and Florida and having locations in multiple states and internationally (www.albaspectrum.com), he is Dexterity, SQL, C#.Net, Crystal Reports and Microsoft CRM SDK developer.

Programming Auto-apply in Accounts Receivable
Comments Off
About Andrew Karasev
Andrew Karasev is Chief Technology Officer in Alba Spectrum Technologies USA nationwide Microsoft CRM, Microsoft Great Plains customization company, based in Chicago, California, Texas, New York, Georgia and Florida and having locations in multiple states and internationally (www.albaspectrum.com), he is Dexterity, SQL, C#.Net, Crystal Reports and Microsoft CRM SDK developer. WebProNews Writer
Top Rated White Papers and Resources

Comments are closed.

  • Join for Access to Our Exclusive Web Tools
  • Sidebar Top
  • Sidebar Middle
  • Sign Up For The Free Newsletter
  • Sidebar Bottom