예제 #1
0
def select_ed_acc():
    import db_common
    import ed_common
    deal_id = request.args(0)
    if not deal_id: return '/[deal_id]/[vol_out_full]/[limited]'
    deal = db.deals[deal_id]
    print deal.name
    curr = db.currs[deal.fee_curr_id]
    ecurr = db(db.ecurrs.curr_id == curr.id).select().first()
    volume_out_full = Decimal(request.args(1) or 0)
    limited = request.args(2)
    dealer, dealer_acc, d_ = ed_common.select_ed_acc(db, deal, ecurr,
                                                     volume_out_full, limited)
    if not dealer_acc:
        return 'dealer_acc=None'
    print dealer_acc.acc, dealer_acc.balance
    h = CAT(
        H1(deal.name, ' : ', curr.abbrev),
        dealer_acc.acc,
        ': ',
        dealer_acc.balance,
        ' day_limit_sum:',
        dealer_acc.day_limit_sum,
        ' mon_limit_sum:',
        dealer_acc.mon_limit_sum,
        ' reserve_MAX:',
        dealer_acc.reserve_MAX,
    )
    return dict(h=h)
예제 #2
0
def pay_test():
    session.forget(response)
    import db_common
    import ed_common
    scid = request.vars.get('pattern_id')
    curr, xcurr, ecurr= db_common.get_currs_by_abbrev(db,'RUB')
    dealer_deal = db((db.dealer_deals.scid==scid)
            & (db.dealer_deals.dealer_id==dealer.id)).select().first()
    deal = db.deals[dealer_deal.deal_id]
    print deal.name
    dealer, dealer_acc, d_ = ed_common.select_ed_acc(db, deal, ecurr)
    print dealer_acc.acc, dealer_acc.balance
    vol = float(request.vars.get('sum') or request.vars.get('redsum') or 13)

    acc = '---???---'
    res = ed_common.pay_test(db, deal, dealer, dealer_acc, dealer_deal, acc, vol, True, request.vars)
    print res
    return BEAUTIFY(res)
예제 #3
0
def pay_test_to_deal():
    if not request.args(0): return '/deal_id - 46 (skype) / summ?acc=_'
    session.forget(response)
    import db_common
    import ed_common
    
    deal = db.deals[request.args(0)]
    dealer = db.dealers[1]
    curr, xcurr, ecurr= db_common.get_currs_by_abbrev(db,'RUB')
    dealer_deal = db((db.dealer_deals.deal_id==deal.id)
            & (db.dealer_deals.dealer_id==dealer.id)).select().first()
    #deal = db.deals[dealer_deal.deal_id]
    print deal.name
    dealer, dealer_acc, d_ = ed_common.select_ed_acc(db, deal, ecurr)
    print dealer_acc.acc, dealer_acc.balance
    
    vol = float(request.args(1) or 100)
    
    acc = request.vars.get('acc')
    res = ed_common.pay_test(db, deal, dealer, dealer_acc, dealer_deal, acc, vol, True, None)
    print res
    return BEAUTIFY(res)
