def createRandomTransactions(book, accountA, accountB): split = Split(book) currency = book.get_table().lookup("CURRENCY", "EUR") print("Create 100 random transactions") for i in range(100): trans = Transaction(book) trans.BeginEdit() trans.SetCurrency(currency) trans.SetDate(randint(1, 28), randint(1, 12), randint(1900, 2000)) trans.SetDescription("Transaction " + str(i)) value = randint(0, 10000) value1 = GncNumeric(value, 100) value2 = GncNumeric(-value, 100) split1 = Split(book) split1.SetValue(value1) split1.SetAccount(accountA) split1.SetMemo("A" + str(i)) split1.SetParent(trans) split2 = Split(book) split2.SetValue(value2) split2.SetAccount(accountB) split2.SetMemo("B" + str(i)) split2.SetParent(trans) trans.CommitEdit()
def create_gnc_prices(self, tx1, tx2): """ create and load Gnucash prices to the Gnucash PriceDB :param tx1: first transaction :param tx2: matching transaction, if exists :return: nil """ print_info('create_gnc_prices()', MAGENTA) pr_date = dt(tx1[TRADE_YR], tx1[TRADE_MTH], tx1[TRADE_DAY]) datestring = pr_date.strftime("%Y-%m-%d") int_price = int((tx1[GROSS] * 100) / (tx1[UNITS] / 10000)) val = GncNumeric(int_price, 10000) print_info("Adding: {}[{}] @ ${}".format(tx1[ACCT].GetName(), datestring, val)) pr1 = GncPrice(self.book) pr1.begin_edit() pr1.set_time64(pr_date) comm = tx1[ACCT].GetCommodity() print_info("Commodity = {}:{}".format(comm.get_namespace(), comm.get_printname())) pr1.set_commodity(comm) pr1.set_currency(self.curr) pr1.set_value(val) pr1.set_source_string("user:price") pr1.set_typestr('nav') pr1.commit_edit() if tx1[SWITCH]: # get the price for the paired Tx int_price = int((tx2[GROSS] * 100) / (tx2[UNITS] / 10000)) val = GncNumeric(int_price, 10000) print_info("Adding: {}[{}] @ ${}".format(tx2[ACCT].GetName(), datestring, val)) pr2 = GncPrice(self.book) pr2.begin_edit() pr2.set_time64(pr_date) comm = tx2[ACCT].GetCommodity() print_info("Commodity = {}:{}".format(comm.get_namespace(), comm.get_printname())) pr2.set_commodity(comm) pr2.set_currency(self.curr) pr2.set_value(val) pr2.set_source_string("user:price") pr2.set_typestr('nav') pr2.commit_edit() if self.mode == PROD: print_info("Mode = {}: Add Price1 to DB.".format(self.mode), GREEN) self.price_db.add_price(pr1) if tx1[SWITCH]: print_info("Mode = {}: Add Price2 to DB.".format(self.mode), GREEN) self.price_db.add_price(pr2) else: print_info("Mode = {}: ABANDON Prices!\n".format(self.mode), RED)
def setUp(self): BookSession.setUp(self) self.today = datetime.today() self.bank = Account(self.book) self.bank.SetType(ACCT_TYPE_BANK) self.bank.SetCommodity(self.currency) self.income = Account(self.book) self.income.SetType(ACCT_TYPE_INCOME) self.income.SetCommodity(self.currency) self.receivable = Account(self.book) self.receivable.SetType(ACCT_TYPE_RECEIVABLE) self.receivable.SetCommodity(self.currency) self.customer = Customer(self.book,'CustomerID',self.currency) self.vendor = Vendor(self.book,'VendorID',self.currency) self.employee = Employee(self.book,'EmployeeID',self.currency) self.job = Job(self.book,'JobID',self.customer) self.invoice = Invoice(self.book,'InvoiceID',self.currency,self.customer) self.invoice.SetDateOpened(self.today) entry = Entry(self.book) entry.SetDate(self.today) entry.SetDescription("Some income") entry.SetQuantity(GncNumeric(1)) entry.SetInvAccount(self.income) entry.SetInvPrice(GncNumeric(100)) self.invoice.AddEntry(entry) self.invoice.PostToAccount(self.receivable, self.today, self.today, "", True, False)
def _insert_transaction(session, record, currency, rec_date, account_to, account_from): book = session.book # set currency comm_table = book.get_table() currency = comm_table.lookup("CURRENCY", currency) transaction = gnucash.Transaction(book) transaction.BeginEdit() split_to = Split(book) # TODO - create money representation based on fractions value = GncNumeric(record.value.cents(), 100) split_to.SetValue(value) split_to.SetAccount(account_to) split_to.SetParent(transaction) split_from = Split(book) split_from.SetValue(value.neg()) split_from.SetAccount(account_from) split_from.SetParent(transaction) # set transaction values transaction.SetDate(rec_date.day, rec_date.month, rec_date.year) transaction.SetDescription(record.description) transaction.SetCurrency(currency) transaction.CommitEdit()
def fi_to_gui (self): npp = GncNumeric(self.financial_info.fi_info.npp, 1) self.amounts[FinCalcDialog.FinCalcValues.PAYMENT_PERIODS].set_amount(npp) self.amounts[FinCalcDialog.FinCalcValues.INTEREST_RATE].set_damount(self.financial_info.fi_info.ir) self.amounts[FinCalcDialog.FinCalcValues.PRESENT_VALUE].set_damount(self.financial_info.fi_info.pv) self.amounts[FinCalcDialog.FinCalcValues.PERIODIC_PAYMENT].set_damount(self.financial_info.fi_info.pmt) self.amounts[FinCalcDialog.FinCalcValues.FUTURE_VALUE].set_damount(self.financial_info.fi_info.fv) pmt = gnucash.gnucash_core_c.double_to_gnc_numeric(self.financial_info.fi_info.pmt, 100000, GNC_HOW_RND_ROUND_HALF_UP) pmt = GncNumeric(instance=pmt) #commodity = gnc_default_currency() #total = npp.mul(pmt, commodity.get_fraction(), GNC_HOW_RND_ROUND_HALF_UP) total = npp.mul(pmt, 1000, GNC_HOW_RND_ROUND_HALF_UP) #total_string = str(total) #total_string = PrintAmount(total, gnc_default_print_info(False)) total_string = PrintAmount(total) self.payment_total_label.set_text(total_string) (i, self.financial_info.fi_info.CF) = self.normalize_period(self.financial_info.fi_info.CF) self.compounding_combo.set_active(i) (i, self.financial_info.fi_info.PF) = self.normalize_period(self.financial_info.fi_info.PF) self.payment_combo.set_active(i) self.end_of_period_radio.set_active(not self.financial_info.fi_info.bep) self.discrete_compounding_radio.set_active(self.financial_info.fi_info.disc)
def add_transaction(book, item, currency): logging.info('Adding transaction for account "%s" (%s %s)..', item.account, item.split_amount, currency.get_mnemonic()) root = book.get_root_account() acc = lookup_account(root, item.account) tx = Transaction(book) tx.BeginEdit() tx.SetCurrency(currency) tx.SetDateEnteredTS(datetime.datetime.now()) tx.SetDatePostedTS(item.date) tx.SetDescription(item.memo) s1 = Split(book) s1.SetParent(tx) s1.SetAccount(acc) amount = int( Decimal(item.split_amount.replace(',', '.')) * currency.get_fraction()) s1.SetValue(GncNumeric(amount, currency.get_fraction())) s1.SetAmount(GncNumeric(amount, currency.get_fraction())) acc2 = lookup_account(root, item.split_category) s2 = Split(book) s2.SetParent(tx) s2.SetAccount(acc2) s2.SetValue(GncNumeric(amount * -1, currency.get_fraction())) s2.SetAmount(GncNumeric(amount * -1, currency.get_fraction())) tx.CommitEdit()
def test_from_int(self): num = GncNumeric(3) self.assertEqual(str(num), "3/1") self.assertEqual(num.num(), 3) self.assertEqual(num.denom(), 1) with self.assertRaises(Exception) as context: GncNumeric((2**64)+1) #On Linux it raises an OverflowError while on MacOS it's a TypeError. self.assertTrue(isinstance(context.exception, TypeError) or isinstance(context.exception, OverflowError))
def test_incorect_args(self): with self.assertRaises(TypeError): GncNumeric(1, 2, 3) with self.assertRaises(TypeError): GncNumeric("1", 2) with self.assertRaises(TypeError): GncNumeric(1.1, "round") with self.assertRaises(TypeError): GncNumeric(complex(1, 1))
def test_from_long(self): num = GncNumeric(3L) self.assertEqual(str(num), "3/1") self.assertEqual(num.num(), 3) self.assertEqual(num.denom(), 1) with self.assertRaises(Exception) as context: GncNumeric((2**64)+1) #On Linux it raises an OverflowError while on MacOS it's a TypeError. self.assertTrue(isinstance(context.exception, TypeError) or isinstance(context.exception, OverflowError))
def gnc_numeric_to_python_decimal(numeric): negative = numeric.negative_p() sign = 1 if negative else 0 copy = GncNumeric(numeric.num(), numeric.denom()) result = copy.to_decimal(None) if not result: raise Exception("GncNumeric value '{}' CANNOT be converted to decimal!".format(copy.to_string())) digit_tuple = tuple(int(char) for char in str(copy.num()) if char != '-') denominator = copy.denom() exponent = int(log10(denominator)) assert( (10 ** exponent) == denominator ) return Decimal((sign, digit_tuple, -exponent))
def _transfer(self, book, d): from_ac = book.get_root_account().lookup_by_code(d['TransferFromAC']) if not from_ac: raise LookupError('TransferFromAC ({0}) not found'.format( d['TransferFromAC'])) to_ac = book.get_root_account().lookup_by_code(d['TransferToAC']) if not to_ac: raise LookupError('TransferToAC ({0}) not found'.format( d['TransferToAC'])) if 'Currency' in d: currency = book.get_table().lookup('CURRENCY', d['Currency']) else: currency = book.get_table().lookup('CURRENCY', 'CHF') if not currency: raise LookupError('Currency ({0}) not found'.format(d['Currency'])) trans = Transaction(book) trans.BeginEdit() trans.SetCurrency(currency) date = d.get('Date', datetime.date.today()) trans.SetDate(date.day, date.month, date.year) # trans.SetDateEnteredTS(datetime.datetime.now()) # trans.SetDatePostedTS(item.date) trans.SetDescription( d.get('Description', 'Auto Generated by Json import')) amount = int(d.get('Amount', 0) * currency.get_fraction()) split1 = Split(book) split1.SetParent(trans) split1.SetAccount(from_ac) split1.SetValue(GncNumeric(amount, currency.get_fraction())) split1.SetAmount(GncNumeric(amount, currency.get_fraction())) split2 = Split(book) split2.SetParent(trans) split2.SetAccount(to_ac) split2.SetValue(GncNumeric(amount * -1, currency.get_fraction())) split2.SetAmount(GncNumeric(amount * -1, currency.get_fraction())) trans.CommitEdit() logging.info( 'New Transfer: Amount {0} , from:{1}, to:{2}, memo: {3}'.format( d.get('Amount', 0), d['TransferFromAC'], d['TransferToAC'], d.get('Description', 'Auto Generated by Json import')))
def decimal_to_gnc_numeric(d): denom = 100 d = d * denom while d % 1: denom *= 10 d *= 10 return GncNumeric(int(d), denom)
def gnc_numeric_from_decimal(decimal_value): sign, digits, exponent = decimal_value.as_tuple() # convert decimal digits to a fractional numerator # equivlent to # numerator = int(''.join(digits)) # but without the wated conversion to string and back, # this is probably the same algorithm int() uses numerator = 0 TEN = int(Decimal(0).radix()) # this is always 10 numerator_place_value = 1 # add each digit to the final value multiplied by the place value # from least significant to most sigificant for i in range(len(digits) - 1, -1, -1): numerator += digits[i] * numerator_place_value numerator_place_value *= TEN if decimal_value.is_signed(): numerator = -numerator # if the exponent is negative, we use it to set the denominator if exponent < 0: denominator = TEN**(-exponent) # if the exponent isn't negative, we bump up the numerator # and set the denominator to 1 else: numerator *= TEN**exponent denominator = 1 return GncNumeric(numerator, denominator)
def record_opening_balance(original_account, new_account, new_book, opening_balance_per_currency, commodity_tuple ): # create an opening balance if the account type is right if new_account.GetType() in ACCOUNT_TYPES_TO_OPEN: final_balance = original_account.GetBalance() if final_balance.num() != 0: # if there is a new currency type, associate with the currency # a Transaction which will be the opening transaction for that # currency and a GncNumeric value which will be the opening # balance acccount amount if commodity_tuple not in opening_balance_per_currency: trans = Transaction(new_book) trans.BeginEdit() opening_balance_per_currency[commodity_tuple] = ( trans, GncNumeric(0, 1) ) trans, total = opening_balance_per_currency[commodity_tuple] new_total = total.sub( final_balance, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT ) initialize_split( new_book, final_balance, new_account, trans) opening_balance_per_currency[commodity_tuple] = \ (trans, new_total )
def test_from_str(self): num = GncNumeric("3.1") self.assertEqual(str(num), "31/10") self.assertEqual(num.num(), 31) self.assertEqual(num.denom(), 10) num = GncNumeric("1/3") self.assertEqual(str(num), "1/3") self.assertEqual(num.num(), 1) self.assertEqual(num.denom(), 3)
def to_string_with_decimal_point_placed(number: GncNumeric): """Convert a GncNumeric to a string with decimal point placed if permissible. Otherwise returns its fractional representation. """ number = copy.copy(number) if not number.to_decimal(None): return str(number) nominator = str(number.num()) point_place = str(number.denom()).count('0') # How many zeros in the denominator? if point_place == 0: return nominator if len(nominator) <= point_place: # prepending zeros if the nominator is too short nominator = '0' * (point_place - len(nominator)) + nominator return '.'.join([nominator[:-point_place - 1], nominator[-point_place:]])
def test_payment(self): self.assertFalse( self.invoice.IsPaid() ) self.customer.ApplyPayment( self.invoice, self.receivable, self.bank, GncNumeric(50), GncNumeric(50), self.today, "", "") self.assertFalse( self.invoice.IsPaid() ) BAL = self.invoice.GetPostedLot().get_balance() self.assertTrue( GncNumeric(50).equal( BAL ) ) self.customer.ApplyPayment( self.invoice, self.receivable, self.bank, GncNumeric(50), GncNumeric(50), self.today, "", "") self.assertTrue( self.invoice.IsPaid() )
def gnc_numeric_to_python_Decimal(numeric): negative = numeric.negative_p() if negative: sign = 1 else: sign = 0 copy = GncNumeric(numeric.num(), numeric.denom()) result = copy.to_decimal(None) if not result: raise Exception("gnc numeric value %s can't be converted to deciaml" % copy.to_string() ) digit_tuple = tuple( int(char) for char in str(copy.num()) if char != '-' ) denominator = copy.denom() exponent = int(log10(denominator)) assert( (10 ** exponent) == denominator ) return Decimal( (sign, digit_tuple, -exponent) )
def get_quote_onvista_bond(isin): url = 'http://www.onvista.de/anleihen/snapshot.html?ISIN={}'.format(isin) r = requests.get(url) soup = BeautifulSoup(r.text) price = soup.select( '.INHALT #KURSINFORMATIONEN ~ .t span:nth-of-type(2)')[0].get_text() currency = 'EUR' logging.info('Got quote for %s: %s%%', isin, price) return GncNumeric(int(price.replace(',', '')), 100 * 100), currency
def get_quote_onvista_stock(isin): url = 'http://www.onvista.de/suche/?searchValue={}'.format(isin) r = requests.get(url) soup = BeautifulSoup(r.text) spans = soup.select('.INHALT ul.KURSDATEN li:nth-of-type(1) span') price = spans[0].get_text() currency = str(spans[1].get_text()) logging.info('Got quote for %s: %s %s', isin, price, currency) return GncNumeric(int(price.replace(',', '')), 1000), currency
def test_from_float(self): num = GncNumeric(3.1, 20, GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER) self.assertEqual(str(num), "62/20") self.assertEqual(num.num(), 62) self.assertEqual(num.denom(), 20) num = GncNumeric(1/3.0, 10000000000, GNC_HOW_RND_FLOOR) self.assertEqual(str(num), "3333333333/10000000000") self.assertEqual(num.num(), 3333333333) self.assertEqual(num.denom(), 10000000000) num = GncNumeric(1/3.0, 10000000000, GNC_HOW_RND_CEIL) self.assertEqual(str(num), "3333333334/10000000000") self.assertEqual(num.num(), 3333333334) self.assertEqual(num.denom(), 10000000000)
def add_transaction(self, item): """ add new transaction item must have following keys """ assert "date" in item.keys() assert "description" in item.keys() assert "notes" in item.keys() assert "soll" in item.keys() assert "soll_value" in item.keys() assert "haben" in item.keys() assert "haben_value" in item.keys() commod_tab = self.__book.get_table() currency = commod_tab.lookup('ISO4217', "EUR") logging.info('Adding transaction for account "%s" (%s %s)..', item["soll"], item["soll_value"], currency.get_mnemonic()) tx = Transaction(self.__book) tx.BeginEdit() tx.SetCurrency(currency) tx.SetDateEnteredTS(datetime.datetime.now()) tx.SetDatePostedTS(item["date"]) tx.SetDescription(item["description"]) tx.SetNotes(item["notes"]) if "num" in item.keys(): tx.SetNum(item["num"]) # soll acc = self.account_from_path(self.get_root(), item["soll"].split(".")) s1 = Split(self.__book) s1.SetParent(tx) s1.SetAccount(acc) amount = int(item["soll_value"] * currency.get_fraction()) s1.SetValue(GncNumeric(amount, currency.get_fraction())) s1.SetAmount(GncNumeric(amount, currency.get_fraction())) # haben acc2 = self.account_from_path(self.get_root(), item["haben"].split(".")) s2 = Split(self.__book) s2.SetParent(tx) s2.SetAccount(acc2) amount = int(item["haben_value"] * currency.get_fraction()) s2.SetValue(GncNumeric(amount, currency.get_fraction())) s2.SetAmount(GncNumeric(amount, currency.get_fraction())) tx.CommitEdit()
def _payment(self, book, d): account = book.get_root_account().lookup_by_code(d['TransferAC']) if not account: raise LookupError('TransferAC not found') if 'Currency' in d: currency = book.get_table().lookup('CURRENCY', d['Currency']) else: currency = book.get_table().lookup('CURRENCY', 'CHF') if not currency: raise LookupError('Currency not found') if 'BillID' in d: invoice = book.InvoiceLookupByID(to_str(d['BillID'], GC_ENC)) if not invoice: logging.error('Invoice {0} not found'.format( d.get('BillID', 'unknown'))) else: if not invoice.IsPosted(): logging.warn('Invoice {0} is not yet posted'.format( d.get('BillID', 'unknown'))) if invoice.IsPaid(): logging.warn( 'Invoice {0} is already paid, create credit note'.format( d.get('BillID', 'unknown'))) invoice.ApplyPayment( None, account, GncNumeric(int(d.get('Amount', 0) * currency.get_fraction()), currency.get_fraction()), GncNumeric(1), d.get('Date', datetime.date.today()), to_str(d.get('Memo', 'File Import'), GC_ENC), to_str(d.get('BillID', 'unknown'), GC_ENC)) logging.info( 'Payment of {0} for bill {1} entered (Memo: {2})'.format( d.get('Amount', 0), d['BillID'], d.get('Memo', 'File Import')))
def pay_invoice(book, invoice_id, amount, date): invoice = book.InvoiceLookupByID(invoice_id) if not invoice: raise InvoiceNotFound("Could not find invoice %s" % invoice_id) if invoice_id in queries.get_payment_refs(book): raise PaymentExists("Payment %s already exists" % invoice_id) bank = queries.get_bank_account(book) amount = gnc_numeric_from_decimal(amount) invoice.ApplyPayment(None, bank, amount, GncNumeric(1), date, "", invoice_id)
def write_transactions(self, transactions): for transaction in transactions: tx = Transaction(self.book) tx.BeginEdit() tx.SetCurrency(self.currency) tx.SetDateEnteredTS(datetime.datetime.now()) tx.SetDatePostedTS(transaction.datetime) tx.SetDescription(transaction.description) tx.SetNotes(transaction.note) for split in transaction.splits: sp = Split(self.book) sp.SetParent(tx) sp.SetAccount(GnucashBook.lookup_account(self, split.account)) sp.SetMemo(split.memo) amount = int( Decimal(split.amount) * self.currency.get_fraction()) sp.SetValue(GncNumeric(amount, self.currency.get_fraction())) sp.SetAmount(GncNumeric(amount, self.currency.get_fraction())) tx.CommitEdit()
def apply_payment(book, customer_id, amount, date): customer = book.CustomerLookupByID(customer_id) if not customer: raise CustomerNotFound("Could not find customer %s" % customer_id) posted_acc = queries.get_accounts_receivable(book) xfer_acc = queries.get_bank_account(book) check = queries.get_duplicate_check_data(xfer_acc) if [date, amount] in check: raise PaymentExists("Payment %s already exists" % customer_id) amount = gnc_numeric_from_decimal(amount) customer.ApplyPayment(None, None, posted_acc, xfer_acc, amount, GncNumeric(1), date, "", "", True)
def gnc_numeric_from_decimal(decimal_value): sign, digits, exponent = decimal_value.as_tuple() numerator = 0 TEN = int(Decimal(0).radix()) # numerator_place_value = 1 for i in xrange(len(digits) - 1, -1, -1): numerator += digits[i] * numerator_place_value numerator_place_value *= TEN if decimal_value.is_signed(): numerator = -numerator if exponent < 0: denominator = TEN**(-exponent) else: numerator *= TEN**exponent denominator = 1 return GncNumeric(numerator, denominator)
class AccountReport: def __init__(self, account, startdate, enddate, title=None): self.account = account self.title = title or self.account.get_full_name() self.startdate = startdate self.enddate = enddate self._get_splits() self._make_report() def _get_splits(self): self.splits = self.account.GetSplitList() def f(x): txn = x.GetParent() txn_date = date.fromtimestamp(txn.GetDate()) return txn_date >= self.startdate and txn_date <= self.enddate self.splits = filter(f, self.splits) def _make_report(self): self.total = GncNumeric() self.entries = [] for split in self.splits: txn = split.GetParent() desc = txn.GetDescription() memo = split.GetMemo() txn_date = date.fromtimestamp(txn.GetDate()) amount = split.GetValue() self.total = self.total.add_fixed(amount) self.entries.append({ 'date': txn_date, 'owner': desc, 'desc': memo, 'amount': amount, }) (self.report_total,self.report_rest) = gncn_round_with_rest(self.total) def write(self,io): w = csv.writer(io) w.writerow([]) w.writerow(['Name',self.title]) w.writerow(['Total',self.total]) w.writerow(['Report Total',str(self.report_total)]) w.writerow(['Report Rest',str(self.report_rest)]) w.writerow(['Transactions','Date','Owner','Description','Amount']) for entry in self.entries: w.writerow(['',entry['date'],entry['owner'],entry['desc'],str(entry['amount'])]) w.writerow([])
def _make_report(self): self.total = GncNumeric() self.entries = [] for split in self.splits: txn = split.GetParent() desc = txn.GetDescription() memo = split.GetMemo() txn_date = date.fromtimestamp(txn.GetDate()) amount = split.GetValue() self.total = self.total.add_fixed(amount) self.entries.append({ 'date': txn_date, 'owner': desc, 'desc': memo, 'amount': amount, }) (self.report_total,self.report_rest) = gncn_round_with_rest(self.total)
def report(s, args): book = s.book table = book.get_table() pricedb = book.get_price_db() # FIXME: hard-coded currency currency_code = 'EUR' currency = table.lookup('ISO4217', currency_code) account = book.get_root_account() for acc in account.get_descendants(): if acc.GetType() == ACCT_TYPE_STOCK: commodity = acc.GetCommodity() namespace = commodity.get_namespace() if namespace != 'CURRENCY': print commodity.get_fullname(), commodity.get_cusip( ), acc.GetBalance() inst = pricedb.lookup_latest(commodity, currency).get_value() print GncNumeric(instance=inst).to_string()
def test_assignlots(self): abc = GncCommodity(self.book, 'ABC Fund', 'COMMODITY','ABC','ABC',100000) self.table.insert(abc) self.account.SetCommodity(abc) other = Account(self.book) other.SetCommodity(self.currency) tx = Transaction(self.book) tx.BeginEdit() tx.SetCurrency(self.currency) tx.SetDateEnteredSecs(datetime.now()) tx.SetDatePostedSecs(datetime.now()) s1a = Split(self.book) s1a.SetParent(tx) s1a.SetAccount(self.account) s1a.SetAmount(GncNumeric(1.3)) s1a.SetValue(GncNumeric(100.0)) s1b = Split(self.book) s1b.SetParent(tx) s1b.SetAccount(other) s1b.SetAmount(GncNumeric(-100.0)) s1b.SetValue(GncNumeric(-100.0)) s2a = Split(self.book) s2a.SetParent(tx) s2a.SetAccount(self.account) s2a.SetAmount(GncNumeric(-1.3)) s2a.SetValue(GncNumeric(-100.0)) s2b = Split(self.book) s2b.SetParent(tx) s2b.SetAccount(other) s2b.SetAmount(GncNumeric(100.0)) s2b.SetValue(GncNumeric(100.0)) tx.CommitEdit() self.account.ScrubLots() self.assertEqual(len(self.account.GetLotList()),1)
class NumericCollector(Collector): def __init__ (self): self.gnc_total = GncNumeric(0) # ((add) (adder value)) # ((debits) (getdebits)) # ((credits) (getcredits)) # ((items) (getitems)) # ((reset) (reset-all)) def add (self, amount): if isinstance(amount,GncNumeric): self.gnc_total = self.gnc_total.add(amount,gnucash.GNC_DENOM_AUTO, gnucash.GNC_HOW_DENOM_LCD) else: gnucash_log.PWARN("gnc.python","gnc:numeric-collector called with wrong argument: %s"%amount) def total (self): return self.gnc_total
def create_gnc_price_txs(self, mtx:dict, ast_parent:Account, rev_acct:Account): """ Create and load Gnucash prices to the Gnucash PriceDB :param mtx: InvestmentRecord transaction :param ast_parent: Asset parent account :param rev_acct: Revenue account :return: nil """ self.logger.print_info('create_gnc_price_txs()', BLUE) conv_date = dt.strptime(mtx[DATE], "%d-%b-%Y") pr_date = dt(conv_date.year, conv_date.month, conv_date.day) datestring = pr_date.strftime("%Y-%m-%d") fund_name = mtx[FUND] if fund_name in MONEY_MKT_FUNDS: return int_price = int(mtx[PRICE].replace('.', '').replace('$', '')) val = GncNumeric(int_price, 10000) self.logger.print_info("Adding: {}[{}] @ ${}".format(fund_name, datestring, val)) pr1 = GncPrice(self.book) pr1.begin_edit() pr1.set_time64(pr_date) asset_acct, rev_acct = self.get_accounts(ast_parent, fund_name, rev_acct) comm = asset_acct.GetCommodity() self.logger.print_info("Commodity = {}:{}".format(comm.get_namespace(), comm.get_printname())) pr1.set_commodity(comm) pr1.set_currency(self.currency) pr1.set_value(val) pr1.set_source_string("user:price") pr1.set_typestr('nav') pr1.commit_edit() if self.mode == PROD: self.logger.print_info("Mode = {}: Add Price to DB.".format(self.mode), GREEN) self.price_db.add_price(pr1) else: self.logger.print_info("Mode = {}: ABANDON Prices!\n".format(self.mode), RED)
def gnc_numeric_to_decimal(numeric): negative = numeric.negative_p() if negative: sign = 1 else: sign = 0 copy = GncNumeric(numeric.num(), numeric.denom()) result = copy.to_decimal(None) if not result: raise Exception("gnc numeric value %s can't be converted to Decimal" % copy.to_string()) digit_tuple = tuple(int(char) for char in str(copy.num()) if char != "-") denominator = copy.denom() exponent = int(log10(denominator)) assert (10**exponent) == denominator return Decimal((sign, digit_tuple, -exponent))
def renderer (self, report): # this actually implements the report look # for some reason if do this if any error occurs in report GUI is locked #report_starting(self.name) # lots of stuff about getting option values optobj = self.options.lookup_name('General','Start Date') from_date_tp = optobj.get_option_value() optobj = self.options.lookup_name('General','End Date') to_date_tp = optobj.get_option_value() #pdb.set_trace() # now for html creation # where do we actually instantiate the Html object # in scheme created new scheme html doc # in python probably should pass the report xml document # does the possibility of having new HtmlDocument make sense?? document = gnc_html_document.HtmlDocument(stylesheet=report.stylesheet()) # temporary measure - set the document style # some this should be done auto by the stylesheet set # but the StyleTable is not currently stored in the stylesheet # or at least not the right one document.style = report.style optobj = self.options.lookup_name('General',"Report's currency") report_currency = optobj.get_value() optobj = self.options.lookup_name('General','Price Source') price_source = optobj.get_option_value() optobj = self.options.lookup_name('General','Show Full Account Names') show_full_names = optobj.get_value() optobj = self.options.lookup_name('Accounts','Account Display Depth') display_depth = int(optobj.get_option_value()) rptopt = self.options.lookup_name('General','Report name') rptttl = rptopt.get_value() + " - " + N_("%s to %s"%(gnc_print_date(from_date_tp),gnc_print_date(to_date_tp))) document.title = rptttl accobj = self.options.lookup_name('Accounts','Account') accounts = accobj.get_option_value() shwobj = self.options.lookup_name('Accounts','Always show sub-accounts') shwopt = shwobj.get_value() print("shwobj",shwobj,shwopt, file=sys.stderr) #if shwopt: # subacclst = get_all_subaccounts(accounts) # for subacc in subacclst: # if not Interest.account_in_list(subacc,accounts): # accounts.append(subacc) #exchange_fn = gnc_commodity_utilities.case_exchange_fn(price_source, report_currency, to_date_tp) #pdb.set_trace() print("account len",len(accounts), file=sys.stderr) if len(accounts) > 0: topdepth = 10000 for acc in accounts: curdep = int(acc.get_current_depth()) if curdep < topdepth: topdepth = curdep print("account min depth",topdepth, file=sys.stderr) if display_depth == 'all': tree_depth = self.accounts_get_children_depth(accounts) else: tree_depth = topdepth+display_depth print("treedepth",tree_depth, file=sys.stderr) #self.time_exchange_fn = gnc_commodity_utilities.case_exchange_time_fn(price_source, report_currency, commodity_list, to_date_tp, 0.0, 0.0) #pdb.set_trace() # need to figure out how to sort by full name # well this is useless - we need the account name!! accounts.sort(key=operator.methodcaller('GetName')) #self.money_in_accounts.sort(key=operator.methodcaller('GetName')) #self.money_out_accounts.sort(key=operator.methodcaller('GetName')) base_text = document.StyleElement('body') base_text.text = N_("Selected Accounts")+"\n" base_text.tail = "\n" ultxt = document.doc.Element("ul") work_done = 0 work_to_do = len(accounts) for acc in accounts: work_done += 1 report_percent_done((work_done/float(work_to_do))*85.0) if acc.get_current_depth() <= tree_depth: if show_full_names: #accnm = acc.GetFullName() accnm = acc.get_full_name() else: accnm = acc.GetName() if acc.get_current_depth() == tree_depth and \ not len(acc.get_children()) == 0: if shwopt: acctxt = N_(" and subaccounts") else: acctxt = N_(" and selected subaccounts") else: acctxt = "" accurl = gnc_html_utilities.account_anchor_text(acc) anchor_li = document.doc.SubElement(ultxt,"li") anchor_markup = document.doc.SubElement(anchor_li,"a") anchor_markup.attrib['href'] = accurl anchor_markup.text = N_(accnm) + "\n" anchor_markup.tail = acctxt + "\n" do_accounts = [] for acc in accounts: doacc = False for split in acc.GetSplitList(): parent = split.GetParent() txn_date = parent.RetDatePosted().date() if (txn_date >= from_date_tp.date() and txn_date <= to_date_tp.date()): doacc = True if doacc: do_accounts.append(acc) # Scheme uses a whole subclass of functions for dealing with # tables - indirectly creating all table elements # ignoring all this for now - just using CSS styles new_table = document.StyleElement('table') new_table.text = "\n" new_row = document.doc.SubElement(new_table,"tr") new_row.tail = "\n" new_data = document.doc.SubElement(new_row,"td",attrib={'rowspan' : "1", 'colspan' : "2" }) new_ruler = document.doc.SubElement(new_data,"hr") new_row = document.StyleSubElement(new_table,'primary-subheading') new_row.text = "" new_row.tail = "\n" #new_col = document.doc.SubElement(new_row,"td",attrib={'rowspan' : "1", 'colspan' : "1"}) new_col = document.doc.SubElement(new_row,"td") new_col.text = N_("Date") new_col = document.doc.SubElement(new_row,"td") new_col.text = N_("Num") new_col = document.doc.SubElement(new_row,"td") new_col.text = N_("Description") new_col = document.doc.SubElement(new_row,"td") new_col.text = N_("Memo/Notes") new_col = document.doc.SubElement(new_row,"td") new_col.text = N_("Amount") new_col = document.doc.SubElement(new_row,"td") new_col.text = N_("Exchange Rate") new_col = document.doc.SubElement(new_row,"td") new_col.text = N_("Report Currency") row_num = 0 work_done = 0 work_to_do = len(accounts) #pdb.set_trace() total_coll = CommodityCollector() total_rpt_coll = CommodityCollector() # this is bad - this assumes all interest in single currency total_commod = None #for acc in accounts: for acc in do_accounts: row_num += 1 work_done += 1 report_percent_done((work_done/float(work_to_do))*5.0+90.0) new_row = document.StyleSubElement(new_table,'normal-row') new_row.text = "\n" new_row.tail = "\n" if show_full_names: #accnm = acc.GetFullName() accnm = acc.get_full_name() else: accnm = acc.GetName() accurl = gnc_html_utilities.account_anchor_text(acc) new_col = document.doc.SubElement(new_row,"td") anchor_markup = document.doc.SubElement(new_col,"a") anchor_markup.attrib['href'] = accurl anchor_markup.text = accnm + "\n" try: jnkstr = accnm.encode('utf-8') except Exception as errexc : pdb.set_trace() #pdb.set_trace() acc_currency = acc.GetCommodity() acc_currency_frac = acc_currency.get_fraction() # for the moment get exchange rate per account - assuming we do not have mutiple currencies in accounts # no easy way to get exchange rate # - even in scheme do it by transforming an amount of 1 # actually uses 1000 to get the sig figs # if no price we get none - make it 1 if not engine_ctypes.CommodityEquiv(acc_currency,report_currency): prcval = GncNumeric(1000,1000) prcmny = gnc_commodity_utilities.GncMonetary(acc_currency,prcval) prcxch = gnc_commodity_utilities.exchange_by_pricedb_nearest(prcmny,report_currency,txn_date) if prcxch == None: prcxch = gnc_commodity_utilities.exchange_by_pricedb_latest(prcmny,report_currency) if prcxch == None: prcxch = gnc_commodity_utilities.GncMonetary(report_currency,GncNumeric(1000,1000)) sclval = GncNumeric(1000,1000) prcxch.amount = sclval.div(prcxch.amount,GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 6*256 | GNC_HOW_RND_ROUND) #exch_rate = gnc_commodity_utilities.GncMonetary(report_currency,prcxch) exch_rate = prcxch.amount else: #exch_rate = gnc_commodity_utilities.GncMonetary(report_currency,GncNumeric(1000,1000)) exch_rate = GncNumeric(1000,1000) acc_coll = CommodityCollector() acc_rpt_coll = CommodityCollector() # new idea - lets have a dict of commodities we find to get a subtotal for each commodity # well thats the goal but we have no connection to the original stock in the Tax # - all we have is the memo - which at least is constant per stock commod_colls = {} for split in acc.GetSplitList(): parent = split.GetParent() txn_date = parent.RetDatePosted().date() split_currency = parent.GetCurrency() split_currency_frac = split_currency.get_fraction() try: other_split = split.GetOtherSplit() except Exception as errexc: other_split = None print("other split for", other_split) #if other_split != None: # other_accnt = corr_accnm = split.GetCorrAccountName() print("corr account", corr_accnm) # what do the functions eg GetCorrAccountName() do?? # #if splt.GetAccount() if (txn_date >= from_date_tp.date() and txn_date <= to_date_tp.date()): row_num += 1 if (row_num % 2) == 0: new_row = document.StyleSubElement(new_table,'normal-row') else: new_row = document.StyleSubElement(new_table,'alternate-row') # Date column new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = N_(gnc_print_date(txn_date)) # Num column new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = N_("") # Description new_col = document.StyleSubElement(new_row,'text-cell') #new_col.text = N_(parent.GetDescription()) # unfortunately GetDescription returns a str type for utf-8 encoded data # - we need to fix it desctxt = parent.GetDescription() try: newtxt = desctxt.encode('utf-8') except Exception as errexc: newtxt = desctxt.decode('utf-8') desctxt = newtxt #pdb.set_trace() new_col.text = N_(desctxt) # Memo/Notes # so the transaction has the Notes and the splits the memo new_col = document.StyleSubElement(new_row,'text-cell') #new_col.text = N_(split.GetMemo()) #new_col.text = N_(parent.GetNotes()) memotxt = split.GetMemo() notestxt = parent.GetNotes() new_col.text = N_(memotxt) split_val = split.GetValue() ## we need to change the sign #split_val = split_val.neg() # so this is not right - the transaction description # is what has the stock description now memostr = "" if other_split != None: # sum the splits per memo memostr = other_split.GetMemo() #if memostr in commod_colls: # commod_colls[memostr].add(acc_currency, split_val) #else: # commod_colls[memostr] = CommodityCollector() # commod_colls[memostr].add(acc_currency, split_val) if desctxt in commod_colls: commod_colls[desctxt].add(acc_currency, split_val) else: commod_colls[desctxt] = CommodityCollector() commod_colls[desctxt].add(acc_currency, split_val) print("split val", memostr, str(split_val.to_double())) # which is currency acc or other_acct?? #pdb.set_trace() #colval = gnc_commodity_utilities.GncMonetary(commod_currency,split_val) colval = gnc_commodity_utilities.GncMonetary(acc_currency,split_val) print("coll val", str(colval.to_currency_string())) # Account new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() # Exchange rate new_col = document.StyleSubElement(new_row,'number-cell') #new_col.text = exch_rate.to_currency_string() new_col.text = str(exch_rate.to_double()) if not engine_ctypes.CommodityEquiv(acc_currency,report_currency): split_mny = gnc_commodity_utilities.GncMonetary(acc_currency,split_val) splt_rpt = gnc_commodity_utilities.exchange_by_pricedb_nearest(split_mny,report_currency,txn_date) if splt_rpt == None: splt_rpt = gnc_commodity_utilities.exchange_by_pricedb_latest(split_mny,report_currency) if splt_rpt == None: splt_rpt = gnc_commodity_utilities.GncMonetary(report_currency,GncNumeric(1000,1000)) else: splt_rpt = gnc_commodity_utilities.GncMonetary(report_currency,split_val) acc_coll.add(acc_currency, split_val) #total_coll.add(acc_currency, split_val) acc_rpt_coll.add(splt_rpt.commodity, splt_rpt.amount) #total_rpt_coll.add(splt_rpt.commodity, splt_rpt.amount) #total_commod = acc_currency #colval = splt_rpt new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() new_row = document.StyleSubElement(new_table,'normal-row') new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" new_row = document.StyleSubElement(new_table,'normal-row') new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "Account Total" # Num new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" # Description new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" # Memo/Notes new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" # Amount #colval = gnc_commodity_utilities.GncMonetary(acc.GetCommodity(),acc.GetBalance().neg()) colval = acc_coll.getmonetary(acc.GetCommodity()) new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() # Exchange Rate new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = N_("") # Amount report currency colval = acc_rpt_coll.getmonetary(report_currency) new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() new_row = document.StyleSubElement(new_table,'normal-row') new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "Joint contribution" # Num new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" # Description new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" # Memo/Notes new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" # Amount #colval = gnc_commodity_utilities.GncMonetary(acc.GetCommodity(),acc.GetBalance().neg()) colval = acc_coll.getmonetary(acc.GetCommodity()) colval.amount = colval.amount.div(GncNumeric(2,1),GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 5*256 | GNC_HOW_RND_ROUND) new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() # Exchange Rate new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" # Amount report currency colval = acc_rpt_coll.getmonetary(report_currency) colval.amount = colval.amount.div(GncNumeric(2,1),GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 5*256 | GNC_HOW_RND_ROUND) new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() new_row = document.StyleSubElement(new_table,'normal-row') new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" new_row = document.StyleSubElement(new_table,'normal-row') new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" # dump totals per stock - in this case per memo pdb.set_trace() for commod in sorted(commod_colls.keys()): new_row = document.StyleSubElement(new_table,'normal-row') new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "Commodity Total" # Num new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" # Description new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = N_(commod) # Memo/Notes new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" # Amount #colval = gnc_commodity_utilities.GncMonetary(acc.GetCommodity(),acc.GetBalance().neg()) commod_coll = commod_colls[commod] colval = commod_coll.getmonetary(acc.GetCommodity()) #colval.amount = colval.amount.div(GncNumeric(2,1),GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 5*256 | GNC_HOW_RND_ROUND) new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() # Exchange Rate new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" # Amount report currency commod_coll = commod_colls[commod] colval = commod_coll.getmonetary(report_currency) #colval.amount = colval.amount.div(GncNumeric(2,1),GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 5*256 | GNC_HOW_RND_ROUND) new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() if len(do_accounts) > 0: #new_row = document.StyleSubElement(new_table,'normal-row') #new_row.text = "\n" #new_row.tail = "\n" #new_data = document.doc.SubElement(new_row,"td",attrib={'rowspan' : "1", 'colspan' : "100%" }) #new_ruler = document.doc.SubElement(new_data,"hr") #new_row = document.StyleSubElement(new_table,'grand-total') #new_row.text = "\n" #new_row.tail = "\n" #new_col = document.StyleSubElement(new_row,'text-cell') #new_col.text = N_("Total") #new_col = document.StyleSubElement(new_row,'text-cell') #new_col.text = " " #colval = total_coll.getmonetary(total_commod) #new_col = document.StyleSubElement(new_row,'total-number-cell') #new_col.text = colval.to_currency_string() #new_col = document.StyleSubElement(new_row,'text-cell') #new_col.text = " " #colval = total_rpt_coll.getmonetary(report_currency) #new_col = document.StyleSubElement(new_row,'total-number-cell') #new_col.text = colval.to_currency_string() #new_row = document.StyleSubElement(new_table,'grand-total') #new_row.text = "\n" #new_row.tail = "\n" #new_col = document.StyleSubElement(new_row,'text-cell') #new_col.text = N_("Joint Contribution Total") #new_col = document.StyleSubElement(new_row,'text-cell') #new_col.text = " " #colval = total_coll.getmonetary(total_commod) #colval.amount = colval.amount.div(GncNumeric(2,1),GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 5*256 | GNC_HOW_RND_ROUND) #new_col = document.StyleSubElement(new_row,'total-number-cell') #new_col.text = colval.to_currency_string() #new_col = document.StyleSubElement(new_row,'text-cell') #new_col.text = " " #colval = total_rpt_coll.getmonetary(report_currency) #colval.amount = colval.amount.div(GncNumeric(2,1),GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 5*256 | GNC_HOW_RND_ROUND) #new_col = document.StyleSubElement(new_row,'total-number-cell') #new_col.text = colval.to_currency_string() pass #new_col = document.StyleSubElement(new_row,'text-cell') #new_col.text = N_("Money In") #new_col = document.StyleSubElement(new_row,'total-number-cell') #colval = self.money_in_collector.sum(report_currency, exchange_fn) #new_col.text = colval.to_currency_string() report_finished() return document
splits_2 = query_splits(book, terms) print( "Query splits with transaction description containing 'Transaction 5': " + str(len(splits_2)) + " (Should be 22).") # query memo and desc isRegex = False terms = [(['memo'], gnucash_core.QueryStringPredicate(QOF_COMPARE_CONTAINS, "A22", QOF_STRING_MATCH_NORMAL, isRegex), QOF_QUERY_AND)] terms += [(['trans', 'desc'], gnucash_core.QueryStringPredicate(QOF_COMPARE_CONTAINS, "Transaction 55", QOF_STRING_MATCH_NORMAL, isRegex), QOF_QUERY_OR)] splits_4 = query_splits(book, terms) print( "Query splits with memo containing 'A22' or transaction desc containing 'Transaction 55': " + str(len(splits_4)) + " (Should be 3).") # query split value threshold = GncNumeric(5000, 100) terms = [(["amount"], gnucash_core.QueryNumericPredicate(QOF_COMPARE_GT, QOF_NUMERIC_MATCH_ANY, threshold), QOF_QUERY_AND)] splits_3 = query_splits(book, terms) print("Query splits with amount > " + str(threshold) + ": " + str(len(splits_3)) + " (Should be about 100).")
session = Session(url, True, False, False) root = session.book.get_root_account() book = session.book account = book.get_root_account() pdb = book.get_price_db() commod_table = book.get_table() cur = commod_table.lookup('CURRENCY', 'GBP') # loop through stocks for d in data: current_account = account.lookup_by_full_name('Oyster') if current_account.get_instance() is None: print("Oyster account missing") sys.exit(1) if d[3] > 0: num1 = GncNumeric(d[3] * 100, 100) elif d[4] > 0: num1 = GncNumeric(0 - d[4] * 100, 100) child_account = get_child_account(d[2].split(':'), account) print(child_account.name) trans = Transaction(book) trans.BeginEdit() trans.SetDate(d[0].day, d[0].month, d[0].year) trans.SetCurrency(cur) trans.SetDescription(d[1]) split = Split(book) split.SetValue(num1) split.SetAccount(current_account) split.SetParent(trans)
def test_from_num_denom(self): num = GncNumeric(1, 2) self.assertEqual(str(num), "1/2") self.assertEqual(num.num(), 1) self.assertEqual(num.denom(), 2)
def test_from_int(self): num = GncNumeric(3) self.assertEqual(str(num), "3/1") self.assertEqual(num.num(), 3) self.assertEqual(num.denom(), 1)
def test_from_float_auto(self): num = GncNumeric(3.1) self.assertEqual(str(num), "31/10") self.assertEqual(num.num(), 31) self.assertEqual(num.denom(), 10)
def get_prices_and_save(self, tx_coll): """ create Gnucash prices, load and save to the Gnucash file's PriceDB :param tx_coll: InvestmentRecord object: transactions to use to extract Gnucash prices :return: message """ print_info('get_prices_and_save()', MAGENTA) gncu = GncUtilities() msg = TEST self.price_db.begin_edit() print_info("self.price_db.begin_edit()", MAGENTA) try: for plan_type in tx_coll.plans: print_info("\n\nPlan type = {}".format(plan_type)) for tx in tx_coll.plans[plan_type]: base = pow(10, len(tx[CENTS])) int_price = int(tx[DOLLARS] + tx[CENTS]) val = GncNumeric(int_price, base) ast_parent_path = copy.copy(ACCT_PATHS[ASSET]) ast_parent_path.append(plan_type) if plan_type != PL_OPEN: if tx_coll.get_owner() == UNKNOWN: raise Exception("PROBLEM!! Trying to process plan type '{}' but NO Owner information found" " in Tx Collection!!".format(plan_type)) ast_parent_path.append(ACCT_PATHS[tx_coll.get_owner()]) print_info("ast_parent_path = {}".format(str(ast_parent_path)), BLUE) asset_parent = gncu.account_from_path(self.root, ast_parent_path) # get the asset account name name_key = tx[FUND_CMPY].split(' ')[0] print_info("name_key = {}".format(name_key), YELLOW) if name_key in FUND_NAME_CODE.keys(): name_code = FUND_NAME_CODE[name_key] # special case if name_code == ATL: asset_acct_name = ATL_O59 else: asset_acct_name = name_code + " " + tx[FUND_CODE] else: raise Exception("Could NOT find name key {}!".format(name_key)) print_info("asset_acct_name = {}".format(asset_acct_name), BLUE) # special location for Trust Asset account if asset_acct_name == TRUST_AST_ACCT: asset_parent = self.root.lookup_by_name(TRUST) print_info("asset_parent = {}".format(asset_parent.GetName()), BLUE) # get the asset account asset_acct = asset_parent.lookup_by_name(asset_acct_name) if asset_acct is None: # just skip updating cash-holding funds if str(val) == '100000/10000': continue else: raise Exception( "Could NOT find acct '{}' under parent '{}'".format(asset_acct_name, asset_parent.GetName())) print_info("Adding: {}[{}] @ ${}".format(asset_acct_name, tx_coll.get_date_str(), val), GREEN) pr = GncPrice(self.book) pr.begin_edit() pr.set_time64(tx_coll.get_date()) comm = asset_acct.GetCommodity() print_info("Commodity = {}:{}".format(comm.get_namespace(), comm.get_printname()), YELLOW) pr.set_commodity(comm) pr.set_currency(self.currency) pr.set_value(val) pr.set_source_string("user:price") pr.set_typestr('last') pr.commit_edit() if self.prod: print_info("PROD: Add Price to DB.\n", GREEN) self.price_db.add_price(pr) else: print_info("PROD: ABANDON Prices!\n", RED) if self.prod: msg = "PROD: COMMIT Price DB edits and Save session." print_info("PROD: COMMIT Price DB edits and Save session.", GREEN) self.price_db.commit_edit() # only ONE session save for the entire run self.session.save() self.session.end() self.session.destroy() except Exception as e: msg = "get_prices_and_save() EXCEPTION!! '{}'".format(repr(e)) print_error(msg) if "session" in locals() and self.session is not None: self.session.end() self.session.destroy() raise return msg
def test_from_instance(self): orig = GncNumeric(3) num = GncNumeric(instance=orig.instance) self.assertEqual(str(num), "3/1") self.assertEqual(num.num(), 3) self.assertEqual(num.denom(), 1)
book = s.book root = book.get_root_account() commod_table = book.get_table() CAD = commod_table.lookup('CURRENCY', 'CAD') my_customer = book.CustomerLookupByID(argv[2]) assert (my_customer != None) assert (isinstance(my_customer, Customer)) assets = root.lookup_by_name("Assets") receivables = assets.lookup_by_name("Receivables") income = root.lookup_by_name("Income") invoice = Invoice(book, argv[3], CAD, my_customer) description = argv[4] invoice_value = gnc_numeric_from_decimal(Decimal(argv[5])) tax_table = book.TaxTableLookupByName('good tax') invoice_entry = Entry(book, invoice) invoice_entry.SetInvTaxTable(tax_table) invoice_entry.SetInvTaxIncluded(False) invoice_entry.SetDescription(description) invoice_entry.SetQuantity(GncNumeric(1)) invoice_entry.SetInvAccount(income) invoice_entry.SetInvPrice(invoice_value) invoice.PostToAccount(receivables, datetime.date.today(), datetime.date.today(), "", True, False) s.save() s.end()
def test_defaut(self): num = GncNumeric() self.assertEqual(str(num), "0/1") self.assertEqual(num.num(), 0) self.assertEqual(num.denom(), 1)
def renderer (self, report): # this actually implements the report look # for some reason if do this if any error occurs in report GUI is locked #report_starting(self.name) # lots of stuff about getting option values optobj = self.options.lookup_name('General','Start Date') from_date_tp = optobj.get_option_value() optobj = self.options.lookup_name('General','End Date') to_date_tp = optobj.get_option_value() #pdb.set_trace() # now for html creation # where do we actually instantiate the Html object # in scheme created new scheme html doc # in python probably should pass the report xml document # does the possibility of having new HtmlDocument make sense?? document = gnc_html_document.HtmlDocument(stylesheet=report.stylesheet()) # temporary measure - set the document style # some this should be done auto by the stylesheet set # but the StyleTable is not currently stored in the stylesheet # or at least not the right one document.style = report.style optobj = self.options.lookup_name('General',"Report's currency") report_currency = optobj.get_value() optobj = self.options.lookup_name('General','Price Source') price_source = optobj.get_option_value() optobj = self.options.lookup_name('General','Show Full Account Names') show_full_names = optobj.get_value() optobj = self.options.lookup_name('Accounts','Account Display Depth') display_depth = optobj.get_option_value() rptopt = self.options.lookup_name('General','Report name') rptttl = rptopt.get_value() + " - " + N_("%s to %s"%(gnc_print_date(from_date_tp),gnc_print_date(to_date_tp))) document.title = rptttl accobj = self.options.lookup_name('Accounts','Account') accounts = accobj.get_option_value() shwobj = self.options.lookup_name('Accounts','Always show sub-accounts') shwopt = shwobj.get_value() print("shwobj",shwobj,shwopt, file=sys.stderr) if shwopt: subacclst = get_all_subaccounts(accounts) for subacc in subacclst: if not Dividends.account_in_list(subacc,accounts): accounts.append(subacc) #exchange_fn = gnc_commodity_utilities.case_exchange_fn(price_source, report_currency, to_date_tp) #pdb.set_trace() if len(accounts) > 0: if display_depth == 'all': tree_depth = self.accounts_get_children_depth(accounts) else: tree_depth = int(display_depth) #self.time_exchange_fn = gnc_commodity_utilities.case_exchange_time_fn(price_source, report_currency, commodity_list, to_date_tp, 0.0, 0.0) #pdb.set_trace() # need to figure out how to sort by full name # well this is useless - we need the account name!! accounts.sort(key=operator.methodcaller('GetName')) #self.money_in_accounts.sort(key=operator.methodcaller('GetName')) #self.money_out_accounts.sort(key=operator.methodcaller('GetName')) # find dividend accounts - junkily just look for name # - they have already been filtered for ACCT_TYPE_INCOME by default # - do we check again here?? dividend_accounts = [] for acc in accounts: if acc.get_current_depth() <= tree_depth: accnm = acc.GetName() if accnm.find('Dividend') >= 0 or accnm.find('dividend') >= 0: if not Dividends.account_in_list(acc,dividend_accounts): dividend_accounts.append(acc) subacclst = get_all_subaccounts([acc]) for subacc in subacclst: if not Dividends.account_in_list(subacc,dividend_accounts): dividend_accounts.append(subacc) else: parent = acc.get_parent() prntnm = parent.GetName() if prntnm.find('Dividend') >= 0 or prntnm.find('dividend') >= 0: if not Dividends.account_in_list(acc,dividend_accounts): dividend_accounts.append(acc) subacclst = get_all_subaccounts([acc]) for subacc in subacclst: if not Dividends.account_in_list(subacc,dividend_accounts): dividend_accounts.append(subacc) base_text = document.StyleElement('body') base_text.text = N_("Selected Accounts")+"\n" base_text.tail = "\n" ultxt = document.doc.Element("ul") work_done = 0 work_to_do = len(dividend_accounts) for acc in dividend_accounts: work_done += 1 report_percent_done((work_done/float(work_to_do))*85.0) if acc.get_current_depth() <= tree_depth: if show_full_names: #accnm = acc.GetFullName() accnm = acc.get_full_name() else: accnm = acc.GetName() if acc.get_current_depth() == tree_depth and \ not len(acc.get_children()) == 0: if shwopt: acctxt = N_(" and subaccounts") else: acctxt = N_(" and selected subaccounts") else: acctxt = "" accurl = gnc_html_utilities.account_anchor_text(acc) anchor_li = document.doc.SubElement(ultxt,"li") anchor_markup = document.doc.SubElement(anchor_li,"a") anchor_markup.attrib['href'] = accurl anchor_markup.text = N_(accnm) + "\n" anchor_markup.tail = acctxt + "\n" do_accounts = [] for acc in dividend_accounts: doacc = False for split in acc.GetSplitList(): parent = split.GetParent() txn_date = parent.RetDatePosted().date() if (txn_date >= from_date_tp.date() and txn_date <= to_date_tp.date()): doacc = True if doacc: do_accounts.append(acc) # Scheme uses a whole subclass of functions for dealing with # tables - indirectly creating all table elements # ignoring all this for now - just using CSS styles new_table = document.StyleElement('table') new_table.text = "\n" new_row = document.doc.SubElement(new_table,"tr") new_row.tail = "\n" new_data = document.doc.SubElement(new_row,"td",attrib={'rowspan' : "1", 'colspan' : "2" }) new_ruler = document.doc.SubElement(new_data,"hr") new_row = document.StyleSubElement(new_table,'primary-subheading') new_row.text = "" new_row.tail = "\n" #new_col = document.doc.SubElement(new_row,"td",attrib={'rowspan' : "1", 'colspan' : "1"}) new_col = document.doc.SubElement(new_row,"td") new_col.text = N_("Dividend Account") new_col = document.doc.SubElement(new_row,"td") new_col.text = N_("Payment Date") new_col = document.doc.SubElement(new_row,"td") new_col.text = N_("Dividend Income") new_col = document.doc.SubElement(new_row,"td") new_col.text = N_("Exchange Rate") new_col = document.doc.SubElement(new_row,"td") new_col.text = N_("Report Currency") row_num = 0 work_done = 0 work_to_do = len(dividend_accounts) #pdb.set_trace() total_coll = CommodityCollector() total_rpt_coll = CommodityCollector() # this is bad - this assumes all dividends in single currency total_commod = None #for acc in dividend_accounts: for acc in do_accounts: row_num += 1 work_done += 1 report_percent_done((work_done/float(work_to_do))*5.0+90.0) if (row_num % 2) == 0: new_row = document.StyleSubElement(new_table,'normal-row') else: new_row = document.StyleSubElement(new_table,'alternate-row') new_row = document.StyleSubElement(new_table,'normal-row') new_row.text = "\n" new_row.tail = "\n" if show_full_names: #accnm = acc.GetFullName() accnm = acc.get_full_name() else: accnm = acc.GetName() accurl = gnc_html_utilities.account_anchor_text(acc) new_col = document.doc.SubElement(new_row,"td") anchor_markup = document.doc.SubElement(new_col,"a") anchor_markup.attrib['href'] = accurl anchor_markup.text = accnm + "\n" acc_coll = CommodityCollector() acc_rpt_coll = CommodityCollector() for split in acc.GetSplitList(): parent = split.GetParent() txn_date = parent.RetDatePosted().date() commod_currency = parent.GetCurrency() commod_currency_frac = commod_currency.get_fraction() try: other_split = split.GetOtherSplit() except Exception as errexc: other_split = None print("other split for", other_split) #if other_split != None: # other_accnt = corr_accnm = split.GetCorrAccountName() print("corr account", corr_accnm) # what do the functions eg GetCorrAccountName() do?? # #if splt.GetAccount() if (txn_date >= from_date_tp.date() and txn_date <= to_date_tp.date()): row_num += 1 if (row_num % 2) == 0: new_row = document.StyleSubElement(new_table,'normal-row') else: new_row = document.StyleSubElement(new_table,'alternate-row') new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = N_(parent.GetDescription()) new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = N_(gnc_print_date(txn_date)) split_val = split.GetValue() # we need to change the sign split_val = split_val.neg() # which is currency acc or other_acct?? #pdb.set_trace() colval = gnc_commodity_utilities.GncMonetary(commod_currency,split_val) new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() # no easy way to get exchange rate # - even in scheme do it by transforming an amount of 1 # actually uses 1000 to get the sig figs # if no price we get none - make it 1 if not engine_ctypes.CommodityEquiv(commod_currency,report_currency): prcval = GncNumeric(1000,1000) prcmny = gnc_commodity_utilities.GncMonetary(commod_currency,prcval) prcxch = gnc_commodity_utilities.exchange_by_pricedb_nearest(prcmny,report_currency,txn_date) if prcxch == None: prcxch = gnc_commodity_utilities.exchange_by_pricedb_latest(prcmny,report_currency) if prcxch == None: prcxch = gnc_commodity_utilities.GncMonetary(report_currency,GncNumeric(1000,1000)) sclval = GncNumeric(1000,1000) prcxch.amount = sclval.div(prcxch.amount,GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 6*256 | GNC_HOW_RND_ROUND) #exch_rate = gnc_commodity_utilities.GncMonetary(report_currency,prcxch) exch_rate = prcxch.amount else: #exch_rate = gnc_commodity_utilities.GncMonetary(report_currency,GncNumeric(1000,1000)) exch_rate = GncNumeric(1000,1000) new_col = document.StyleSubElement(new_row,'number-cell') #new_col.text = exch_rate.to_currency_string() new_col.text = str(exch_rate.to_double()) if not engine_ctypes.CommodityEquiv(commod_currency,report_currency): split_mny = gnc_commodity_utilities.GncMonetary(commod_currency,split_val) splt_rpt = gnc_commodity_utilities.exchange_by_pricedb_nearest(split_mny,report_currency,txn_date) if splt_rpt == None: splt_rpt = gnc_commodity_utilities.exchange_by_pricedb_latest(split_mny,report_currency) if splt_rpt == None: splt_rpt = gnc_commodity_utilities.GncMonetary(report_currency,GncNumeric(1000,1000)) else: splt_rpt = gnc_commodity_utilities.GncMonetary(report_currency,split_val) acc_coll.add(commod_currency, split_val) total_coll.add(commod_currency, split_val) acc_rpt_coll.add(splt_rpt.commodity, splt_rpt.amount) total_rpt_coll.add(splt_rpt.commodity, splt_rpt.amount) total_commod = commod_currency colval = splt_rpt new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() new_row = document.StyleSubElement(new_table,'normal-row') new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "Balance" new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" #colval = gnc_commodity_utilities.GncMonetary(acc.GetCommodity(),acc.GetBalance().neg()) colval = acc_coll.getmonetary(acc.GetCommodity()) new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" colval = acc_rpt_coll.getmonetary(report_currency) new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() new_row = document.StyleSubElement(new_table,'normal-row') new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "Joint contribution" new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" #colval = gnc_commodity_utilities.GncMonetary(acc.GetCommodity(),acc.GetBalance().neg()) colval = acc_coll.getmonetary(acc.GetCommodity()) colval.amount = colval.amount.div(GncNumeric(2,1),GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 5*256 | GNC_HOW_RND_ROUND) new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = "" colval = acc_rpt_coll.getmonetary(report_currency) colval.amount = colval.amount.div(GncNumeric(2,1),GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 5*256 | GNC_HOW_RND_ROUND) new_col = document.StyleSubElement(new_row,'number-cell') new_col.text = colval.to_currency_string() if len(do_accounts) > 0: new_row = document.StyleSubElement(new_table,'normal-row') new_row.text = "\n" new_row.tail = "\n" new_data = document.doc.SubElement(new_row,"td",attrib={'rowspan' : "1", 'colspan' : "100%" }) new_ruler = document.doc.SubElement(new_data,"hr") new_row = document.StyleSubElement(new_table,'grand-total') new_row.text = "\n" new_row.tail = "\n" new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = N_("Total") new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = " " colval = total_coll.getmonetary(total_commod) new_col = document.StyleSubElement(new_row,'total-number-cell') new_col.text = colval.to_currency_string() new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = " " colval = total_rpt_coll.getmonetary(report_currency) new_col = document.StyleSubElement(new_row,'total-number-cell') new_col.text = colval.to_currency_string() new_row = document.StyleSubElement(new_table,'grand-total') new_row.text = "\n" new_row.tail = "\n" new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = N_("Joint Contribution Total") new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = " " colval = total_coll.getmonetary(total_commod) colval.amount = colval.amount.div(GncNumeric(2,1),GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 5*256 | GNC_HOW_RND_ROUND) new_col = document.StyleSubElement(new_row,'total-number-cell') new_col.text = colval.to_currency_string() new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = " " colval = total_rpt_coll.getmonetary(report_currency) colval.amount = colval.amount.div(GncNumeric(2,1),GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 5*256 | GNC_HOW_RND_ROUND) new_col = document.StyleSubElement(new_row,'total-number-cell') new_col.text = colval.to_currency_string() new_row = document.StyleSubElement(new_table,'grand-total') new_row.text = "\n" new_row.tail = "\n" new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = N_("Joint Contribution US Tax (15%)") new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = " " # 15% is 0.15 (3/20) but halve for joint 0.15/2 or 3/40 colval = total_coll.getmonetary(total_commod) colval.amount = colval.amount.mul(GncNumeric(3,40),GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 5*256 | GNC_HOW_RND_ROUND) new_col = document.StyleSubElement(new_row,'total-number-cell') new_col.text = colval.to_currency_string() new_col = document.StyleSubElement(new_row,'text-cell') new_col.text = " " # 15% is 0.15 (3/20) but halve for joint 0.15/2 or 3/40 colval = total_rpt_coll.getmonetary(report_currency) colval.amount = colval.amount.mul(GncNumeric(3,40),GNC_DENOM_AUTO,GNC_HOW_DENOM_SIGFIG | 5*256 | GNC_HOW_RND_ROUND) new_col = document.StyleSubElement(new_row,'total-number-cell') new_col.text = colval.to_currency_string() #new_col = document.StyleSubElement(new_row,'text-cell') #new_col.text = N_("Money In") #new_col = document.StyleSubElement(new_row,'total-number-cell') #colval = self.money_in_collector.sum(report_currency, exchange_fn) #new_col.text = colval.to_currency_string() report_finished() return document
def __init__ (self): self.gnc_total = GncNumeric(0)
book = session.book root_acct = Account(book) expenses_acct = Account(book) savings_acct = Account(book) opening_acct = Account(book) trans1 = Transaction(book) trans1.BeginEdit() trans2 = Transaction(book) trans2.BeginEdit() split1 = Split(book) split3 = Split(book) comm_table = book.get_table() cad = comm_table.lookup("CURRENCY", "CAD") num1 = GncNumeric(4, 1) num2 = GncNumeric(100, 1) #Set new root account book.set_root_account(root_acct) #Set up root account and add sub-accounts root_acct.SetName("Root") root_acct.SetType(13) #ACCT_TYPE_ROOT = 13 root_acct.append_child(expenses_acct) root_acct.append_child(savings_acct) root_acct.append_child(opening_acct) #Set up Expenses account expenses_acct.SetCommodity(cad) expenses_acct.SetName("Expenses")