Updated Procedure with Bank Balances
SqlServer,
SqlServer Useful functions
Introduction
ALTER PROCEDURE [dbo].[GetCategoryAccountSummary]
@FromDate DATE = NULL,
@ToDate DATE = NULL
AS
BEGIN
-- Normalize date range
IF @FromDate IS NULL SET @FromDate = DATEFROMPARTS(YEAR(GETDATE()), 4, 1);
IF @ToDate IS NULL SET @ToDate = EOMONTH(GETDATE());
-- Cash Opening Balance
DECLARE @OpeningCashBalance DECIMAL(18,2);
SELECT @OpeningCashBalance = SUM(TransactionNetAmount)
FROM AccountHierarchyNew
WHERE Category = 'Cash-In-Hand'
AND TransactionDate = DATEFROMPARTS(YEAR(@FromDate), 4, 1);
-- Cash Movement
DECLARE @CashMovement DECIMAL(18,2);
SELECT @CashMovement =
SUM(CASE WHEN TransactionType = 'Credit' THEN TransactionNetAmount ELSE 0 END) -
SUM(CASE WHEN TransactionType = 'Debit' THEN TransactionNetAmount ELSE 0 END)
FROM VoucherDetails
WHERE Receipt_PaymentMode = 'Cash'
AND ReceiptDate BETWEEN @FromDate AND @ToDate;
DECLARE @CashBalance DECIMAL(18,2) = ISNULL(@OpeningCashBalance, 0) + ISNULL(@CashMovement, 0);
-- Bank Opening Balance
DECLARE @OpeningBankBalance DECIMAL(18,2);
SELECT @OpeningBankBalance = SUM(TransactionNetAmount)
FROM AccountHierarchyNew
WHERE AccountType IN ('Canara Bank Current A/c', 'ICICI Bank Current A/c')
AND TransactionDate = DATEFROMPARTS(YEAR(@FromDate), 4, 1);
-- Bank Movement
DECLARE @BankMovement DECIMAL(18,2);
SELECT @BankMovement =
SUM(CASE WHEN TransactionType = 'Credit' THEN TransactionNetAmount ELSE 0 END) -
SUM(CASE WHEN TransactionType = 'Debit' THEN TransactionNetAmount ELSE 0 END)
FROM VoucherDetails
WHERE AccountType IN ('Canara Bank Current A/c', 'ICICI Bank Current A/c')
AND ReceiptDate BETWEEN @FromDate AND @ToDate;
DECLARE @BankBalance DECIMAL(18,2) = ISNULL(@OpeningBankBalance, 0) + ISNULL(@BankMovement, 0);
-- Base data
CREATE TABLE #BaseData (
Section NVARCHAR(20),
Category NVARCHAR(100),
Account NVARCHAR(100),
Amount DECIMAL(18, 2),
SortRank INT
);
-- Actual voucher data
INSERT INTO #BaseData (Section, Category, Account, Amount, SortRank)
SELECT
CASE
WHEN Prefix IN ('R', 'A') THEN 'Receipts'
WHEN Prefix = 'V' THEN 'Payments'
END,
Receipt_PaymentMode,
AccountType,
TransactionNetAmount,
2
FROM VoucherDetails
WHERE Prefix IN ('R', 'A', 'V')
AND ReceiptDate BETWEEN @FromDate AND @ToDate;
-- Synthetic Opening Balances
INSERT INTO #BaseData VALUES ('Receipts', 'Cash', 'Opening Balance', @CashBalance, 1);
INSERT INTO #BaseData VALUES ('Receipts', 'Bank', 'Opening Balance', @BankBalance, 1);
-- Synthetic Closing Balances
INSERT INTO #BaseData VALUES ('Payments', 'Cash', 'Closing Balance', @CashBalance, 3);
INSERT INTO #BaseData VALUES ('Payments', 'Bank', 'Closing Balance', @BankBalance, 3);
-- CTEs
WITH ReceiptsCTE AS (
SELECT
ROW_NUMBER() OVER (ORDER BY SortRank, Category, Account) AS RowNum,
Category AS ReceiptCategory,
Account AS ReceiptAccount,
SUM(Amount) AS Receipts
FROM #BaseData
WHERE Section = 'Receipts'
GROUP BY Category, Account, SortRank
),
PaymentsCTE AS (
SELECT
ROW_NUMBER() OVER (ORDER BY SortRank, Category, Account) AS RowNum,
Category AS PaymentCategory,
Account AS PaymentAccount,
SUM(Amount) AS Payments
FROM #BaseData
WHERE Section = 'Payments'
GROUP BY Category, Account, SortRank
),
Combined AS (
SELECT
R.ReceiptCategory,
R.ReceiptAccount,
R.Receipts,
P.PaymentCategory,
P.PaymentAccount,
P.Payments
FROM ReceiptsCTE R
FULL OUTER JOIN PaymentsCTE P ON R.RowNum = P.RowNum
)
-- Final output
SELECT *
FROM (
SELECT
ReceiptCategory,
ReceiptAccount,
Receipts,
PaymentCategory,
PaymentAccount,
Payments,
0 AS SortOrder
FROM Combined
UNION ALL
SELECT
'TOTAL',
NULL,
SUM(Receipts),
'TOTAL',
NULL,
SUM(Payments),
1
FROM Combined
) AS FinalResult
ORDER BY SortOrder,
CASE
WHEN ReceiptCategory = 'Cash' AND ReceiptAccount = 'Opening Balance' THEN 0
WHEN ReceiptCategory = 'Bank' AND ReceiptAccount = 'Opening Balance' THEN 1
ELSE 2
END,
CASE
WHEN PaymentCategory = 'Cash' AND PaymentAccount = 'Closing Balance' THEN 2
WHEN PaymentCategory = 'Bank' AND PaymentAccount = 'Closing Balance' THEN 3
ELSE 1
END,
ReceiptCategory,
ReceiptAccount;
DROP TABLE #BaseData;
END;
Description
ALTER PROCEDURE [dbo].[GetCategoryAccountSummary]
@FromDate DATE = NULL,
@ToDate DATE = NULL
AS
BEGIN
-- Normalize date range
IF @FromDate IS NULL SET @FromDate = DATEFROMPARTS(YEAR(GETDATE()), 4, 1);
IF @ToDate IS NULL SET @ToDate = EOMONTH(GETDATE());
-- Cash Opening Balance
DECLARE @OpeningCashBalance DECIMAL(18,2);
SELECT @OpeningCashBalance = SUM(TransactionNetAmount)
FROM AccountHierarchyNew
WHERE Category = 'Cash-In-Hand'
AND TransactionDate = DATEFROMPARTS(YEAR(@FromDate), 4, 1);
-- Cash Movement
DECLARE @CashMovement DECIMAL(18,2);
SELECT @CashMovement =
SUM(CASE WHEN TransactionType = 'Credit' THEN TransactionNetAmount ELSE 0 END) -
SUM(CASE WHEN TransactionType = 'Debit' THEN TransactionNetAmount ELSE 0 END)
FROM VoucherDetails
WHERE Receipt_PaymentMode = 'Cash'
AND ReceiptDate BETWEEN @FromDate AND @ToDate;
DECLARE @CashBalance DECIMAL(18,2) = ISNULL(@OpeningCashBalance, 0) + ISNULL(@CashMovement, 0);
-- Bank Opening Balance
DECLARE @OpeningBankBalance DECIMAL(18,2);
SELECT @OpeningBankBalance = SUM(TransactionNetAmount)
FROM AccountHierarchyNew
WHERE AccountType IN ('Canara Bank Current A/c', 'ICICI Bank Current A/c')
AND TransactionDate = DATEFROMPARTS(YEAR(@FromDate), 4, 1);
-- Bank Movement
DECLARE @BankMovement DECIMAL(18,2);
SELECT @BankMovement =
SUM(CASE WHEN TransactionType = 'Credit' THEN TransactionNetAmount ELSE 0 END) -
SUM(CASE WHEN TransactionType = 'Debit' THEN TransactionNetAmount ELSE 0 END)
FROM VoucherDetails
WHERE AccountType IN ('Canara Bank Current A/c', 'ICICI Bank Current A/c')
AND ReceiptDate BETWEEN @FromDate AND @ToDate;
DECLARE @BankBalance DECIMAL(18,2) = ISNULL(@OpeningBankBalance, 0) + ISNULL(@BankMovement, 0);
-- Base data
CREATE TABLE #BaseData (
Section NVARCHAR(20),
Category NVARCHAR(100),
Account NVARCHAR(100),
Amount DECIMAL(18, 2),
SortRank INT
);
-- Actual voucher data
INSERT INTO #BaseData (Section, Category, Account, Amount, SortRank)
SELECT
CASE
WHEN Prefix IN ('R', 'A') THEN 'Receipts'
WHEN Prefix = 'V' THEN 'Payments'
END,
Receipt_PaymentMode,
AccountType,
TransactionNetAmount,
2
FROM VoucherDetails
WHERE Prefix IN ('R', 'A', 'V')
AND ReceiptDate BETWEEN @FromDate AND @ToDate;
-- Synthetic Opening Balances
INSERT INTO #BaseData VALUES ('Receipts', 'Cash', 'Opening Balance', @CashBalance, 1);
INSERT INTO #BaseData VALUES ('Receipts', 'Bank', 'Opening Balance', @BankBalance, 1);
-- Synthetic Closing Balances
INSERT INTO #BaseData VALUES ('Payments', 'Cash', 'Closing Balance', @CashBalance, 3);
INSERT INTO #BaseData VALUES ('Payments', 'Bank', 'Closing Balance', @BankBalance, 3);
-- CTEs
WITH ReceiptsCTE AS (
SELECT
ROW_NUMBER() OVER (ORDER BY SortRank, Category, Account) AS RowNum,
Category AS ReceiptCategory,
Account AS ReceiptAccount,
SUM(Amount) AS Receipts
FROM #BaseData
WHERE Section = 'Receipts'
GROUP BY Category, Account, SortRank
),
PaymentsCTE AS (
SELECT
ROW_NUMBER() OVER (ORDER BY SortRank, Category, Account) AS RowNum,
Category AS PaymentCategory,
Account AS PaymentAccount,
SUM(Amount) AS Payments
FROM #BaseData
WHERE Section = 'Payments'
GROUP BY Category, Account, SortRank
),
Combined AS (
SELECT
R.ReceiptCategory,
R.ReceiptAccount,
R.Receipts,
P.PaymentCategory,
P.PaymentAccount,
P.Payments
FROM ReceiptsCTE R
FULL OUTER JOIN PaymentsCTE P ON R.RowNum = P.RowNum
)
-- Final output
SELECT *
FROM (
SELECT
ReceiptCategory,
ReceiptAccount,
Receipts,
PaymentCategory,
PaymentAccount,
Payments,
0 AS SortOrder
FROM Combined
UNION ALL
SELECT
'TOTAL',
NULL,
SUM(Receipts),
'TOTAL',
NULL,
SUM(Payments),
1
FROM Combined
) AS FinalResult
ORDER BY SortOrder,
CASE
WHEN ReceiptCategory = 'Cash' AND ReceiptAccount = 'Opening Balance' THEN 0
WHEN ReceiptCategory = 'Bank' AND ReceiptAccount = 'Opening Balance' THEN 1
ELSE 2
END,
CASE
WHEN PaymentCategory = 'Cash' AND PaymentAccount = 'Closing Balance' THEN 2
WHEN PaymentCategory = 'Bank' AND PaymentAccount = 'Closing Balance' THEN 3
ELSE 1
END,
ReceiptCategory,
ReceiptAccount;
DROP TABLE #BaseData;
END;