Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_budgets(load_doc):
"""
2016-01-01 custom "budget" Expenses:Groceries "weekly" 100.00 CNY
2016-06-01 custom "budget" Expenses:Groceries "weekly" 10.00 EUR"""
entries, _, _ = load_doc
budget = Budgets(entries)
budgets = budget.budget('Expenses:Groceries', date(2016, 6, 1), date(2016, 6, 8)) # noqa
assert budgets['CNY'] == Decimal(100)
assert budgets['EUR'] == Decimal(10)
def test_fmt_number_de():
assert fmt_number_de('1') == Decimal(1)
assert fmt_number_de('1,50') == Decimal(1.50)
assert fmt_number_de('150') == Decimal(150)
assert fmt_number_de('15,0') == Decimal(15)
assert fmt_number_de('1234,0') == Decimal(1234)
def test_fmt_number_de():
assert fmt_number_de('1') == Decimal(1)
assert fmt_number_de('1,50') == Decimal(1.50)
assert fmt_number_de('150') == Decimal(150)
assert fmt_number_de('15,0') == Decimal(15)
assert fmt_number_de('1234,0') == Decimal(1234)
groups = collections.defaultdict(list)
for position in self:
key = (position.units.currency,
position.cost.currency if position.cost else None)
groups[key].append(position)
average_inventory = Inventory()
for (currency, cost_currency), positions in groups.items():
total_units = sum(position.units.number
for position in positions)
units_amount = Amount(total_units, currency)
if cost_currency:
total_cost = sum(convert.get_cost(position).number
for position in positions)
cost_number = (Decimal('Infinity')
if total_units == ZERO
else (total_cost / total_units))
min_date = None
for pos in positions:
pos_date = pos.cost.date if pos.cost else None
if pos_date is not None:
min_date = (pos_date
if min_date is None
else min(min_date, pos_date))
cost = Cost(cost_number, cost_currency, min_date, None)
else:
cost = None
average_inventory.add_amount(units_amount, cost)
return average_inventory
def _portfolio_data(self, nodes, date):
"""
Turn a portfolio of tree nodes into querytable-style data.
Args:
nodes: Account tree nodes.
date: Date.
Return:
types: Tuples of column names and types as strings.
rows: Dictionaries of row data by column names.
"""
operating_currency = self.ledger.options["operating_currency"][0]
acct_type = ("account", str(str))
bal_type = ("balance", str(Decimal))
alloc_type = ("allocation", str(Decimal))
types = [acct_type, bal_type, alloc_type]
rows = []
portfolio_total = ZERO
for node in nodes:
row = {}
row["account"] = node.name
balance = cost_or_value(node.balance, date)
if operating_currency in balance:
balance_dec = balance[operating_currency]
portfolio_total += balance_dec
row["balance"] = balance_dec
rows.append(row)
for row in rows:
def normalize_fraction(d: Decimal) -> Decimal:
normalized = d.normalize()
sign, digits, exponent = normalized.as_tuple()
if exponent > 0:
return Decimal((sign, tuple(digits) + (0, ) * exponent, 0))
else:
return normalized
def fix_meta(meta):
if meta is None:
return None
meta = meta.copy()
for k in meta:
if isinstance(meta[k], int):
meta[k] = Decimal(meta[k])
return meta
# A regular expression to match the name of a currency.
# Note: This is kept in sync with "beancount/parser/lexer.l".
CURRENCY_RE = '[A-Z][A-Z0-9\'\.\_\-]{0,22}[A-Z0-9]'
class Amount:
"""An 'Amount' represents a number of a particular unit of something.
It's essentially a typed number, with corresponding manipulation operations
defined on it.
"""
__slots__ = ('number', 'currency')
valid_types_number = (Decimal, type, type(None))
valid_types_currency = (str, type, type(None))
def __init__(self, number, currency):
"""Constructor from a number and currency.
Args:
number: A string or Decimal instance. Will get converted automatically.
currency: A string, the currency symbol to use.
"""
assert isinstance(number, self.valid_types_number), repr(number)
assert isinstance(currency, self.valid_types_currency), repr(currency)
self.number = number
self.currency = currency
def to_string(self, dformat=DEFAULT_FORMATTER):
"""Convert an Amount instance to a printable string.
lines, delimiter=';', quoting=csv.QUOTE_MINIMAL, quotechar='"'
)
for line in reader:
key, value, _ = line
line_index += 1
if key.startswith('Von'):
self._date_from = datetime.strptime(
value, '%d.%m.%Y'
).date()
elif key.startswith('Bis'):
self._date_to = datetime.strptime(value, '%d.%m.%Y').date()
elif key.startswith('Saldo'):
self._balance_amount = Amount(
Decimal(value.rstrip(' EUR')), self.currency
)
closing_balance_index = line_index
elif key.startswith('Datum'):
self._balance_date = datetime.strptime(
value, '%d.%m.%Y'
).date() + timedelta(days=1)
expected_keys.remove(key)
if expected_keys:
raise ValueError()
# Another empty line
line = fd.readline().strip()
line_index += 1
else:
# Merge the matching postings to a single one.
merged_units = inventory.Inventory()
merged_cost = inventory.Inventory()
for match in matches:
merged_units.add_amount(match.units)
merged_cost.add_amount(convert.get_weight(match))
if len(merged_units) != 1 or len(merged_cost) != 1:
errors.append(
AmbiguousMatchError(
entry.meta,
'Cannot merge positions in multiple currencies: {}'.format(
', '.join(position.to_string(match_posting)
for match_posting in matches)), entry))
else:
if (isinstance(posting.cost.number_per, Decimal) or
isinstance(posting.cost.number_total, Decimal)):
errors.append(
AmbiguousMatchError(
entry.meta,
"Explicit cost reductions aren't supported yet: {}".format(
position.to_string(posting)), entry))
else:
# Insert postings to remove all the matches.
postings.extend(posting._replace(units=-match.units, cost=match.cost,
flag=flags.FLAG_MERGING)
for match in matches)
units = merged_units[0].units
date = matches[0].cost.date ## FIXME: Select which one,
## oldest or latest.
cost_units = merged_cost[0].units
cost = Cost(cost_units.number/units.number, cost_units.currency,