def shop_bill_show(): ## при показе счета xpairs = closed and {} or db_client.get_xcurrs_for_shop( db, 0, curr, shop, shop_order.curr_in_stop, shop_order.curr_in) ## при показе выбранной валюты best_rate = None pr_b, pr_s, pr_avg = rates_lib.get_average_rate_bsa( db, curr_in.id, curr.id, None) #print pr_b, pr_s, pr_avg if pr_avg: # примерное кол-во найдем vol_in = volume_out / pr_b #print vol_in, curr_in.abbrev, '-->', volume_out, curr.abbrev # точный курс возьмем amo_out, _, best_rate = rates_lib.get_rate(db, curr_in, curr, vol_in) #print best_rate, pair if not best_rate: response.title = T("ОШИБКА") return dict(uri='[' + curr_in.name + '] -> [' + curr.name + ']' + T(' - лучшая цена не доступна.'), addr=None, shop_id=shop.id) volume_in = volume_out / best_rate # теперь добавим погрешность курса volume_in = common.rnd_8(rates_lib.add_limit(volume_in, xcurr_in.txfee * 3)) # пересчет курса с погрешностью к курсу best_rate = volume_out / volume_in response.vars['best_rate'] = best_rate response.vars['best_rate_rev'] = 1.0 / best_rate response.vars['volume_in'] = volume_in
def get_xcurrs_for_shop(db, volume_out, curr_out, shop, not_used=None, only_used=None): curr_out_id = curr_out.id pairs = [] dealer_id = None s_b = True d_e = None # теперь по всем криптам пройдемся и если нет в парах то # значит запрет в форме сделаем for rec_in in db((db.currs.used==True) & (db.xcurrs.curr_id==db.currs.id)).select(orderby='currs.name'): curr_in = rec_in.currs if not_used and curr_in.abbrev in not_used: continue if only_used and curr_in.abbrev not in only_used: continue disabled = None exchg_lst = '' if curr_in.id == curr_out.id: pr_b = 1.0 else: #acurr_in = db(db.acurrs.xcurr_id==xcurr_in.id).select().first() # берем в расчет только недавние цены pr_b, pr_s, pr_avg = rates_lib.get_average_rate_bsa(db, curr_in.id, curr_out_id) #if curr_in.abbrev == 'CLR': print curr_in.name, pr_b, pr_s, pr_avg pp = None if pr_b: volume_in = volume_out / float(pr_b) #if curr_in.abbrev == 'CLR': print volume_in, volume_out, pr_b # тут уже с учетом комиссии биржи на фиат # get_best_price_for_volume(db, id1, id2, vol, expired, s_b=None, dealer_id=None, d_e=None): ao_, ro_, pr_b = rates_lib.get_rate(db, curr_in, curr_out, volume_in) #if curr_in.abbrev == 'CLR': print 'pr_b', pr_b if not pr_b: pr_b = -1 disabled = True else: for p in pp or []: exch = db.exchgs[p['exchg_id']] exchg_lst = exchg_lst + exch.name + ' ' #currs_stats = db((db.currs_stats.curr_id==curr_in.id) # & (db.currs_stats.shop_id==shop.id)).select().first() pairs.append({ 'id':curr_in.id, 'price': pr_b, 'name': curr_in.name, 'abbrev': curr_in.abbrev, 'icon': curr_in.icon, 'exch': exchg_lst, 'expired': disabled, 'name_out': curr_out.abbrev, #'used': currs_stats and currs_stats.count or 0, 'curr_id': curr_in.id, # для того чтобы по 2му разу не брало #'bal': curr_in.balance, #'bal_out': curr_free_bal(curr_in) # сколько можно продать }) return pairs
def get_xcurrs_for_buy(db, curr_in, deal): curr_in_id = curr_in.id # берем в расчет только недавние цены expired = datetime.now() - timedelta(0, 360) pairs = [] # теперь по всем криптам пройдемся и если нет в парах то # значит запрет в форме сделаем for curr_out in db(db.currs.used == True).select(orderby='name'): xcurr = db(db.xcurrs.curr_id == curr_out.id).select().first() if not xcurr: continue disabled = None if curr_out.id == curr_in_id: rate = 1.0 else: # берем в расчет только недавние цены ao_, ro_, rate = rates_lib.get_rate(db, curr_in, curr_out) #print ao_, ro_, rate if rate: rate = 1 / rate else: rate = -1 disabled = True currs_stats = db((db.currs_stats.curr_id == curr_out.id) & (db.currs_stats.deal_id == deal.id)).select().first() if curr_out.tax_out < 0: # мы даем бонус за покуцпку этой крипты - отразим сразу в курсе rate = rate * (1 + 0.01 * float(curr_out.tax_out)) pairs.append({ 'id': curr_out.id, 'price': rate, 'name': curr_out.name, 'abbrev': curr_out.abbrev, 'icon': curr_out.icon, 'expired': disabled, #'name_out': curr_out.abbrev, 'used': currs_stats and currs_stats.count_ or 0, 'curr_id': curr_out.id, # для того чтобы по 2му разу не брало 'bal': curr_out.balance, 'bal_out': 9 * curr_free_bal(curr_out) / 10 # сколько можно продать }) return pairs
def get_best_rate(): if len(request.args) == 0: mess = 'len(request.args)==0 - [pay_in]/[amo]' print mess return mess import rates_lib pay_in = db.pay_ins[request.args[0]] shop_order_addr = db.shop_order_addrs[pay_in.shop_order_addr_id] shop_order = db.shop_orders[shop_order_addr.shop_order_id] xcurr_in = db.xcurrs[shop_order_addr.xcurr_id] curr_in = db.currs[xcurr_in.curr_id] curr_out = db.currs[shop_order.curr_id] amo = float(request.args[1]) amo_out, rate_order, rate = rates_lib.get_rate(db, curr_in, curr_out, amo, pay_in.created_on, shop_order_addr) return '%s[%s] -> %s[%s] x%s /%s' % (amo, curr_in.abbrev, amo_out, curr_out.abbrev, rate, 1 / rate)
def get_rate(): if len(request.args) < 2: mess = 'len(request.args)==0 - [pay_in]/[pay_out]/[amo]' print mess return mess import rates_lib import db_common curr_in, x, e = db_common.get_currs_by_abbrev(db, request.args[0]) curr_out, x, e = db_common.get_currs_by_abbrev(db, request.args[1]) amo = float(len(request.args) > 2 and request.args[2] or 1) / 10 res = '' for i in range(1, 4): amo = amo * 10 amo_out, rate_order, rate = rates_lib.get_rate(db, curr_in, curr_out, amo) res = res + '%s[%s] -> %s[%s] x%s /%s <br>' % ( amo, curr_in.abbrev, amo_out, curr_out.abbrev, rate, rate and 1 / rate or 0) return res
def get(): args = request.args #print args, '\n', request.vars if len(args) != 1: return mess('err...') curr_id = args(0) if not curr_id.isdigit(): return mess('dig...') # теперь можно задать открытие кнопки scr = "$('#cvr%s').css('display','none');$('#tag%s').show('slow');" % ( curr_id, curr_id) response.js = scr vol = request.vars.vol if not vol or len(vol) > 20: return mess(T('ОШИБКА') + ': ' + T('Задайте количество')) try: vol = float(vol) curr_id = int(curr_id) dealer_id = int(request.vars['dealer']) dealer = db.dealers[dealer_id] except: return mess('digs...') acc = request.vars.acc #print request.vars if not acc: return mess(T('ОШИБКА: Задайте кошелек')) try: if len(acc) < 6 or len(acc) > 40 or not IS_EMAIL( acc) and not valid_phone(acc) and not acc.isdidit(): ##проверка на счет - если это не емайл и не ттелефон то надо длинну и на циифры return mess(T('ОШИБКА: неверный кошелек')) except: return mess(T('ОШИБКА: неверный кошелек 2')) curr_in = db.currs[curr_id] if not curr_in: return mess(T('curr...')) xcurr_in = db(db.xcurrs.curr_id == curr_id).select().first() if not xcurr_in: return mess(T('xcurr...')) try: session.toDlrAcc = acc except: print 'to_wallet session error .toDlrAcc:', type(acc), acc dealer_acc = ed_common.sel_acc_max(db, dealer, ecurr_out, vol) if not dealer_acc: return mess( '''Извините, возможно достигнуто ограничение переводов на сотовые телефоны и электронные кошельки, просьба воспользоваться прямой оплатой нужных Вам услуг, например из меню "Всё". Или можно уменьшить сумму платежа или подождать до следующего дня или месяца для снятия лимитов. ''', 'warning') dealer_deal = db((db.dealer_deals.dealer_id == dealer.id) & (db.dealer_deals.deal_id == deal.id)).select().first() if not dealer_deal: return mess( T('Не найден дилер для дела [%s]... Зайдите позже') % deal.name, 'warning') MIN = db_common.gMIN(deal, dealer) if vol < MIN: try: session.vol = MIN except: print 'to_wallet session error .vol:', type(MIN), MIN return mess( T('ОШИБКА: Слишком маленькая сумма платежа %s < %s') % (vol, MIN)) else: try: session.vol = vol except: print 'to_wallet session error .vol:', type(vol), vol # теперь проверку на правильность кошелька для дилера электронных платежей #res = ed_common.pay_test(db, deal, dealer, dealer_acc, dealer_deal, acc, deal.MIN_pay or dealer.pay_out_MIN or 20, False) #res = {'error': ' TEST'} if False and res.get('status') != 'success': m = 'error_description' in res and res.ger( 'error_description', res.get('error', 'dealer error')) m = T('Платежная система %s отвергла платеж, потому что: %s') % ( dealer.name, m) return mess(m, 'warning') curr_out_abbrev = curr_out.abbrev x_acc_label = db_client.make_x_acc(deal, acc, curr_out_abbrev) # найдем ранее созданный адресс для этого телефона, этой крипты и этого фиата # сначала найтем аккаунт у дела deal_acc_id = db_client.get_deal_acc_id(db, deal, acc, curr_out) # теперь найдем кошелек для данной крипты deal_acc_addr = db_client.get_deal_acc_addr_for_xcurr( db, deal_acc_id, curr_in, xcurr_in, x_acc_label) if not deal_acc_addr: return mess((T('Связь с сервером %s прервана') % curr_in.name) + '. ' + T('Невозможно получить адрес для платежа') + '. ' + T('Пожалуйста попробуйте позже'), 'warning') #request.vars['deal_acc_addr']=deal_acc_addr addr = deal_acc_addr.addr curr_in_abbrev = curr_in.abbrev h = CAT() e_bal, MAX = get_e_bal(deal, dealer, dealer_acc) if vol > MAX: vol = MAX h += mess( T('Сумма платежа снижена до возможного наибольшего значения, желательно не превышать его' ), 'warning') okIN = session.okWt h += sect( DIV(okIN and DIV(H3(A('Правила оплаты', _onclick='$(".okIN").show("fast");', _class='button warn right'), _class='pull-right-'), _class='col-sm-12') or '', DIV(okIN and ' ' or H3('ПРАВИЛА ОПЛАТЫ', _class='center'), P(T('При оплате необходимо соблюдать следующие правила:')), UL( T('У оплат дела [%s] существуют ограничения по суммам, поэтому если Вы хотите оплатить бОльшую сумму, то Вам нужно делать платежи небольшими суммами в эквиваленте до %s рублей на тот же адрес кошелька криптовалюты, который Вы получили от нашей службы для этой услуги' ) % (deal.name, MAX * 1.0), T('Желательно задать обратный адрес для возврата монет на случай если наша служба по каким-либо причинам не сможет совершить оплату по делу [%s]' ) % deal.name, T('Если Вы не задали обратный адрес для возврата монет, то необходимо платить биткоины и другую криптовалюту только со своего кошелька, задав адреса входов, которыми Вы действительно обладаете, а не с кошельков бирж, пулов или разных онлайн-кошельков. Так как монеты, в случае если платеж будет отвергнут нашим партнёром, могут автоматически вернуться только на адрес отправителя.' ), T('Если Вы оплатите другую сумму, то курс обмена может немножко измениться' ), T('Если Вы платите регулярно, то можете платить на тот же адрес кошелька криптовалюты, что получили ранее. Хотя желательно заходить на нашу службу для получения новостей хотябы раз в пол года или подписаться на важные новости и сообщения оставив свой емайл.' ), ), H4(A('Понятно', _onclick='$(".okIN").hide("fast");ajax("%s")' % URL('aj', 'ok_to', args=['Wt']), _class='button warn'), _class='center'), _class='col-sm-12 okIN', _style='color:chocolate;display:%s;' % (okIN and 'none' or 'block')), _class='row'), 'bg-warning pb-10') # если есть скрытый партнерский код то его забьем пользователю deal_acc = db.deal_accs[deal_acc_id] import gifts_lib adds_mess = XML(gifts_lib.adds_mess(deal_acc, PARTNER_MIN, T)) if adds_mess: h += sect(XML(adds_mess), 'gift-bgc pb-10 pb-10') volume_out = vol hh = CAT(H2(T('3. Оплатите по данным реквизитам'))) # используем быстрый поиск курса по формуле со степенью на количество входа # только надо найти кол-во входа от выхода pr_b, pr_s, pr_avg = rates_lib.get_average_rate_bsa( db, curr_in.id, curr_out.id, None) if pr_avg: vol_in = volume_out / pr_b amo_out, _, best_rate = rates_lib.get_rate(db, curr_in, curr_out, vol_in) else: best_rate = None if best_rate: is_order = True # сначала открутим обратную таксу volume_in, mess_in = db_client.calc_fees_back(db, deal, dealer_deal, curr_in, curr_out, volume_out, best_rate, is_order, note=0) ## теперь таксы для человека получим и должна та же цифра выйти vol_out_new, tax_rep = db_client.calc_fees(db, deal, dealer_deal, curr_in, curr_out, volume_in, best_rate, is_order, note=1) vol_out_new = common.rnd_8(vol_out_new) if volume_out != vol_out_new: print 'to_phone error_in_fees: volume_out != vol_out_new', volume_out, vol_out_new volume_in = common.rnd_8(volume_in) rate_out = volume_out / volume_in # new make order order_id = db.orders.insert( ref_=deal_acc_addr.id, volume_in=volume_in, volume_out=volume_out, ) # теперь стек добавим, который будем удалять потом db.orders_stack.insert(ref_=order_id) hh += DIV( T('Создан заказ №'), ' ', order_id, ' ', T('на заморозку обменного курса по'), ' ', rate_out, #T('обратный курс'), ' ', round(1.0/rate_out,8), H5( T('*Данный курс будет заморожен для Вас на 20 минут для объёма криптовалюты не больше указанного. Проверить можно по номеру заказа в списке платежей.' )), _class='row') else: volume_in = rate_out = None tax_rep = '-' hh += mess( '[' + curr_in.name + '] -> [' + curr_out.name + ']' + T(' - лучшая цена не доступна.') + T('Но Вы можете оплатить вперед'), 'warning pb-10') _, url_uri = common.uri_make( curr_in.name2, addr, { 'amount': volume_in, 'label': db_client.make_x_acc_label(deal, acc, curr_out_abbrev) }) lim_bal, may_pay = db_client.is_limited_ball(curr_in) if lim_bal: if may_pay > 0: lim_bal_mess = P( 'Внимание! Для криптовалюты %s существует предел запаса и поэтому наша служба может принять только %s [%s], Просьба не превышать это ограничение' % (curr_in.name, may_pay, curr_in_abbrev), '.', _style='color:black;') else: lim_bal_mess = P( 'ВНИМАНИЕ! Наша служба НЕ может сейчас принимать %s, так как уже достугнут предел запаса её у нас. Просьба попробовать позже, после того как запасы [%s] снизятся благодаря покупке её другими пользователями' % (curr_in.name, curr_in_abbrev), '. ', 'Иначе Ваш платеж будет ожидать момента когда запасы снизятся ниже %s' % lim_bal, '.', _style='color:brown;') else: lim_bal_mess = '' free_bal, MAX = get_e_bal(deal, dealer, dealer_acc) hh += DIV( P( T('Оплата %s') % dealer.name, ': ', acc, ' ', T('на сумму'), ' ', volume_out, ' ', curr_out_abbrev, ' ', T('из доступных в службе'), ' ', free_bal, '. ', T('Наибольший возможный платеж'), ' ', MAX, ), volume_out > free_bal and P( H3(T('Сейчас средств на балансе меньше чем Вам надо'), _style='color:crimson;'), SPAN(T('Поэтому Ваш заказ будет исполнен позже'), BR(), T('когда на балансе службы появится достаточно средств'), _style='color:black;'), BR(), ) or '', lim_bal_mess, DIV(CENTER( A(SPAN( T('Оплатить'), ' ', volume_in or '', ' ', IMG(_src=URL('static', 'images/currs/' + curr_in.abbrev + '.png'), _width=50)), _class='block button blue-bgc', _style='font-size:x-large; max-width:500px; margin:0px 7px;', _href=url_uri), ), _class='row'), BR(), DIV( A( T('Показать QR-код'), _class='btn btn-info', ##_onclick="jQuery(this).parent().html('%s')" % IMG(_src=URL('static','images/loading.gif'), _width=64), _onclick= "jQuery(this).parent().html('<i class=\"fa fa-spin fa-refresh\" />')", callback=URL('plugins', 'qr', vars={'mess': url_uri}), target='tag0', #delete='div#tag0' ), _id='tag0'), T('или'), BR(), T('Оплатите вручную'), ': ', FORM( ## ВНИМАНИЕ !!! тут имена полей надр друние указывать или # FORM в основной делать тоже иначе они складываются INPUT(_name='v', value=volume_in, _class="pay_val", _readonly=''), curr_in.abbrev, BR(), T("Для этого скопируйте сумму и адрес (двойной клик по полю для выделения) и вставьте их в платеж на вашем кошельке" ), ': ', INPUT(_name='addr', _value=addr, _class='wallet', _readonly=''), BR(), #T('Резервы службы'), ' ', B(free_bal), ' ', T('рублей'), BR(), #LOAD('where', 'for_addr', vars={'addr': addr}, ajax=True, times=100, timeout=20000, # content=IMG(_src=URL('static','images/loading.gif'), _width=48)), INPUT( _type='submit', _class='button blue-bgc', _value=T('Подробный просмотр платежей'), _size=6, ), _action=URL('where', 'index'), _method='post', )) h += sect(hh, 'bg-info pb-10') h += sect( DIV(DIV( H3(T('Почему получился такой курс?')), tax_rep, BR(), T('При этом Вы получаете следующие преимущества при оплате биткоинами услуг и дел у нас' ), UL([ T('не нужно нигде регистрироваться'), T('не нужно делать подтверждения по СМС или по емайл'), T('не нужно копить много денег - платежи возможны от %s [%s]') % (MIN, curr_out_abbrev), T('не нужно ждать сутки вывода') ]), T(' Время - деньги!'), _class='col-sm-12'), _class='row')) h += SCRIPT(''' $('html, body').animate( { scrollTop: $('#cvr%s').offset().top - $('#aside1').height() }, 500 ); ''' % (curr_id)) return h
def get(): #common.page_stats(db, response['view']) #print request.vars args = request.args if len(args) < 2: return mess('args<2 err...') curr_id = args(0) if len(curr_id) > 5 or not curr_id.isdigit(): return mess('curr_id dig...') # теперь можно задать открытие кнопки scr = "$('#cvr%s').css('display','none');$('#tag%s').show('slow');" % ( curr_id, curr_id) response.js = scr deal_id = args(1) if not deal_id or len(deal_id) > 10 or not deal_id.isdigit(): return mess('deal_id vars..') curr_in = db.currs[curr_id] if not curr_in: return mess(T('curr...')) xcurr_in = db(db.xcurrs.curr_id == curr_id).select().first() if not xcurr_in: return mess(T('xcurr...')) #print request.vars try: # если русский язык то выдаст ошибку в if v.find(c) >-1: for k, v in request.vars.items(): #print k, v for c in u'\\/<>\'"': if v.find(c) > -1: return mess('error in pars <script>') except: pass client = db(db.clients.deal_id == deal_id).select().first() if client: redirect(URL('to_shop', 'index', args=[client.id], vars={})) volume_out = test_vol(request.vars.vol) if not volume_out: return mess('volume_out error...') deal = db.deals[deal_id] vol = (deal.MIN_pay or 100) * 2 dealer, dealer_acc, dealer_deal = ed_common.select_ed_acc( db, deal, ecurr_out, vol, True) if not dealer: return mess('ERROR: not found dealer for "%s"' % deal.name) dealer_acc = ed_common.sel_acc_max_for_balance(db, dealer, ecurr_out, vol, unlim=True) MIN = db_common.gMIN(deal, dealer) #MAX = deal.MAX_ or 777 if MIN > volume_out: return mess('ОШИБКА: Слишком маленькая сумма платежа, меньше чем: %s' % MIN) ################################################ # соберем аккаунт для оплаты из введенных данных ################################################ if dealer_deal.grab_form: deal_pars = {} #print request.post_vars # удалим наши параметры for key in ['xcurr', 'volume', 'deal_id']: deal_pars[key] = request.post_vars.pop(key) # парамтеры что ввел пользователь обрежем чтобы скрипты не писали for (k, v) in request.post_vars.iteritems(): if len(v) > 20: request.post_vars[k] = v[:20] acc = request.post_vars #.list.sort() if len(acc) > 10: m = 'ОШИБКА: параметров слишком много: %s, свяжитесь с администратором' % acc print m return mess(m) acc = json.dumps(acc) #print 'ACC:', acc else: # проверку параметров # и собрем из параметров счет клиента acc_pars = [] if dealer_deal.p2p: if deal.template_ == '--': pay_pars_deal = [] pay_pars_dealer = [] acc_pars.append('main') else: pay_pars_deal = ed_common.PAY_PARS_P2P pay_pars_dealer = ed_YD.PAY_PARS_P2P else: pay_pars_deal = deal.template_ and json.loads( deal.template_) or ed_common.PAY_PARS pay_pars_dealer = dealer_deal.template_ and json.loads( dealer_deal.template_) or ed_YD.PAY_PARS #print request.vars for par in pay_pars_deal: ## par - параметры от ДЕЛА if 'calc' in par: continue p_n_name = par.get('n') if not p_n_name: continue val = request.vars[p_n_name] or '' p = pay_pars_dealer[p_n_name] #print p, val if 'f' in par: # фильтр регулярный #regular = re.compile(p['f']) #val = regular.sub("","%s" % val) val = re.sub(p['f'], "", "%s" % val) if 'ln' in p: # проверка длинны ln = (p['ln'] + 0) if len(val) != ln: l = p['l'] db.deal_errs.insert(deal_id=deal.id, err='len!=%s - %s = %s' % (ln, l, val)) l = l.encode('utf8') return mess('ОШИБКА: Проверьте введенные данные!') acc_pars.append(val) #все прошло # теперь проверку на правильность лицевого счета и прочего для дилера электронных платежей #dealer_acc #print pars if len(acc_pars) > 10: m = 'ОШИБКА: параметров слишком много: %s, свяжитесь с администратором' % acc_pars print m return mess(m) acc = ' '.join( acc_pars).rstrip() # и удалим пробелы справа от калькуляторов #print 'ACCOUNT:',acc if not acc or len(acc) < 3: return mess('ОШИБКА: Аккаунт слишком короткий: %s' % acc) # запомним что это дело кто-то захотел оплатить dealer_deal.update_record(wanted=dealer_deal.wanted + 1) pattern_id = dealer_deal.scid res = ed_common.pay_test( db, deal, dealer, dealer_acc, dealer_deal, acc, #(deal.MIN_pay or dealer.pay_out_MIN or 10)*2, volume_out, False) err_mess = '%s' % res if res['status'] != 'success': ed_common.dealer_deal_errs_add(db, dealer_deal, acc, err_mess) response.title = T("ОШИБКА") #print res mm = 'error_description' in res and res['error_description'] or res[ 'error'] or 'dealer error' mm = T('Платежная система %s отвергла платеж, потому что: %s') % ( dealer.name, mm) return mess(mm) dealer_info = json.loads(dealer.info) if deal.url and len(deal.url) > 0: shops_url = deal.url else: shops_url = dealer_info['shops_url'] + "%s" % dealer_deal.scid deal_img = make_img(deal, dealer_info, shops_url) # get new or old adress for payment x_acc_label = db_client.make_x_acc(deal, acc, curr_out.abbrev) #print x_acc_label # найдем ранее созданный адресс для этого телефона, этой крипты и этого фиата # сначала найтем аккаунт у дела deal_acc_id = db_client.get_deal_acc_id(db, deal, acc, curr_out) #print 'deal_acc_id',deal_acc_id #return # теперь найдем кошелек для данной крипты #print x_acc_label deal_acc_addr = db_client.get_deal_acc_addr_for_xcurr( db, deal_acc_id, curr_in, xcurr_in, x_acc_label) if not deal_acc_addr: return mess(T(' связь с кошельком ') + curr_in.name + T(' прервана.')) addr = deal_acc_addr.addr deal_name = deal.name # если есть скрытый партнерский код то его забьем пользователю deal_acc = db.deal_accs[deal_acc_id] import gifts_lib adds_mess = XML(gifts_lib.adds_mess(deal_acc, PARTNER_MIN, T)) deal_url = A(deal.name, _href=shops_url, _target="_blank") e_bal, MAX = get_e_bal(deal, dealer, dealer_acc) if MAX and volume_out > MAX: volume_out = MAX # используем быстрый поиск курса по формуле со степенью на количество входа # только надо найти кол-во входа от выхода pr_b, pr_s, pr_avg = rates_lib.get_average_rate_bsa( db, curr_in.id, curr_out.id, None) if pr_avg: vol_in = volume_out / pr_b amo_out, _, best_rate = rates_lib.get_rate(db, curr_in, curr_out, vol_in) else: best_rate = None if not best_rate: return mess('[' + curr_in.name + '] -> [' + curr_out.name + ']' + T(' - лучшая цена не доступна.')) is_order = True # сначала открутим обратную таксу volume_in, mess_in = db_client.calc_fees_back(db, deal, dealer_deal, curr_in, curr_out, volume_out, best_rate, is_order, note=0) ## теперь таксы для человека получим и должна та же цифра выйти vol_out_new, tax_rep = db_client.calc_fees(db, deal, dealer_deal, curr_in, curr_out, volume_in, best_rate, is_order, note=1) vol_out_new = common.rnd_8(vol_out_new) if volume_out != vol_out_new: print 'to_phone error_in_fees: volume_out != vol_out_new', volume_out, vol_out_new # теперь для заказ на курс уберем комиссию диллера - просто пересчитаем вход с наченкой диллера fee_curr = db.currs[deal.fee_curr_id] fee_rate = Decimal( rates_lib.get_avr_rate_or_null(db, fee_curr.id, curr_out.id)) vol_out_dd_neg, _ = db_client.dealer_deal_tax_neg(db, T, fee_rate, dealer_deal, '', Decimal(volume_out), '') #print vol_out_dd_neg # причем тут учитываем уже накрутку диллера за дело - в заказе курс будет с учетом накрутки автоматом volume_in = common.rnd_8(volume_in) rate_out = volume_out / volume_in # new make order order_rate_id = db.orders.insert( ref_=deal_acc_addr.id, volume_in=volume_in, volume_out=vol_out_dd_neg, ) # теперь стек добавим, который будем удалять потом db.orders_stack.insert(ref_=order_rate_id) addr_return = deal_acc_addr.addr_return if addr_return: addr_ret = DIV( DIV(T('Адрес для возвратов'), ': ', B(addr_return[:5] + '...' + addr_return[-5:]), _class='col-sm-12'), _class='row success', ) else: addr_ret = LOAD( 'aj', 'addr_ret', #args=[deal_acc_addr.addr_return or 0, deal_acc_addr.id, ], # лучше передавать через переменные - чтобы там по кругу они гонялись # в request args=[deal_acc_addr.id], ajax= False, # тут без асинхронной подгрузки модуля - вместе со страницей сразу грузим модуль ) _uri, uri_url = common.uri_make( curr_in.name2, addr, { 'amount': volume_in, 'label': db_client.make_x_acc_label(deal, acc, curr_out.abbrev) }) qr = DIV(DIV(DIV(P(T('Показать QR-код'), _class='btn_mc2'), _class='btn_mc1'), _onclick=''' jQuery(this).html('%s'); ajax("%s", [], 'tag_qr'); ''' % (IMG(_src=URL('static', 'images/loading.gif'), _width=64), URL('plugins', 'qr', vars={'mess': uri_url})), _id='tag_qr', _class='btn_mc col-sm-6'), _class='row') curr_in_abbrev = curr_in.abbrev lim_bal, may_pay = db_client.is_limited_ball(curr_in) if lim_bal: if may_pay > 0: lim_bal_mess = P( 'Внимание! Для криптовалюты %s существует предел запаса и поэтому наша служба может принять только %s [%s], Просьба не превышать это ограничение' % (curr_in.name, may_pay, curr_in_abbrev), '.', _style='color:black;') else: lim_bal_mess = P( 'ВНИМАНИЕ! Наша служба НЕ может сейчас принимать %s, так как уже достугнут предел запаса её у нас. Просьба попробовать позже, после того как запасы [%s] снизятся благодаря покупке её другими пользователями' % (curr_in.name, curr_in_abbrev), '. ', 'Иначе Ваш платеж будет ожидать момента когда запасы снизятся ниже %s' % lim_bal, '.', _style='color:brown;') else: lim_bal_mess = '' return dict(deal_name=deal_name, adds_mess=adds_mess, MIN=MIN, MAX=MAX, acc=acc, order_rate_id=order_rate_id, rate_out=rate_out, curr_in_name=curr_in_abbrev, curr_out_name=curr_out.abbrev, e_bal=e_bal, deal_url=deal_url, volume_in=volume_in, volume_out=volume_out, tax_rep=tax_rep, deal_img=deal_img, uri_url=uri_url, addr=addr, addr_ret=addr_ret, qr=qr, curr_id=curr_id, lim_bal_mess=lim_bal_mess)
def make_edealer_free_payment( db, curr_in, xcurr, #account, deal_acc_addr, geted_pays, amo): # возьмем дело для этой валюты и этого акка # имя акка + валюта входа должно быть уникальным (выходная валютта в имени аккаунта) r = db.deal_accs[deal_acc_addr.deal_acc_id] if not r: print 'ERROR: (make_edealer_free_payment) "deal_accs" not found - ', curr_in.abbrev, deal_acc_addr, amo mark_pay_ins( db, geted_pays, 'refuse', current.T('"deal_accs[%s]" не найден') % deal_acc_addr.deal_acc_id) db.commit() return if not r.acc: print 'ERROR: (make_edealer_free_payment) "deal_accs.acc" = None ', curr_in.abbrev, deal_acc_addr, amo mark_pay_ins(db, geted_pays, 'refuse', 'deal_accs[%s].acc=None' % deal_acc_addr.deal_acc_id) db.commit() return deal = db.deals[r.deal_id] if not deal: print 'ERROR: (make_edealer_free_payment) "deal" = None ', curr_in.abbrev, deal_acc_addr, amo mark_pay_ins(db, geted_pays, 'refuse', 'deal[%s]=None' % r.deal_id) db.commit() return volume_in = amo #log( db, 'make free-pay for deal_acc: %s %s[%s]' % ( r.acc, volume_in, curr_in.abbrev)) curr_out = db.currs[r.curr_id] ecurr = dealer = dealer_acc = dealer_deal = None # у клиентов тут Ноне client = db(db.clients.deal_id == deal.id).select().first() if client: pass #dealer = None else: # тут только фиат на выходе ecurr = db(db.ecurrs.curr_id == curr_out.id).select().first() # курс реальный берем - чем больше тем ниже s_b = True d_e = None # перевод с биржи на диллера # так как у нас тут неизвестно количестыво на выходе а есть # количество на входе, то надо обратную операцию: # поменяем in out s_b pr_b, pr_s, pr_avg = rates_lib.get_average_rate_bsa( db, curr_in.id, curr_out.id, None) if not pr_avg: mark_pay_ins(db, geted_pays, 'wait', 'best rate not found!') db.commit() log( db, '%s[%s] -> [%s] - best rate not found!' % (amo, curr_in.abbrev, curr_out.abbrev)) return volume_out, _, best_rate = rates_lib.get_rate(db, curr_in, curr_out, amo) if volume_out == None: mark_pay_ins(db, geted_pays, 'wait', 'best rate not found!') db.commit() log( db, '%s[%s] -> [%s] - best rate not found!' % (amo, curr_in.abbrev, curr_out.abbrev)) return best_rate = Decimal(best_rate) volume_out = Decimal(volume_out) if client: pass else: if ecurr: # теперь нам известен объем на выходе - найдм диллера dealer, dealer_acc, dealer_deal = ed_common.select_ed_acc( db, deal, ecurr, volume_out, unlim=USE_UNLIM) # тут добавляем еще мизерный оброк себе в карман = 1 рубль например: # и оброк с конкретнгого дела is_order = True try: # тут берем без учета что еще на нас начислит диллер за эту услугу (учет в ed_common.pay) volume_out, mess = db_client.calc_fees(db, deal, dealer_deal_NONE, curr_in, curr_out, amo, best_rate, is_order, note=0) except Exception as e: print 'PAY error db_client.calc_fees', e volume_out, mess = amo * best_rate, 'error in fees' #log_commit(db, mess) #print volume_in, volume_out, best_rate, '=', volume_in * best_rate ##print 'volume_in:', type(volume_in), 'volume_out:', type(volume_out) ################################################# # оплатить и обновить базу # тут уже берем dealer_acc, dealer_deal make_edealer_payment(db, geted_pays, curr_in, xcurr, curr_out, ecurr, volume_in, volume_out, deal_acc_addr, best_rate, None, dealer, dealer_acc, dealer_deal)
def get(): args = request.args ##print args, '\n', request.vars if len(args) < 2: return mess('err...') deal_id = args(0) curr_id = args(1) if not deal_id.isdigit() or not curr_id.isdigit(): return mess('dig...') # теперь можно задать открытие кнопки scr = "$('#cvr%s').css('display','none');$('#tag%s').show('slow');" % (curr_id, curr_id) response.js = scr vol = request.vars.vol if not vol or len(vol) > 20: return mess(T('ОШИБКА') + ': ' + T('Задайте количество')) try: vol = float(vol) curr_id = int(curr_id) except: return mess('digs...') addr_out = request.vars.addr #print request.vars if not addr_out: return mess(T('ОШИБКА: Задайте кошелек')) try: if len(addr_out) < 25 or len(addr_out) > 40: ##проверка на счет - если это не емайл и не ттелефон то надо длинну и на циифры return mess(T('ОШИБКА: неверный кошелек')) except: return mess(T('ОШИБКА: неверный кошелек 2')) deal = db.deals[ deal_id ] if not deal: return mess(T('deal...')) curr_in = db.currs[ curr_id ] if not curr_in: return mess(T('curr...')) xcurr_in = db(db.xcurrs.curr_id == curr_id).select().first() if not xcurr_in: return mess(T('xcurr...')) #print request.vars curr_out = db.currs[ request.vars.curr_out ] xcurr_out = db(db.xcurrs.curr_id == curr_out.id).select().first() curr_out_abbrev = curr_out.abbrev curr_out_name = curr_out.name #print request.application[-5:] if request.application[:-3] != '_dvlp': # чето конфликт если из ipay3_dvlp вызывать то кошелек на ipay3 не коннектится import crypto_client cc = crypto_client.conn(curr_out, xcurr_out) if not cc: return mess(T('Connection to [%s] id lost, try lates ') % curr_out_name) if crypto_client.is_not_valid_addr(cc, addr_out): return mess(T('address not valid for ') + curr_out_name) try: session.toCoin = curr_out_abbrev session.toCoinA = addr_out except: print 'to_coin session error .toCoinA:', type(addr_out), addr_out try: session.vol = vol except: print 'to_coin session error .vol:', type(vol), vol curr_in_name = curr_in.name x_acc_label = db_client.make_x_acc(deal, addr_out, curr_out_abbrev) # найдем ранее созданный адресс для этого телефона, этой крипты и этого фиата # сначала найтем аккаунт у дела deal_acc_id = db_client.get_deal_acc_id(db, deal, addr_out, curr_out) # теперь найдем кошелек для данной крипты deal_acc_addr = db_client.get_deal_acc_addr_for_xcurr(db, deal_acc_id, curr_in, xcurr_in, x_acc_label) if not deal_acc_addr: return mess((T('Связь с сервером %s прервана') % curr_in_name) + '. ' + T('Невозможно получить адрес для платежа') + '. ' + T('Пожалуйста попробуйте позже'), 'warning') addr = deal_acc_addr.addr h = CAT() okIN = session.okWt h += sect(DIV( okIN and DIV(H3(A(T('Правила оплаты'), _onclick='$(".okIN").show("fast");', _class='button warn right'), _class='pull-right-'), _class='col-sm-12') or '', DIV(okIN and ' ' or H3(T('ПРАВИЛА ОПЛАТЫ'), _class='center'), P(T('При оплате необходимо соблюдать следующие правила:')), UL( T('Желательно задать обратный адрес для возврата монет на случай если наша служба по каким-либо причинам не сможет совершить оплату по делу [%s]') % deal.name, T('Если Вы не задали обратный адрес для возврата монет, то необходимо платить биткоины и другую криптовалюту только со своего кошелька, задав адреса входов, которыми Вы действительно обладаете, а не с кошельков бирж, пулов или разных онлайн-кошельков. Так как монеты, в случае если платеж будет отвергнут нашим партнёром, могут автоматически вернуться только на адрес отправителя.'), T('Комиссия сети добавляется к сумме для обмена, о чем указывается ниже.'), T('Если Вы оплатите другую сумму, то курс обмена может немножко измениться'), T('Если Вы платите регулярно, то можете платить на тот же адрес кошелька криптовалюты, что получили ранее. Хотя желательно заходить на нашу службу для получения новостей хотябы раз в пол года или подписаться на важные новости и сообщения оставив свой емайл.'), ), H4(A(T('Понятно'), _onclick='$(".okIN").hide("fast");ajax("%s")' % URL('aj','ok_to',args=['Wt']), _class='button warn'), _class='center'), _class='col-sm-12 okIN', _style='color:chocolate;display:%s;' % (okIN and 'none' or 'block')), _class='row'), 'bg-warning pb-10') # если есть скрытый партнерский код то его забьем пользователю deal_acc = db.deal_accs[deal_acc_id] if not deal_acc.partner: try: _ = GIFT_CODE except: GIFT_CODE = session.gc #from gifts_lib import gift_proc #GIFT_CODE, gift_mess = gift_proc(db, T, deal, deal_acc, request, session, GIFT_CODE) #if GIFT_CODE: # h += sect(XML(gift_mess), 'gift-bgc pb-10 pb-10') import gifts_lib adds_mess = XML(gifts_lib.add_mess_curr(deal_acc, curr_out, T)) if adds_mess: h += sect(XML(adds_mess), 'gift-bgc pb-10 pb-10') volume_out = vol hh = CAT(H2('3. ' + T('Оплатите по данным реквизитам'), _class='center')) # используем быстрый поиск курса по формуле со степенью на количество входа # только надо найти кол-во входа от выхода pr_b, pr_s, pr_avg = rates_lib.get_average_rate_bsa(db, curr_in.id, curr_out.id, None) if pr_avg: vol_in = volume_out / pr_b amo_out, _, best_rate = rates_lib.get_rate(db, curr_in, curr_out, vol_in) else: best_rate = None if best_rate: is_order = True dealer_deal = None # сначала открутим обратную таксу txfee = float(xcurr_out.txfee or 0.0001) volume_out += txfee volume_in, mess_in = db_client.calc_fees_back(db, deal, dealer_deal, curr_in, curr_out, volume_out, best_rate, is_order, note=0) ## теперь таксы для человека получим и должна та же цифра выйти vol_out_new, tax_rep = db_client.calc_fees(db, deal, dealer_deal, curr_in, curr_out, volume_in, best_rate, is_order, note=1) vol_out_new = common.rnd_8(vol_out_new) if common.rnd_8(volume_out) != vol_out_new: print 'to_phone error_in_fees: volume_out != vol_out_new', volume_out, vol_out_new volume_in = common.rnd_8(volume_in) rate_out = volume_out / volume_in # new make order order_id = db.orders.insert( ref_ = deal_acc_addr.id, volume_in = volume_in, volume_out = volume_out, ) # теперь стек добавим, который будем удалять потом db.orders_stack.insert( ref_ = order_id ) hh += DIV( T('Создан заказ №%s') % order_id,' ', T('на заморозку обменного курса по'), ' ', rate_out, ' (',T('обратный курс'), ' ', round(1.0/float(rate_out),8),') ', T('для объема'),' ',volume_out, ' ', curr_out_abbrev, ' (', T('с учётом комиссии сети'),' ',txfee,').', H5('*',T('Данный курс будет заморожен для Вас на 20 минут для объёма криптовалюты не больше указанного. Проверить можно по номеру заказа в списке платежей.')), _class='row') else: volume_in = rate_out = tax_rep = None hh += mess('[' + curr_in_name + '] -> [' + curr_out_name + ']' + T(' - лучшая цена не доступна.') + T('Но Вы можете оплатить вперед'), 'warning pb-10') _, url_uri = common.uri_make( curr_in.name2, addr, {'amount':volume_in, 'label': db_client.make_x_acc_label(deal, addr_out, curr_out_abbrev)}) curr_in_abbrev = curr_in.abbrev lim_bal, may_pay = db_client.is_limited_ball(curr_in) if lim_bal: if may_pay> 0: lim_bal_mess = P( T('Внимание! Для криптовалюты %s существует предел запаса и поэтому наша служба может принять только %s [%s], Просьба не превышать это ограничение') % (curr_in.name, may_pay, curr_in_abbrev), '.', _style='color:black;' ) else: lim_bal_mess = P( T('ВНИМАНИЕ! Наша служба НЕ может сейчас принимать %s, так как уже достугнут предел запаса её у нас. Просьба попробовать позже, после того как запасы [%s] снизятся благодаря покупке её другими пользователями') % (curr_in.name, curr_in_abbrev), '. ', T('Иначе Ваш платеж будет ожидать момента когда запасы снизятся ниже %s') % lim_bal,'.', _style='color:brown;') else: lim_bal_mess = '' free_bal = db_client.curr_free_bal(curr_out) hh += DIV( P( T('Оплата обмена на'), ' ',curr_out_abbrev, ' ', T('с выплатой монет на адрес'), ': ', addr_out, '. ', T('Текущая сумма обмена'), ' ', volume_out, ' ', curr_out_abbrev,' (', T('с учётом комиссии сети'),') ', ' ', T('из доступных в службе'), ' ', free_bal, '. ', T('Так же Вы можете делать ещё платежи на созданый %s адрес для совершения автоматического обмена %s на %s по текущему курсу.') % (curr_in_name, curr_in_name, curr_out_name), ), volume_out > free_bal and P( H3(T('Сейчас средств на балансе меньше чем Вам надо'), _style='color:crimson;'), SPAN(T('Поэтому Ваш заказ будет исполнен позже'), BR(), T('когда на балансе службы появится достаточно средств'), _style='color:black;'), BR(), ) or '', lim_bal_mess, DIV(CENTER( A(SPAN(T('Оплатить'),' ', volume_in or '', ' ', IMG(_src=URL('static','images/currs/' + curr_in_abbrev + '.png'), _width=50)), _class='block button blue-bgc', _style='font-size:x-large; max-width:500px; margin:0px 7px;', _href=url_uri), ), _class='row' ), BR(), DIV( A(T('Показать QR-код'), _class='btn btn-info', ##_onclick="jQuery(this).parent().html('%s')" % IMG(_src=URL('static','images/loading.gif'), _width=64), _onclick="jQuery(this).parent().html('<i class=\"fa fa-spin fa-refresh\" />')", callback=URL('plugins','qr', vars={'mess': url_uri}), target='tag0', #delete='div#tag0' ), _id='tag0'), T('или'), BR(), T('Оплатите вручную'), ': ', FORM( ## ВНИМАНИЕ !!! тут имена полей надр друние указывать или # FORM в основной делать тоже иначе они складываются INPUT(_name='v', value=volume_in, _class="pay_val", _readonly=''), curr_in_abbrev, BR(), T("Для этого скопируйте сумму и адрес (двойной клик по полю для выделения) и вставьте их в платеж на вашем кошельке"), ': ', INPUT(_name='addr_in', _value=addr, _class='wallet', _readonly=''), BR(), #T('Резервы службы'), ' ', B(free_bal), ' ', T('рублей'), BR(), #LOAD('where', 'for_addr', vars={'addr': addr}, ajax=True, times=100, timeout=20000, # content=IMG(_src=URL('static','images/loading.gif'), _width=48)), INPUT( _type='submit', _class='button blue-bgc', _value=T('Подробный просмотр платежей'), _size=6, ), _action=URL('where', 'index'), _method='post', ) ) h += sect(hh, 'bg-info pb-10') h += sect(DIV(DIV( H3(T('Почему получился такой курс?')), tax_rep, BR(), T('При этом Вы получаете следующие преимущества при обмене криптовалют у нас'),':', UL( [ T('Вы можете теперь постоянно делать обмен со своего кошелька на полученный адрес даже не заходя на наш сайт'), T('не нужно нигде регистрироваться'), T('не нужно делать подтверждения по СМС или по емайл'), T('обмен производится быстро и автоматически'), T('Вам не нужно хранить свои деньги у нас'), ] ), T('Время - деньги!'), _class='col-sm-12'), _class='row')) h += SCRIPT(''' $('html, body').animate( { scrollTop: $('#cvr%s').offset().top - $('#aside1').height() }, 500 ); ''' % (curr_id)) return h
def pay(): # TODO тут на входе дело ловить а не валюту выхода #common.page_stats(db, response['view']) #print response['view'], ss, db_common.ip() response.title = T("Проверьте данные") ph = request.vars.get('phone') if not ph or len(ph) == 0: redirect(URL('to_wallet', 'index', args=['err01'])) return try: volume_out = float(request.vars['volume']) dealer_id = request.vars['dealer'] dealer = db.dealers[dealer_id] except: time.sleep(333) raise HTTP('bee-bee-bee') dealer_acc = ed_common.sel_acc_max(db, dealer, ecurr_out, volume_out) if not dealer_acc: return dict(uri=T( 'Не найден акк-дилер для обмена, возможно превышены лимиты, просьба подождать до следующего дня или месяца' ), addr=None) dealer_deal = db((db.dealer_deals.dealer_id == dealer.id) & (db.dealer_deals.deal_id == deal.id)).select().first() if not dealer_deal: response.title = T("ОШИБКА") return dict(uri=T('Не найден дилер для дела:'), addr=None) # теперь проверку на правильность кошелька для дилера электронных платежей #dealer_acc # pay_test(deal, dealer, dealer_acc, dealer_deal, acc, volume_out) res = ed_common.pay_test(db, deal, dealer, dealer_acc, dealer_deal, ph, deal.MIN_pay or dealer.pay_out_MIN or 20, False) if res['status'] != 'success': response.title = T("ОШИБКА") mess = 'error_description' in res and res['error_description'] or res[ 'error'] or 'dealer error' mess = T('Платежная система %s отвергла платеж, потому что: %s') % ( dealer.name, mess) return dict(uri=mess, addr=None) session.visitor_wallet = ph # найдем по имени крипту curr_in, xcurr_in, e = db_common.get_currs_by_abbrev( db, request.vars['curr_in']) if not xcurr_in: response.title = T("ОШИБКА") return dict(uri=T('Криптовалюта ') + request.vars['curr_in'] + T(' не найдена в базе данных.'), addr=None) # get new or old adress for payment x_acc_label = db_client.make_x_acc(deal, ph, curr_out.abbrev) # найдем ранее созданный адресс для этого телефона, этой крипты и этого фиата # сначала найтем аккаунт у дела deal_acc_id = db_client.get_deal_acc_id(db, deal, ph, curr_out) # теперь найдем кошелек для данной крипты deal_acc_addr = db_client.get_deal_acc_addr_for_xcurr( db, deal_acc_id, curr_in, xcurr_in, x_acc_label) if not deal_acc_addr: response.title = T("ОШИБКА") return dict(uri=T(' связь с кошельком ') + curr_in.name + T(' прервана.'), addr=None) #request.vars['deal_acc_addr']=deal_acc_addr addr = deal_acc_addr.addr request.vars['addr'] = addr MIN = deal.MIN_pay or dealer.pay_out_MIN or 3 if MIN > volume_out: u = URL('to_wallet', 'index', args=['err02']) #, vars={'l':deal.MIN_pay}) redirect(u) return request.vars['e_bal'], MAX = get_e_bal(deal, dealer, dealer_acc) if volume_out > MAX: volume_out = MAX ###best_rate, pairs, taxs, ed_fee = db_client.get_best_price_by_volume_out(db, curr_in.id, curr_out.id, volume_out, dealer.id) # используем быстрый поиск курса по формуле со степенью на количество входа # только надо найти кол-во входа от выхода best_rate = pairs = taxs = ed_fee = None pr_b, pr_s, pr_avg = rates_lib.get_average_rate_bsa( db, curr_in.id, curr_out.id, None) #print pr_b, pr_s, pr_avg if pr_avg: vol_in = volume_out / pr_b #print vol_in, curr_in.abbrev, '-->', volume_out, curr_out.abbrev amo_out, _, best_rate = rates_lib.get_rate(db, curr_in, curr_out, vol_in) #best_rate = best_rate and 1/best_rate #print best_rate, 1/best_rate #print best_rate, pair if not best_rate: response.title = T("ОШИБКА") return dict(uri='[' + curr_in.name + '] -> [' + curr_out.name + ']' + T(' - лучшая цена не доступна.'), addr=None) # найдем цену без процентов - чтобы было не так страшно #best_rate_clear = best_rate / (1 - ed_fee) #for t in taxs: # best_rate_clear = best_rate_clear / (1 - t['tax']) volume_in, rate_out, tax_info = db_client.get_fees_for_out( db, deal, dealer_deal, curr_in, curr_out, volume_out, best_rate, pairs, taxs, ed_fee) #print tax_info request.vars['dealer_name'] = dealer.name request.vars['curr_out_name'] = curr_out.abbrev request.vars['curr_in_name'] = curr_in.abbrev request.vars['best_rate'] = rate_out request.vars['best_rate_rev'] = round(1.0 / best_rate, 8) request.vars['volume_in'] = volume_in request.vars['volume'] = volume_out # make tax and fee report for this RATE tax_rep = '' for ss in tax_info: tax_rep = tax_rep + ss request.vars['rate_report'] = tax_rep #deal = db(db.deals.name==deal_name).select().first() # new make order #print deal_acc_addr id = db.orders.insert( ref_=deal_acc_addr.id, volume_in=volume_in, volume_out=volume_out, ) # теперь стек добавим, который будем удалять потом db.orders_stack.insert(ref_=id) request.vars['order'] = id uri, qr = common.uri_make( curr_in.name2, addr, { 'amount': volume_in, 'label': db_client.make_x_acc_label(deal, ph, curr_out.abbrev) }) return dict(uri=uri, addr=addr, qr=qr)
def go2(): dealer_id = request.args(0) if not dealer_id or not dealer_id.isdigit(): return T('Empty dealer_id') ecurr_id = request.args(1) if not ecurr_id or not ecurr_id.isdigit(): return T('Empty ecurr_id') dealer = db.dealers[dealer_id] if not dealer: return T('Empty dealer') ecurr = db.ecurrs[ecurr_id] if not ecurr: return T('Empty ecurr') curr_out = db.currs[ecurr.curr_id] if not curr_out: return T('Empty curr') #print request.vars best_rate = pairs = taxs = ed_fee = k = v = None for k, v in request.vars.iteritems(): pass #return '%s: %s' % (k,v) # берем теперь наилучший аккаунт у этого диллера для нас volume_out = v and v.replace('.', '').isdigit() and float(v) or 3 dealer_acc = ed_common.sel_acc_max(db, dealer, ecurr, volume_out, not volume_out) if not dealer_acc: return T( 'Не найден акк-дилер для обмена, возможно превышены лимиты, просьба подождать до следующего дня или месяца' ) dealer_deal = db((db.dealer_deals.dealer_id == dealer.id) & (db.dealer_deals.deal_id == deal.id)).select().first() if not dealer_deal: response.title = T("ОШИБКА") return T('Не найден дилер для дела:') h = CAT() MIN = deal.MIN_pay or dealer.pay_out_MIN or 3 if MIN > volume_out: return T('ОШИБКА: Слишком маленькая сумма платежа') request.vars['e_bal'], MAX = get_e_bal(deal, dealer, dealer_acc) if volume_out > MAX: volume_out = float(MAX) _style = 'background-color: rgba(0, 0, 0, 0.25);' for rc in db((db.xcurrs.curr_id == db.currs.id) & (db.currs.used == True)).select(): #curr_in = db.currs[ xcurr.curr_id ] curr_in = rc.currs if not curr_in.used: hh = T('Not used') else: pr_b, pr_s, pr_avg = rates_lib.get_average_rate_bsa( db, curr_in.id, curr_out.id, None) #print pr_b, pr_s, pr_avg if pr_avg: vol_in = volume_out / pr_b #print vol_in, curr_in.abbrev, '-->', volume_out, curr_out.abbrev amo_out, _, best_rate = rates_lib.get_rate( db, curr_in, curr_out, vol_in) #best_rate = best_rate and 1/best_rate #print best_rate, 1/best_rate #print best_rate, pair if not best_rate: hh = CAT('[' + curr_in.name + '] -> [' + curr_out.name + ']' + T(' - лучшая цена не доступна.')) else: # найдем цену без процентов - чтобы было не так страшно #best_rate_clear = best_rate / (1 - ed_fee) #for t in taxs: # best_rate_clear = best_rate_clear / (1 - t['tax']) volume_in, rate_out, tax_info = db_client.get_fees_for_out( db, deal, dealer_deal, curr_in, curr_out, volume_out, best_rate, pairs, taxs, ed_fee) hh = CAT( DIV( DIV(_class='col-md-1'), ug( CAT( IMG(_src=URL('default', 'download', args=['db', curr_in.icon]), _width=64, _class='lst_icon', _alt=curr_in.name), ' ', curr_in.name), None, 'col-md-4 col-sm-5', None, #onclick="$('#%s').text('%s');ajax('%s', ['%s'], '%s')" % (tag, T('Working...'),url, curr.abbrev, tag), #'background-color: rgba(19, 159, 24, 0.6);' ), DIV(T('For GET:'), ' ', volume_out, BR(), T('To PAY:'), ' ', volume_in, BR(), T('By RATE:'), ' ', rate_out, _class='btn_mc col-sm-7'), _class='row'), DIV(tax_info, _class='small row'), HR(), ) #hc = curr h += DIV(hh, _style=_style, _class='row') h += DIV(T('Max amount:'), ' ', dealer_acc.balance) return h
def get_xcurrs_for_deal(db, amo_out, curr_out, deal, dealer=None, s_b_in=None, not_used=None): curr_out_id = curr_out.id dealer_id = dealer and dealer.id or None # берем в расчет только недавние цены expired = datetime.now() - timedelta(0, 360) pairs = [] is_order = False dealer_deal = None deal = db.deals[current.TO_COIN_ID] s_b = s_b_in == None and True or s_b_in ############################ d_e = None # теперь по всем криптам пройдемся и если нет в парах то # значит запрет в форме сделаем for rec_in in db((db.currs.used == True) & (db.xcurrs.curr_id == db.currs.id)).select( orderby='currs.name'): curr_in = rec_in.currs if not_used and curr_in.abbrev in not_used: continue disabled = None if curr_in.id == curr_out.id: continue if not amo_out: rates = rates_lib.get_best_rates(db, curr_in, curr_out) if rates: amo_in = rates[curr_out.id][0] else: amo_in = 0 else: # количество уже жестко задано от магазина pr_b, pr_s, pr_avg = rates_lib.get_average_rate_bsa( db, curr_in.id, curr_out.id, expired) #print pr_b, pr_s, pr_avg if pr_b: amo_in = amo_out / pr_b rate = None if False: # OLD style - without taxes if not amo_out or pr_b: #print 'amo_in:', amo_in amo_out, rate_order, rate = rates_lib.get_rate( db, curr_in, curr_out, amo_in) else: # new STYLE - full price # amo_in = 1 _, _, best_rate = rates_lib.get_rate(db, curr_in, curr_out, amo_in) if best_rate: amo_out, mess_out = calc_fees(db, deal, dealer_deal, curr_in, curr_out, amo_in, best_rate, is_order=0, note=0, only_tax=1) ## vol_out - is Decimal amo_out = common.rnd_8(amo_out) if amo_in: rate = amo_out / amo_in if not rate: rate = -1 disabled = True currs_stats = db((db.currs_stats.curr_id == curr_in.id) & (db.currs_stats.deal_id == deal.id)).select().first() pairs.append({ 'id': curr_in.id, 'price': rate, 'name': curr_in.name, 'abbrev': curr_in.abbrev, 'icon': curr_in.icon, 'expired': disabled, 'name_out': curr_out.abbrev, 'used': currs_stats and currs_stats.count_ or 0, 'curr_id': curr_in.id, # для того чтобы по 2му разу не брало 'bal': curr_in.balance, 'bal_out': curr_free_bal(curr_in) # сколько можно продать }) return pairs
def get(): args = request.args if len(args) != 1: return mess('err...') curr_id = args(0) ##scr = "$('#cvr%s').css('z-index',-1);$('#tag%s').show('slow');" % (curr_id, curr_id) scr = "$('#cvr%s').css('display','none');$('#tag%s').show('slow');" % ( curr_id, curr_id) response.js = scr if not curr_id.isdigit(): return mess('dig...') vol = request.vars['vol'] if not vol or len(vol) > 20: return mess(T('ОШИБКА') + ': ' + T('Задайте количество')) try: vol = float(vol) curr_id = int(curr_id) except: return mess('digs...') addr = request.vars['wallet'] if not addr or len(addr) < 30 or len(addr) > 35: return mess( T('ОШИБКА') + ': ' + T('Введите адрес кошелька криптовалют')) curr_out = db.currs[curr_id] if not curr_out: return mess(T('curr...')) xcurr_out = db(db.xcurrs.curr_id == curr_id).select().first() if not xcurr_out: return mess(T('xcurr...')) curr_out_name = curr_out.name amo_in = vol _amo_out, rate_order, best_rate = rates_lib.get_rate( db, curr_in, curr_out, amo_in) try: dealer_id = request.vars['dealer'] dealer = db.dealers[dealer_id] except: return mess('digs...') MIN = db_common.gMIN(deal, dealer) if vol < MIN: try: vol = MIN session.vol = vol except: print 'to_buy session error .vol:', type(addr), addr return mess( T('ОШИБКА: Слишком маленькая сумма платежа %s < %s') % (vol, MIN)) dealer_acc = ed_common.sel_acc_min(db, dealer, ecurr, amo_in) if not dealer_acc: return mess( (T('Электронные деньги [%s] не доступны сейчас.' % dealer.name) + ' ' + T('Попробуйте позже')), 'warning') if not best_rate: response.title = T("ОШИБКА") return mess(T('Курс не найден'), 'warning') try: session.buyAddr = addr session.buyVol = vol except: print 'list session error .buyAddr:', type(addr), vol print 'list session error .buyVol:', type(vol), vol #print best_rate if request.application[:-3] != '_dvlp': # чето конфликт если из ipay3_dvlp вызывать то кошелек на ipay3 не коннектится cc = crypto_client.conn(curr_out, xcurr_out) if cc: if crypto_client.is_not_valid_addr(cc, addr): #return mess(T('address not valid for ') + curr_out_name) return mess( T('ОШИБКА') + ': ' + T('Адрес кошелька не подходит для выбранной криптовалюты %s' ) % curr_out_name) else: # ЕСЛИ НЕТ СВЯЗИ - пусть пллатит - потом связь появится #return mess(T('Connection to [%s] is lost, try later ') % curr_out_name) ##return mess(T('Связь с кошельком ') + curr_out_name + T(' прервана.') + ' ' + T('Пожалуйста попробуйте позже'), 'warning') pass volume_in = vol is_order = True dealer_deal = db( (db.dealer_deals.deal_id == deal.id) & (db.dealer_deals.dealer_id == dealer_id)).select().first() ## теперь таксы для человека получим и должна та же цифра выйти vol_out, tax_rep = db_client.calc_fees(db, deal, dealer_deal, curr_in, curr_out, volume_in, best_rate, is_order, note=1) volume_out = common.rnd_8(vol_out) volume_in = common.rnd_8(volume_in) rate_end = volume_in / volume_out ##print 'buy:', volume_in, vol_out, rate_end h = CAT() okIN = session.okBu h += sect( DIV(okIN and DIV(H3(A('Правила оплаты', _onclick='$(".okIN").show("fast");', _class='button warn right'), _class='pull-right-'), _class='col-sm-12') or '', DIV(okIN and ' ' or H3('ПРАВИЛА ОПЛАТЫ', _class='center'), P(T('При оплате необходимо соблюдать следующие правила:')), UL( T('Если Вы хотите оплатить большую сумму, то нужно делать платежи небольшими суммами по 2000-3000 рублей и получать разные счета - просто еще раз нажмите на кнопку выбора необходимой валюты' ), T('Если Вы оплатите другую сумму, то курс обмена может немножко измениться' ), T('Если Вы платите регулярно, то просьба каждый раз получать счет нажатием на кнопку выбора валюты - возможно счет будет выбран другой, а ранее полученный счет может быть перегружен и заморожен на сутки и более' ), ), H4(A('Понятно', _onclick='$(".okIN").hide("fast");ajax("%s")' % URL('aj', 'ok_to', args=['Bu']), _class='button warn'), _class='center'), _class='col-sm-12 okIN', _style='color:chocolate;display:%s;' % (okIN and 'none' or 'block')), _class='row'), 'bg-warning pb-10') # создадим номер заказа чтобы не показывать что мы на крипту принимаем платеж order = db((db.addr_orders.xcurr_id == xcurr_out.id) & (db.addr_orders.addr == addr)).select().first() if not order: order_id = db.addr_orders.insert(xcurr_id=xcurr_out.id, addr=addr) else: order_id = order.id amo_in = round(amo_in * 1.005, 2) # добавим таксу яндекса 0.5% destination = '7pb%s' % order_id # + ' ' + T('или') +' ' + curr_out.abbrev + ' ' + addr free_bal = db_client.curr_free_bal(curr_out) h += sect( DIV(DIV( H2(T('3. Оплатите по данным реквизитам покупку %s') % curr_out_name, _class='center'), P( T('курс обмена: %s (обратный курс: %s)') % (round(rate_end, 8), round(1 / rate_end, 8)), BR(), T('Вы получите'), ' ', B(round(volume_out, 8)), IMG(_src=URL('static', 'images/currs/' + curr_out.abbrev + '.png'), _width=36), ' ', T('из доступных'), ' ', free_bal, ), P( volume_out > free_bal and CAT( H3(T('Сейчас средств на балансе меньше чем Вам надо'), _style='color:crimson;'), SPAN( T('Поэтому Ваш заказ будет исполнен позже'), BR(), T('когда на балансе службы появится достаточно средств' ), _style='color:black;'), BR(), ) or '', ), DIV(CENTER( A(SPAN( T('Оплатить'), ' ', amo_in, ' ', IMG(_src=URL('static', 'images/currs/' + curr_in.abbrev + '.png'), _width=50)), _class='block button blue-bgc', _style='font-size:x-large; max-width:500px; margin:0px 7px;', _href= 'https://money.yandex.ru/direct-payment.xml?scid=767&receiver=%s&sum=%s&destination=%s&FormComment=buy %s on ' + DOMEN % (dealer_acc.acc, amo_in, destination, curr_out.abbrev)), ), _class='row'), BR(), P( T('Или сделайте платеж вручную на %s кошелек %s') % (dealer.name, dealer_acc.acc), BR(), T('указав в назначении платежа код оплаты'), ':', BR(), B(destination), ), tax_rep, FORM(INPUT(_name='addr', _value=addr, _type='hidden'), INPUT( _type='submit', _class='button blue-bgc', _value=T('Подробный просмотр платежей'), _size=6, ), _action=URL('where', 'index'), _method='post'), _class='center', _style='color:blue;'), _class='row'), 'bg-info pb-10') h += sect( CAT( DIV(H3(T('Так же Вы можете пополнить этот %s кошелек') % dealer.name, ':', _class='center'), _class='row'), DIV(DIV( IMG(_src=URL('static', 'images/m-cards.png'), _style='float:left;margin:10px;'), T('С любой банковской карточки, указав в сообщении получателю код оплаты (как показано выше)' ), _class='col-lg-8 col-lg-offset-2 col-sm-12', _style='black;padding: 5px;'), _class='row'), DIV(DIV( IMG(_src=URL('static', 'images/m-banks.png'), _style='float:left;margin:10px;'), T('Из любого банка, например Альфа-Банк (пока Сбербанк не даёт такие данные)' ), '. ', T('После чего'), ' ', A(B(T('ПОДТВЕРДИТЬ')), _href=URL('to_buy', 'bank')), ' ', T('покупку биткоинов по банковским реквизитам платежа (сумме и референсу платёжки)' ), _class='col-lg-8 col-lg-offset-2 col-sm-12', _style='black;padding: 5px;'), _class='row'), ), #_style='background-color:#FFF47D;color:black;' 'gold-bgc pb-10') h += SCRIPT(''' $('html, body').animate( { scrollTop: $('#cvr%s').offset().top - $('#aside1').height() }, 500 ); ''' % (curr_id)) return h
def get_uri(): import rates_lib, common args = request.args ##print args, '\n', request.vars if len(args) < 2: return mess('err...') deal_id = args(0) curr_id = args(1) or vars.get('curr_in') if not curr_id or len(curr_id) > 20: return mess('error curr_in') try: curr_id = int(curr_id) curr_in = db.currs[curr_id] if not curr_in: return mess('curr in id...') except: curr_in = db(db.currs.abbrev == curr_id).select().first() curr_id = curr_in.id if not curr_in: return mess('curr in id...') curr_id = curr_in.id curr_out_id = args(2) or vars.get('curr_out') if not curr_out_id or len(curr_out_id) > 20: return mess('error curr_out') try: curr_out_id = int(curr_out_id) curr_out = db.currs[curr_out_id] if not curr_out: return mess('curr out id...') except: curr_out = db(db.currs.abbrev == curr_out_id).select().first() if not curr_out: return mess('curr out id...') curr_out_id = curr_out.id addr_out = args(3) #if not deal_id.isdigit() or not curr_id.isdigit(): # return mess('dig...') vol = args(4) if not vol or len(vol) > 20: return mess('error amount') try: vol = float(vol) except: return mess('digs...') if not addr_out: return mess('error address') try: if len(addr_out) < 25 or len(addr_out) > 40: return mess('error address') except: return mess('error address') deal = db.deals[deal_id] if not deal: return mess('deal...') xcurr_in = db(db.xcurrs.curr_id == curr_id).select().first() if not xcurr_in: return mess('xcurr...') xcurr_out = db(db.xcurrs.curr_id == curr_out.id).select().first() if not xcurr_out: return mess('xcurr out...') curr_out_abbrev = curr_out.abbrev curr_out_name = curr_out.name token_system_in = None token_key_in = xcurr_in.as_token if token_key_in: token_in = db.tokens[token_key_in] token_system_in = db.systems[token_in.system_id] import rpc_erachain token_system_out = None token_key_out = xcurr_out.as_token if token_key_out: token_out = db.tokens[token_key_out] token_system_out = db.systems[token_out.system_id] import rpc_erachain #print request.application[-5:] if request.application[:-3] != '_dvlp': # conflicts to call if from [ipay3_dvlp] - wallet not in connection... if token_system_out: curr_block = rpc_erachain.get_info(token_system_out.connect_url) if type(curr_block) != type(1): return mess('Connection to [%s] is lost, try later ' % curr_out_name) if rpc_erachain.is_not_valid_addr(token_system_out.connect_url, addr_out): return mess('address not valid for ' + curr_out_name + ' - ' + addr_out) pass else: import crypto_client try: cc = crypto_client.conn(curr_out, xcurr_out) except: cc = None if not cc: return mess('Connection to [%s] is lost, try later ' % curr_out_name) if crypto_client.is_not_valid_addr(cc, addr_out): return mess('address not valid for - ' + curr_out_name + ' - ' + addr_out) curr_in_name = curr_in.name if token_system_in: deal_acc_id, deal_acc_addr = rpc_erachain.get_deal_acc_addr( db, deal_id, curr_out, addr_out, token_system_in.account, xcurr_in) addr_in = token_system_in.account pass else: x_acc_label = db_client.make_x_acc(deal, addr_out, curr_out_abbrev) deal_acc_id = db_client.get_deal_acc_id(db, deal, addr_out, curr_out) deal_acc_addr = db_client.get_deal_acc_addr_for_xcurr( db, deal_acc_id, curr_in, xcurr_in, x_acc_label) if not deal_acc_addr: return mess('Connection to [%s] is lost, try later ' % curr_in_name) addr_in = deal_acc_addr.addr deal_acc = db.deal_accs[deal_acc_id] volume_out = vol # fast search of RATE first # pr_b, pr_s, pr_avg = rates_lib.get_average_rate_bsa( db, curr_in.id, curr_out.id, None) if pr_avg: vol_in = volume_out / pr_b amo_out, _, best_rate = rates_lib.get_rate(db, curr_in, curr_out, vol_in) else: best_rate = None if best_rate: is_order = True dealer_deal = None # first add TAX txfee = float(xcurr_out.txfee or 0.0001) volume_out += txfee volume_in, mess_in = db_client.calc_fees_back(db, deal, dealer_deal, curr_in, curr_out, volume_out, best_rate, is_order, note=0) volume_in = common.rnd_8(volume_in) rate_out = volume_out / volume_in # new make order order_id = db.orders.insert( ref_=deal_acc_addr.id, volume_in=volume_in, volume_out=volume_out, ) db.orders_stack.insert(ref_=order_id) else: volume_in = rate_out = tax_rep = None _, uri = common.uri_make( curr_in.name2, addr_in, { 'amount': volume_in, 'label': db_client.make_x_acc_label(deal, addr_out, curr_out_abbrev) }) curr_in_abbrev = curr_in.abbrev # lim_bal, may_pay = db_client.is_limited_ball(curr_in) free_bal = db_client.curr_free_bal(curr_out) if token_system_in: addr_out_full = (token_system_out and ('%d' % token_out.token_key) or curr_out.abbrev) + ':' + addr_out else: addr_out_full = addr_out out_res = dict(curr_out_abbrev=curr_out_abbrev, addr_out=addr_out, volume_out=volume_out, bal=float(free_bal / 2), rate=rate_out, curr_in_name=curr_in_name, volume_in=volume_in, curr_in_abbrev=curr_in_abbrev, addr_in=addr_in, uri=uri) if lim_bal > 0: out_res['may_pay'] = float(may_pay / 2) if not volume_in: out_res['wrong'] = 'rate not found' if token_system_in: out_res['addr_out_full'] = addr_out_full return request.extension == 'html' and dict( h=DIV(BEAUTIFY(out_res), _class='container')) or out_res
def get_xcurrs_for_deal(db, amo_out, curr_out, deal, dealer=None, s_b_in=None, not_used=None): curr_out_id = curr_out.id dealer_id = dealer and dealer.id or None # берем в расчет только недавние цены expired = datetime.now() - timedelta(0, 360) pairs = [] s_b = s_b_in == None and True or s_b_in ############################ d_e = None # теперь по всем криптам пройдемся и если нет в парах то # значит запрет в форме сделаем for rec_in in db((db.currs.used == True) & (db.xcurrs.curr_id == db.currs.id)).select( orderby='currs.name'): curr_in = rec_in.currs if not_used and curr_in.abbrev in not_used: continue disabled = None if curr_in.id == curr_out.id: rate = 1.0 else: # берем в расчет только недавние цены if amo_out: # количество уже жестко задано от магазина pr_b, pr_s, pr_avg = rates_lib.get_average_rate_bsa( db, curr_in.id, curr_out.id, expired) #print pr_b, pr_s, pr_avg if pr_b: amo_in = amo_out / pr_b else: amo_in = 0 rate = None if not amo_out or pr_b: #print 'amo_in:', amo_in amo_out, rate_order, rate = rates_lib.get_rate( db, curr_in, curr_out, amo_in) if not rate: rate = -1 disabled = True currs_stats = db((db.currs_stats.curr_id == curr_in.id) & (db.currs_stats.deal_id == deal.id)).select().first() pairs.append({ 'id': curr_in.id, 'price': rate, 'name': curr_in.name, 'abbrev': curr_in.abbrev, 'icon': curr_in.icon, 'expired': disabled, 'name_out': curr_out.abbrev, 'used': currs_stats and currs_stats.count_ or 0, 'curr_id': curr_in.id, # для того чтобы по 2му разу не брало 'bal': curr_in.balance, 'bal_out': curr_free_bal(curr_in) # сколько можно продать }) return pairs
def buy_free(db, deal, curr_in, ecurr, volume_in, curr_out, xcurr, addr, conn, mess_in=None): volume_in = float(volume_in) print 'try buy_free %s [%s] -> %s %s' % (volume_in, curr_in.abbrev, curr_out.abbrev, addr) if not conn: mess = '[' + curr_out.name + '] not connection' print mess return { 'error': mess }, None ecurr_id = ecurr.id xcurr_id = xcurr.id _, _, best_rate = rates_lib.get_rate(db, curr_in, curr_out, volume_in) if not best_rate: mess = '[' + curr_in.name + '] -> [' + curr_out.name + ']' + current.T(' - лучший КУРС не найден!') print mess return { 'error': mess }, None ##print best_rate, '1/r=', round(1/best_rate,8) # возьмем таксы все dealer_deal = None # там входной оброк не берется - так как он берется с заказов только # тоесть со входа фиата рубль не берется #deal_fee = dealer_deal_fee = None #volume_out, tax_mess = db_client.use_fees_for_in(db, deal_fee, dealer_deal_fee, curr_in, curr_out, volume_in, best_rate) is_order = True try: volume_out, tax_mess = db_client.calc_fees(db, deal, dealer_deal, curr_in, curr_out, volume_in, best_rate, is_order, note=1) except Exception as e: print 'BUY error db_client.calc_fees %s' % e volume_out, tax_mess = volume_in * best_rate * 0.99, 'error in fees [%s], get rate 0.99' % e volume_out = common.rnd_8(volume_out) print volume_in, curr_in.abbrev, '--> - tax - fee -->', volume_out, curr_out.abbrev, '\n mess:', tax_mess #log_commit(db, tax_mess) ################################################# bal_free = db_client.curr_free_bal(curr_out) print '\nsend:', volume_out, curr_out.abbrev, 'bal_free:', bal_free, addr if bal_free < volume_out: res = {'error': 'out off free funds', 'not_log': True} bal = None #curr_out.balance #log(db, res) else: # внутри там еще вычтется комиссия сети res, bal = crypto_client.send(db, curr_out, xcurr, addr, volume_out, conn) print 'buy_free RES:', res, bal log(db, res) #log(db, bal) if type(res) == type(u' '): # прошла транзакция, создадим массив инфо res = { 'txid': res } #if 'mess' in res: res['txid'] = res['mess'] if res: err = res.get('error') if err: code = err.get('code') if code == -3: # нехваватило монет - они еще не вернулись в кошелек pass else: if res.get('mess'): volume_out = 0 res['amo_out'] = volume_out res['tax_mess'] = tax_mess print res return res, bal