HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Determining which accounts are to be credited/debited

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
determiningarewhichcreditedaccountsdebited

Problem

I recently discovered/came across linq and have been trying to learn and utilize its features. Here's my first function UpdateTransactionsData(). This method is for a PurchaseDocument class which I have included partially. Basically this function loops through the selected items on the PurchaseDocument, and works out which accounts (chart of accounts, as per accounting) are to be credited/debited for each purchased item.

After I have populated the dictionary properties with the transaction amounts, I use Linq to first remove all the transactions with amount 0 and then to generate XML elements to represent the transactions (provided a sample of the output).

The code works. Am I using LINQ right? Is the code optimal? Can I improve the LINQ code? Should I even be using it?

XmlOutput





PurchaseDocument.cs

`public class PurchaseDocument
{
public Dictionary DebitTransactions = new Dictionary();
public Dictionary CreditTransactions = new Dictionary();
public Dictionary InventoryTransactions = new Dictionary();

#region public ObservableCollection Items;
private ObservableCollection _Items = new ObservableCollection();
public ObservableCollection Items
{
get { return _Items; }
set
{
string property = "Items";
OnPropertyChanging(property);
_Items = value;
OnPropertyChanged(property);
}
}
#endregion

private void UpdateTransactionsData()
{
DebitTransactions.Clear();
CreditTransactions.Clear();
InventoryTransactions.Clear();
Entity.TransactionsData = "";

foreach (PurchaseDocumentItem item in Items.Where(x => x.InventoryItem != null))
{
// asset and expense transactions
int account = (item.InventoryItem.IsService) ? item.InventoryItem.CogsAccountID : item.InventoryItem.AssetAccountID;
if(!DebitTransactions.ContainsKey(account))
DebitTransact

Solution

I don't see any problem with the LINQ you have.

If you wanted, you could use a little bit of LINQ to get rid of that foreach loop you have. You can create two LINQ queries to query the Items collection, group accounts/items together, and return the sum of the Amounts/Quantities as a Dictionary:

DebitTransactions = (from item in Items
                     where item.InventoryItem != null

                     let account = (item.InventoryItem.IsService) ? item.InventoryItem.CogsAccountID : item.InventoryItem.AssetAccountID

                     group item by account into itemGroup
                     select new 
                     {
                        Account = itemGroup.Key,
                        Amount = itemGroup.Sum(i => i.Amount)
                     }).ToDictionary(k => k.Account, v => v.Amount);

InventoryTransactions = (from item in Items
                         where item.InventoryItem != null && !item.InventoryItem.IsService

                         group item by item.ItemID into itemGroup
                         select new
                         {
                            ItemID = itemGroup.Key
                            Quantity = itemGroup.Sum(i => i.Quantity)
                         }).ToDictionary(k => k.ItemID, v => v.Quantity);


It's a little more messy and probably a little less efficient, but good for learning LINQ.

Code Snippets

DebitTransactions = (from item in Items
                     where item.InventoryItem != null

                     let account = (item.InventoryItem.IsService) ? item.InventoryItem.CogsAccountID : item.InventoryItem.AssetAccountID

                     group item by account into itemGroup
                     select new 
                     {
                        Account = itemGroup.Key,
                        Amount = itemGroup.Sum(i => i.Amount)
                     }).ToDictionary(k => k.Account, v => v.Amount);

InventoryTransactions = (from item in Items
                         where item.InventoryItem != null && !item.InventoryItem.IsService

                         group item by item.ItemID into itemGroup
                         select new
                         {
                            ItemID = itemGroup.Key
                            Quantity = itemGroup.Sum(i => i.Quantity)
                         }).ToDictionary(k => k.ItemID, v => v.Quantity);

Context

StackExchange Code Review Q#4364, answer score: 2

Revisions (0)

No revisions yet.