예제 #4
0
def index():
    #if not IS_LOCAL:
    #    redirect(URL('ipay','more','to_pay',args=request.args))

    #common.page_stats(db, response['view'])

    if len(request.args) == 0: redirect(URL('deal', 'index'))
    deal_id = request.args(0)
    if len(deal_id) > 10 or not deal_id.isdigit():
        redirect(URL('deal', 'index'))

    deal = db.deals[deal_id]
    if not deal:
        redirect(URL('deal', 'index'))

    deal.update_record(wants=deal.wants + 1)

    if not deal.used:
        redirect(URL('deal', 'index'))

    response.title = 'Платежи оплата биткоинами криптовалютой услуги %s' % deal.name

    client = db(db.clients.deal_id == deal.id).select().first()
    if client:
        # to_shop/index/2?order=12&user=eytu
        #redirect(URL('to_shop','index',args=[client.id], vars=request.vars))
        raise HTTP(200, T('ERROR: it is client "%s"') % client.email)

    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:
        raise HTTP(200, T('ERROR: not found dealer for "%s"') % deal.name)
    dealer_acc = ed_common.sel_acc_max_for_balance(db,
                                                   dealer,
                                                   ecurr_out,
                                                   vol,
                                                   unlim=True)

    #print dealer.info
    dealer_info = dealer.info and json.loads(dealer.info)
    shops_url = dealer_info['shops_url']
    #MAX = deal.MAX_pay or 777
    MIN = db_common.gMIN(deal, dealer)

    if not response.vars: response.vars = {}

    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)

    title=XML(XML(T("Задайте параметры платежа для ") + '<BR>') + XML( deal_img or '' ) + ' ' +\
            XML( A(deal.name, _href=shops_url, _target="_blank")))
    title = XML(
        XML(deal_img or '') + ' <b>' + deal.name + '</b> ' +
        'оплата биткоинами и криптовалютой')
    deal_cat = db.deals_cat[deal.cat_id]
    subtitle = XML(
        'Другие услуги вида %s' %
        A(deal_cat.name, _href=URL('deal', 'index', args=[deal_cat.id])))

    response.vars['s_url'] = XML(A(T('тут'), _href=shops_url,
                                   _target="_blank"))
    response.vars['shops_url'] = shops_url

    acc_pars = None
    if dealer_deal.grab_form:
        # тут тырим форму с сайта яндекса напрямую
        #scid, name, img, form = ed_form.load_YD(...)
        response.vars['grab_form'] = ed_form.load_YD(shops_url,
                                                     URL('more', 'pay'))
        #print response.vars['grab_form']

    else:
        acc_pars = []
        ajax_vars = []
        if dealer_deal.p2p:
            if deal.template_ == '--':
                pay_pars_deal = []
                pay_pars_dealer = []
            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 dealer_deal.template_, json.loads(dealer_deal.template_)
        #print dealer_deal
        #print pay_pars_deal
        #print pay_pars_dealer
        calcs = dealer_deal.calcs_ or {}
        for p in pay_pars_deal:
            read_only = None
            if 'calc' in p: continue
            if type(p) == type([]): continue

            #print p
            p_n_name = p.get('n')
            p_t = p_n_name and pay_pars_dealer.get(p_n_name)
            def_val = subsel_parent = None
            add_pars = {}
            calc2 = calcs.get(p_n_name)
            #print 'calc2', calc2
            if calc2 != None and type(calc2) not in [
                    type(dict()), type([]), type({})
            ]:
                # тут простое вычисление - прпустим
                continue
            if calc2:
                # это поле вычисляется автоматически
                # или есть зависимые от него поля
                subsel_name = calc2.get('subsel')
                subsel_parent = calc2.get('parent')
                if subsel_name:
                    # это поле главное и у него есть подчиненное поле
                    add_pars[
                        '_onChange'] = 'ajax("../subsel_callback", ["%s", "deal_id", "dealer_deal_id"], "%s");' % (
                            p_n_name, 'div_' + subsel_name)
                    #_onChange="ajax('selsub2_callback', ['%s'], '%s');" % (sel1_name, sel2_div_name),
                if subsel_parent:
                    add_pars['_disabled'] = 'disabled'
                if not subsel_name and not subsel_parent:
                    # это поле обычное вычисляемое -- пропустим
                    continue

            # если параметры передаются как параметры после ?
            def_val = request.vars.get(p_n_name)
            if def_val:
                read_only = True

            sel = p_t and p_t.get('sel')
            lab_ = p.get('l')
            tip_ = p.get('m')
            if sel:
                lab_ = LABEL(lab_ and T(lab_) or p_n_name)
                opt = []
                for item in sel:
                    #for (v, l) in item.iteritems():
                    opt.append(OPTION(item['label'], _value=item['value']))
                #print opt
                inp = SELECT(opt,
                             _name=p_n_name,
                             _id=p_n_name,
                             _type="text",
                             _class='field blue-c',
                             **add_pars)
            elif p_n_name:
                lab_ = LABEL(lab_ and T(lab_) or p_n_name)
                # если имя поля задано то поле покажем
                inp = INPUT(
                    _name=p_n_name,
                    _id=p_n_name,  # тут имя поля указываем для диллера
                    _placeholder=p.get('ph', ''),
                    _value=def_val
                    or session.vars and session.vars.get(p.get('n'))
                    or p.get('v'),
                    _readonly=read_only,
                    #_size=('ln' in p and p['ln'] or 5)+1,
                    _onblur='ln' in p and 'get_acc(this, %s, "%s");' %
                    (p['ln'] or 0, 'символов %s'),
                    requires=IS_NOT_EMPTY(),
                    _class='field blue-c',
                    **add_pars)
            elif lab_:
                acc_pars.append({
                    'l':
                    HR(_align="center",
                       _width="auto",
                       _size="3",
                       _color="#ffffff"),
                    'i':
                    ''
                })
                ##lab_ = LABEL(lab_ and T(lab_) or '')
                lab_ = LABEL(H5(T(lab_)))
                inp = ''
            elif tip_:
                lab_ = LABEL(
                    H4(
                        TAG.i(_class='fa fa-exclamation-triangle',
                              _style='color:yellow; font-size:1.5em;'), ' ',
                        tip_))
                inp = ''

            if subsel_parent:
                # это подчиненное поле - результат аякса
                # то вложем его внутрь
                inp = DIV(inp, _id='div_' + p_n_name)

            item = {
                'l': lab_,
                'i': inp,
            }
            info = p.get('i')
            if info:
                item['l'] += '*'
                item['m'] = XML(info)
            acc_pars.append(item)

            if p_n_name:
                ## для полей АЯКСа
                ## причем надо от УНИКОДЕ строки избавиться - поэтому %
                _sss = p_n_name.encode('ascii')
                ##print _sss, type(_sss)
                ajax_vars.append(_sss)

        #print i_d, request.args
        #if False and len(request.args)>i_d+1:
        #    # цена тоже задана
        #    volume_out = float(request.args[i_d+1])
        #    response.vars['vol_readonly'] = True

    response.vars['e_bal'], MAX = get_e_bal(deal, dealer, dealer_acc)
    volume_out = 377
    if request.vars:
        #print request.vars
        if 'mess' in request.vars:
            response.vars['shop_mess'] = request.vars['mess']
        if 'sum' in request.vars:
            volume_out = test_vol(request.vars['sum'], MIN, MAX)
            response.vars['vol_readonly'] = True
        session.vol = volume_out

    response.vars['deal_id'] = deal_id
    response.vars['dealer_deal_id'] = dealer_deal.id
    response.vars['MIN'] = MIN
    response.vars['MAX'] = MAX
    response.vars['volume_out'] = volume_out
    response.vars['not_gifted'] = deal.not_gifted

    #  except Exception as e:
    #    db.deal_errs.insert( deal_id = deal.id, dealer_id = dealer.id, err = '%s' % e)

    # поля для передачи по запросу АЯКСа
    ajax_vars.append('vol')
    ajax_vars = '%s' % ajax_vars
    h = CAT()
    for rr in db_client.get_xcurrs_for_deal(db, 0, curr_out, deal, dealer):
        #print row
        id = '%s' % rr['id']
        disabled = rr['expired']
        #bgc = 'gold'
        if disabled:
            memo = CAT(
                T('Курс не найден'), ', ',
                T('Когда курс будет получен платеж пройдёт автоматически'),
                '. ', T('Или попробуйте зайти позже'))
            _class = 'col sel_xcurrNRT'
        else:
            memo = CAT(
                SPAN(' ', T('по курсу'), (' %8g' % rr['price']), ' ',
                     T('нужно оплатить примерно')), ' ',
                B(SPAN(_class='pay_vol')), ' ', rr['name'])
            _class = 'col sel_xcurrRTE'

        # пусть клики все равно будут
        onclick = '''
                      //$(this).css('z-index','0');
                      $('#tag%s').hide('fast');
                      $('#cvr%s').css('display','block'); // .css('z-index','10');
                      ajax('%s',%s,'tag%s');
                      ''' % (id, id, URL('get', args=[id, deal_id
                                                      ]), ajax_vars, id)
        #print row
        h += DIV(
            DIV(
                DIV(
                    #T('Есть'), ': ', rr['bal_out'],' ',
                    IMG(_src=URL('static',
                                 'images/currs/' + rr['abbrev'] + '.png'),
                        _width=60,
                        __height=36,
                        _class='lst_icon',
                        _id='lst_icon' + id),
                    SPAN(rr['price'], _class='price hidden'),
                    SPAN(rr['abbrev'], _class='abbrev hidden'),
                    memo,
                    '. ',
                    SPAN(T('Всего было оплат:'), rr['used'], _class='small'),
                    _onclick=onclick if onclick else '',
                    #_style=style,
                    _id='btn%s' % id,
                    _class=_class,
                ),
                DIV(TAG.i(_class='fa fa-spin fa-spinner right wait1'),
                    _id='cvr%s' % id,
                    _class='col sel_xcurrCVR'),
                _class='row sel_xcurr'),
            _class='container')
        h += DIV(_id='tag%s' % id, _class='blue-c')
    xcurrs_h = h

    #response.top_line = None

    return dict(
        title=title,
        subtitle=subtitle,
        deal_name=deal.name,
        deal_info=deal.show_text,
        deal_icon=make_img(deal, dealer_info),
        MIN=MIN,
        MAX=MAX,  #reclams=reclams,
        pars=acc_pars,
        xcurrs_h=xcurrs_h)
