SELECT
mmatter AS 'Matter #',
clname1 AS 'Client Name',
dbo.udfMattDesc(mmatter) AS 'Matter Description',
prohead.phindex AS 'Proforma #',
phdate AS 'Date',
dbo.udfTKFullName(mbillaty) AS 'Billing Aty',
COUNT(timecard.tindex) AS '# Timecards',
ISNULL(SUM(timecard.tbilldol),0) AS 'Fee Amount',
COUNT(cost.cindex) AS '# Costcards',
ISNULL(SUM(cost.cbillamt),0) AS 'Cost Amount'
FROM prohead
INNER JOIN matter ON mmatter=phmatter
INNER JOIN client ON mclient=clnum
INNER JOIN timekeep ON mbillaty=tkinit
INNER JOIN prodetail ON prohead.phindex=prodetail.phindex
LEFT OUTER JOIN cost ON prodetail.pddetail=cost.cindex AND pdtype='C' AND cinvoice IS NULL
LEFT OUTER JOIN timecard ON prodetail.pddetail=timecard.tindex AND pdtype='T' AND tinvoice IS NULL
WHERE
phdate >= '1/1/09'
AND phstatus LIKE 'C%'
GROUP BY mmatter,
clname1,
mbillaty,
prohead.phindex,
phdate
HAVING COUNT(timecard.tindex)>0 OR COUNT(cost.cindex)>0
ORDER BY prohead.phindex
Friday, October 30, 2009
Current Proformas
Occasionally I will find myself in need of a list of current proformas pertaining to a specific client or timekeeper. The following code will pull a list of current proformas along with the number and amount of fee entries and number and amount of cost entries. I've used a beginning date in the query that is rather arbitrary, however, some 'recent' date was needed to remove anomalies from conversions long ago. This query uses the Matter Description user defined function.
Labels:
cost,
enterprise,
proforma,
sql,
timecard
Tuesday, October 27, 2009
Volumes - Vouchers
The following is a simple query to assess the volume of vouchers being processed each month. This includes all voucher types.
SELECT
YEAR(votrdt) AS 'Year',
MONTH(votrdt) AS 'Month',
COUNT(vo_id) AS '# Vouchers',
SUM(voamt) AS 'Voucher Amt'
FROM apvo
WHERE
YEAR(votrdt) >= '2005'
GROUP BY YEAR(votrdt),MONTH(votrdt)
ORDER BY YEAR(votrdt),MONTH(votrdt)
Monday, October 26, 2009
Volumes - Credits
This will be the first in a series of queries on volumes of transactions. Understanding the volume of transactions flowing through the system is an important aspect of managing the accounting department. The following measures the number of documents and dollar value of non-reversed payments received by period.
SELECT
YEAR(peendt) AS 'Year',
MONTH(peendt) AS 'Month',
SUM(numdocs) AS '# Documents',
SUM(sumpmt) AS '$ Payments'
FROM
(SELECT
lbatch,
lperiod,
llcode,
peendt,
COUNT(DISTINCT ldocumnt) AS numdocs,
SUM(lamount) AS sumpmt
FROM
ledger
INNER JOIN periodt ON lperiod=pe
INNER JOIN ledcode ON llcode=lccode
WHERE lccollhs='Y'
AND peendt >= '1/1/05'
AND lzero <> 'R'
GROUP BY lbatch,lperiod,llcode,peendt) AS batchledg
GROUP BY YEAR(peendt),MONTH(peendt)
ORDER BY YEAR(peendt),MONTH(peendt)
Labels:
credits,
enterprise,
Ledger,
payments,
sql,
transaction,
volume
Thursday, October 22, 2009
Collections by Worked Period for Specific Collections Month
Collections is an important aspect of any law firm's monthly stats. Delving a little deeper into the collections number, though, can yield some interesting information. The following query will tell you which worked period your collections have come from. For example, let's say in September you collected $5 million dollars. Of that $5 million, 3 million was worked in August and 1 million was worked in July and the other million was worked prior to July. You could now compare this to prior months or prior years to see if your worked period comparisons are staying consistent.
SELECT
peendt,
SUM(lfamnt) AS 'Fee Collections'
FROM ledger l1
INNER JOIN ledgfee l2 ON l1.lindex=l2.lindex
INNER JOIN periodt p1 ON l2.lwoper=p1.pe
INNER JOIN ledcode ON llcode=lccode
WHERE l1.lperiod = '0909' --Collections Period
AND lccollhs = 'Y'
GROUP BY peendt
ORDER BY peendt DESC
Thursday, October 15, 2009
Timekeepers Who've Worked on a Client
The following will return a list of timekeepers that have worked on a particular client for 2009 with the total hours worked. This is sorted by title and then by hours worked descending.
SELECT
tkinit AS 'TK #',
dbo.udfTKFullName(tkinit) AS Timekeeper,
tktitle AS Title,
tkstrate AS 'Standard Rate',
SUM(mthrwkdw) AS 'Hours Worked'
FROM
timekeep
INNER JOIN mattimhs ON mttk=tkinit
INNER JOIN matter ON mtmatter=mmatter
INNER JOIN periodt ON mtper=pe
WHERE mclient='112233'
AND peendt >= '1/1/09'
GROUP BY tktitle,tkstrate,tkinit
ORDER BY tktitle,SUM(mthrwkdw) DESC
Year-to-Date Billed Fees and Cost with Current Work in Process
Elite provides a host of pre-written reports in it's Reports & Queues module, but most never seem to get at exactly what you need. And then when they do, the client names and matter descriptions are cut off at 20 characters (or some other insane #). The below query will give you year-to-date billed fees and costs as well as the current work in process values by matter for a specific client.
SELECT
mmatter AS 'Matter #',
dbo.udfMattDesc(mmatter) AS 'Matter Description',
ISNULL(t.feewip,0) AS 'Fee WIP',
ISNULL(c.wipcost,0) AS 'Cost WIP',
ISNULL(t.feewip,0)+ISNULL(c.wipcost,0) AS 'Total WIP',
ISNULL(t.billamt,0) AS 'Fees Billed YTD',
ISNULL(c.cbillamt,0) AS 'Costs Billed YTD',
ISNULL(t.billamt,0)+ISNULL(c.cbillamt,0) AS 'Total Billed'
FROM matter
LEFT OUTER JOIN
(
SELECT tmatter,
SUM(CASE WHEN tbilldt IS NULL THEN tbilldol ELSE 0 END) AS feewip,
SUM(CASE WHEN RIGHT(tbiper,2)='09' THEN tbilldol ELSE 0 END) AS billamt
FROM timecard
GROUP BY tmatter
) AS t ON mmatter=t.tmatter
LEFT OUTER JOIN
(
SELECT cmatter,
SUM(CASE WHEN cbilldt IS NULL THEN cbillamt ELSE 0 END) AS wipcost,
SUM(CASE WHEN RIGHT(cbiper,2)='09' THEN cbillamt ELSE 0 END) AS cbillamt
FROM cost
GROUP BY cmatter
) AS c ON mmatter = c.cmatter
WHERE mclient='998877'
Labels:
billings,
enterprise,
sql,
wip
Wednesday, October 14, 2009
Conflicts Search Options
One thing about the search options in Conflicts Prospective Search and Quick Search is that the user can modify settings as to which fields in the database are being searched. This can lead to different users performing the same search, but getting different results. To check your users settings here, you can use the following code:
If you notice many differences, especially among a group of people that should have the same settings, you can verify the 'correctness' of an individual and copy those settings to other users without them having to print out the options screen and go item by item. The following code will suffice:
It goes without saying that when you are performing an update on Elite, test liberally on a test system first, and apply update to production system after hours.
select * from vboptions where vboname = 'CnfSearchCustom_UserFields' -- Quick Search settings
select * from vboptions where vboname = 'CnfSearchPro_UserFields' -- Prospective settings
If you notice many differences, especially among a group of people that should have the same settings, you can verify the 'correctness' of an individual and copy those settings to other users without them having to print out the options screen and go item by item. The following code will suffice:
--View Options for user with 'correct' settings.
select vbovalue from vboptions where vboname = 'CnfSearchCustom_UserFields' and vbouser = 'xyz'
--Copy Results from above to the long value below
begin transaction conflictsupdate
update vboptions
set vboptions.vbovalue = 'YYYYYNNNNNNNNYYYNNNNNNYNNNYYNNNNNNNN'
where vboname = 'CnfSearchCustom_UserFields'
and vbouser in ('jkl','ghi','def','abc')
commit transaction conflictsupdate
begin transaction conflictsupdate
update vboptions
set vboptions.vbovalue = 'YYYYYNNNNNNNNYYYNNNNNNYNNNYYNNNNNNNN'
where vboname = 'CnfSearchPro_UserFields'
and vbouser in ('jkl','ghi','def','abc')
commit transaction conflictsupdate
It goes without saying that when you are performing an update on Elite, test liberally on a test system first, and apply update to production system after hours.
Monday, October 5, 2009
Checks with Descriptions for Specific Bank Account
The following will provide a list of checks disbursed on a specific bank account. You can add date qualifications or any other criteria as well. It will return a line for each 'check line', so check numbers and amounts will repeat for checks with multiple lines. This was originally developed for an Extend event, but we ended up going a different direction. This uses the check line description user defined function.
SELECT
csd.cknum,
csd.ckdate,
csd.apnum,
csd.ckamt,
csd.appynm,
csddt.ckline,
csddt.vo_id,
csddt.glnum,
csddt.glrc1,
csddt.amt,
dbo.udfCsdDes(csddt.baid,csddt.cknum,csddt.ckline) AS ckdes,
apvo.voinv,
apvo.voindt,
'********'+RIGHT(ap.apaccount,4) AS acctno
FROM
csd
INNER JOIN csddt ON csd.cknum=csddt.cknum AND csd.baid=csddt.baid
INNER JOIN apvo ON csddt.vo_id = apvo.vo_id
INNER JOIN ap ON csd.apnum=ap.apnum
WHERE csd.baid = 'BANKIACH'
AND voiddt IS NULL
Labels:
accounts payable,
ap,
check,
enterprise,
Extend,
sql
Check Line Description User Defined Function
Ok, by now you've probably figured out that I'm a huge fan of user defined functions. Well, I am. Just this past week I had the need for yet another concatenation of rows thanks to Elite's bizarre handling of description fields. This one relates to check descriptions. Each GL line of a check has a description attached to it that can span multiple lines in the csddes table. So, the following udf will combine all the description lines for each bank / check / check line combination.
You can call this udf in any query by passing the bankid, check number and check line variable, typically from the csddt table. Example will follow in the next post.
USE [son_db]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[udfCsdDes]
(
@baid VARCHAR(8),
@cknum VARCHAR(8),
@ckline INT
)
RETURNS VARCHAR(4800) AS
BEGIN
DECLARE @description VARCHAR(4800)
SELECT @description = ''
SELECT @description = @description + ' ' + des FROM csddes WHERE baid = @baid AND cknum = @cknum AND ckline = @ckline ORDER BY dsline
RETURN LTRIM(RTRIM(@description))
END
You can call this udf in any query by passing the bankid, check number and check line variable, typically from the csddt table. Example will follow in the next post.
Subscribe to:
Posts (Atom)