bal/bs/cf/is: sort accounts by account code, if any, then account name
If any accounts have numeric codes assigned via account directives, those accounts will be listed first, lowest account codes first.
This commit is contained in:
		
							parent
							
								
									d420a8b534
								
							
						
					
					
						commit
						9b88fc2ed0
					
				| @ -47,6 +47,7 @@ instance Eq Account where | ||||
| 
 | ||||
| nullacct = Account | ||||
|   { aname = "" | ||||
|   , acode = Nothing | ||||
|   , aparent = Nothing | ||||
|   , asubs = [] | ||||
|   , anumpostings = 0 | ||||
| @ -90,6 +91,10 @@ tieAccountParents = tie Nothing | ||||
|       where | ||||
|         a' = a{aparent=parent, asubs=map (tie (Just a')) asubs} | ||||
| 
 | ||||
| -- | Look up an account's numeric code, if any, from the Journal and set it. | ||||
| accountSetCodeFrom :: Journal -> Account -> Account | ||||
| accountSetCodeFrom j a = a{acode=fromMaybe Nothing $ (lookup (aname a) $ jaccounts j)} | ||||
| 
 | ||||
| -- | Get this account's parent accounts, from the nearest up to the root. | ||||
| parentAccounts :: Account -> [Account] | ||||
| parentAccounts Account{aparent=Nothing} = [] | ||||
| @ -188,7 +193,9 @@ filterAccounts p a | ||||
| -- | Sort each level of an account tree by inclusive amount, | ||||
| -- so that the accounts with largest normal balances are listed first.   | ||||
| -- The provided normal balance sign determines whether normal balances | ||||
| -- are negative or positive. | ||||
| -- are negative or positive, affecting the sort order. Ie, | ||||
| -- if balances are normally negative, then the most negative balances | ||||
| -- sort first, and vice versa. | ||||
| sortAccountTreeByAmount :: NormalSign -> Account -> Account | ||||
| sortAccountTreeByAmount normalsign a | ||||
|   | null $ asubs a = a | ||||
| @ -199,6 +206,19 @@ sortAccountTreeByAmount normalsign a | ||||
|     maybeflip | normalsign==NormallyNegative = id | ||||
|               | otherwise                  = flip | ||||
| 
 | ||||
| -- | Sort each level of an account tree first by the account code | ||||
| -- if any, with the empty account code sorting last, and then by | ||||
| -- the account name.  | ||||
| sortAccountTreeByAccountCodeAndName :: Account -> Account | ||||
| sortAccountTreeByAccountCodeAndName a | ||||
|   | null $ asubs a = a | ||||
|   | otherwise      = a{asubs= | ||||
|       sortBy (comparing accountCodeAndNameForSort) $ map sortAccountTreeByAccountCodeAndName $ asubs a} | ||||
| 
 | ||||