예제 #5
0
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)
예제 #6
0
def make_edealer_payment(db,
                         geted_pays,
                         curr_in,
                         xcurr,
                         curr_out,
                         ecurr,
                         vol_in,
                         volume_out,
                         deal_acc_addr,
                         rate,
                         order_stack_id=None,
                         dealer=None,
                         dealer_acc=None,
                         dealer_deal=None):
    #print 'try payout rub:', vol_in, curr_in.abbrev, volume_out , curr_out.abbrev, deal_acc_addr.addr, '\n', geted_pays
    # заодно проверим не занята ли база is loocked
    # сейчас копим на счету услуги if volume_out>13:
    #    # но это не для мелких платежей
    #    log_commit( db, 'try payout: make_edealer_payment %s[%s] -> %s[%s] %s \n geted_pays: %s' % ( vol_in, curr_in.abbrev, volume_out, curr_out.abbrev, deal_acc_addr.addr, geted_pays))
    #return

    ## проверим запасы - если есть ограничение по баласу то откажем в выплатах
    max_bal = Decimal(curr_in.max_bal or 0)
    ##print 'types:', type(curr_in.balance), type(curr_in.deposit)
    ## float - Decimal - хотя в базе поле описано как ДЕЦИМАЛ
    bal_dep = Decimal(curr_in.balance or 0) - Decimal(curr_in.deposit or 0)
    if max_bal and max_bal > 0 and max_bal - bal_dep < 0:  ##vol_in: тут уже в баланс упал вход
        mark_pay_ins(
            db, geted_pays, 'wait',
            current.T('Превышен запас монет: %s + %s > %s') %
            (bal_dep, vol_in, max_bal))
        db.commit()
        return

    deal_acc = db.deal_accs[deal_acc_addr.deal_acc_id]
    deal = db.deals[deal_acc.deal_id]

    in_proc = random.randint(1, 99999)
    desc = []
    for id in geted_pays:
        inp_stk = db.pay_ins_stack[id]
        # запомним что мы обрабатываем этот вход
        inp_stk.update_record(in_proc=in_proc)
        inp_rec = db.pay_ins[inp_stk.ref_]
        desc.append({'txid': inp_rec.txid, 'vout': inp_rec.vout})
    # сохраним базу - чтобы все процессы видели что мы обрабатываем записи стека
    db.commit()
    #print 'make_edealer_payment', deal_acc.acc, volume_out, curr_out.abbrev, '%s' % desc
    #  теперь ждем чтобы записи в базк записались
    # - так чтобы пораллельно их не обработали
    sleep(1)
    pay_error = None  # если мы не заплатили то не вносить изменения баланса и пр

    # если уже идет обработка стека то выход
    # и она не наша
    for id in geted_pays:
        inp_stk = db.pay_ins_stack[id]
        if inp_stk.in_proc and inp_stk.in_proc != in_proc:
            # если этот вход в стеке уже вобработке то удалим его
            # нет просто выход нажмем - чтобы не было свалки обработки входов
            log(db, ' input_stack.in_proc == True : return')
            return

    print '\ntry payout:', vol_in, curr_in.abbrev, '-->', volume_out, curr_out.abbrev, deal_acc_addr.addr, '\n', 'geted_pays:', geted_pays
    #log(db, '%s %s %s %s %s %s %s %s %s' % ('try payout:', vol_in, curr_in.abbrev, '-->', volume_out, curr_out.abbrev, deal_acc_addr.addr,  ' - geted_pays:', geted_pays))

    if ecurr:
        MIN = deal.MIN_pay
    else:
        xcurr_out = db(db.xcurrs.curr_id == curr_out.id).select().first()
        MIN = (xcurr_out.txfee or curr_out.fee_in or curr_out.fee_out) * 3

    #log(db, 'volume_out %s, MIN %s' % (volume_out, MIN))

    if volume_out <= 0 or MIN > 0 and volume_out < MIN:
        print volume_out, ' <<< ', MIN
        #Теперь добавляем к переплате на счет услуги
        # так как в volume_out есть вычета абсолютные мзды то оно меньше нуля
        if order_stack_id:
            # если есть заказ на курс то по этому курсу
            volume_out = vol_in * rate
            print 'volume_out by ORDER', order_stack_id, rate, ' ->', volume_out
        else:
            # иначе возьмем просто по курсу без абсолютных добавок
            if ecurr and not dealer_deal:
                volume_out = vol_in * rate
                # лимиты диллера не учитываем
                dealer, dealer_acc, dealer_deal = ed_common.select_ed_acc(
                    db, deal, ecurr, volume_out, unlim=USE_UNLIM)
            # и возьмем таксу без fee
            # тут берем без учета что еще на нас начислит диллер за эту услугу (учет в ed_common.pay)
            volume_out, _ = db_client.calc_fees(db,
                                                deal,
                                                dealer_deal_NONE,
                                                curr_in,
                                                curr_out,
                                                vol_in,
                                                rate,
                                                is_order=None,
                                                note=None,
                                                only_tax=1)
            print 'volume_out by TAX', volume_out
        print 'add to_pay', volume_out
        deal_acc.update_record(to_pay=(deal_acc.to_pay or 0) + volume_out)
        pay_ins_recs = get_pay_ins_recs(db, geted_pays)
        # и запомним на что потратили входы
        for pay_in in pay_ins_recs:
            ## None pay_in.payout_id = pay_out_id
            if pay_in.amount == vol_in:
                volume_out_it = volume_out
            else:
                volume_out_it = round(
                    float(volume_out * pay_in.amount / vol_in), 8)
            pay_in.status = 'added'
            pay_in.status_mess = volume_out_it
            ## Njne еще не определили заказ  pay_in.order_id = order_id # запомним использованный заказ
            pay_in.update_record()
        db.commit()
        return

    client = db(db.clients.deal_id == deal.id).select().first()
    if client:
        # это наш клиент- магазин, у него не делаем перебор
        # и не делаем платеж вообще, а учитываем его просто в своей базе
        print 'make_edealer_payment ist my CLIENT:', deal.id, 'client:', client
        # здесь валюта выходя есть авлюта входа для клиента - так как он
        # вообще не должен знать чем нам пользователь наш заплатил
        clients_tran_id, client_bal = clients_lib.mem_input(
            db, client, deal_acc.acc, volume_out, curr_out, '%s' % desc)
        #mark_pay_ins(db, geted_pays, 'client', 'client_trans: %s' % clients_tran_id)
        res = None
        order_id = check_order(db, order_stack_id)
        # и запомним на что потратили входы
        # удалим все взятые входы крипты для этого вывода
        # имеено ТУТ чтобы ошибки ниже уже не повлияли на ошибочный повторный вывод
        # а то иногда ошибки ниже не дают запомнить что мы уже выплатили все тут
        pay_ins_recs = get_pay_ins_recs(db, geted_pays)
        for pay_in in pay_ins_recs:
            print 'clients_tran_id:', clients_tran_id
            pay_in.clients_tran_id = clients_tran_id
            pay_in.status = 'ok'
            pay_in.order_id = order_id  # запомним использованный заказ
            pay_in.update_record()
        db.commit()
    else:

        # здесь выплаты только электронными деньгами
        gift_amo = 0
        if deal_acc.gift_amount and deal_acc.gift_amount > 0 and deal_acc.gift_pick > 0:
            # если есть подарок у аккаунта то его включим
            gift_amo = Decimal(deal_acc.gift_amount < deal_acc.gift_pick
                               and deal_acc.gift_amount or deal_acc.gift_pick)
            ##print type(Decimal(0.3)), type(volume_out)
            if gift_amo > Decimal(0.3) * volume_out:
                gift_amo = Decimal(0.3) * volume_out
            rrr = random.randint(1, 100)
            # вероятность берем
            # сделаем случайны подарок - чем меньше сумма остатка тем меньше вероятность подарка
            pick_ver = gifts_lib.pick_ver(deal_acc.gift_amount, gift_amo)
            if rrr > int(pick_ver * 100):
                gift_amo = 0
                #print 'NOT lucky'
            else:
                # подарок выпал
                deal_acc.gift_amount = deal_acc.gift_amount - gift_amo
                deal_acc.gift_payed = deal_acc.gift_payed and deal_acc.gift_payed + gift_amo or gift_amo
        #print 'gift_amo:', gift_amo

        # проверим бонус патртнера - если он больше 100 то выплатим его
        partner_sum = Decimal(deal_acc.partner_sum or 0)
        if partner_sum:  ## тут разные валюты и разные значения! and partner_sum > current.PARTNER_MIN:
            #print 'PARTNER -> deal_acc.partner_sum:', partner_sum
            deal_acc.partner_sum = 0
            deal_acc.partner_payed = (deal_acc.partner_payed
                                      or 0) + partner_sum
        else:
            # Сбросим а то оно прибавится ниже
            partner_sum = 0

        amo_to_pay = Decimal(deal_acc.to_pay or 0)
        add_vol = gift_amo + partner_sum + amo_to_pay

        volume_out_full = volume_out + add_vol

        # тут ищем акккаунт с еще не превышенным лимитом на платежи и максим балансом среди разных диллеров
        if ecurr:
            # это фиат с аккаунтами разными у диллера
            ##dealer_acc = None ## тут могут добавиться на счету недоплаты! поэтому новый нужно выбрать счет диллера
            if dealer_acc and dealer_acc.balance > volume_out_full:
                print 'preselected dealer_acc:', dealer_acc.acc, dealer_acc.balance
            else:
                dealer, dealer_acc, dealer_deal = ed_common.select_ed_acc(
                    db, deal, ecurr, volume_out_full, unlim=USE_UNLIM)
                if dealer_acc:
                    print 'select_ed_acc -> dealer_acc:', dealer_acc.acc, dealer_acc.balance
                else:
                    mark_pay_ins(db, geted_pays, 'try',
                                 (dealer and dealer.name or 'dealer=None') +
                                 ': dealer_acc not found')
                    db.commit()
                    print 'ERROR: make_edealer_payment - dealer_acc=', dealer_acc, 'deal id:', deal.id, 'ecurr id:', ecurr.id
                    return

            balance = dealer_acc.balance
            if not balance:
                balance = ed_common.get_balance(dealer, dealer_acc)
                if not balance or balance < 0:
                    mark_pay_ins(db, geted_pays, 'wait',
                                 dealer.name + ': balance=None')
                    db.commit()
                    print 'ERROR: make_edealer_payment - not balance', dealer_acc
                    return
            #print 'make_edealer_payment', dealer.name, ':', dealer_acc.acc, 'balance:', balance

            ###############################################################
            # теперь надо посмотреть насколько превышен лимит платежа за месяц для этого аккаунта этого дела
            if not deal_acc.payed_month_num or datetime.date.today(
            ).month != deal_acc.payed_month_num:
                # если новый месяц то сбросим в ноль
                deal_acc.payed_month_num = datetime.date.today().month
                deal_acc.payed_month = 0

            if deal.is_shop:
                # для сайтов и обмена - без изменения величины оплаты так как там жесткая величина
                over_turns = 0
            else:
                over_turns = (deal_acc.payed_month or 0) / (deal.MAX_pay
                                                            or 777)

            if over_turns > 5:
                volume_out_full = volume_out_full * Decimal(
                    0.98)  # если превышение боле чем в 6 раза то 2% себе сразу
            elif over_turns > 4:
                volume_out_full = volume_out_full * Decimal(
                    0.99)  # если превышение боле чем в 4 раза то 1% себе сразу
            elif over_turns > 3:
                volume_out_full = volume_out_full * Decimal(
                    0.995
                )  # если превышение боле чем в 2 раза то 0.5% себе сразу
            elif over_turns > 2:
                volume_out_full = volume_out_full * Decimal(
                    0.9925
                )  # если превышение боле чем в 1 раза то 0.25% себе сразу

        else:
            # это обмен на другую крипту
            # тут баланс просто у крипты берем
            balance = db_client.curr_free_bal(curr_out)

        ######################################################
        print 'volume_out_full > balance', volume_out_full, balance
        if volume_out_full > balance:
            if len(geted_pays) == 1:
                pay_error = 'out of balance'
                res = {'error': pay_error}
                #print pay_error, volume_out_full, balance, curr_out.abbrev
            else:
                for id in geted_pays:
                    p_i_s = db.pay_ins_stack[id]
                    pay_in = db.pay_ins[p_i_s.ref_]
                    vol_in_one = pay_in.amount
                    volume_out_one = vol_in_one / vol_in * volume_out
                    # размарозим вход - чтобы его могли обработать
                    p_i_s.update_record(in_proc=False)
                    db.commit()
                    # тут dealer_acc, dealer_deal не передаем - там новые берем
                    make_edealer_payment(db, [id], curr_in, xcurr, curr_out,
                                         ecurr, vol_in_one, volume_out_one,
                                         deal_acc_addr, rate, order_stack_id)
                return
        elif ecurr:
            # надо проверить величину выплат в месяц - не более 60тыс можно
            # только для фиата
            if deal_acc.payed_month and deal_acc.payed_month + volume_out_full > MAX_PAYMENT_IN_MONTH:
                # переплата - включаем задержку
                pay_error = 'monthly_limit_60_exceeded'
                res = {
                    'status': 'wait',
                    'error': 'wait',
                    'error_description': pay_error
                }
            else:
                ####################
                #res = {'status':'success', 'balance': 123, 'payment_id': 'sldkflsfj3', 'invoice_id': '78676654',
                #    'sum_taken': volume_out_full}
                #res = {'status':'testedd', 'error':'test', 'error_description':'tst_descr', }
                log_on = None  # None - log some, False - notg, True - log all
                res = ed_common.pay(db, deal, dealer, dealer_acc, dealer_deal,
                                    deal_acc.acc, volume_out_full, log_on)
                log(db, 'PAYed ecurr - res: %s' % res)
        else:
            # сюда пришло значит баланса хватает и это на выходе криптовалюта
            dealer_acc = None
            ## ыше уже задали xcurr_out = db(db.xcurrs.curr_id == curr_out.id).select().first()
            res, bal = crypto_client.send(db, curr_out, xcurr_out,
                                          deal_acc.acc, volume_out_full)
            #print bal, res
            if bal:
                curr_out.update_record(balance=bal)
            if type(res) == type(u' '):
                # прошла транзакция, создадим массив инфо
                res = {'payment_id': res, 'status': 'success'}
            log(db, 'PAYed xcurr - res: %s' % res)

        ####################
        if not res or 'error' in res or res.get('status') != 'success':
            ## res = { 'status': 'error', 'error':'so_small','error_description': '%s < txfee %s' % (amo, txfee) }
            # платежа не произошло - выход
            pay_error = res.get('error_description')
            if not pay_error or pay_error == u'':
                pay_error = res.get('error', 'dealer error')
            elif ecurr:
                # только для фиата с дилерами
                if pay_error == 'limit_exceeded':
                    # тут превышен лимит в день или даже в месяц - надо брать другой счет
                    # причем сумму в месяц не меняем - чтобы знать сколько в месяц прошло
                    dealer_acc.day_limit = datetime.date.today().day
                    dealer_acc.day_limit_sum = -dealer_acc.day_limit_sum
                    dealer_acc.update_record()
                elif pay_error == 'monthly_limit_60_exceeded':
                    # тут превышен лимит в день или даже в месяц - надо брать другой счет
                    # причем сумму в месяц не меняем - чтобы знать сколько в месяц прошло
                    dealer_acc.mon_limit = datetime.date.today().month
                    dealer_acc.mon_limit_sum = -dealer_acc.mon_limit_sum
                    dealer_acc.update_record()
                elif pay_error == 'not_enough_funds':
                    # баланс кошелька поменялся - видимо вручную политили с него
                    balance = ed_common.get_balance(dealer, dealer_acc)
                    dealer_acc.update_record(balance=balance or 0)
                else:
                    ed_common.dealer_deal_errs_add(db, dealer_deal,
                                                   deal_acc.acc, '%s' % res)

            # нельзя менять так как не будет возврата pay_error = pay_error + ' (%s ... %s)' % (round(volume_out_full,2), dealer_acc.acc[-5:])
            if pay_error == 'technical_error' or pay_error == 'payment_refused':
                mark_pay_ins(db, geted_pays, 'try', pay_error)
            elif 'Unknown operator for phone' in pay_error:
                ## Unknown operator for phone-number=PhoneNumber{79016661485 (RU)}
                ## тут сразу возврат и написать туда чтобы оператора нашел сам
                pay_error = 'Unknown operator. Please find this operator in list of services'
                mark_pay_ins(db,
                             geted_pays,
                             'refuse',
                             pay_error,
                             to_refuse=True)
                pass
            else:
                mark_pay_ins(db, geted_pays, 'wait', pay_error)
            db.commit()
            print 'serv to pay **** - ERROR: make_edealer_payment ', pay_error, 'RES:', res
            return

        # удалим все взятые входы крипты для этого вывода
        # имеено ТУТ чтобы ошибки ниже уже не повлияли на ошибочный повторный вывод
        # а то иногда ошибки ниже не дают запомнить что мы уже выплатили все тут
        # запомним платеж фиата
        amo_taken = Decimal(res.get('sum_taken', volume_out_full))
        pay_out_id = db.pay_outs.insert(
            ref_=deal_acc.id,  # за какое дело и за какого клиента
            dealer_acc_id=dealer_acc
            and dealer_acc.id,  # с какого моего аккаунта дилера оплачено
            amount=volume_out,
            amo_taken=amo_taken,
            amo_to_pay=amo_to_pay,
            amo_in=vol_in,
            amo_gift=gift_amo,
            amo_partner=partner_sum,
            created_on=datetime.datetime.now(),
            #info=json.dumps({'payment_id'res['payment_id'], 'invoice_id': res['invoice_id'] })
            #info = res and json.dumps(res) or None
            vars=res,
            ## возможно что нет выплаты - то добавим ссобщение об ошибке
            txid=res.get('payment_id', pay_error),
        )
        order_id = check_order(db, order_stack_id)
        # тут внутри commit сразу
        pay_ins_recs = get_pay_ins_recs(db, geted_pays)
        # и запомним на что потратили входы
        for pay_in in pay_ins_recs:
            pay_in.payout_id = pay_out_id
            pay_in.status = 'ok'
            pay_in.status_mess = pay_in.status_mess and (
                '(%s)' % pay_in.status_mess) or ''
            pay_in.order_id = order_id  # запомним использованный заказ
            pay_in.update_record()
        db.commit()

        # тут же в ответе приходит новый баланс
        # запомним суммарно по этому счету
        if ecurr:
            if res and 'balance' in res:
                dealer_acc.balance = Decimal(res['balance'])
            # лимиты дневные - месячные подправим
            dealer_acc.day_limit_sum = dealer_acc.day_limit_sum + amo_taken
            dealer_acc.mon_limit_sum = dealer_acc.mon_limit_sum + amo_taken
            dealer_acc.update_record()
            #print 'payed, new balance:', dealer_acc.balance
            # сразу таксу дилера на это дело запомним
            tax = res.get('tax')
            # причем только если они еще не заданы вообще
            # и число использований меньше 3
            if not dealer_deal.tax and dealer_deal.fee and tax and dealer_deal.taken and dealer_deal.taken < 3:
                # для ПРИН английское имя только чтобы ошибок конверт не было
                print 'dealer new TAX:', deal.name2, tax
                # если уже много раз использовано то не изменяем таксу - мож она вручную уже выставлена
                dealer_deal.tax = tax
            dealer_deal.taken += 1
            dealer_deal.update_record()

        # теперь надо заплатить нашему партнеру
        # если это дело партнерам оплачивается
        if deal_acc.gift and not deal.not_gifted:  # and not deal_acc.partner: # andl en(deal_acc.gift) > 5:
            try:
                partners_lib.calc(db, deal, curr_out, deal_acc, volume_out)
            except:
                print 'except partners_lib.calc(db, deal, curr_out, deal_acc, volume_out)'

        # запомним месячную выплату - ее надо ограничивать
        deal_acc.payed_month = deal_acc.payed_month and deal_acc.payed_month + volume_out or volume_out

        # запомним всего оплачено по этому заказу - и для клиентов тоже
        deal_acc.payed = deal_acc.payed and deal_acc.payed + volume_out or volume_out
        # надо запомнить если недоплатили или переплатили
        #print res
        #print 'deal_acc.to_pay = volume_out_full - amo_taken'
        #print deal_acc.to_pay, volume_out_full, amo_taken
        try:
            # дадим на следующий платеж ему от нас 0,5%!
            #   TO_COIN_ID != deal.id
            add_bonus = 0
            deal_tax = deal.tax
            if deal_tax and deal_tax > 0:
                ##if deal.id == TO_COIN_ID:
                ##    add_bonus = 0.001
                if deal_tax > 1.9:
                    add_bonus = 0.005
                elif deal_tax > 0.9:
                    add_bonus = 0.002
                else:
                    add_bonus = 0.001
                add_bonus = Decimal(add_bonus) * volume_out_full
            ## найденнный бонус начислим или как партнерские или как подарок
            if deal_acc.partner:
                deal_acc.partner_sum = (deal_acc.partner_sum or 0) + add_bonus
            else:
                deal_acc.gift_amount = (deal_acc.gift_amount or 0) + add_bonus
                ## и если кусочек меньше намного то увеличим кусочек
                if deal_acc.gift_pick * 7 < deal_acc.gift_amount:
                    deal_acc.gift_pick = deal_acc.gift_amount / 7

            deal_acc.to_pay = volume_out_full - amo_taken
        except:
            print 'deal_acc.to_pay = volume_out_full - amo_taken:', type(
                deal_acc.to_pay), type(volume_out_full), type(amo_taken)

    deal_acc.update_record()

    # запомниим статисткиу по делу
    count = deal.count_ or 0
    average = deal.average_ or 0
    if volume_out:
        deal.average_ = count / (count + 1) * average + volume_out / (count +
                                                                      1)
    deal.count_ = count + 1
    deal.update_record()

    ####################

    # заплмним сатиститку для крипты по этому делу
    if volume_out:
        db_common.currs_stats_update(db, curr_in.id, deal.id, volume_out)

    # обновим балансы дилеров и валюты
    # поидее это в ed_common YD_ все проходит
    ##if not client: db_common.update_balances(curr_out, -amo_taken, dealer)

    #if gift_amo and gift_amo > 0:
    #    print 'gift_amo', gift_amo
    #print 'Payed!'
    log(db, 'Payed! geted_pays: %s' % geted_pays)
    db.commit()
