fix: csv: Handle multiple zero amounts in postings in csv files. (#1733)

This commit is contained in:
Stephen Morgan 2021-11-17 10:12:55 +11:00 committed by Simon Michael
parent c6beb581a1
commit 87a7a586d4
2 changed files with 37 additions and 21 deletions

View File

@ -996,33 +996,31 @@ getAmount rules record currency p1IsVirtual n =
]
-- if any of the numbered field names are present, discard all the unnumbered ones
assignments' | any isnumbered assignments = filter isnumbered assignments
| otherwise = assignments
discardUnnumbered xs = if null numbered then xs else numbered
where
isnumbered (f,_) = T.any isDigit f
numbered = filter (T.any isDigit . fst) xs
-- if there's more than one value and only some are zeros, discard the zeros
assignments''
| length assignments' > 1 && not (null nonzeros) = nonzeros
| otherwise = assignments'
where nonzeros = filter (not . mixedAmountLooksZero . snd) assignments'
-- discard all zero amounts, unless all amounts are zero, in which case discard all but the first
discardExcessZeros xs = if null nonzeros then take 1 xs else nonzeros
where
nonzeros = filter (not . mixedAmountLooksZero . snd) xs
in case -- dbg0 ("amounts for posting "++show n)
assignments'' of
[] -> Nothing
[(f,a)] | "-out" `T.isSuffixOf` f -> Just (maNegate a) -- for -out fields, flip the sign
-- XXX unless it's already negative ? back compat issues / too confusing ?
[(_,a)] -> Just a
fs -> error' . T.unpack . T.unlines $ [ -- PARTIAL:
"multiple non-zero amounts or multiple zero amounts assigned,"
-- for -out fields, flip the sign XXX unless it's already negative ? back compat issues / too confusing ?
negateIfOut f = if "-out" `T.isSuffixOf` f then maNegate else id
in case discardExcessZeros $ discardUnnumbered assignments of
[] -> Nothing
[(f,a)] -> Just $ negateIfOut f a
fs -> error' . T.unpack . T.unlines $ -- PARTIAL:
["multiple non-zero amounts assigned,"
,"please ensure just one. (https://hledger.org/csv.html#amount)"
," " <> showRecord record
," for posting: " <> T.pack (show n)
]
++ [" assignment: " <> f <> " " <>
fromMaybe "" (hledgerField rules record f) <>
"\t=> value: " <> wbToText (showMixedAmountB noColour a) -- XXX not sure this is showing all the right info
| (f,a) <- fs]
] ++
[" assignment: " <> f <> " " <>
fromMaybe "" (hledgerField rules record f) <>
"\t=> value: " <> wbToText (showMixedAmountB noColour a) -- XXX not sure this is showing all the right info
| (f,a) <- fs]
-- | Figure out the expected balance (assertion or assignment) specified for posting N,
-- if any (and its parse position).

View File

@ -996,6 +996,24 @@ $ ./csvtest.sh
>=0
# 49. Handle an entry with all zeros
<
Date;Description;Category;Debit;Credit;Balance
"2020-01-21","Client card point of sale fee",Fees,"0","0","1068.94"
RULES
skip 1
fields date, description, category, amount-out, amount-in, balance
currency $
account1 assets:bank:checking
$ ./csvtest.sh
2020-01-21 Client card point of sale fee
assets:bank:checking 0 = $1068.94
expenses:unknown 0
>=0
## .
#<
#$ ./csvtest.sh