| accountCodeAndNameForSort a = (acode', aname a) | ||||
|   where | ||||
|     acode' = fromMaybe maxBound (acode a) | ||||
| 
 | ||||
| -- | Search an account list by name. | ||||
| lookupAccount :: AccountName -> [Account] -> Maybe Account | ||||
| lookupAccount a = find ((==a).aname) | ||||
|  | ||||
| @ -47,7 +47,7 @@ ledgerFromJournal q j = nullledger{ljournal=j'', laccounts=as} | ||||
|     (q',depthq)  = (filterQuery (not . queryIsDepth) q, filterQuery queryIsDepth q) | ||||
|     j'  = filterJournalAmounts (filterQuery queryIsSym q) $ -- remove amount parts which the query's sym: terms would exclude | ||||
|           filterJournalPostings q' j | ||||
|     as  = accountsFromPostings $ journalPostings j' | ||||
|     as  = map (accountSetCodeFrom j) $ accountsFromPostings $ journalPostings j' | ||||
|     j'' = filterJournalPostings depthq j' | ||||
| 
 | ||||
| -- | List a ledger's account names. | ||||
|  | ||||
| @ -354,6 +354,7 @@ instance Show Reader where show r = rFormat r ++ " reader" | ||||
| -- which let you walk up or down the account tree. | ||||
| data Account = Account { | ||||
|   aname                     :: AccountName,   -- ^ this account's full name | ||||
|   acode                     :: Maybe AccountCode,   -- ^ this account's numeric code, if any (not always set)  | ||||
|   aebalance                 :: MixedAmount,   -- ^ this account's balance, excluding subaccounts | ||||
|   asubs                     :: [Account],     -- ^ sub-accounts | ||||
|   anumpostings              :: Int,           -- ^ number of postings to this account | ||||
|  | ||||
| @ -88,7 +88,7 @@ balanceReport opts q j = (items, total) | ||||
|                          dbg1 "accts" $ | ||||
|                          take 1 $ clipAccountsAndAggregate (queryDepth q) $ flattenAccounts accts | ||||
|           | flat_ opts = dbg1 "accts" $ | ||||
|                          maybesortflat $ | ||||
|                          sortflat $ | ||||
|                          filterzeros $ | ||||
|                          filterempty $ | ||||
|                          drop 1 $ clipAccountsAndAggregate (queryDepth q) $ flattenAccounts accts | ||||
| @ -97,7 +97,7 @@ balanceReport opts q j = (items, total) | ||||
|                          drop 1 $ flattenAccounts $ | ||||
|                          markboring $ | ||||
|                          prunezeros $ | ||||
|                          maybesorttree $ | ||||
|                          sorttree $ | ||||
|                          clipAccounts (queryDepth q) accts | ||||
|           where | ||||
|             balance     = if flat_ opts then aebalance else aibalance | ||||
| @ -105,12 +105,12 @@ balanceReport opts q j = (items, total) | ||||
|             filterempty = filter (\a -> anumpostings a > 0 || not (isZeroMixedAmount (balance a))) | ||||
|             prunezeros  = if empty_ opts then id else fromMaybe nullacct . pruneAccounts (isZeroMixedAmount . balance) | ||||
|             markboring  = if no_elide_ opts then id else markBoringParentAccounts | ||||
|             maybesortflat | sort_amount_ opts = sortBy (maybeflip $ comparing balance) | ||||
|                           | otherwise = id | ||||
|             sortflat | sort_amount_ opts = sortBy (maybeflip $ comparing balance) | ||||
|                      | otherwise         = sortBy (comparing accountCodeAndNameForSort) | ||||
|               where | ||||
|                 maybeflip = if normalbalance_ opts == Just NormallyNegative then id else flip | ||||
|             maybesorttree | sort_amount_ opts = sortAccountTreeByAmount (fromMaybe NormallyPositive $ normalbalance_ opts) | ||||
|                           | otherwise = id | ||||
|             sorttree | sort_amount_ opts = sortAccountTreeByAmount (fromMaybe NormallyPositive $ normalbalance_ opts) | ||||
|                      | otherwise         = sortAccountTreeByAccountCodeAndName | ||||
|       items = dbg1 "items" $ map (balanceReportItem opts q) accts' | ||||
|       total | not (flat_ opts) = dbg1 "total" $ sum [amt | (_,_,indent,amt) <- items, indent == 0] | ||||
|             | otherwise        = dbg1 "total" $ | ||||
|  | ||||
| @ -172,12 +172,13 @@ multiBalanceReport opts q j = MultiBalanceReport (displayspans, sorteditems, tot | ||||
| 
 | ||||
|       sorteditems :: [MultiBalanceReportRow] = | ||||
|         dbg1 "sorteditems" $ | ||||
|         maybesort items | ||||
|         sortitems items | ||||
|         where | ||||
|           maybesort | ||||
|             | not $ sort_amount_ opts         = id | ||||
|             | accountlistmode_ opts == ALTree = sortTreeMultiBalanceReportRowsByAmount | ||||
|             | otherwise                       = sortFlatMultiBalanceReportRowsByAmount | ||||
|           sortitems | ||||
|             | sort_amount_ opts && accountlistmode_ opts == ALTree       = sortTreeMultiBalanceReportRowsByAmount | ||||
|             | sort_amount_ opts                                          = sortFlatMultiBalanceReportRowsByAmount | ||||
|             | not (sort_amount_ opts) && accountlistmode_ opts == ALTree = sortTreeMultiBalanceReportRowsByAccountCodeAndName | ||||
|             | otherwise                                                  = sortFlatMultiBalanceReportRowsByAccountCodeAndName | ||||
|             where | ||||
|               -- Sort the report rows, representing a flat account list, by row total.  | ||||
|               sortFlatMultiBalanceReportRowsByAmount = sortBy (maybeflip $ comparing fifth6) | ||||
| @ -201,11 +202,31 @@ multiBalanceReport opts q j = MultiBalanceReport (displayspans, sorteditems, tot | ||||
|                       setibalance a = a{aibalance=fromMaybe (error "sortTreeMultiBalanceReportRowsByAmount 1") $ lookup (aname a) atotals} | ||||
|                   sortedaccounttree = sortAccountTreeByAmount (fromMaybe NormallyPositive $ normalbalance_ opts) accounttreewithbals | ||||
|                   sortedaccounts = drop 1 $ flattenAccounts sortedaccounttree | ||||
|                   sortedrows = [  | ||||
|                     -- this error should not happen, but it's ugly TODO  | ||||
|                     fromMaybe (error "sortTreeMultiBalanceReportRowsByAmount 2") $ lookup (aname a) anamesandrows | ||||
|                     | a <- sortedaccounts  | ||||
|                     ] | ||||
|                   -- dropped the root account, also ignore any parent accounts not in rows | ||||
|                   sortedrows = concatMap (\a -> maybe [] (:[]) $ lookup (aname a) anamesandrows) sortedaccounts  | ||||
| 
 | ||||
|               -- Sort the report rows by account code if any, with the empty account code coming last, then account name.  | ||||
|               sortFlatMultiBalanceReportRowsByAccountCodeAndName = sortBy (comparing acodeandname) | ||||
|                 where | ||||
|                   acodeandname r = (acode', aname) | ||||
|                     where | ||||
|                       aname = first6 r | ||||
|                       macode = fromMaybe Nothing $ lookup aname $ jaccounts j | ||||
|                       acode' = fromMaybe maxBound macode  | ||||
| 
 | ||||
|               -- Sort the report rows, representing a tree of accounts, by account code and then account name at each level. | ||||
|               -- Convert a tree of account names, look up the account codes, sort and flatten the tree, reorder the rows. | ||||
|               sortTreeMultiBalanceReportRowsByAccountCodeAndName rows = sortedrows | ||||
|                 where | ||||
|                   anamesandrows = [(first6 r, r) | r <- rows] | ||||
|                   anames = map fst anamesandrows | ||||
|                   nametree = treeFromPaths $ map expandAccountName anames | ||||
|                   accounttree = nameTreeToAccount "root" nametree | ||||
|                   accounttreewithcodes = mapAccounts (accountSetCodeFrom j) accounttree | ||||
|                   sortedaccounttree = sortAccountTreeByAccountCodeAndName accounttreewithcodes | ||||
|                   sortedaccounts = drop 1 $ flattenAccounts sortedaccounttree | ||||
|                   -- dropped the root account, also ignore any parent accounts not in rows | ||||
|                   sortedrows = concatMap (\a -> maybe [] (:[]) $ lookup (aname a) anamesandrows) sortedaccounts  | ||||
| 
 | ||||
|       totals :: [MixedAmount] = | ||||
|           -- dbg1 "totals" $ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user