예제 #7
0
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)
예제 #8
0
파일: api.py 프로젝트: FoilNetwork/Wrap-Hub
def rates():
    import time
    time.sleep(1)
    if 'wp' in request.args:
        # это переделать имена параметров под http://web-payment.ru/ стандарт
        WPnames = request.args.index('wp')
        deal_sel = WPnames and request.args(0) or request.args(1)
        WPnames = True
    else:
        deal_sel = request.args(0)
        WPnames = False

    #print deal_sel
    if deal_sel and deal_sel.upper() == 'HELP':
        return 'rates/[deal] - deal = PH_7RUB | TO_YDRUB | IN_YDRUB | TO_COIN | None - all'
    import rates_lib, db_client, ed_common
    rub_curr, x, ecurr_out = db_common.get_currs_by_abbrev(db, "RUB")
    ecurr_out_id = ecurr_out.id
    vol_rub = 1000
    res = []
    currs_in_max = {}
    currs_to_max = {}
    dealer_deal = None
    to_abbrev = 'PH_7RUB'
    if not deal_sel or deal_sel.upper() == to_abbrev:
        ## сначала длля телефона
        if TO_PHONE7_ID:
            deal = db.deals[TO_PHONE7_ID]
        else:
            deal = db(db.deals.name == 'phone +7').select().first()
        dealer, dealer_acc, dealer_deal = ed_common.select_ed_acc(
            db, deal, ecurr_out)
        #print deal.name, 'dealer:', dealer_deal
        to_max = round(float(db_common.get_balance_dealer_acc(dealer_acc)), 8)

        for r in db((db.currs.id == db.xcurrs.curr_id)
                    & (db.currs.used == True)).select():
            curr_in = r.currs
            # теперь курс и мзду нашу найдем
            pr_b, pr_s, rate = rates_lib.get_average_rate_bsa(
                db, curr_in.id, rub_curr.id, None)
            if not rate: continue
            vol_out = vol_rub  # в рублях
            in_max = curr_in.max_bal or 0
            if in_max > 0:
                bal = db_client.curr_free_bal(curr_in)
                in_max = round(float(in_max - bal), 8)
            in_abbrev = curr_in.abbrev
            currs_in_max[in_abbrev] = in_max

            is_order = True
            vol_in, tax_rep = db_client.calc_fees_back(db,
                                                       deal,
                                                       dealer_deal,
                                                       curr_in,
                                                       rub_curr,
                                                       vol_out,
                                                       rate,
                                                       is_order,
                                                       note=0)
            ##rate = vol_out_new / vol_in
            '''
            <rates>
                <item>
                <from>PMEUR</from>
                <to>PMUSD</to>
                <in>1</in>
                <out>1.07</out>
                <amount>4322.79649</amount>
                <param>manual</param>
                <minamount>0 EUR</minamount>
                </item>
            '''
            if WPnames:
                item = {
                    'from': in_abbrev,
                    'to': to_abbrev,
                    'in': round(float(vol_in), 8),
                    'out': vol_out,
                    'amount': to_max
                }
            else:
                item = {
                    'in': in_abbrev,
                    'to': to_abbrev,
                    'in_vol': round(float(vol_in), 8),
                    'to_vol': vol_out,
                    'to_max': to_max
                }
            if in_max: item['in_max'] = in_max
            res.append(item)
    ###############
    ## теперь на ЯД кошелек
    to_abbrev = 'YDRUB'
    if not deal_sel or deal_sel.upper() == 'TO_YDRUB':
        if TO_WALLET_ID:
            deal = db.deals[TO_WALLET_ID]
        else:
            deal = db(db.deals.name == 'BUY').select().first()
        dealer, dealer_acc, dealer_deal = ed_common.select_ed_acc(
            db, deal, ecurr_out)
        #print deal.name, 'dealer:', dealer_deal
        to_max = dealer_max = round(
            float(db_common.get_balance_dealer_acc(dealer_acc)), 8)
        for r in db((db.currs.id == db.xcurrs.curr_id)
                    & (db.currs.used == True)).select():
            curr_in = r.currs
            # теперь курс и мзду нашу найдем
            pr_b, pr_s, rate = rates_lib.get_average_rate_bsa(
                db, curr_in.id, rub_curr.id, None)
            if not rate: continue

            vol_out = vol_rub  # в рублях
            is_order = True
            vol_in, tax_rep = db_client.calc_fees_back(db,
                                                       deal,
                                                       dealer_deal,
                                                       curr_in,
                                                       rub_curr,
                                                       vol_out,
                                                       rate,
                                                       is_order,
                                                       note=0)
            in_abbrev = curr_in.abbrev
            if WPnames:
                item = {
                    'from': in_abbrev,
                    'to': to_abbrev,
                    'in': round(float(vol_in), 8),
                    'out': vol_out,
                    'amount': to_max
                }
            else:
                item = {
                    'in': in_abbrev,
                    'to': to_abbrev,
                    'in_vol': round(float(vol_in), 8),
                    'to_vol': vol_out,
                    'to_max': to_max
                }
            ## вытащим из кеша если он там есть
            in_max = currs_in_max.get(in_abbrev)
            if in_max == None:
                in_max = curr_in.max_bal or 0
                if in_max > 0:
                    bal = db_client.curr_free_bal(curr_in)
                    in_max = round(float(in_max - bal), 8)
            if in_max: item['in_max'] = in_max
            res.append(item)

        ###### покупка через ЯДеньги
    if not deal_sel or deal_sel.upper() == 'IN_YDRUB':
        in_abbrev = 'YDRUB'
        if TO_BUY_ID:
            deal = db.deals[TO_BUY_ID]
        else:
            deal = db(db.deals.name == 'BUY').select().first()
        # тут пустой %% dealer, dealer_acc, dealer_deal = ed_common.select_ed_acc(db, deal, ecurr_out)
        #print deal.name, 'dealer:', dealer_deal
        dealer_deal = None
        in_max = 57000  # у фиатного диллера одну покупку ограничим
        for r in db((db.currs.id == db.xcurrs.curr_id)
                    & (db.currs.used == True)).select():
            curr_out = r.currs
            vol_in = vol_rub  # в рублях
            to_abbrev = curr_out.abbrev
            currs_to_max[to_abbrev] = to_max = round(
                float(db_client.curr_free_bal(curr_out)), 8)

            # теперь курс и мзду нашу найдем
            pr_b, pr_s, rate = rates_lib.get_average_rate_bsa(
                db, rub_curr.id, curr_out.id, None)
            if not rate: continue
            is_order = True
            vol_out, tax_rep = db_client.calc_fees(db,
                                                   deal,
                                                   dealer_deal,
                                                   rub_curr,
                                                   curr_out,
                                                   vol_in,
                                                   rate,
                                                   is_order,
                                                   note=0)
            if WPnames:
                item = {
                    'from': in_abbrev,
                    'to': to_abbrev,
                    'in': vol_in,
                    'out': round(float(vol_out), 8),
                    'amount': to_max,
                    'in_max': in_max
                }
            else:
                item = {
                    'in': in_abbrev,
                    'to': to_abbrev,
                    'in_vol': vol_in,
                    'to_vol': round(float(vol_out), 8),
                    'to_max': to_max,
                    'in_max': in_max
                }
            res.append(item)

    #########
    # обмен крипты
    if not deal_sel or deal_sel.upper() == 'TO_COIN':
        if TO_COIN_ID:
            deal = db.deals[TO_COIN_ID]
        else:
            deal = db(db.deals.name == 'to COIN').select().first()
        for r_in in db((db.currs.id == db.xcurrs.curr_id)
                       & (db.currs.used == True)).select():
            curr_in = r_in.currs
            in_abbrev = curr_in.abbrev
            vol_in = vol_rub * rates_lib.get_avr_rate_or_null(
                db, rub_curr.id, curr_in.id)
            vol_out = vol_rub  # в рублях
            to_max = 0

            in_max = currs_in_max.get(in_abbrev)
            if in_max == None:
                in_max = curr_in.max_bal or 0
                if in_max > 0:
                    bal = db_client.curr_free_bal(curr_in)
                    in_max = round(float(in_max - bal), 8)
            #print curr_in.abbrev, ' to RUB', vol_in
            for r_out in db((db.currs.id == db.xcurrs.curr_id)
                            & (db.currs.used == True)).select():
                curr_out = r_out.currs
                if curr_in.id == curr_out.id: continue
                # теперь курс и мзду нашу найдем
                pr_b, pr_s, rate = rates_lib.get_average_rate_bsa(
                    db, curr_in.id, curr_out.id, None)
                if not rate: continue

                to_abbrev = curr_out.abbrev
                to_max = currs_to_max.get(
                    to_abbrev,
                    round(float(db_client.curr_free_bal(curr_out)), 8))
                # для каждого направление - свое дело

                is_order = True
                vol_out, tax_rep = db_client.calc_fees(db,
                                                       deal,
                                                       dealer_deal,
                                                       curr_in,
                                                       curr_out,
                                                       vol_in,
                                                       rate,
                                                       is_order,
                                                       note=0)
            if WPnames:
                item = {
                    'from': in_abbrev,
                    'to': to_abbrev,
                    'in': round(float(vol_in), 8),
                    'out': round(float(vol_out), 8),
                    'amount': to_max
                }
            else:
                item = {
                    'in': in_abbrev,
                    'to': to_abbrev,
                    'in_vol': round(float(vol_in), 8),
                    'to_vol': round(float(vol_out), 8),
                    'to_max': to_max
                }
                if in_max: item['in_max'] = in_max
                res.append(item)
    return request.extension == 'html' and dict(
        h=DIV(BEAUTIFY({'rates': res}), _class='container')) or {
            'rates': res
        }
