def processStockDividend(self, ledger): asset_amount = ledger.getAmount(BookAccount.Assets, self._account, self._asset) if asset_amount < -Setup.CALC_TOLERANCE: raise NotImplemented( self.tr( "Not supported action: stock dividend closes short trade.") + f" Operation: {self.dump()}") quote = JalDB().get_quote(self._asset, JalDB().get_account_currency(self._account), self._timestamp) if quote is None: raise ValueError( self.tr("No stock quote for stock dividend.") + f" Operation: {self.dump()}") _ = executeSQL( "INSERT INTO open_trades(timestamp, op_type, operation_id, account_id, asset_id, price, remaining_qty) " "VALUES(:timestamp, :type, :operation_id, :account_id, :asset_id, :price, :remaining_qty)", [(":timestamp", self._timestamp), (":type", self._otype), (":operation_id", self._oid), (":account_id", self._account), (":asset_id", self._asset), (":price", quote), (":remaining_qty", self._amount)]) ledger.appendTransaction(self, BookAccount.Assets, self._amount, asset_id=self._asset, value=self._amount * quote) if self._tax: ledger.appendTransaction(self, BookAccount.Money, -self._tax) ledger.appendTransaction(self, BookAccount.Costs, self._tax, category=PredefinedCategory.Taxes, peer=self._broker)
def _import_asset_payments(self, payments): for payment in payments: if payment['account'] > 0: raise Statement_ImportError( self.tr("Unmatched account for payment: ") + f"{payment}") if payment['asset'] > 0: raise Statement_ImportError( self.tr("Unmatched asset for payment: ") + f"{payment}") tax = payment['tax'] if 'tax' in payment else 0 if payment['type'] == FOF.PAYMENT_DIVIDEND: if payment['id'] > 0: # New dividend JalDB().add_dividend(DividendSubtype.Dividend, payment['timestamp'], -payment['account'], -payment['asset'], payment['amount'], payment['description'], tax=tax) else: # Dividend exists, only tax to be updated JalDB().update_dividend_tax(-payment['id'], payment['tax']) elif payment['type'] == FOF.PAYMENT_INTEREST: if 'number' not in payment: payment['number'] = '' JalDB().add_dividend(DividendSubtype.BondInterest, payment['timestamp'], -payment['account'], -payment['asset'], payment['amount'], payment['description'], payment['number'], tax=tax) else: raise Statement_ImportError( self.tr("Unsupported payment type: ") + f"{payment}")
def main(): sys.excepthook = exception_logger os.environ[ 'QT_MAC_WANTS_LAYER'] = '1' # Workaround for https://bugreports.qt.io/browse/QTBUG-87014 error = JalDB().init_db(get_app_path()) app = QApplication([]) language = JalDB().get_language_code(JalSettings().getValue('Language', default=1)) translator = QTranslator(app) language_file = get_app_path( ) + Setup.LANG_PATH + os.sep + language + '.qm' translator.load(language_file) app.installTranslator(translator) if error.code == JalDBError.OutdatedDbSchema: error = JalDB().update_db_schema(get_app_path()) if error.code != JalDBError.NoError: window = QMessageBox() window.setAttribute(Qt.WA_DeleteOnClose) window.setWindowTitle("JAL: Start-up aborted") window.setIcon(QMessageBox.Critical) window.setText(error.message) window.setInformativeText(error.details) else: window = MainWindow(language) window.show() app.exec() app.removeTranslator(translator)
def _import_imcomes_and_spendings(self, actions): for action in actions: if action['account'] > 0: raise Statement_ImportError( self.tr("Unmatched account for income/spending: ") + f"{action}") if action['peer'] > 0: raise Statement_ImportError( self.tr("Unmatched peer for income/spending: ") + f"{action}") peer = JalDB().get_account_bank( -action['account']) if action['peer'] == 0 else -action['peer'] if len(action['lines'] ) != 1: # FIXME - need support for multilines here raise Statement_ImportError( self.tr("Unsupported income/spending: ") + f"{action}") amount = action['lines'][0]['amount'] category = -action['lines'][0]['category'] if category <= 0: raise Statement_ImportError( self.tr("Unmatched category for income/spending: ") + f"{action}") description = action['lines'][0]['description'] JalDB().add_cash_transaction(-action['account'], peer, action['timestamp'], amount, category, description)
def load(self): try: data = pandas.read_html(self._filename, encoding='cp1251', converters={self.Qty: convert_amount, self.Amount: convert_amount, self.Price: convert_amount, self.Coupon: convert_amount}) except: logging.error(self.tr("Can't read statement file")) return False report_info = data[0] deals_info = data[1] parts = re.match(self.ClientPattern, report_info[0][2]) if parts: account_id = JalDB().get_account_id(parts.group(1)) else: logging.error(self.tr("Can't get account number from the statement.")) return False if account_id is None: logging.error(self.tr("Account with number ") + f"{parts.group(1)}" + self.tr(" not found. Import cancelled.")) return False for index, row in deals_info.iterrows(): if row[self.Type] == self.Buy: qty = int(row[self.Qty]) elif row[self.Type] == self.Sell: qty = -int(row[self.Qty]) elif row[self.Type][:len(self.Total)] == self.Total: break # End of statement reached else: logging.warning(self.tr("Unknown operation type ") + f"'{row[self.Type]}'") continue asset_id = JalDB().get_asset_id(row[self.Symbol]) if asset_id is None: logging.warning(self.tr("Unknown asset ") + f"'{row[self.Symbol]}'") continue timestamp = int( datetime.strptime(row[self.DateTime], "%d.%m.%Y %H:%M:%S").replace(tzinfo=timezone.utc).timestamp()) settlement = int( datetime.strptime(row[self.SettleDate], "%d.%m.%Y").replace(tzinfo=timezone.utc).timestamp()) number = row[self.TradeNumber] price = row[self.Price] amount = row[self.Amount] lot_size = math.pow(10, round(math.log10(amount / (price * abs(qty))))) qty = qty * lot_size fee = float(row[self.Fee]) if self.FeeEx in row: # Broker dependent fee import fee = fee + float(row[self.FeeEx]) else: fee = fee + float(row[self.FeeEx1]) + float(row[self.FeeEx2]) + float(row[self.FeeEx3]) bond_interest = float(row[self.Coupon]) JalDB().add_trade(account_id, asset_id, timestamp, settlement, number, qty, price, fee) if bond_interest != 0: JalDB().add_dividend(Dividend.BondInterest, timestamp, account_id, asset_id, bond_interest, "НКД", number) return True
def _import_trades(self, trades): for trade in trades: if trade['account'] > 0: raise Statement_ImportError(self.tr("Unmatched account for trade: ") + f"{trade}") if trade['asset'] > 0: raise Statement_ImportError(self.tr("Unmatched asset for trade: ") + f"{trade}") note = trade['note'] if 'note' in trade else '' if 'cancelled' in trade and trade['cancelled']: JalDB().del_trade(-trade['account'], -trade['asset'], trade['timestamp'], trade['settlement'], trade['number'], trade['quantity'], trade['price'], trade['fee']) continue JalDB().add_trade(-trade['account'], -trade['asset'], trade['timestamp'], trade['settlement'], trade['number'], trade['quantity'], trade['price'], trade['fee'], note)
def __init__(self, operation_id=None): super().__init__(operation_id) self._table = "trades" self._otype = LedgerTransaction.Trade self._view_rows = 2 self._data = readSQL( "SELECT t.timestamp, t.number, t.account_id, t.asset_id, t.qty, t.price AS price, " "t.fee, t.note FROM trades AS t WHERE t.id=:oid", [(":oid", self._oid)], named=True) self._label, self._label_color = ( 'S', CustomColor.DarkRed) if self._data['qty'] < 0 else ( 'B', CustomColor.DarkGreen) self._timestamp = self._data['timestamp'] self._account = JalDB().get_account_name(self._data['account_id']) self._account = self._data['account_id'] self._account_name = JalDB().get_account_name(self._account) self._account_currency = JalDB().get_asset_name( JalDB().get_account_currency(self._account)) self._reconciled = JalDB().account_reconciliation_timestamp( self._account) >= self._timestamp self._asset = self._data['asset_id'] self._asset_symbol = JalDB().get_asset_name(self._asset) self._asset_name = JalDB().get_asset_name(self._asset, full=True) self._number = self._data['number'] self._qty = self._data['qty'] self._price = self._data['price'] self._fee = self._data['fee'] self._note = self._data['note'] self._broker = JalDB().get_account_bank(self._account)
def onStatementImport(self, timestamp, totals): self.ledger.rebuild() for account_id in totals: for asset_id in totals[account_id]: amount = JalDB().get_asset_amount(timestamp, account_id, asset_id) if amount is not None: if abs(totals[account_id][asset_id] - amount) <= Setup.DISP_TOLERANCE: JalDB().reconcile_account(account_id, timestamp) self.updateWidgets() else: account = JalDB().get_account_name(account_id) asset = JalDB().get_asset_name(asset_id) logging.warning(self.tr("Statement ending balance doesn't match: ") + f"{account} / {asset} / {amount} <> {totals[account_id][asset_id]}")
def _import_transfers(self, transfers): for transfer in transfers: for account in transfer['account']: if account > 0: raise Statement_ImportError( self.tr("Unmatched account for transfer: ") + f"{transfer}") for asset in transfer['asset']: if asset > 0: raise Statement_ImportError( self.tr("Unmatched asset for transfer: ") + f"{transfer}") if transfer['account'][0] == 0 or transfer['account'][1] == 0: text = '' pair_account = 1 if transfer['account'][0] == 0: # Deposit text = self.tr("Deposit of ") + f"{transfer['deposit']:.2f} " + \ f"{JalDB().get_asset_name(-transfer['asset'][1])} " + \ f"@{datetime.utcfromtimestamp(transfer['timestamp']).strftime('%d.%m.%Y')}\n" + \ self.tr("Select account to withdraw from:") pair_account = -transfer['account'][1] if transfer['account'][1] == 0: # Withdrawal text = self.tr("Withdrawal of ") + f"{transfer['withdrawal']:.2f} " + \ f"{JalDB().get_asset_name(-transfer['asset'][0])} " + \ f"@{datetime.utcfromtimestamp(transfer['timestamp']).strftime('%d.%m.%Y')}\n" + \ self.tr("Select account to deposit to:") pair_account = -transfer['account'][0] try: chosen_account = self._previous_accounts[ JalDB().get_account_currency(pair_account)] except KeyError: chosen_account = self.select_account( text, pair_account, self._last_selected_account) if chosen_account == 0: raise Statement_ImportError( self.tr("Account not selected")) self._last_selected_account = chosen_account if transfer['account'][0] == 0: transfer['account'][0] = -chosen_account if transfer['account'][1] == 0: transfer['account'][1] = -chosen_account description = transfer[ 'description'] if 'description' in transfer else '' JalDB().add_transfer(transfer['timestamp'], -transfer['account'][0], transfer['withdrawal'], -transfer['account'][1], transfer['deposit'], -transfer['account'][2], transfer['fee'], description)
def refreshAssetPrice(self): if self.type.currentIndex() == Dividend.StockDividend: price = JalDB().get_quote(self.asset_widget.selected_id, JalDB().get_account_currency(self.account_widget.selected_id), self.timestamp_editor.dateTime().toSecsSinceEpoch()) if price is not None: self.price_edit.setText(str(price)) self.price_edit.setStyleSheet('') self.price_edit.setToolTip("") else: self.price_edit.setText(self.tr("No quote")) self.price_edit.setStyleSheet("color: red") self.price_edit.setToolTip( self.tr("You should set quote via Data->Quotes menu for Date/Time of the dividend"))
def prepare_chart_data(self): min_price = max_price = 0 min_ts = max_ts = 0 self.currency_name = JalDB().get_asset_name(JalDB().get_account_currency(self.account_id)) start_time = readSQL("SELECT MAX(ts) FROM " # Take either last "empty" timestamp "(SELECT coalesce(MAX(timestamp), 0) AS ts " "FROM ledger_sums WHERE account_id=:account_id AND asset_id=:asset_id " "AND book_account=:assets_book AND sum_amount==0 " "UNION " # or first timestamp where position started to appear "SELECT coalesce(MIN(timestamp), 0) AS ts " "FROM ledger_sums WHERE account_id=:account_id AND asset_id=:asset_id " "AND book_account=:assets_book AND sum_amount!=0)", [(":account_id", self.account_id), (":asset_id", self.asset_id), (":assets_book", BookAccount.Assets)]) # Get quotes quotes query = executeSQL("SELECT timestamp, quote FROM quotes WHERE asset_id=:asset_id AND timestamp>:last", [(":asset_id", self.asset_id), (":last", start_time)]) while query.next(): quote = readSQLrecord(query, named=True) self.quotes.append({'timestamp': quote['timestamp'] * 1000, 'quote': quote['quote']}) # timestamp to ms min_price = quote['quote'] if min_price == 0 or quote['quote'] < min_price else min_price max_price = quote['quote'] if quote['quote'] > max_price else max_price min_ts = quote['timestamp'] if min_ts == 0 or quote['timestamp'] < min_ts else min_ts max_ts = quote['timestamp'] if quote['timestamp'] > max_ts else max_ts # Get deals quotes query = executeSQL("SELECT timestamp, price, qty FROM trades " "WHERE account_id=:account_id AND asset_id=:asset_id AND timestamp>=:last", [(":account_id", self.account_id), (":asset_id", self.asset_id), (":last", start_time)]) while query.next(): trade = readSQLrecord(query, named=True) self.trades.append({'timestamp': trade['timestamp'] * 1000, 'price': trade['price'], 'qty': trade['qty']}) min_price = trade['price'] if min_price == 0 or trade['price'] < min_price else min_price max_price = trade['price'] if trade['price'] > max_price else max_price min_ts = trade['timestamp'] if min_ts == 0 or trade['timestamp'] < min_ts else min_ts max_ts = trade['timestamp'] if trade['timestamp'] > max_ts else max_ts # Round min/max values to near "round" values in order to have 10 nice intervals step = 10 ** floor(log10(max_price - min_price)) min_price = floor(min_price / step) * step max_price = ceil(max_price / step) * step # Add a gap at the beginning and end min_ts -= 86400 * 3 max_ts += 86400 * 3 self.range = [min_ts, max_ts, min_price, max_price]
def __init__(self, account_id, asset_id, currency_id, _asset_qty, parent=None): super().__init__(parent) self.account_id = account_id self.asset_id = asset_id self.currency_id = currency_id if asset_id != currency_id else 1 # Check whether we have currency or asset self.asset_name = JalDB().get_asset_name(self.asset_id) self.quotes = [] self.trades = [] self.currency_name = '' self.range = [0, 0, 0, 0] self.prepare_chart_data() self.chart = ChartWidget(self, self.quotes, self.trades, self.range, self.currency_name) self.layout = QHBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) # Remove extra space around layout self.layout.addWidget(self.chart) self.setLayout(self.layout) self.setWindowTitle(self.tr("Price chart for ") + self.asset_name) self.ready = True
def setEditorData(self, editor, index): account_currency = JalDB().get_account_currency(index.model().data( index.sibling(index.row(), index.model().fieldIndex('account_id')), Qt.EditRole)) editor.setFilterValue(account_currency) QStyledItemDelegate.setEditorData(self, editor, index)
def test_backup_load(tmp_path, project_root): # Prepare environment src_path = project_root + os.sep + 'jal' + os.sep + Setup.INIT_SCRIPT_PATH target_path = str(tmp_path) + os.sep + Setup.INIT_SCRIPT_PATH copyfile(src_path, target_path) JalDB().init_db(str(tmp_path) + os.sep) # Here backup is created without parent window - need to use with care db_file_name = get_dbfilename(str(tmp_path) + os.sep) backup = JalBackup(None, db_file_name) backup.backup_name = project_root + os.sep + "tests" + os.sep + "test_data" + os.sep + "deals_set.tgz" assert backup.validate_backup() # Check validation assert backup._backup_label_date == '2021/01/01 00:00:00+0300' backup.do_restore() # Check restoration db = sqlite3.connect(db_file_name) cursor = db.cursor() cursor.execute("SELECT COUNT(*) FROM settings") assert cursor.fetchone()[0] == 7 db.close() os.remove(target_path) # Clean db init script os.remove(get_dbfilename(str(tmp_path) + os.sep)) # Clean db file
def _match_account_ids(self): for account in self._data[FOF.ACCOUNTS]: account_id = JalDB().find_account(account['number'], -account['currency']) if account_id: old_id, account['id'] = account['id'], -account_id self._update_id("account", old_id, account_id)
def _import_assets(self, assets): for asset in assets: isin = asset['isin'] if 'isin' in asset else '' name = asset['name'] if 'name' in asset else '' country_code = asset['country'] if 'country' in asset else '' if asset['id'] < 0: JalDB().update_asset_data(-asset['id'], {'isin': isin, 'name': name, 'country': country_code}) continue asset_id = JalDB().add_asset(self._asset_types[asset['type']], name, isin, country_code=country_code) if asset_id: old_id, asset['id'] = asset['id'], -asset_id self._update_id("asset", old_id, asset_id) if asset['type'] == FOF.ASSET_MONEY: self._update_id("currency", old_id, asset_id) else: raise Statement_ImportError(self.tr("Can't create asset: ") + f"{asset}")
def setId(self, account_id): self.p_account_id = account_id if self.p_account_id: self.setText(JalDB().get_account_name(account_id)) else: self.setText(self.tr("ANY")) self.changed.emit(self.p_account_id)
def __init__(self, account_id, asset_id, asset_qty, parent=None): super(TaxEstimator, self).__init__(parent) self.setupUi(self) self.account_id = account_id self.asset_id = asset_id self.asset_name = JalDB().get_asset_name(self.asset_id) self.asset_qty = asset_qty self.dataframe = None self.ready = False self.setWindowTitle(self.tr("Tax estimation for ") + self.asset_name) font = self.DealsView.horizontalHeader().font() font.setBold(True) self.DealsView.horizontalHeader().setFont(font) self.quote = 0 self.rate = 1 self.currency_name = '' self.prepare_tax() if self.dataframe is None: return self.QuoteLbl.setText(f"{self.quote:.4f}") self.RateLbl.setText(f"{self.rate:.4f} {self.currency_name}/RUB") self.model = TaxEstimatorModel(self.dataframe, self.currency_name) self.DealsView.setModel(self.model) self.ready = True
def setId(self, new_value): if self._id == new_value: return self._id = new_value self.updateView() name = JalDB().get_asset_name(self._id) self.name_updated.emit('' if name is None else name)
def __init__(self, account_id, asset_id, _asset_qty, position, parent=None): super().__init__(parent) self.account_id = account_id self.asset_id = asset_id self.asset_name = JalDB().get_asset_name(self.asset_id) self.quotes = [] self.trades = [] self.currency_name = '' self.range = [0, 0, 0, 0] self.prepare_chart_data() self.chart = ChartWidget(self, self.quotes, self.trades, self.range, self.currency_name) self.layout = QHBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) # Remove extra space around layout self.layout.addWidget(self.chart) self.setLayout(self.layout) self.setWindowTitle(self.tr("Price chart for ") + self.asset_name) self.setWindowFlag(Qt.Tool) self.setGeometry(position.x(), position.y(), self.width(), self.height()) self.ready = True
def _import_corporate_actions(self, actions): for action in actions: if action['account'] > 0: raise Statement_ImportError( self.tr("Unmatched account for corporate action: ") + f"{action}") if type(action['asset']) == list: asset_old = -action['asset'][0] asset_new = -action['asset'][1] else: asset_old = asset_new = -action['asset'] if asset_old < 0 or asset_new < 0: raise Statement_ImportError( self.tr("Unmatched asset for corporate action: ") + f"{action}") if type(action['quantity']) == list: qty_old = action['quantity'][0] qty_new = action['quantity'][1] else: qty_old = -1 qty_new = action['quantity'] try: action_type = self._corp_actions[action['type']] except KeyError: raise Statement_ImportError( self.tr("Unsupported corporate action: ") + f"{action}") JalDB().add_corporate_action(-action['account'], action_type, action['timestamp'], action['number'], asset_old, qty_old, asset_new, qty_new, action['cost_basis'], action['description'])
def _import_assets(self, assets): for asset in assets: if asset['id'] < 0: continue isin = asset['isin'] if 'isin' in asset else '' reg_code = asset['reg_code'] if 'reg_code' in asset else '' name = asset['name'] if 'name' in asset else '' country_code = asset['country'] if 'country' in asset else '' expiry = asset['expiry'] if 'expiry' in asset else 0 try: source = self._sources[asset['exchange']] except KeyError: source = MarketDataFeed.NA asset_id = JalDB().add_asset(asset['symbol'], name, self._asset_types[asset['type']], isin, expiry=expiry, data_source=source, reg_code=reg_code, country_code=country_code) if asset_id: old_id, asset['id'] = asset['id'], -asset_id self._update_id("asset", old_id, asset_id) if asset['type'] == FOF.ASSET_MONEY: self._update_id("currency", old_id, asset_id) else: raise Statement_ImportError( self.tr("Can't create asset: ") + f"{asset}")
def __init__(self, operation_id=None): labels = { CorporateAction.Merger: ('âƒ', CustomColor.Black), CorporateAction.SpinOff: ('⎇', CustomColor.DarkGreen), CorporateAction.Split: ('á—•', CustomColor.Black), CorporateAction.SymbolChange: ('🡘', CustomColor.Black), CorporateAction.Delisting: ('✖', CustomColor.DarkRed) } self.CorpActionNames = { CorporateAction.SymbolChange: self.tr("Symbol change {old} -> {new}"), CorporateAction.Split: self.tr("Split {old} {before} into {after}"), CorporateAction.SpinOff: self.tr("Spin-off {after} {new} from {before} {old}"), CorporateAction.Merger: self.tr("Merger {before} {old} into {after} {new}"), CorporateAction.Delisting: self.tr("Delisting of {before} {old}") } super().__init__(operation_id) self._table = "corp_actions" self._otype = LedgerTransaction.CorporateAction self._view_rows = 2 self._data = readSQL( "SELECT a.type, a.timestamp, a.number, a.account_id, " "a.qty, a.asset_id, a.qty_new, a.asset_id_new, a.basis_ratio, a.note " "FROM corp_actions AS a WHERE a.id=:oid", [(":oid", self._oid)], named=True) self._subtype = self._data['type'] self._label, self._label_color = labels[self._subtype] self._timestamp = self._data['timestamp'] self._account = self._data['account_id'] self._account_name = JalDB().get_account_name(self._account) self._account_currency = JalDB().get_asset_name( JalDB().get_account_currency(self._account)) self._reconciled = JalDB().account_reconciliation_timestamp( self._account) >= self._timestamp self._asset = self._data['asset_id'] self._asset_symbol = JalDB().get_asset_name(self._asset) self._asset_name = JalDB().get_asset_name(self._asset, full=True) self._qty = self._data['qty'] self._asset_new = self._data['asset_id_new'] self._asset_new_symbol = JalDB().get_asset_name(self._asset_new) self._asset_name_new = JalDB().get_asset_name(self._asset_new, full=True) self._qty_after = self._data['qty_new'] self._number = self._data['number'] self._basis = self._data['basis_ratio'] self._broker = JalDB().get_account_bank(self._account)
def _match_asset_isin(self): for asset in self._data[FOF.ASSETS]: if asset['id'] < 0: # already matched continue if 'isin' in asset: asset_id = JalDB().get_asset_id({'isin': asset['isin']}) if asset_id is not None: old_id, asset['id'] = asset['id'], -asset_id self._update_id("asset", old_id, asset_id)
def select_account(self, text, account_id, recent_account_id=0): if "pytest" in sys.modules: return 1 # Always return 1st account if we are in testing mode dialog = SelectAccountDialog(text, account_id, recent_account=recent_account_id) if dialog.exec() != QDialog.Accepted: return 0 else: if dialog.store_account: self._previous_accounts[JalDB().get_account_currency(dialog.account_id)] = dialog.account_id return dialog.account_id
def _match_asset_reg_number(self): for asset in self._data[FOF.ASSETS_DATA]: if asset['asset'] < 0: # already matched continue if 'reg_number' in asset: asset_id = JalDB().get_asset_id({'reg_number': asset['reg_number']}) if asset_id is not None: asset = self._find_in_list(self._data[FOF.ASSETS], "id", asset['asset']) old_id, asset['id'] = asset['id'], -asset_id self._update_id("asset", old_id, asset_id)
def _match_asset_ids(self, verbal): for asset in self._data[FOF.ASSETS]: isin = asset['isin'] if 'isin' in asset else '' reg_code = asset['reg_code'] if 'reg_code' in asset else '' name = asset['name'] if 'name' in asset else '' country_code = asset['country'] if 'country' in asset else '' expiry = asset['expiry'] if 'expiry' in asset else 0 asset_id = JalDB().get_asset_id(asset['symbol'], isin=isin, reg_code=reg_code, name=name, expiry=expiry, dialog_new=verbal) if asset_id is not None: JalDB().update_asset_data(asset_id, asset['symbol'], isin, reg_code, country_code) old_id, asset['id'] = asset['id'], -asset_id self._update_id("asset", old_id, asset_id) if asset['type'] == FOF.ASSET_MONEY: self._update_id("currency", old_id, asset_id)
def _add_asset(self, isin, reg_code, symbol=''): if self._find_asset_id(symbol, isin, reg_code) != 0: raise Statement_ImportError( self.tr("Attempt to recreate existing asset: ") + f"{isin}/{reg_code}") asset_id = JalDB().get_asset_id('', isin=isin, reg_code=reg_code, dialog_new=False) if asset_id is None: asset = QuoteDownloader.MOEX_info(symbol=symbol, isin=isin, regnumber=reg_code) if asset: asset['id'] = asset_id = max([0] + [x['id'] for x in self._data[FOF.ASSETS]]) + 1 asset['exchange'] = "MOEX" asset['type'] = FOF.convert_predefined_asset_type(asset['type']) else: raise Statement_ImportError(self.tr("Can't import asset: ") + f"{isin}/{reg_code}") else: asset = {"id": -asset_id, "symbol": JalDB().get_asset_name(asset_id), "type": FOF.convert_predefined_asset_type(JalDB().get_asset_type(asset_id)), 'name': '', "isin": isin, "reg_code": reg_code} asset_id = -asset_id self._data[FOF.ASSETS].append(asset) return asset_id
def _match_currencies(self): for asset in self._data[FOF.ASSETS]: if asset['type'] != FOF.ASSET_MONEY: continue symbol = self._find_in_list(self._data[FOF.SYMBOLS], "asset", asset['id']) asset_id = JalDB().get_asset_id({'symbol': symbol['symbol'], 'type': self._asset_types[asset['type']]}) if asset_id is not None: symbol['asset'] = -asset_id old_id, asset['id'] = asset['id'], -asset_id self._update_id("currency", old_id, asset_id) self._update_id("asset", old_id, asset_id) # TRANSFERS section may have currency in asset list
def prepare_db(project_root, tmp_path, data_path): # Prepare environment src_path = project_root + os.sep + 'jal' + os.sep + Setup.INIT_SCRIPT_PATH target_path = str(tmp_path) + os.sep + Setup.INIT_SCRIPT_PATH copyfile(src_path, target_path) # Activate db connection error = JalDB().init_db(str(tmp_path) + os.sep) assert error.code == JalDBError.NoError error = JalDB().init_db(str(tmp_path) + os.sep) assert error.code == JalDBError.NoError db = QSqlDatabase.database(Setup.DB_CONNECTION) assert db.isValid() lang_id = JalDB().get_language_id('en') assert lang_id == 1 yield os.remove(target_path) # Clean db init script os.remove(get_dbfilename(str(tmp_path) + os.sep)) # Clean db file