E-Mail Reminders for Overdue Receivables

This topic contains instructions for creating a job that identifies overdue receivables and sends e-mail reminders to the financial managers of debtors.
Declaring Global Variables
First, declare the global variables:
declare
@cSubjekt char(40), -- subject ID
@cImePriimek varchar(255), -- full name of financial manager
@cEmail varchar(255), -- e-mail address
@cVezniDok varchar(20), -- linked document (invoice number)
@dDatumVal datetime, -- due date
@dDatumDok datetime, -- document date
@mDebet money, -- debit amount
@mKredit money, -- credit amount
@mSaldo money, -- balance
@mGrandTotal money, -- total balance of subject
@cNaslovEmaila varchar(255), -- e-mail subject
@cSeznam varchar(8000) -- list of overdue invoices
Retrieving Financial Managers
The following code opens a recordset containing the names, subject IDs, and e-mail addresses of financial managers.
Because e-mails are sent only to contacts with a valid e-mail address, a standard JOIN is sufficient and there is no need to use a LEFT JOIN or RIGHT JOIN.
-- Prepare recordset with all financial managers
declare crDolzniki cursor local fast_forward for
select RTrim(C.IME)+' '+RTrim(C.PRIIMEK) as IMEPRIIMEK,C.SUBJEKT, A.TEL
from CONTACTS C
join CONTADDRESS A on C.SUBJEKT = A.SUBJEKT and C.POZ = A.POZ and TIP = 'E'
where C.VLOGA like 'Financial manager'
open crDolzniki
fetch next from crDolzniki into @cImePriimek, @cSubjekt, @cEmail
while @@fetch_status = 0
begin -- loop through all financial managers
-- !!! INSERT SOMETHING USEFUL HERE !!! --
fetch next from crDolzniki into @cImePriimek, @cSubjekt, @cEmail
end
close crDolzniki
deallocate crDolzniki
Retrieving Overdue Invoices
The following query retrieves all overdue invoices for a specific subject and stores them in a recordset.
-- Create a recordset with overdue items for each subject
declare crOdprte cursor local fast_forward for
select
P.VEZNIDOK,
(select top 1 X.DATUMVAL
from TEMEPOZ X
where X.SUBJEKT = P.SUBJEKT
and X.KONTO = P.KONTO
and X.VEZNIDOK = P.VEZNIDOK
and X.DEBET <> 0
order by X.DATUMVAL) as DATUMVAL,
(select top 1 X.DATUMDOK
from TEMEPOZ X
where X.SUBJEKT = P.SUBJEKT
and X.KONTO = P.KONTO
and X.VEZNIDOK = P.VEZNIDOK
and X.DEBET <> 0
order by X.DATUMVAL) as DATUMDOK,
Sum(P.DEBET) as DEBET,
Sum(P.KREDIT) as KREDIT,
Sum(P.DEBET - P.KREDIT) as Saldo
from TEME G
join TEMEPOZ P on P.KLJUC = G.KLJUC
and P.KONTO = '1200'
and (P.DATUMVAL <= GetDate())
where P.SUBJEKT = @cSubjekt
group by P.VEZNIDOK, P.SUBJEKT, P.KONTO
having (Sum(P.DEBET - P.KREDIT) <> 0)
order by P.VEZNIDOK
Building the E-Mail Message
Use the following code to transfer data from the recordset into the e-mail message body (@cSeznam).
set @cSeznam = ''
set @mGrandTotal = 0
open crOdprte
fetch next from crOdprte into @cVezniDok,@dDatumVal,@dDatumDok,@mDebet,@mKredit,@mSaldo
while @@fetch_status = 0
begin
set @cSeznam = @cSeznam + @cVezniDok + Convert(char(12),@dDatumVal,104) + Convert(char(12),@dDatumDok,104)
+ Convert(char(17),@mDebet,1) + Convert(char(17),@mKredit,1) + Convert(char(17),@mSaldo,1)
+ Char(13) + Char(10)
set @mGrandTotal = @mGrandTotal + @mSaldo
fetch next from crOdprte into @cVezniDok,@dDatumVal,@dDatumDok,@mDebet,@mKredit,@mSaldo
end
close crOdprte
deallocate crOdprte
Sending the E-Mail
Check whether the list contains any overdue items and send the e-mail message.
if @cSeznam <> ''
begin
set @cNaslovEmaila = 'List of overdue items for ' + @cSubjekt + ' as of: ' + Convert(varchar(12),GetDate(),104)
set @cSeznam = '-----------------------------------------------------------------------------------------------' + Char(13) + Char(10) + @cSeznam
set @cSeznam = 'Linked document Due date Doc. date Debit Credit Balance' + Char(13) + Char(10) + @cSeznam
set @cSeznam = @cNaslovEmaila + Char(13) + Char(10) + @cSeznam
set @cSeznam = @cSeznam + Char(13) + Char(10) + 'Total:.....................................................................' + Convert(char(19),@mGrandTotal,1)
-- Send e-mail
exec master.dbo.xp_sendmail
@recipients = @cEmail,
@message = @cSeznam,
@subject = @cNaslovEmaila
end
Scheduling the Job
Add the complete query to a SQL Server Job, define an execution schedule, and the process is ready to run automatically.
Note: One SQL Server Job step can contain a maximum of 7,800 characters.
The query below is provided without comments and unnecessary spaces to comply with this limitation.
declare
@cSubjekt char(40),
@cImePriimek varchar(255),
@cEmail varchar(255),
@cVezniDok varchar(20),
@dDatumVal datetime,
@dDatumDok datetime,
@mDebet money,
@mKredit money,
@mSaldo money,
@mGrandTotal money,
@cNaslovEmaila varchar(255),
@cSeznam varchar(8000)
declare crDolzniki cursor local fast_forward for
select RTrim(C.IME)+' '+RTrim(C.PRIIMEK) as IMEPRIIMEK,C.SUBJEKT, A.TEL
from CONTACTS C
join CONTADDRESS A on C.SUBJEKT = A.SUBJEKT and C.POZ = A.POZ and TIP = 'E'
where C.VLOGA like 'Finančni direktor'
open crDolzniki
fetch next from crDolzniki into @cImePriimek, @cSubjekt, @cEmail
while @@fetch_status = 0
begin
declare crOdprte cursor local fast_forward for
select
P.VEZNIDOK,
(select top 1 X.DATUMVAL
from TEMEPOZ X
where X.SUBJEKT = P.SUBJEKT
and X.KONTO = P.KONTO
and X.VEZNIDOK = P.VEZNIDOK
and X.DEBET <> 0
order by X.DATUMVAL) as DATUMVAL,
(select top 1 X.DATUMDOK
from TEMEPOZ X
where X.SUBJEKT = P.SUBJEKT
and X.KONTO = P.KONTO
and X.VEZNIDOK = P.VEZNIDOK
and X.DEBET <> 0
order by X.DATUMVAL) as DATUMDOK,
Sum(P.DEBET) as DEBET,
Sum(P.KREDIT) as KREDIT,
Sum(P.DEBET - P.KREDIT) as Saldo
from TEME G
join TEMEPOZ P on P.KLJUC = G.KLJUC
and P.KONTO = '1200'
and (P.DATUMVAL <= GetDate())
where P.SUBJEKT = @cSubjekt
group by P.VEZNIDOK, P.SUBJEKT, P.KONTO
having (Sum(P.DEBET - P.KREDIT) <> 0)
order by P.VEZNIDOK
set @cSeznam = ''
set @mGrandTotal = 0
open crOdprte
fetch next from crOdprte into @cVezniDok,@dDatumVal,@dDatumDok,@mDebet,@mKredit,@mSaldo
while @@fetch_status = 0
begin
set @cSeznam = @cSeznam + @cVezniDok + Convert(char(12),@dDatumVal,104) + Convert(char(12),@dDatumDok,104)
+ Convert(char(17),@mDebet,1) + Convert(char(17),@mKredit,1) + Convert(char(17),@mSaldo,1) + Char(13) + Char(10)
set @mGrandTotal = @mGrandTotal + @mSaldo
fetch next from crOdprte into @cVezniDok,@dDatumVal,@dDatumDok,@mDebet,@mKredit,@mSaldo
end
close crOdprte
deallocate crOdprte
if @cSeznam <> ''
begin
set @cNaslovEmaila = 'List of overdue items for ' + @cSubjekt + ' as of: ' + Convert(varchar(12),GetDate(),104)
set @cSeznam = '-----------------------------------------------------------------------------------------------' + Char(13) + Char(10) + @cSeznam
set @cSeznam = 'Linked document Due date Doc. date Debit Credit Balance' + Char(13) + Char(10) + @cSeznam
set @cSeznam = @cNaslovEmaila + Char(13) + Char(10) + @cSeznam
set @cSeznam = @cSeznam + Char(13) + Char(10) + 'Total:.....................................................................' + Convert(char(19),@mGrandTotal,1)
exec master.dbo.xp_sendmail
@recipients = @cEmail,
@message = @cSeznam,
@subject = @cNaslovEmaila
end
fetch next from crDolzniki into @cImePriimek, @cSubjekt, @cEmail
end
close crDolzniki
deallocate crDolzniki