I think the main reason this type of thing has not been done before is that there are to many scenarios to take into account, so it is not as straight forward as it might seem. If you are confident about making some assumptions as to how a Ticket is Paid, then it can be simplified, but chances are, there will be times when the results will not be correct. For example, here is the values returned for a single Ticket - look at how many rows it can return for something you may consider to be “simple”:
###SQL:
SELECT
tv.[Id]
,[AccountTransactionId] as [TxId]
,[AccountTransactionDocumentId] as [DocId]
,tv.[Date]
--,[AccountTypeId]
,atyp.[Name] as [AccType]
--,[AccountId]
,acc.[Name] as [Account]
,[Debit]
,[Credit]
,[Exchange]
,tv.[Name]
--,[AccountTransactionTypeId]
,txtyp.[Name] as [TxType]
--,[DepartmentId]
FROM [AccountTransactionValues] tv
JOIN [AccountTypes] atyp on atyp.[Id]=tv.[AccountTypeId]
JOIN [Accounts] acc on acc.[Id]=tv.[AccountId]
JOIN [AccountTransactionTypes] txtyp on txtyp.[Id]=tv.[AccountTransactionTypeId]
###RESULT:
So that Ticket contains the Sale, Tax T1 and Tax T2, a Rounding Calculation, Payment by 2 types of Cash Currency, and Change was issued in a single Currency (HNL).
Now imagine that Ticket also had a Service Charge Calculation (ie. Tip), and besides being Paid with Cash USD and Cash HNL, it was also partially paid with Customer Account. Or maybe it was Paid with Cash USD only, but the Change amount (Calculation) went to Credit the Customer Account. Or maybe there was a Discount Calculation on the Ticket as well … it just goes on and on …
I could probably eventually craft something that works for my system that takes into account all of the different Transaction Types and scenarios, but it would be very specific to my system, and probably would not work for most other systems.
The real problem here I think is that we should not assume that there is a 1-to-1 Product-to-Payment ratio, which is what your Excel sheet is doing, but it really is rarely that simple.
Anyway, while you can (almost) always get the results you want by building a statement with joins and sub-queries, it can quickly become rather complex and difficult to read and understand. So my preference a lot of the time is to break things down into smaller parts and store the results in @temp
tables, then query them and/or loop through them, and store those results in another @temp
table.
I mean, if you look at the SQL above, that just gets the Values and returns things in a readable format, but to do so, it already joins 4 tables together. Now you want to join the Tickets table on the DocId, and the Orders table on the TicketId.
So for example, I might first get the Ticket Values first (ie. Sale Tx, Tax Tx, Calc Tx, etc.) and maybe the Orders, and compile them into a @Charges
table. Then get all the Payment Values (Cash, CC, Customer Account, etc.) and compile them into a @Payments
table. Then gather all Account Payments into a @Credits
table so we have records for when the Customer made a Payment to their Account. All the while taking into account whatever particular date-span you want to report on.
Of course the Charges and Payments tables should balance each other out, but the total of the Orders often times will not match due to Discounts/Services etc. And that is where things start to break.