예제 #9
0
curr_out = db.currs[CURR_RUB_ID]
ecurr_out = db(db.ecurrs.curr_id == curr_out.id).select().first()
ecurr_out_id = ecurr_out.id

if TO_PHONE7_ID:
    deal = db.deals[TO_PHONE7_ID]
    deal_name = deal.name
else:
    deal_name = 'phone +7'  # 'to phone +7 RUBs'
    # найдем дело
    deal = db(db.deals.name == deal_name).select().first()

if not deal: raise HTTP(200, T('ERROR: Not found deal "%s"') % deal_name)
# найдем счет у диллера электронных денег для этого дела
vol = (deal.MIN_pay or 100) * 2
dealer, dealer_acc, dealer_deal = ed_common.select_ed_acc(
    db, deal, ecurr_out, vol)
print dealer, '\n', dealer_acc, '\n', dealer_deal
dealer_acc = ed_common.sel_acc_max_for_balance(db,
                                               dealer,
                                               ecurr_out,
                                               vol,
                                               unlim=False)

if False and not dealer:
    raise HTTP(
        200,
        #T('ERROR: Not found dealer for "%s". Please try in next month') % deal_name
        'Просьба подождать до следующего дня или месяца - превышен лимит по данному виду операций'
    )
if False and not dealer_acc:
    raise HTTP(