Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
PadError(entry.meta,
("Attempt to pad an entry with cost for "
"balance: {}".format(pad_balance)),
active_pad))
# Thus our padding lot is without cost by default.
diff_position = position.Position.from_amounts(
amount.Amount(check_amount.number - balance_amount.number,
check_amount.currency))
# Synthesize a new transaction entry for the difference.
narration = ('(Padding inserted for Balance of {} for '
'difference {})').format(check_amount, diff_position)
new_entry = data.Transaction(
active_pad.meta.copy(), active_pad.date, flags.FLAG_PADDING,
None, narration, data.EMPTY_SET, data.EMPTY_SET, [])
new_entry.postings.append(
data.Posting(active_pad.account,
diff_position.units, diff_position.cost,
None, None, None))
neg_diff_position = -diff_position
new_entry.postings.append(
data.Posting(active_pad.source_account,
neg_diff_position.units, neg_diff_position.cost,
None, None, None))
# Save it for later insertion after the active pad.
new_entries[id(active_pad)].append(new_entry)
# Fixup the running balance.
pos, _ = pad_balance.add_position(diff_position)
def extract(self, file, existing_entries):
entries = []
meta = data.new_metadata(file.name, 0)
txn = data.Transaction(
meta,
parse('2017-11-20').date(),
'*',
None,
'Two Postings',
data.EMPTY_SET,
data.EMPTY_SET,
[
data.Posting('Assets:Patrick:CHF', amount.Amount(D('12'), 'CHF'), None, None, None, None),
data.Posting('Assets:Patrick:USD', amount.Amount(D('12'), 'CHF'), None, None, None, None),
]
)
entries.append(txn)
txn = data.Transaction(
meta,
parse('2017-11-20').date(),
'*',
None,
'Single Posting',
data.EMPTY_SET,
data.EMPTY_SET,
def extract_tags_links(string):
"""Extract tags and links from a narration string.
Args:
string: A string, possibly containing tags (`#tag`) and links
(`^link`).
Returns:
A triple (new_string, tags, links) where `new_string` is `string`
stripped of tags and links.
"""
if string is None:
return None, EMPTY_SET, EMPTY_SET
tags = re.findall(r"(?:^|\s)#([A-Za-z0-9\-_/.]+)", string)
links = re.findall(r"(?:^|\s)\^([A-Za-z0-9\-_/.]+)", string)
new_string = re.sub(r"(?:^|\s)[#^]([A-Za-z0-9\-_/.]+)", "", string).strip()
return new_string, frozenset(tags), frozenset(links)
payee = assets_posting.meta[VENMO_PAYEE_KEY] = raw_txn[CSV_TO_KEY if txn_type == 'Payment' else CSV_FROM_KEY]
if note:
assets_posting.meta[VENMO_DESCRIPTION_KEY] = note
if is_transfer:
assets_posting.meta[VENMO_ACCOUNT_DESCRIPTION_KEY] = raw_txn[CSV_DESTINATION_KEY] or raw_txn[CSV_FUNDING_SOURCE_KEY]
links = EMPTY_SET
if link:
links = frozenset(['venmo.%s' % raw_txn[CSV_ID_KEY]])
return Transaction(
meta=None,
date=txn_time.date(),
flag=FLAG_OKAY,
payee=payee,
narration='Transfer' if is_transfer else note,
tags=EMPTY_SET,
links=links,
postings=[
assets_posting,
Posting(
account=FIXME_ACCOUNT,
units=-amount,
cost=None,
price=None,
flag=None,
meta=None,
),
# Create a transaction
meta = data.new_metadata(file.name, index)
if txn_date is not None:
meta['date'] = parse_date_liberally(txn_date,
self.dateutil_kwds)
if txn_time is not None:
meta['time'] = str(dateutil.parser.parse(txn_time).time())
if balance is not None:
meta['balance'] = D(balance)
if last4:
last4_friendly = self.last4_map.get(last4.strip())
meta['card'] = last4_friendly if last4_friendly else last4
date = parse_date_liberally(date, self.dateutil_kwds)
txn = data.Transaction(meta, date, self.FLAG, payee, narration,
tags, data.EMPTY_SET, [])
# Attach one posting to the transaction
amount_debit, amount_credit = get_amounts(iconfig, row)
# Skip empty transactions
if amount_debit is None and amount_credit is None:
continue
for amount in [amount_debit, amount_credit]:
if amount is None:
continue
units = Amount(amount, self.currency)
txn.postings.append(
data.Posting(account, units, None, None, None, None))
# Attach the other posting(s) to the transaction.
if conversion_cost_balance.is_empty():
return entries
# Calculate the index and the date for the new entry. We want to store it as
# the last transaction of the day before.
if date is not None:
index = bisect_key.bisect_left_with_key(entries, date, key=lambda entry: entry.date)
last_date = date - datetime.timedelta(days=1)
else:
index = len(entries)
last_date = entries[-1].date
meta = data.new_metadata('', -1)
narration = 'Conversion for {}'.format(conversion_balance)
conversion_entry = Transaction(meta, last_date, flags.FLAG_CONVERSIONS,
None, narration, data.EMPTY_SET, data.EMPTY_SET, [])
for position in conversion_cost_balance.get_positions():
# Important note: Set the cost to zero here to maintain the balance
# invariant. (This is the only single place we cheat on the balance rule
# in the entire system and this is necessary; see documentation on
# Conversions.)
price = amount.Amount(ZERO, conversion_currency)
neg_pos = -position
conversion_entry.postings.append(
data.Posting(conversion_account, neg_pos.units, neg_pos.cost,
price, None, None))
# Make a copy of the list of entries and insert the new transaction into it.
new_entries = list(entries)
new_entries.insert(index, conversion_entry)
return new_entries
elif rtype == 'SELL':
# Extract the lot. In practice this information not be there
# and you will have to identify the lots manually by editing
# the resulting output. You can leave the cost.number slot
# set to None if you like.
match = re.search(r'\(LOT ([0-9.]+)\)', row['DESCRIPTION'])
if not match:
logging.error("Missing cost basis in '%s'", row['DESCRIPTION'])
continue
cost_number = D(match.group(1))
cost = position.Cost(cost_number, self.currency, None, None)
price = amount.Amount(rate, self.currency)
account_gains = self.account_gains.format(instrument)
txn = data.Transaction(
meta, date, self.FLAG, None, desc, data.EMPTY_SET, {link}, [
data.Posting(self.account_cash, units, None, None, None, None),
data.Posting(self.account_fees, fees, None, None, None, None),
data.Posting(account_inst, units_inst, cost, price, None, None),
data.Posting(account_gains, None, None, None, None, None),
])
else:
logging.error("Unknown row type: %s; skipping", rtype)
continue
entries.append(txn)
# Insert a final balance check.
if index:
entries.append(
data.Balance(meta, date + datetime.timedelta(days=1),
amount = float(real_price.replace(',', ''))
if account == "Unknown":
flag = "!"
meta = {}
meta = data.new_metadata(
'beancount/core/testing.beancount',
12345,
meta
)
entry = Transaction(
meta,
time,
flag,
description,
None,
data.EMPTY_SET,
data.EMPTY_SET, []
)
data.create_simple_posting(
entry, account, trade_price, trade_currency)
data.create_simple_posting(entry, Account中信, None, None)
if not self.deduplicate.find_duplicate(entry, -amount, None, Account中信):
transactions.append(entry)
self.deduplicate.apply_beans()
return transactions
asset_account = holding.account
income_account = account.join(account_types.income,
account.sans_root(holding.account))
if subaccount:
asset_account = account.join(asset_account, subaccount)
income_account = account.join(income_account, subaccount)
# Create a new transaction to account for this difference in gain.
gain_loss_str = "gain" if pnl > ZERO else "loss"
narration = ("Unrealized {} for {h.number} units of {h.currency} "
"(price: {h.price_number:.4f} {h.cost_currency} as of {h.price_date}, "
"average cost: {h.cost_number:.4f} {h.cost_currency})").format(
gain_loss_str, h=holding)
entry = data.Transaction(data.new_metadata(meta["filename"], lineno=1000 + index),
latest_date, flags.FLAG_UNREALIZED,
None, narration, EMPTY_SET, EMPTY_SET, [])
# Book this as income, converting the account name to be the same, but as income.
# Note: this is a rather convenient but arbitrary choice--maybe it would be best to
# let the user decide to what account to book it, but I don't a nice way to let the
# user specify this.
#
# Note: we never set a price because we don't want these to end up in Conversions.
entry.postings.extend([
data.Posting(
asset_account,
amount.Amount(pnl, holding.cost_currency),
None,
None,
None,
None),
data.Posting(
memo = None
narration = ' - '.join(
filter(None,
(raw.trantype, raw.incometype, raw.inv401ksource, name,
memo)))
if ignore_re and re.match(ignore_re, narration):
continue
entry = Transaction(
meta=None,
date=raw.date,
flag=FLAG_OKAY,
payee=None,
narration=narration,
tags=EMPTY_SET,
links=EMPTY_SET,
postings=[])
base_meta = [(OFX_FITID_KEY, raw.fitid)]
posting_meta = collections.OrderedDict(base_meta)
posting_meta[POSTING_DATE_KEY] = raw.date
posting_meta[OFX_TYPE_KEY] = raw.trantype
if memo:
posting_meta[OFX_MEMO_KEY] = memo
if name:
posting_meta[OFX_NAME_KEY] = name