csv: don't discard explicit assignments of a 0 amount
Eg: an `amount1 $0.00` assignment was generating a posting1 with missing amount.
This commit is contained in:
		
							parent
							
								
									f219bba494
								
							
						
					
					
						commit
						3cc79a67f2
					
				| @ -859,37 +859,47 @@ transactionFromCsvRecord sourcepos rules record = t | ||||
|           }   | ||||
| 
 | ||||
| -- | Figure out the amount specified for posting N, if any. | ||||
| -- Looks for a non-zero amount assigned to one of "amountN", "amountN-in", "amountN-out". | ||||
| -- Postings 1 or 2 also look at "amount", "amount-in", "amount-out". | ||||
| -- Throws an error if more than one of these has a non-zero amount assigned. | ||||
| -- A currency symbol to prepend to the amount, if any, is provided, | ||||
| -- and whether posting 1 requires balancing or not. | ||||
| -- This looks for a non-empty amount value assigned to "amountN", "amountN-in", or "amountN-out". | ||||
| -- For postings 1 or 2 it also looks at "amount", "amount-in", "amount-out". | ||||
| -- If more than one of these has a value, it looks for one that is non-zero. | ||||
| -- If there's multiple non-zeros, or no non-zeros but multiple zeros, it throws an error. | ||||
| getAmount :: CsvRules -> CsvRecord -> String -> Bool -> Int -> Maybe MixedAmount | ||||
| getAmount rules record currency p1IsVirtual n = | ||||
|   -- The corner cases are tricky here. | ||||
|   let | ||||
|     unnumberedfieldnames = ["amount","amount-in","amount-out"] | ||||
|     fieldnames = map (("amount"++show n)++) ["","-in","-out"] | ||||
|                  -- For posting 1, also recognise the old amount/amount-in/amount-out names. | ||||
|                  -- For posting 2, the same but only if posting 1 needs balancing. | ||||
|                  ++ if n==1 || n==2 && not p1IsVirtual then unnumberedfieldnames else [] | ||||
|     nonzeroamounts = [(f,a') | f <- fieldnames | ||||
|     nonemptyamounts = [(f,a') | f <- fieldnames | ||||
|                      , Just v@(_:_) <- [strip . renderTemplate rules record <$> hledgerField rules record f] | ||||
|                      , let a = parseAmount rules record currency v | ||||
|                      , not $ isZeroMixedAmount a | ||||
|                        -- With amount/amount-in/amount-out, in posting 2, | ||||
|                        -- flip the sign and convert to cost, as they did before 1.17 | ||||
|                      , let a' = if f `elem` unnumberedfieldnames && n==2 then costOfMixedAmount (-a) else a | ||||
|                      ] | ||||
|     -- If there's more than one non-empty amount, ignore the zeros. | ||||
|     -- Unless they're all zeros. | ||||
|     amounts | ||||
|       | length nonemptyamounts <= 1 = nonemptyamounts | ||||
|       | otherwise = | ||||
|           if null nonzeros then zeros else nonzeros | ||||
|           where (zeros,nonzeros) = partition (isZeroMixedAmount . snd) nonemptyamounts | ||||
| 
 | ||||
|     -- if there's "amount" and "amountN"s, just discard the former | ||||
|     nonzeroamounts' | ||||
|       | length nonzeroamounts > 1 = filter ((/="amount").fst) nonzeroamounts | ||||
|       | otherwise                 = nonzeroamounts | ||||
|   in case nonzeroamounts' of | ||||
|     amounts' | ||||
|       | length amounts > 1 = filter ((/="amount").fst) amounts | ||||
|       | otherwise          = amounts | ||||
| 
 | ||||
|   in case amounts' of | ||||
|       [] -> Nothing | ||||
|       [(f,a)] | "-out" `isSuffixOf` f -> Just (-a)  -- for -out fields, flip the sign | ||||
|       [(_,a)] -> Just a | ||||
|       fs      -> error' $ | ||||
|            "more than one non-zero amount for this record, please ensure just one\n" | ||||
|            "more than one non-zero amount for this record, or multiple zeros - please ensure just one\n" | ||||
|         ++ "    " ++ showRecord record ++ "\n" | ||||
|         ++ unlines ["    rule: " ++ f ++ " " ++ | ||||
|                     fromMaybe "" (hledgerField rules record f) ++ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user