Пример #1
3
    def __new__(cls, value=0, context=None):
        """ Initialize a new Size object.  Must pass a bytes or a spec value
            for size. The bytes value is a numerical value for the size
            this object represents, in bytes.  The spec value is a string
            specification of the size using any of the size specifiers in the
            _decimalPrefixes or _binaryPrefixes lists combined with a 'b' or
            'B'.  For example, to specify 640 kilobytes, you could pass any of
            these spec parameters:

                "640kb"
                "640 kb"
                "640KB"
                "640 KB"
                "640 kilobytes"

            If you want to use a spec value to represent a bytes value,
            you can use the letter 'b' or 'B' or omit the size specifier.
        """
        if isinstance(value, (unicode, str)):
            size = _parseSpec(value)
        elif isinstance(value, (int, long, float, Decimal)):
            size = Decimal(value)
        elif isinstance(value, Size):
            size = Decimal(value.convertTo("b"))
        else:
            raise ValueError("invalid value %s for size" % value)

        # drop any partial byte
        size = size.to_integral_value(rounding=ROUND_DOWN)
        self = Decimal.__new__(cls, value=size)
        return self
Пример #2
3
    def value_of(self, currency, volume=1):
        """Returns the amount that would be yielded if the trade volume,
        denominated in `currency`, were executed.
        Does not handle volumes that exceed the top order's volume at the
        moment, as such functionality is not yet necessary for our purposes.

        Args:
        volume - The amount of the given currency to remove from the top.
        currency - The currency denomination of the volume.

        """
        if volume == 0:
            return 0

        depth = self.get_depth()

        if depth["asks"][0]["price"] == 0:
            return 0

        volume = self.add_fee(volume)

        if currency == self.amount_currency:
            gross = Decimal(str(volume)) * Decimal(str(depth["bids"][0]["price"]))

        elif currency == self.price_currency:
            gross = Decimal(str(volume)) / Decimal(str(depth["asks"][0]["price"]))

        else:
            self._raise_currency_exception(currency)

        return float(gross.quantize(Decimal('1.00000000')))
def dorefund(request, error_url, success_url, template = "paypal/dorefund.html"):
    if request.POST:
        # normalize the given amount
        amount = request.POST.get("amount")
        trans_id = request.POST.get("transactionid")
        try:
            amount = Decimal(amount)
            amount = str(amount.quantize(Decimal(".01"), rounding = ROUND_UP))
        except:
            if request.user.is_authenticated():
                request.user.message_set.create(message = _("No given valid amount. Please check the amount that will be charged."))
            return HttpResponseRedirect(error_url)
        
        response_obj = get_object_or_404(PayPalResponse, trans_id = trans_id)
        
        # charge from PayPal
        result, response = process_refund_request(response_obj, amount)
        # process the result
        if not result:
            # show the error message (comes from PayPal API) and redirect user to the error page
            if request.user.is_authenticated():
                request.user.message_set.create(message = _("Amount %s has not been charged, server error is '%s'" % (amount, response.error)))
            return HttpResponseRedirect(error_url)
        
        # Now we are gone, redirect user to success page
        if request.user.is_authenticated():
            request.user.message_set.create(message = _("Amount %s has been successfully refunded, your transaction id is '%s'" % (amount, response.trans_id)))
        
        return HttpResponseRedirect(success_url)

    return render_to_response(template,
                              {'error_url': error_url,
                               'success_url': success_url,
                               }, context_instance = RequestContext(request))
Пример #4
0
    def r_value_of(self, currency, volume = 1):
        """Returns the amount of currency necessary to return the given volume
        of the given currency.
        Useful for working backwards to the amount of money that needs to go
        into the system after working out the maximum trade volume across
        market order books.
        Does not handle volumes that exceed the top order's volume at the
        moment, as such functionality is not yet necessary for our purposes.

        Args:
        volume - The amount of the given currency to remove from the top.
        currency - The currency denomination of the volume.

        """
        if volume == 0:
            return 0

        depth = self.get_depth()

        if depth["bids"][0]["price"] == 0:
            return 0

        volume = self.remove_fee(volume)

        if currency == self.amount_currency:
            gross = Decimal(str(volume)) * Decimal(str(depth["asks"][0]["price"]))

        elif currency == self.price_currency:
            gross = Decimal(str(volume)) / Decimal(str(depth["bids"][0]["price"]))

        else:
            self._raise_currency_exception(currency)

        return float(gross.quantize(Decimal('1.00000000')))
Пример #5
0
def html_scientific_notation_rate(rate):
    """Helper for convert decimal rate using scientific notation.

    For example we want to show the very detail value of fatality rate
    because it might be a very small number.

    :param rate: Rate value
    :type rate: float

    :return: Rate value with html tag to show the exponent
    :rtype: str
    """
    precision = '%.3f'
    if rate * 100 > 0:
        decimal_rate = Decimal(precision % (rate * 100))
        if decimal_rate == Decimal((precision % 0)):
            decimal_rate = Decimal(str(rate * 100))
    else:
        decimal_rate = Decimal(str(rate * 100))
    if decimal_rate.as_tuple().exponent >= -3:
        rate_percentage = str(decimal_rate)
    else:
        rate = '%.2E' % decimal_rate
        html_rate = rate.split('E')
        # we use html tag to show exponent
        html_rate[1] = '10<sup>{exponent}</sup>'.format(
            exponent=html_rate[1])
        html_rate.insert(1, 'x')
        rate_percentage = ''.join(html_rate)
    return rate_percentage
Пример #6
0
def format_price(price, currency, decimal_pos=None):
    if not currency:
        return price

    if decimal_pos is None:
        decimal_pos = currency.decimal_places

    d = Decimal(str(price))
    if decimal_pos == 0:
        exp = Decimal(1)
    else:
        exp = Decimal('1.0') / (Decimal(10)**abs(decimal_pos))

    formatted_price = numberformat.format(
        u'%s' % str(d.quantize(exp, ROUND_HALF_UP)),
        currency.decimal_separator,
        abs(decimal_pos),
        grouping=3,
        thousand_sep=currency.thousand_separator)

    if currency.symbol_preceeds:
        params = (currency.symbol, formatted_price)
    else:
        params = (formatted_price, currency.symbol)
    return u'%s %s' % params
Пример #7
0
    def corpo_IX_observacoes_contribuinte(self):
        infCpl = self.root.findtext('./infCFe/infAdic/infCpl')
        vCFeLei12741 = Decimal(
                self.root.findtext('./infCFe/total/vCFeLei12741') or 0)

        if infCpl or not vCFeLei12741.is_zero():
            self.normal()
            self.esquerda()
            self.separador()
            self.negrito()
            self.texto(u'OBSERVAÇÕES DO CONTRIBUINTE')
            self.negrito()

            if infCpl:
                self.condensado()
                self.quebrar(infCpl)
                self.condensado()

            if not vCFeLei12741.is_zero():
                self.condensado()
                self.quebrar(u'Valor aproximado dos tributos deste cupom')
                self.bordas(
                        u'(Lei Fed. 12.741/2012) R$',
                        '{:n}'.format(vCFeLei12741))
                self.condensado()
Пример #8
0
 def get_custom_balance(cls, accounts, name):
     
     balances = {}
     for account in accounts:
         balance = Decimal()
         if account.is_current_capital == True:
             balance = account.get_difference_between_childs()
         elif account.is_recommended_capital == True: 
             balance = account.get_recommended_capital()
         elif account.is_cash == True: 
             balance = account.get_cash()
         elif account.is_current_liability == True: 
             balance = account.get_current_liability()
         elif account.is_current_asset == True: 
             balance = account.get_current_asset()
         elif account.is_revenue == True: 
             balance = account.get_revenues()
         elif account.is_expense == True: 
             balance = account.get_expenses()
         elif account.type == 'root':
             balance = account.get_difference_between_childs()
         if account.display_balance == 'credit-debit' and balance:
             balance *= -1
         exp = Decimal(str(10.0 ** -account.currency_digits))
         balances[account.id] = balance.quantize(exp)
     return balances
Пример #9
0
def chakra(N):
    b = Decimal(1)
    k = Decimal(0)

    while not issquare(k + N):  k = k + 1
    l = Decimal(0)
    while not issquare(l + N):  l = l - 1
    if abs(l) < abs(k):         k = l

    a = Decimal(k + N).sqrt()

    while k != 1 or (not isnatural(a) or not isnatural(b)):
        #print a, b, k
        d = [a, b, k]
        if k.copy_abs() == 4:
            [a, b, k] = [a / 2, b / 2, k / 4]
            continue
        if k == 1:
            while not isnatural(a) or not isnatural(b):
                [a, b, k] = compose([a, b, k], d, N)
            continue
        if k == -1:
            [a, b, k] = compose(d, d, N)
            while not isnatural(a) or not isnatural(b):
                [a, b, k] = compose([a, b, k], d, N)
            continue
        if k.copy_abs() == 2:
            [a, b, k] = compose(d, d, N)
            continue
        m = findm(a, b, k, N)
        [a, b, k] = [(a * m + N * b) / k.copy_abs(), (a + m * b) / k.copy_abs(), (m ** 2 - N) / k]
    
    return a, b, k
Пример #10
0
def get_int_exp(str_n):
    # makes int from fractional by multiplying by 10
    # as much time as needed to get int
    n = Decimal(str_n)
    sign, digits, exp = n.as_tuple()
    int_n = int(n*10**(-exp))
    return (abs(int_n), exp)
Пример #11
0
def _create_cache_key(lat, lng):
    key_parts = []
    for float_num in lat, lng:
        decimal_num = Decimal(float_num)
        decimal_num = decimal_num.quantize(Decimal('1.0'))
        key_parts.append(str(decimal_num))
    return ';'.join(key_parts)
Пример #12
0
    def charge(self, amount):
        """
        Charges the users credit card, with he passed $amount, if they are in the vault. Returns the payment_log instance
        or None (if charge fails etc.)
        """
        # TODO: refactor! This is not how such operations should be done.
        amount = Decimal(amount)
        try:
            result = Transaction.sale(
                {
                    'amount': amount.quantize(Decimal('.01')),
                    'customer_id': self.vault_id,
                    'options': {
                        'submit_for_settlement': True
                    }
                }
            )

            if result.is_success:
                # create a payment log
                payment_log = PaymentLog.objects.create(user=self.user,
                                        amount=amount,
                                        transaction_id=result.transaction.id)
                return payment_log
            else:
                logging.error("Bad braintree response %s" % result)
                raise Exception("Logical error in CC transaction")
        except Exception, e:
            logging.error("Failed to charge $%s to user:"******" %s with vault_id: %s error was %s" % (amount, self.user,
                                                     self.vault_id, e))
            return None
Пример #13
0
 def __setitem__(self, key, value):
     try:
         key = key.upper()
     except AttributeError:
         raise AttributeError('Keys stored as upper-case strings: %s unsuitable' % (key))
     value = Decimal(value)
     if key in self.keys() and not 'CURRENT' in key:
         # Validate choosing more detailed value for variable
         existing_exp = self[key].as_tuple().exponent  # 0.1111 --> -4
         candidate_exp = value.as_tuple().exponent
         if existing_exp > candidate_exp:  # candidate has more digits
             places = Decimal(10) ** (existing_exp + 1)  # exp+1 permits slack in rounding
             best_value = value
         else:                             # existing has more digits
             places = Decimal(10) ** (candidate_exp + 1)
             best_value = self[key]
         # Validate values are the same
         places = max(places, Decimal('1E-11'))  # for computed psivars
         #print('FLOOR: ', self[key].quantize(places, rounding=ROUND_FLOOR) - value.quantize(places, rounding=ROUND_FLOOR))
         #print('CEIL:  ', self[key].quantize(places, rounding=ROUND_CEILING) - value.quantize(places, rounding=ROUND_CEILING))
         if (self[key].quantize(places, rounding=ROUND_CEILING).compare(value.quantize(places, rounding=ROUND_CEILING)) != 0) and \
            (self[key].quantize(places, rounding=ROUND_FLOOR).compare(value.quantize(places, rounding=ROUND_FLOOR)) != 0):
             raise ParsingValidationError(
                 """Output file yielded both %s and %s as values for quantity %s.""" %
                 (self[key].to_eng_string(), value.to_eng_string(), key))
         #print 'Resetting variable %s to %s' % (key, best_value.to_eng_string())
     else:
         best_value = value
         #print 'Setting   variable %s to %s' % (key, best_value.to_eng_string())
     super(PreservingDict, self).__setitem__(key, best_value)
Пример #14
0
def PHI2(n=2):
	''' PHI(int) -> Decimal -- returns (1+√5)/2 to int precision, increasing the precision of Decimal if required'''
	from decimal import Context,Decimal
	dot100 = Context(prec=n)
	d5 = Decimal(5)
	s5 = d5.sqrt(dot100)
	return (1 + s5)/2
Пример #15
0
def _tipo_para_string(valor, tipo, obrigatorio, dec_min):
    if (not obrigatorio) and (not valor):
        return '', ''

    decimais = ''

    # Cuidado!!!
    # Aqui não dá pra usar a função strftime pois em alguns
    # casos a data retornada é 01/01/0001 00:00:00
    # e a função strftime só aceita data com anos a partir de 1900
    if (tipo in ('d', 'h', 'dh')) and isinstance(valor, (datetime, date, time,)):
        valor = formata_datahora(valor, tipo)
    elif (tipo == 'n') and isinstance(valor, (int, long, float, Decimal)):
        if isinstance(valor, (int, long, float)):
            valor = Decimal(unicode(valor))

        valor = unicode(valor).strip()

        if '.' in valor:
            decimais = valor.split('.')[1]

        if dec_min:
            decimais = decimais.ljust(dec_min, '0')

            if '.' in valor:
                valor = valor.split('.')[0]

            valor += '.' + decimais

    return valor, decimais
Пример #16
0
 def format_amount(self, satoshis):
     if self.amount_format == 'satoshis':
         return str(satoshis)
     elif self.amount_format == 'coins':
         amount = Decimal(satoshis) / pow(10, 8)
         amount = amount.quantize(Decimal('0.00000001'), rounding=decimal.ROUND_DOWN)
         return '{:f}'.format(amount)
Пример #17
0
    def get_pending_amount(cls, agents, name):
        pool = Pool()
        Commission = pool.get('commission')
        commission = Commission.__table__()
        cursor = Transaction().connection.cursor()

        ids = [a.id for a in agents]
        amounts = dict.fromkeys(ids, None)
        for sub_ids in grouped_slice(ids):
            where = reduce_ids(commission.agent, sub_ids)
            where &= commission.invoice_line == Null
            query = commission.select(commission.agent, Sum(commission.amount),
                where=where,
                group_by=commission.agent)
            cursor.execute(*query)
            amounts.update(dict(cursor.fetchall()))
        digits = cls.pending_amount.digits
        exp = Decimal(str(10.0 ** -digits[1]))
        for agent_id, amount in amounts.items():
            if amount:
                # SQLite uses float for SUM
                if not isinstance(amount, Decimal):
                    amount = Decimal(str(amount))
                amounts[agent_id] = amount.quantize(exp)
        return amounts
Пример #18
0
def redondear(formato, clave, valor):
    from formato_txt import A, N, I
    # corregir redondeo (aparentemente sqlite no guarda correctamente los decimal)
    import decimal
    try:
        long = [fmt[1] for fmt in formato if fmt[0]==clave]
        tipo = [fmt[2] for fmt in formato if fmt[0]==clave]
        if not tipo:
            return valor
        tipo = tipo[0]
        if DEBUG: print "tipo", tipo, clave, valor, long
        if valor is None:
            return None
        if valor == "":
            return ""
        if tipo == A:
            return valor
        if tipo == N:
            return int(valor)
        if isinstance(valor, (int, float)):
            valor = str(valor)
        if isinstance(valor, basestring):
            valor = Decimal(valor) 
        if long and isinstance(long[0], (tuple, list)):
            decimales = Decimal('1')  / Decimal(10**(long[0][1]))
        else:
            decimales = Decimal('.01')
        valor1 = valor.quantize(decimales, rounding=decimal.ROUND_DOWN)
        if valor != valor1 and DEBUG:
            print "REDONDEANDO ", clave, decimales, valor, valor1
        return valor1
    except Exception as e:
        print "IMPOSIBLE REDONDEAR:", clave, valor, e
Пример #19
0
    def decode(data):
        """From a string formatted as specified in the RFC2616, it builds a
        data structure which provides a high level interface to implement
        language negotiation.
        """
        data = data.strip()
        if not data:
            return AcceptLanguage({})

        accept = {}
        for language in data.lower().split(','):
            language = language.strip()
            if ';' in language:
                language, quality = language.split(';')
                # Get the number (remove "q=")
                quality = Decimal(quality.strip()[2:])
            else:
                quality = one

            if language == '*':
                language = ''

            accept[language] = quality

        return AcceptLanguage(accept)
Пример #20
0
def moneyfmt(
    value,
    places=2,
    curr='',
    sep=',',
    dp='.',
    pos='',
    neg='-',
    trailneg=''
):
    """Convert Decimal to a money formatted string.

    places:  required number of places after the decimal point
    curr:    optional currency symbol before the sign (may be blank)
    sep:     optional grouping separator (comma, period, space, or blank)
    dp:      decimal point indicator (comma or period)
             only specify as blank when places is zero
    pos:     optional sign for positive numbers: '+', space or blank
    neg:     optional sign for negative numbers: '-', '(', space or blank
    trailneg:optional trailing minus indicator:  '-', ')', space or blank

    >>> d = Decimal('-1234567.8901')
    >>> moneyfmt(d, curr='$')
    '-$1,234,567.89'
    >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')
    '1.234.568-'
    >>> moneyfmt(d, curr='$', neg='(', trailneg=')')
    '($1,234,567.89)'
    >>> moneyfmt(Decimal(123456789), sep=' ')
    '123 456 789.00'
    >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')
    '<0.02>'

    From: https://docs.python.org/3/library/decimal.html#recipes
    """
    if type(value) != Decimal:
        value = Decimal(value)
    q = Decimal(10) ** -places      # 2 places --> '0.01'
    sign, digits, exp = value.quantize(q).as_tuple()
    result = []
    digits = list(map(str, digits))
    build, next = result.append, digits.pop
    if sign:
        build(trailneg)
    for i in range(places):
        build(next() if digits else '0')
    if places:
        build(dp)
    if not digits:
        build('0')
    i = 0
    while digits:
        build(next())
        i += 1
        if i == 3 and digits:
            i = 0
            build(sep)
    build(curr)
    build(neg if sign else pos)
    return ''.join(reversed(result))
def test_floats_in_tiny_interval_within_bounds(data, center):
    assume(not (math.isinf(next_down(center)) or math.isinf(next_up(center))))
    lo = Decimal.from_float(next_down(center)).next_plus()
    hi = Decimal.from_float(next_up(center)).next_minus()
    assert float(lo) < lo < center < hi < float(hi)
    val = data.draw(st.floats(lo, hi))
    assert lo < val < hi
Пример #22
0
 def __eq__(self, other):
     if isinstance(other, Money):
         return Decimal.__eq__(self, other)
     elif isinstance(other, six.integer_types + (float, Decimal)):
         return Decimal.__eq__(self, self._sanitize(other))
     else:
         return False
Пример #23
0
def decimal_places(arg):
    """
    Returns the number of decimal places in the given number

    Parameters
    ----------
    arg: Numeric or string
        A number to determine the number of decimal places

    Returns
    -------
    Number of decimal places found.

    Raises
    ------
    IllegalArgumentException if argument is not numeric.
    """

    if not is_number(str(arg)):
        raise IllegalArgumentException("[{0}] is not a number".format(arg))

    dec = Decimal(str(arg))
    exp = dec.as_tuple().exponent
    result = -exp

    return result
Пример #24
0
def export_attr_edits(cls, attrs):
    edits_iter = iter_attr_edits(cls, attrs)
    maxes = dict.fromkeys(attrs, 0)
    totals = dict.fromkeys(attrs, 0)
    count = 0

    for pk, attr_times in edits_iter:
        for a in attrs:
            maxes[a] = max(maxes[a], len(attr_times[a]))
            totals[a] += len(attr_times[a])
        count += 1

    edits = OrderedDict()
    for a in attrs:
        if count == 0:
            edits[a] = {
                'max': 0,
                'avg': Decimal('0.00'),
            }

        else:
            avg = Decimal(totals[a]) / count
            edits[a] = {
                'max': maxes[a],
                'avg': avg.quantize(Decimal('0.01')),
            }

    return edits
Пример #25
0
def money_format(value, places=2, curr='$', sep=',', dp='.', pos='', neg='-', trailneg=''):
    try:
        value = Decimal(value)
    except:
        raise Exception("Failed to convert '{}' to Decimal".format(value))

    q = Decimal(10) ** -places      # 2 places --> '0.01'
    sign, digits, exp = value.quantize(q).as_tuple()
    result = []
    digits = map(str, digits)
    build, next = result.append, digits.pop
    if sign:
        build(trailneg)
    for i in range(places):
        build(next() if digits else '0')
    build(dp)
    if not digits:
        build('0')
    i = 0
    while digits:
        build(next())
        i += 1
        if i == 3 and digits:
            i = 0
            build(sep)
    build(curr)
    build(neg if sign else pos)
    return ''.join(reversed(result))
Пример #26
0
def round_decimal(raw_val, decimals=1, track_significance=False):
    '''
    Round to the specified decimals
    
    @param track_significance if True then remove trailing zeros
    
    @return Decimal representing the rounded raw_val as a decimal
    '''
    assert decimals >= 0, 'decimals must be >= 0'
    
    if raw_val is None: 
        return None
    
    val = Decimal(raw_val)

    logger.debug('convert_decimal: %r, %r, %r, %r',
        raw_val, decimals, track_significance)
    
    # Convert the decimal argument to a Decimal value
    decimals = Decimal('1e-%d'%int(decimals))
    # Quantize: Return a value equal to the first operand after rounding and 
    # having the exponent of the second operand. (see python doc)
    val = val.quantize(decimals, decimal.ROUND_HALF_UP)
        
    if track_significance is False:
        val = remove_exponent(val)

    return val
Пример #27
0
    def set_content(self, addr, label, amount, currency):
        self.address = addr
        address_text = "<span style='font-size: 18pt'>%s</span>" % addr if addr else ""
        self.address_label.setText(address_text)

        if currency == 'BTC': currency = None
        amount_text = ''
        if amount:
            if currency:
                self.amount = Decimal(amount) / self.exchanger.exchange(1, currency) if currency else amount
            else:
                self.amount = Decimal(amount)
            self.amount = self.amount.quantize(Decimal('1.0000'))

            if currency:
                amount_text += "<span style='font-size: 18pt'>%s %s</span><br/>" % (amount, currency)
            amount_text += "<span style='font-size: 21pt'>%s</span> <span style='font-size: 16pt'>BTC</span> " % str(self.amount) 
        self.amount_label.setText(amount_text)

        self.label = label
        label_text = "<span style='font-size: 21pt'>%s</span>" % label if label else ""
        self.label_label.setText(label_text)

        msg = 'bitcoin:'+self.address
        if self.amount is not None:
            msg += '?amount=%s'%(str( self.amount))
            if self.label is not None:
                msg += '&label=%s'%(self.label)
        elif self.label is not None:
            msg += '?label=%s'%(self.label)
            
        self.qrw.set_addr( msg )
Пример #28
0
def staffdiscount(tablenumber,item):
    if tablenumber!=1234: return zero
    discount=item.price*Decimal("0.4")
    if discount>Decimal("3.00"): discount=Decimal("3.00")
    discount=discount.quantize(Decimal("0.1"),rounding=ROUND_UP)
    discount=discount.quantize(penny)
    return discount
Пример #29
0
def print_si_unit(raw_val, default_unit, symbol, decimals=1, 
    multiplier=1, track_significance=False):

    if raw_val is None:
        return None
    
    val = Decimal(raw_val)
    
    if multiplier is not None:
        # get the scale (exponent) of the multiplier
        multiplier = Decimal(str(multiplier)).adjusted()
        val = val.scaleb(multiplier)
    
    # NOTE: convert to string to avoid float numeric errors
    default_unit = Decimal(str(default_unit))
    
    if val >= default_unit:
        return '{} {}{}'.format(
            convert_decimal(
                val,default_unit, decimals, track_significance=track_significance),
            get_siunit_symbol(default_unit), symbol)
    else:
        (unit_symbol,default_unit) = get_siunit(val)
        
        return '{} {}{}'.format(
            convert_decimal(
                val,default_unit, decimals, track_significance=track_significance),
            unit_symbol, symbol)
Пример #30
0
def calculate_tax(table_name, table_type, value):
    """
    Calculate the tax based on the table name and the table type.
    :param table_name: this is the name of the table, federal/state.
    :param table_type: this is the type of the table, 'single', 'married', etc.
    :param value: value of income to calculate the tax for.
    :return:
    """

    current_tax = Decimal('0.0')
    previous_maximum = Decimal('0.0')

    table = _tax_tables.get(table_name, dict()).get(table_type, None)
    if table is None:
        raise AttributeError('Unknown table type: %s' % table_type)

    for tax_bracket in table:
        max_value = Decimal('0.0')
        if 'maximum' in tax_bracket:
            if previous_maximum < value:
                max_value = min(value - previous_maximum, tax_bracket['maximum'] - previous_maximum)
            previous_maximum = tax_bracket['maximum']
        else:
            if previous_maximum < value:
                max_value = value - previous_maximum

        current_tax += tax_bracket['rate'] * max_value

    current_tax = current_tax.to_integral_value('ROUND_HALF_UP')

    return current_tax
Пример #31
0
    def test_get_total_penalty(self):
        method = PaymentMethod.get_by_name(self.store, u'check')

        # Test for a group in a sale
        # On sale's group, total value should return
        # sum(inpayments.penalty) - sum(outpayments.penalty)
        sale = self.create_sale()
        group = sale.group
        self.assertEqual(group.get_total_value(), 0)

        p = method.create_payment(Payment.TYPE_IN, group, sale.branch,
                                  Decimal(10))
        p.penalty = Decimal(10)
        self.assertEqual(group.get_total_penalty(), Decimal(10))

        p = method.create_payment(Payment.TYPE_IN, group, sale.branch,
                                  Decimal(10))
        p.penalty = Decimal(20)
        self.assertEqual(group.get_total_penalty(), Decimal(30))

        p = method.create_payment(Payment.TYPE_OUT, group, sale.branch,
                                  Decimal(10))
        p.penalty = Decimal(10)
        self.assertEqual(group.get_total_penalty(), Decimal(20))

        # Test for a group in a purchase
        # On purchase's group, total value should return
        # sum(inpayments.penalty) - sum(outpayments.penalty)
        purchase = self.create_purchase_order()
        group = purchase.group
        self.assertEqual(group.get_total_value(), 0)

        p = method.create_payment(Payment.TYPE_OUT, group, purchase.branch,
                                  Decimal(10))
        p.penalty = Decimal(10)
        self.assertEqual(group.get_total_penalty(), Decimal(10))

        p = method.create_payment(Payment.TYPE_OUT, group, purchase.branch,
                                  Decimal(10))
        p.penalty = Decimal(20)
        self.assertEqual(group.get_total_penalty(), Decimal(30))

        p = method.create_payment(Payment.TYPE_IN, group, purchase.branch,
                                  Decimal(10))
        p.penalty = Decimal(10)
        self.assertEqual(group.get_total_penalty(), Decimal(20))
Пример #32
0
class OrderLine(models.Model):
    order = models.ForeignKey(
        Order, related_name="lines", editable=False, on_delete=models.CASCADE
    )
    variant = models.ForeignKey(
        "product.ProductVariant",
        related_name="order_lines",
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )
    # max_length is as produced by ProductVariant's display_product method
    product_name = models.CharField(max_length=386)
    variant_name = models.CharField(max_length=255, default="", blank=True)
    translated_product_name = models.CharField(max_length=386, default="", blank=True)
    translated_variant_name = models.CharField(max_length=255, default="", blank=True)
    product_sku = models.CharField(max_length=255, null=True, blank=True)
    # str with GraphQL ID used as fallback when product SKU is not available
    product_variant_id = models.CharField(max_length=255, null=True, blank=True)
    is_shipping_required = models.BooleanField()
    is_gift_card = models.BooleanField()
    quantity = models.IntegerField(validators=[MinValueValidator(1)])
    quantity_fulfilled = models.IntegerField(
        validators=[MinValueValidator(0)], default=0
    )

    currency = models.CharField(
        max_length=settings.DEFAULT_CURRENCY_CODE_LENGTH,
    )

    unit_discount_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
    )
    unit_discount = MoneyField(
        amount_field="unit_discount_amount", currency_field="currency"
    )
    unit_discount_type = models.CharField(
        max_length=10,
        choices=DiscountValueType.CHOICES,
        default=DiscountValueType.FIXED,
    )
    unit_discount_reason = models.TextField(blank=True, null=True)

    unit_price_net_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
    )
    # stores the value of the applied discount. Like 20 of %
    unit_discount_value = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
    )
    unit_price_net = MoneyField(
        amount_field="unit_price_net_amount", currency_field="currency"
    )

    unit_price_gross_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
    )
    unit_price_gross = MoneyField(
        amount_field="unit_price_gross_amount", currency_field="currency"
    )

    unit_price = TaxedMoneyField(
        net_amount_field="unit_price_net_amount",
        gross_amount_field="unit_price_gross_amount",
        currency="currency",
    )

    total_price_net_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
    )
    total_price_net = MoneyField(
        amount_field="total_price_net_amount",
        currency_field="currency",
    )

    total_price_gross_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
    )
    total_price_gross = MoneyField(
        amount_field="total_price_gross_amount",
        currency_field="currency",
    )

    total_price = TaxedMoneyField(
        net_amount_field="total_price_net_amount",
        gross_amount_field="total_price_gross_amount",
        currency="currency",
    )

    undiscounted_unit_price_gross_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
    )
    undiscounted_unit_price_net_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
    )
    undiscounted_unit_price = TaxedMoneyField(
        net_amount_field="undiscounted_unit_price_net_amount",
        gross_amount_field="undiscounted_unit_price_gross_amount",
        currency="currency",
    )

    undiscounted_total_price_gross_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
    )
    undiscounted_total_price_net_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
    )
    undiscounted_total_price = TaxedMoneyField(
        net_amount_field="undiscounted_total_price_net_amount",
        gross_amount_field="undiscounted_total_price_gross_amount",
        currency="currency",
    )

    tax_rate = models.DecimalField(
        max_digits=5, decimal_places=4, default=Decimal("0.0")
    )

    # Fulfilled when voucher code was used for product in the line
    voucher_code = models.CharField(max_length=255, null=True, blank=True)

    # Fulfilled when sale was applied to product in the line
    sale_id = models.CharField(max_length=255, null=True, blank=True)

    objects = models.Manager.from_queryset(OrderLineQueryset)()

    class Meta:
        ordering = ("pk",)

    def __str__(self):
        return (
            f"{self.product_name} ({self.variant_name})"
            if self.variant_name
            else self.product_name
        )

    @property
    def quantity_unfulfilled(self):
        return self.quantity - self.quantity_fulfilled

    @property
    def is_digital(self) -> Optional[bool]:
        """Check if a variant is digital and contains digital content."""
        if not self.variant:
            return None
        is_digital = self.variant.is_digital()
        has_digital = hasattr(self.variant, "digital_content")
        return is_digital and has_digital
Пример #33
0
import sys
import copy

from decimal import Decimal, ROUND_DOWN

from colorama import Fore

from ...config import config
from ..out_record import TransactionOutRecord
from ..dataparser import DataParser
from ..exceptions import DataRowError, UnexpectedTypeError

WALLET = "Hotbit"

PRECISION = Decimal('0.00000000')
MAKER_FEE = Decimal(0.0005)
TAKER_FEE = Decimal(0.002)

def parse_hotbit_orders_v3(data_rows, parser, **kwargs):
    parse_hotbit_orders_v1(data_rows, parser, type_str='Side', amount_str='Volume', **kwargs)

def parse_hotbit_orders_v2(data_rows, parser, **kwargs):
    parse_hotbit_orders_v1(data_rows, parser, type_str='Side', amount_str='Amount', **kwargs)

def parse_hotbit_orders_v1(data_rows, parser, **kwargs):
    if kwargs.get('type_str'):
        type_str = kwargs['type_str']
    else:
        type_str = 'Type'
Пример #34
0
solution.solution('77')
Output:
    4208

Input:
solution.solution('5')
Output:
    19
    
FOR PYTHON 2.7
"""

from decimal import Decimal, getcontext

getcontext().prec = 101
r = Decimal(2).sqrt()
p = r - 1

def solution(str_n):
    n = long(str_n)
    
    def beatty_sequence(n):
        if n == 1:
            return 1
        if n < 1:
            return 0
        m = long(p*n)
        return n*m + (n*(n+1))//2 - (m*(m+1))//2 - beatty_sequence(m)
    
    return str(ans)
Пример #35
0
    def run_test(self):

        #prepare some coins for multiple *rawtransaction commands
        self.nodes[2].generate(1)
        self.sync_all()
        self.nodes[0].generate(101)
        self.sync_all()
        self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5);
        self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0);
        self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0);
        self.sync_all()
        self.nodes[0].generate(5)
        self.sync_all()

        #########################################
        # sendrawtransaction with missing input #
        #########################################
        inputs  = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1}] #won't exists
        outputs = { self.nodes[0].getnewaddress() : 4.998 }
        rawtx   = self.nodes[2].createrawtransaction(inputs, outputs)
        rawtx   = self.nodes[2].signrawtransaction(rawtx)

        errorString = ""
        try:
            rawtx   = self.nodes[2].sendrawtransaction(rawtx['hex'])
        except JSONRPCException as e:
            errorString = e.error['message']

        assert_equal("Missing inputs" in errorString, True);

        #####################################
        # getrawtransaction with block hash #
        #####################################

        # make a tx by sending then generate 2 blocks; block1 has the tx in it
        tx = self.nodes[2].sendtoaddress(self.nodes[1].getnewaddress(), 1)
        block1, block2 = self.nodes[2].generate(2)
        self.sync_all()
        # We should be able to get the raw transaction by providing the correct block
        gottx = self.nodes[0].getrawtransaction(tx, 1, block1)
        assert_equal(gottx['txid'], tx)
        assert_equal(gottx['in_active_chain'], True)
        # We should not have the 'in_active_chain' flag when we don't provide a block
        gottx = self.nodes[0].getrawtransaction(tx, 1)
        assert_equal(gottx['txid'], tx)
        assert 'in_active_chain' not in gottx
        # We should have hex for the transaction from the getblock and getrawtransaction calls.
        blk = self.nodes[0].getblock(block1, 2)
        assert_equal(gottx['hex'], blk['tx'][1]['hex'])
        # We should not get the tx if we provide an unrelated block
        assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, tx, 1, block2)
        # An invalid block hash should raise errors
        assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, tx, 1, True)
        assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, tx, 1, "foobar")
        assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, tx, 1, "abcd1234")
        assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, tx, 1, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")

        #########################
        # RAW TX MULTISIG TESTS #
        #########################
        # 2of2 test
        addr1 = self.nodes[2].getnewaddress()
        addr2 = self.nodes[2].getnewaddress()

        addr1Obj = self.nodes[2].validateaddress(addr1)
        addr2Obj = self.nodes[2].validateaddress(addr2)

        mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])
        mSigObjValid = self.nodes[2].validateaddress(mSigObj)

        #use balance deltas instead of absolute values
        bal = self.nodes[2].getbalance()

        # send 1.2 BTC to msig adr
        txId       = self.nodes[0].sendtoaddress(mSigObj, 1.2);
        self.sync_all()
        self.nodes[0].generate(1)
        self.sync_all()
        assert_equal(self.nodes[2].getbalance(), bal+Decimal('1.20000000')) #node2 has both keys of the 2of2 ms addr., tx should affect the balance




        # 2of3 test from different nodes
        bal = self.nodes[2].getbalance()
        addr1 = self.nodes[1].getnewaddress()
        addr2 = self.nodes[2].getnewaddress()
        addr3 = self.nodes[2].getnewaddress()

        addr1Obj = self.nodes[1].validateaddress(addr1)
        addr2Obj = self.nodes[2].validateaddress(addr2)
        addr3Obj = self.nodes[2].validateaddress(addr3)

        mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']])
        mSigObjValid = self.nodes[2].validateaddress(mSigObj)
        assert_equal(mSigObjValid['isvalid'], True)

        txId       = self.nodes[0].sendtoaddress(mSigObj, 2.2);
        decTx = self.nodes[0].gettransaction(txId)
        rawTx = self.nodes[0].decoderawtransaction(decTx['hex'])
        sPK = rawTx['vout'][0]['scriptPubKey']['hex']
        [sPK] # hush pyflakes
        self.sync_all()
        self.nodes[0].generate(1)
        self.sync_all()

        # THIS IS A INCOMPLETE FEATURE
        # NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND COUNT AT BALANCE CALCULATION
        assert_equal(self.nodes[2].getbalance(), bal) # for now, assume the funds of a 2of3 multisig tx are not marked as spendable

        txDetails = self.nodes[0].gettransaction(txId, True)
        rawTx = self.nodes[0].decoderawtransaction(txDetails['hex'])
        vout = False
        for outpoint in rawTx['vout']:
            if outpoint['value'] == Decimal('2.20000000'):
                vout = outpoint
                break;

        bal = self.nodes[0].getbalance()
        inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "amount" : vout['value']}]
        outputs = { self.nodes[0].getnewaddress() : 2.199 }
        rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
        rawTxPartialSigned = self.nodes[1].signrawtransaction(rawTx, inputs)
        assert_equal(rawTxPartialSigned['complete'], False) # node1 only has one key, can't comp. sign the tx

        rawTxSigned = self.nodes[2].signrawtransaction(rawTx, inputs)
        assert_equal(rawTxSigned['complete'], True) # node2 can sign the tx compl., own two of three keys
        self.nodes[2].sendrawtransaction(rawTxSigned['hex'])
        rawTx = self.nodes[0].decoderawtransaction(rawTxSigned['hex'])
        self.sync_all()
        self.nodes[0].generate(1)
        self.sync_all()
        assert_equal(self.nodes[0].getbalance(), bal+Decimal('97.00000000')+Decimal('2.19900000')) #block reward + tx

        inputs  = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 1000}]
        outputs = { self.nodes[0].getnewaddress() : 1 }
        rawtx   = self.nodes[0].createrawtransaction(inputs, outputs)
        decrawtx= self.nodes[0].decoderawtransaction(rawtx)
        assert_equal(decrawtx['vin'][0]['sequence'], 1000)
Пример #36
0
    response = authorized_client.get(url)
    assert product in response.context_data["products"][0]


@patch("saleor.product.thumbnails.create_thumbnails")
def test_create_product_thumbnails(mock_create_thumbnails, product_with_image):
    product_image = product_with_image.images.first()
    create_product_thumbnails(product_image.pk)
    assert mock_create_thumbnails.called_once_with(
        product_image.pk, models.ProductImage, "products"
    )


@pytest.mark.parametrize(
    "expected_price, include_discounts",
    [(Decimal("10.00"), True), (Decimal("15.0"), False)],
)
def test_get_price(
    product_type,
    category,
    sale,
    expected_price,
    include_discounts,
    site_settings,
    discount_info,
):
    product = models.Product.objects.create(
        product_type=product_type,
        category=category,
        price=Money(Decimal("15.00"), "USD"),
    )
Пример #37
0
class Order(ModelWithMetadata):
    created = models.DateTimeField(default=now, editable=False)
    status = models.CharField(
        max_length=32, default=OrderStatus.UNFULFILLED, choices=OrderStatus.CHOICES
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        blank=True,
        null=True,
        related_name="orders",
        on_delete=models.SET_NULL,
    )
    language_code = models.CharField(
        max_length=35, choices=settings.LANGUAGES, default=settings.LANGUAGE_CODE
    )
    tracking_client_id = models.CharField(max_length=36, blank=True, editable=False)
    billing_address = models.ForeignKey(
        "account.Address",
        related_name="+",
        editable=False,
        null=True,
        on_delete=models.SET_NULL,
    )
    shipping_address = models.ForeignKey(
        "account.Address",
        related_name="+",
        editable=False,
        null=True,
        on_delete=models.SET_NULL,
    )
    user_email = models.EmailField(blank=True, default="")
    original = models.ForeignKey(
        "self", null=True, blank=True, on_delete=models.SET_NULL
    )
    origin = models.CharField(max_length=32, choices=OrderOrigin.CHOICES)

    currency = models.CharField(
        max_length=settings.DEFAULT_CURRENCY_CODE_LENGTH,
    )

    shipping_method = models.ForeignKey(
        ShippingMethod,
        blank=True,
        null=True,
        related_name="orders",
        on_delete=models.SET_NULL,
    )
    collection_point = models.ForeignKey(
        "warehouse.Warehouse",
        blank=True,
        null=True,
        related_name="orders",
        on_delete=models.SET_NULL,
    )
    shipping_method_name = models.CharField(
        max_length=255, null=True, default=None, blank=True, editable=False
    )
    collection_point_name = models.CharField(
        max_length=255, null=True, default=None, blank=True, editable=False
    )

    channel = models.ForeignKey(
        Channel,
        related_name="orders",
        on_delete=models.PROTECT,
    )
    shipping_price_net_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
        editable=False,
    )
    shipping_price_net = MoneyField(
        amount_field="shipping_price_net_amount", currency_field="currency"
    )

    shipping_price_gross_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
        editable=False,
    )
    shipping_price_gross = MoneyField(
        amount_field="shipping_price_gross_amount", currency_field="currency"
    )

    shipping_price = TaxedMoneyField(
        net_amount_field="shipping_price_net_amount",
        gross_amount_field="shipping_price_gross_amount",
        currency_field="currency",
    )
    shipping_tax_rate = models.DecimalField(
        max_digits=5, decimal_places=4, default=Decimal("0.0")
    )

    token = models.CharField(max_length=36, unique=True, blank=True)
    # Token of a checkout instance that this order was created from
    checkout_token = models.CharField(max_length=36, blank=True)

    total_net_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
    )
    undiscounted_total_net_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
    )

    total_net = MoneyField(amount_field="total_net_amount", currency_field="currency")
    undiscounted_total_net = MoneyField(
        amount_field="undiscounted_total_net_amount", currency_field="currency"
    )

    total_gross_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
    )
    undiscounted_total_gross_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
    )

    total_gross = MoneyField(
        amount_field="total_gross_amount", currency_field="currency"
    )
    undiscounted_total_gross = MoneyField(
        amount_field="undiscounted_total_gross_amount", currency_field="currency"
    )

    total = TaxedMoneyField(
        net_amount_field="total_net_amount",
        gross_amount_field="total_gross_amount",
        currency_field="currency",
    )
    undiscounted_total = TaxedMoneyField(
        net_amount_field="undiscounted_total_net_amount",
        gross_amount_field="undiscounted_total_gross_amount",
        currency_field="currency",
    )

    total_paid_amount = models.DecimalField(
        max_digits=settings.DEFAULT_MAX_DIGITS,
        decimal_places=settings.DEFAULT_DECIMAL_PLACES,
        default=0,
    )
    total_paid = MoneyField(amount_field="total_paid_amount", currency_field="currency")

    voucher = models.ForeignKey(
        Voucher, blank=True, null=True, related_name="+", on_delete=models.SET_NULL
    )
    gift_cards = models.ManyToManyField(GiftCard, blank=True, related_name="orders")

    display_gross_prices = models.BooleanField(default=True)
    customer_note = models.TextField(blank=True, default="")
    weight = MeasurementField(
        measurement=Weight,
        unit_choices=WeightUnits.CHOICES,  # type: ignore
        default=zero_weight,
    )
    redirect_url = models.URLField(blank=True, null=True)
    search_document = models.TextField(blank=True, default="")

    objects = models.Manager.from_queryset(OrderQueryset)()

    class Meta:
        ordering = ("-pk",)
        permissions = ((OrderPermissions.MANAGE_ORDERS.codename, "Manage orders."),)
        indexes = [
            *ModelWithMetadata.Meta.indexes,
            GinIndex(
                name="order_search_gin",
                # `opclasses` and `fields` should be the same length
                fields=["search_document"],
                opclasses=["gin_trgm_ops"],
            ),
            GinIndex(
                name="order_email_search_gin",
                # `opclasses` and `fields` should be the same length
                fields=["user_email"],
                opclasses=["gin_trgm_ops"],
            ),
        ]

    def save(self, *args, **kwargs):
        if not self.token:
            self.token = str(uuid4())
        return super().save(*args, **kwargs)

    def is_fully_paid(self):
        return self.total_paid >= self.total.gross

    def is_partly_paid(self):
        return self.total_paid_amount > 0

    def get_customer_email(self):
        return self.user.email if self.user else self.user_email

    def update_total_paid(self):
        self.total_paid_amount = (
            sum(self.payments.values_list("captured_amount", flat=True)) or 0
        )
        self.save(update_fields=["total_paid_amount"])

    def _index_billing_phone(self):
        return self.billing_address.phone

    def _index_shipping_phone(self):
        return self.shipping_address.phone

    def __repr__(self):
        return "<Order #%r>" % (self.id,)

    def __str__(self):
        return "#%d" % (self.id,)

    def get_last_payment(self):
        # Skipping a partial payment is a temporary workaround for storing a basic data
        # about partial payment from Adyen plugin. This is something that will removed
        # in 3.1 by introducing a partial payments feature.
        payments = [payment for payment in self.payments.all() if not payment.partial]
        return max(payments, default=None, key=attrgetter("pk"))

    def is_pre_authorized(self):
        return (
            self.payments.filter(
                is_active=True,
                transactions__kind=TransactionKind.AUTH,
                transactions__action_required=False,
            )
            .filter(transactions__is_success=True)
            .exists()
        )

    def is_captured(self):
        return (
            self.payments.filter(
                is_active=True,
                transactions__kind=TransactionKind.CAPTURE,
                transactions__action_required=False,
            )
            .filter(transactions__is_success=True)
            .exists()
        )

    def is_shipping_required(self):
        return any(line.is_shipping_required for line in self.lines.all())

    def get_subtotal(self):
        return get_subtotal(self.lines.all(), self.currency)

    def get_total_quantity(self):
        return sum([line.quantity for line in self.lines.all()])

    def is_draft(self):
        return self.status == OrderStatus.DRAFT

    def is_unconfirmed(self):
        return self.status == OrderStatus.UNCONFIRMED

    def is_open(self):
        statuses = {OrderStatus.UNFULFILLED, OrderStatus.PARTIALLY_FULFILLED}
        return self.status in statuses

    def can_cancel(self):
        statuses_allowed_to_cancel = [
            FulfillmentStatus.CANCELED,
            FulfillmentStatus.REFUNDED,
            FulfillmentStatus.REPLACED,
            FulfillmentStatus.REFUNDED_AND_RETURNED,
            FulfillmentStatus.RETURNED,
        ]
        return (
            not self.fulfillments.exclude(
                status__in=statuses_allowed_to_cancel
            ).exists()
        ) and self.status not in {OrderStatus.CANCELED, OrderStatus.DRAFT}

    def can_capture(self, payment=None):
        if not payment:
            payment = self.get_last_payment()
        if not payment:
            return False
        order_status_ok = self.status not in {OrderStatus.DRAFT, OrderStatus.CANCELED}
        return payment.can_capture() and order_status_ok

    def can_void(self, payment=None):
        if not payment:
            payment = self.get_last_payment()
        if not payment:
            return False
        return payment.can_void()

    def can_refund(self, payment=None):
        if not payment:
            payment = self.get_last_payment()
        if not payment:
            return False
        return payment.can_refund()

    def can_mark_as_paid(self, payments=None):
        if not payments:
            payments = self.payments.all()
        return len(payments) == 0

    @property
    def total_authorized(self):
        return get_total_authorized(self.payments.all(), self.currency)

    @property
    def total_captured(self):
        return self.total_paid

    @property
    def total_balance(self):
        return self.total_captured - self.total.gross

    def get_total_weight(self, *_args):
        return self.weight
def collect_and_write_to_csv(currency_from, currency_to, interval, api_key, file_name):
    # Setup
    url = "https://www.alphavantage.co/query?function=FX_INTRADAY&"
    # url = "https://www.alphavantage.co/query?function=FX_DAILY&"
    url += "from_symbol={}&".format(currency_from)
    url += "to_symbol={}&".format(currency_to)
    url += "interval={}&".format(interval)
    url += "outputsize=full&apikey={}".format(api_key)
    decimal_places = Decimal(10) ** -8

    # Collect
    response = get(url).json()

    # Write to file
    with open(file_name, "w", newline="") as csvfile:
        field_names = ["Timestamp", "Open", "High", "Low", "Close", "Difference", "Stagnated", "Increased", "Decreased", "Trending Up", "Trending Down"]
        writer = DictWriter(csvfile, fieldnames=field_names)
        writer.writeheader()
        timeseries = response["Time Series FX ({})".format(interval)]

        for tick in timeseries.items():
            timestamp = tick[0]
            values = tick[1]
            open_value = Decimal(values["1. open"]).quantize(decimal_places)
            high_value = Decimal(values["2. high"]).quantize(decimal_places)
            low_value = Decimal(values["3. low"]).quantize(decimal_places)
            close_value = Decimal(values["4. close"]).quantize(decimal_places)

            difference = (close_value - open_value).quantize(decimal_places)
            if close_value == open_value:
                difference = 0

            increased = 0
            if close_value > open_value:
                increased = 1

            decreased = 0
            if close_value < open_value:
                decreased = 1

            stagnated = 0
            if (increased + decreased) == 0:
                stagnated = 1

            trend_up = 0
            trend_down = 0
            if determine_trend(open_value, close_value, high_value, low_value):
                trend_up = 1
            else:
                trend_down = 1

            writer.writerow({"Timestamp": timestamp,
                             "Open": open_value,
                             "High": high_value,
                             "Low": low_value,
                             "Close": close_value,
                             "Difference": difference,
                             "Stagnated": stagnated,
                             "Increased": increased,
                             "Decreased": decreased,
                             "Trending Up": trend_up,
                             "Trending Down": trend_down})
Пример #39
0
def satoshis(amount):
    # satoshi conversion must not be performed by the parser
    return int(COIN * Decimal(amount)) if amount not in ['!', None] else amount
Пример #40
0
    def run_test(self):
        # Create and fund a raw tx for sending 10 XUEZ
        psbtx1 = self.nodes[0].walletcreatefundedpsbt([], {self.nodes[2].getnewaddress():10})['psbt']

        # If inputs are specified, do not automatically add more:
        utxo1 = self.nodes[0].listunspent()[0]
        assert_raises_rpc_error(-4, "Insufficient funds", self.nodes[0].walletcreatefundedpsbt, [{"txid": utxo1['txid'], "vout": utxo1['vout']}], {self.nodes[2].getnewaddress():90})

        psbtx1 = self.nodes[0].walletcreatefundedpsbt([{"txid": utxo1['txid'], "vout": utxo1['vout']}], {self.nodes[2].getnewaddress():90}, 0, {"add_inputs": True})['psbt']
        assert_equal(len(self.nodes[0].decodepsbt(psbtx1)['tx']['vin']), 2)

        # Inputs argument can be null
        self.nodes[0].walletcreatefundedpsbt(None, {self.nodes[2].getnewaddress():10})

        # Node 1 should not be able to add anything to it but still return the psbtx same as before
        psbtx = self.nodes[1].walletprocesspsbt(psbtx1)['psbt']
        assert_equal(psbtx1, psbtx)

        # Sign the transaction and send
        signed_tx = self.nodes[0].walletprocesspsbt(psbtx)['psbt']
        final_tx = self.nodes[0].finalizepsbt(signed_tx)['hex']
        self.nodes[0].sendrawtransaction(final_tx)

        # Manually selected inputs can be locked:
        assert_equal(len(self.nodes[0].listlockunspent()), 0)
        utxo1 = self.nodes[0].listunspent()[0]
        psbtx1 = self.nodes[0].walletcreatefundedpsbt([{"txid": utxo1['txid'], "vout": utxo1['vout']}], {self.nodes[2].getnewaddress():1}, 0,{"lockUnspents": True})["psbt"]
        assert_equal(len(self.nodes[0].listlockunspent()), 1)

        # Locks are ignored for manually selected inputs
        self.nodes[0].walletcreatefundedpsbt([{"txid": utxo1['txid'], "vout": utxo1['vout']}], {self.nodes[2].getnewaddress():1}, 0)

        # Create p2sh, p2wpkh, and p2wsh addresses
        pubkey0 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())['pubkey']
        pubkey1 = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress())['pubkey']
        pubkey2 = self.nodes[2].getaddressinfo(self.nodes[2].getnewaddress())['pubkey']

        # Setup watchonly wallets
        self.nodes[2].createwallet(wallet_name='wmulti', disable_private_keys=True)
        wmulti = self.nodes[2].get_wallet_rpc('wmulti')

        # Create all the addresses
        p2sh = wmulti.addmultisigaddress(2, [pubkey0, pubkey1, pubkey2], "", "legacy")['address']
        p2wsh = wmulti.addmultisigaddress(2, [pubkey0, pubkey1, pubkey2], "", "bech32")['address']
        p2sh_p2wsh = wmulti.addmultisigaddress(2, [pubkey0, pubkey1, pubkey2], "", "p2sh-segwit")['address']
        if not self.options.descriptors:
            wmulti.importaddress(p2sh)
            wmulti.importaddress(p2wsh)
            wmulti.importaddress(p2sh_p2wsh)
        p2wpkh = self.nodes[1].getnewaddress("", "bech32")
        p2pkh = self.nodes[1].getnewaddress("", "legacy")
        p2sh_p2wpkh = self.nodes[1].getnewaddress("", "p2sh-segwit")

        # fund those addresses
        rawtx = self.nodes[0].createrawtransaction([], {p2sh:10, p2wsh:10, p2wpkh:10, p2sh_p2wsh:10, p2sh_p2wpkh:10, p2pkh:10})
        rawtx = self.nodes[0].fundrawtransaction(rawtx, {"changePosition":3})
        signed_tx = self.nodes[0].signrawtransactionwithwallet(rawtx['hex'])['hex']
        txid = self.nodes[0].sendrawtransaction(signed_tx)
        self.nodes[0].generate(6)
        self.sync_all()

        # Find the output pos
        p2sh_pos = -1
        p2wsh_pos = -1
        p2wpkh_pos = -1
        p2pkh_pos = -1
        p2sh_p2wsh_pos = -1
        p2sh_p2wpkh_pos = -1
        decoded = self.nodes[0].decoderawtransaction(signed_tx)
        for out in decoded['vout']:
            if out['scriptPubKey']['addresses'][0] == p2sh:
                p2sh_pos = out['n']
            elif out['scriptPubKey']['addresses'][0] == p2wsh:
                p2wsh_pos = out['n']
            elif out['scriptPubKey']['addresses'][0] == p2wpkh:
                p2wpkh_pos = out['n']
            elif out['scriptPubKey']['addresses'][0] == p2sh_p2wsh:
                p2sh_p2wsh_pos = out['n']
            elif out['scriptPubKey']['addresses'][0] == p2sh_p2wpkh:
                p2sh_p2wpkh_pos = out['n']
            elif out['scriptPubKey']['addresses'][0] == p2pkh:
                p2pkh_pos = out['n']

        inputs = [{"txid": txid, "vout": p2wpkh_pos}, {"txid": txid, "vout": p2sh_p2wpkh_pos}, {"txid": txid, "vout": p2pkh_pos}]
        outputs = [{self.nodes[1].getnewaddress(): 29.99}]

        # spend single key from node 1
        created_psbt = self.nodes[1].walletcreatefundedpsbt(inputs, outputs)
        walletprocesspsbt_out = self.nodes[1].walletprocesspsbt(created_psbt['psbt'])
        # Make sure it has both types of UTXOs
        decoded = self.nodes[1].decodepsbt(walletprocesspsbt_out['psbt'])
        assert 'non_witness_utxo' in decoded['inputs'][0]
        assert 'witness_utxo' in decoded['inputs'][0]
        # Check decodepsbt fee calculation (input values shall only be counted once per UTXO)
        assert_equal(decoded['fee'], created_psbt['fee'])
        assert_equal(walletprocesspsbt_out['complete'], True)
        self.nodes[1].sendrawtransaction(self.nodes[1].finalizepsbt(walletprocesspsbt_out['psbt'])['hex'])

        self.log.info("Test walletcreatefundedpsbt fee rate of 10000 sat/vB and 0.1 XUEZ/kvB produces a total fee at or slightly below -maxtxfee (~0.05290000)")
        res1 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": 10000, "add_inputs": True})
        assert_approx(res1["fee"], 0.055, 0.005)
        res2 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": "0.1", "add_inputs": True})
        assert_approx(res2["fee"], 0.055, 0.005)

        self.log.info("Test min fee rate checks with walletcreatefundedpsbt are bypassed, e.g. a fee_rate under 1 sat/vB is allowed")
        res3 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": "0.99999999", "add_inputs": True})
        assert_approx(res3["fee"], 0.00000381, 0.0000001)
        res4 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": 0.00000999, "add_inputs": True})
        assert_approx(res4["fee"], 0.00000381, 0.0000001)

        self.log.info("Test min fee rate checks with walletcreatefundedpsbt are bypassed and that funding non-standard 'zero-fee' transactions is valid")
        for param in ["fee_rate", "feeRate"]:
            assert_equal(self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {param: 0, "add_inputs": True})["fee"], 0)

        self.log.info("Test invalid fee rate settings")
        for param, value in {("fee_rate", 100000), ("feeRate", 1)}:
            assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
                self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: value, "add_inputs": True})
            assert_raises_rpc_error(-3, "Amount out of range",
                self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: -1, "add_inputs": True})
            assert_raises_rpc_error(-3, "Amount is not a number or string",
                self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: {"foo": "bar"}, "add_inputs": True})
            assert_raises_rpc_error(-3, "Invalid amount",
                self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: "", "add_inputs": True})

        self.log.info("- raises RPC error if both feeRate and fee_rate are passed")
        assert_raises_rpc_error(-8, "Cannot specify both fee_rate (sat/vB) and feeRate (XUEZ/kvB)",
            self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": 0.1, "feeRate": 0.1, "add_inputs": True})

        self.log.info("- raises RPC error if both feeRate and estimate_mode passed")
        assert_raises_rpc_error(-8, "Cannot specify both estimate_mode and feeRate",
            self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"estimate_mode": "economical", "feeRate": 0.1, "add_inputs": True})

        for param in ["feeRate", "fee_rate"]:
            self.log.info("- raises RPC error if both {} and conf_target are passed".format(param))
            assert_raises_rpc_error(-8, "Cannot specify both conf_target and {}. Please provide either a confirmation "
                "target in blocks for automatic fee estimation, or an explicit fee rate.".format(param),
                self.nodes[1].walletcreatefundedpsbt ,inputs, outputs, 0, {param: 1, "conf_target": 1, "add_inputs": True})

        self.log.info("- raises RPC error if both fee_rate and estimate_mode are passed")
        assert_raises_rpc_error(-8, "Cannot specify both estimate_mode and fee_rate",
            self.nodes[1].walletcreatefundedpsbt ,inputs, outputs, 0, {"fee_rate": 1, "estimate_mode": "economical", "add_inputs": True})

        self.log.info("- raises RPC error with invalid estimate_mode settings")
        for k, v in {"number": 42, "object": {"foo": "bar"}}.items():
            assert_raises_rpc_error(-3, "Expected type string for estimate_mode, got {}".format(k),
                self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"estimate_mode": v, "conf_target": 0.1, "add_inputs": True})
        for mode in ["", "foo", Decimal("3.141592")]:
            assert_raises_rpc_error(-8, 'Invalid estimate_mode parameter, must be one of: "unset", "economical", "conservative"',
                self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"estimate_mode": mode, "conf_target": 0.1, "add_inputs": True})

        self.log.info("- raises RPC error with invalid conf_target settings")
        for mode in ["unset", "economical", "conservative"]:
            self.log.debug("{}".format(mode))
            for k, v in {"string": "", "object": {"foo": "bar"}}.items():
                assert_raises_rpc_error(-3, "Expected type number for conf_target, got {}".format(k),
                    self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"estimate_mode": mode, "conf_target": v, "add_inputs": True})
            for n in [-1, 0, 1009]:
                assert_raises_rpc_error(-8, "Invalid conf_target, must be between 1 and 1008",  # max value of 1008 per src/policy/fees.h
                    self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"estimate_mode": mode, "conf_target": n, "add_inputs": True})

        self.log.info("Test walletcreatefundedpsbt with too-high fee rate produces total fee well above -maxtxfee and raises RPC error")
        # previously this was silently capped at -maxtxfee
        for bool_add, outputs_array in {True: outputs, False: [{self.nodes[1].getnewaddress(): 1}]}.items():
            msg = "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)"
            assert_raises_rpc_error(-4, msg, self.nodes[1].walletcreatefundedpsbt, inputs, outputs_array, 0, {"fee_rate": 1000000, "add_inputs": bool_add})
            assert_raises_rpc_error(-4, msg, self.nodes[1].walletcreatefundedpsbt, inputs, outputs_array, 0, {"feeRate": 1, "add_inputs": bool_add})

        self.log.info("Test various PSBT operations")
        # partially sign multisig things with node 1
        psbtx = wmulti.walletcreatefundedpsbt(inputs=[{"txid":txid,"vout":p2wsh_pos},{"txid":txid,"vout":p2sh_pos},{"txid":txid,"vout":p2sh_p2wsh_pos}], outputs={self.nodes[1].getnewaddress():29.99}, options={'changeAddress': self.nodes[1].getrawchangeaddress()})['psbt']
        walletprocesspsbt_out = self.nodes[1].walletprocesspsbt(psbtx)
        psbtx = walletprocesspsbt_out['psbt']
        assert_equal(walletprocesspsbt_out['complete'], False)

        # Unload wmulti, we don't need it anymore
        wmulti.unloadwallet()

        # partially sign with node 2. This should be complete and sendable
        walletprocesspsbt_out = self.nodes[2].walletprocesspsbt(psbtx)
        assert_equal(walletprocesspsbt_out['complete'], True)
        self.nodes[2].sendrawtransaction(self.nodes[2].finalizepsbt(walletprocesspsbt_out['psbt'])['hex'])

        # check that walletprocesspsbt fails to decode a non-psbt
        rawtx = self.nodes[1].createrawtransaction([{"txid":txid,"vout":p2wpkh_pos}], {self.nodes[1].getnewaddress():9.99})
        assert_raises_rpc_error(-22, "TX decode failed", self.nodes[1].walletprocesspsbt, rawtx)

        # Convert a non-psbt to psbt and make sure we can decode it
        rawtx = self.nodes[0].createrawtransaction([], {self.nodes[1].getnewaddress():10})
        rawtx = self.nodes[0].fundrawtransaction(rawtx)
        new_psbt = self.nodes[0].converttopsbt(rawtx['hex'])
        self.nodes[0].decodepsbt(new_psbt)

        # Make sure that a non-psbt with signatures cannot be converted
        # Error could be either "TX decode failed" (segwit inputs causes parsing to fail) or "Inputs must not have scriptSigs and scriptWitnesses"
        # We must set iswitness=True because the serialized transaction has inputs and is therefore a witness transaction
        signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx['hex'])
        assert_raises_rpc_error(-22, "", self.nodes[0].converttopsbt, hexstring=signedtx['hex'], iswitness=True)
        assert_raises_rpc_error(-22, "", self.nodes[0].converttopsbt, hexstring=signedtx['hex'], permitsigdata=False, iswitness=True)
        # Unless we allow it to convert and strip signatures
        self.nodes[0].converttopsbt(signedtx['hex'], True)

        # Explicitly allow converting non-empty txs
        new_psbt = self.nodes[0].converttopsbt(rawtx['hex'])
        self.nodes[0].decodepsbt(new_psbt)

        # Create outputs to nodes 1 and 2
        node1_addr = self.nodes[1].getnewaddress()
        node2_addr = self.nodes[2].getnewaddress()
        txid1 = self.nodes[0].sendtoaddress(node1_addr, 13)
        txid2 = self.nodes[0].sendtoaddress(node2_addr, 13)
        blockhash = self.nodes[0].generate(6)[0]
        self.sync_all()
        vout1 = find_output(self.nodes[1], txid1, 13, blockhash=blockhash)
        vout2 = find_output(self.nodes[2], txid2, 13, blockhash=blockhash)

        # Create a psbt spending outputs from nodes 1 and 2
        psbt_orig = self.nodes[0].createpsbt([{"txid":txid1,  "vout":vout1}, {"txid":txid2, "vout":vout2}], {self.nodes[0].getnewaddress():25.999})

        # Update psbts, should only have data for one input and not the other
        psbt1 = self.nodes[1].walletprocesspsbt(psbt_orig, False, "ALL")['psbt']
        psbt1_decoded = self.nodes[0].decodepsbt(psbt1)
        assert psbt1_decoded['inputs'][0] and not psbt1_decoded['inputs'][1]
        # Check that BIP32 path was added
        assert "bip32_derivs" in psbt1_decoded['inputs'][0]
        psbt2 = self.nodes[2].walletprocesspsbt(psbt_orig, False, "ALL", False)['psbt']
        psbt2_decoded = self.nodes[0].decodepsbt(psbt2)
        assert not psbt2_decoded['inputs'][0] and psbt2_decoded['inputs'][1]
        # Check that BIP32 paths were not added
        assert "bip32_derivs" not in psbt2_decoded['inputs'][1]

        # Sign PSBTs (workaround issue #18039)
        psbt1 = self.nodes[1].walletprocesspsbt(psbt_orig)['psbt']
        psbt2 = self.nodes[2].walletprocesspsbt(psbt_orig)['psbt']

        # Combine, finalize, and send the psbts
        combined = self.nodes[0].combinepsbt([psbt1, psbt2])
        finalized = self.nodes[0].finalizepsbt(combined)['hex']
        self.nodes[0].sendrawtransaction(finalized)
        self.nodes[0].generate(6)
        self.sync_all()

        # Test additional args in walletcreatepsbt
        # Make sure both pre-included and funded inputs
        # have the correct sequence numbers based on
        # replaceable arg
        block_height = self.nodes[0].getblockcount()
        unspent = self.nodes[0].listunspent()[0]
        psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], block_height+2, {"replaceable": False, "add_inputs": True}, False)
        decoded_psbt = self.nodes[0].decodepsbt(psbtx_info["psbt"])
        for tx_in, psbt_in in zip(decoded_psbt["tx"]["vin"], decoded_psbt["inputs"]):
            assert_greater_than(tx_in["sequence"], MAX_BIP125_RBF_SEQUENCE)
            assert "bip32_derivs" not in psbt_in
        assert_equal(decoded_psbt["tx"]["locktime"], block_height+2)

        # Same construction with only locktime set and RBF explicitly enabled
        psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], block_height, {"replaceable": True, "add_inputs": True}, True)
        decoded_psbt = self.nodes[0].decodepsbt(psbtx_info["psbt"])
        for tx_in, psbt_in in zip(decoded_psbt["tx"]["vin"], decoded_psbt["inputs"]):
            assert_equal(tx_in["sequence"], MAX_BIP125_RBF_SEQUENCE)
            assert "bip32_derivs" in psbt_in
        assert_equal(decoded_psbt["tx"]["locktime"], block_height)

        # Same construction without optional arguments
        psbtx_info = self.nodes[0].walletcreatefundedpsbt([], [{self.nodes[2].getnewaddress():unspent["amount"]+1}])
        decoded_psbt = self.nodes[0].decodepsbt(psbtx_info["psbt"])
        for tx_in, psbt_in in zip(decoded_psbt["tx"]["vin"], decoded_psbt["inputs"]):
            assert_equal(tx_in["sequence"], MAX_BIP125_RBF_SEQUENCE)
            assert "bip32_derivs" in psbt_in
        assert_equal(decoded_psbt["tx"]["locktime"], 0)

        # Same construction without optional arguments, for a node with -walletrbf=0
        unspent1 = self.nodes[1].listunspent()[0]
        psbtx_info = self.nodes[1].walletcreatefundedpsbt([{"txid":unspent1["txid"], "vout":unspent1["vout"]}], [{self.nodes[2].getnewaddress():unspent1["amount"]+1}], block_height, {"add_inputs": True})
        decoded_psbt = self.nodes[1].decodepsbt(psbtx_info["psbt"])
        for tx_in, psbt_in in zip(decoded_psbt["tx"]["vin"], decoded_psbt["inputs"]):
            assert_greater_than(tx_in["sequence"], MAX_BIP125_RBF_SEQUENCE)
            assert "bip32_derivs" in psbt_in

        # Make sure change address wallet does not have P2SH innerscript access to results in success
        # when attempting BnB coin selection
        self.nodes[0].walletcreatefundedpsbt([], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], block_height+2, {"changeAddress":self.nodes[1].getnewaddress()}, False)

        # Make sure the wallet's change type is respected by default
        small_output = {self.nodes[0].getnewaddress():0.1}
        psbtx_native = self.nodes[0].walletcreatefundedpsbt([], [small_output])
        self.assert_change_type(psbtx_native, "witness_v0_keyhash")
        psbtx_legacy = self.nodes[1].walletcreatefundedpsbt([], [small_output])
        self.assert_change_type(psbtx_legacy, "pubkeyhash")

        # Make sure the change type of the wallet can also be overwritten
        psbtx_np2wkh = self.nodes[1].walletcreatefundedpsbt([], [small_output], 0, {"change_type":"p2sh-segwit"})
        self.assert_change_type(psbtx_np2wkh, "scripthash")

        # Make sure the change type cannot be specified if a change address is given
        invalid_options = {"change_type":"legacy","changeAddress":self.nodes[0].getnewaddress()}
        assert_raises_rpc_error(-8, "both change address and address type options", self.nodes[0].walletcreatefundedpsbt, [], [small_output], 0, invalid_options)

        # Regression test for 14473 (mishandling of already-signed witness transaction):
        psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], 0, {"add_inputs": True})
        complete_psbt = self.nodes[0].walletprocesspsbt(psbtx_info["psbt"])
        double_processed_psbt = self.nodes[0].walletprocesspsbt(complete_psbt["psbt"])
        assert_equal(complete_psbt, double_processed_psbt)
        # We don't care about the decode result, but decoding must succeed.
        self.nodes[0].decodepsbt(double_processed_psbt["psbt"])

        # BIP 174 Test Vectors

        # Check that unknown values are just passed through
        unknown_psbt = "cHNidP8BAD8CAAAAAf//////////////////////////////////////////AAAAAAD/////AQAAAAAAAAAAA2oBAAAAAAAACg8BAgMEBQYHCAkPAQIDBAUGBwgJCgsMDQ4PAAA="
        unknown_out = self.nodes[0].walletprocesspsbt(unknown_psbt)['psbt']
        assert_equal(unknown_psbt, unknown_out)

        # Open the data file
        with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/rpc_psbt.json'), encoding='utf-8') as f:
            d = json.load(f)
            invalids = d['invalid']
            valids = d['valid']
            creators = d['creator']
            signers = d['signer']
            combiners = d['combiner']
            finalizers = d['finalizer']
            extractors = d['extractor']

        # Invalid PSBTs
        for invalid in invalids:
            assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].decodepsbt, invalid)

        # Valid PSBTs
        for valid in valids:
            self.nodes[0].decodepsbt(valid)

        # Creator Tests
        for creator in creators:
            created_tx = self.nodes[0].createpsbt(creator['inputs'], creator['outputs'])
            assert_equal(created_tx, creator['result'])

        # Signer tests
        for i, signer in enumerate(signers):
            self.nodes[2].createwallet(wallet_name="wallet{}".format(i))
            wrpc = self.nodes[2].get_wallet_rpc("wallet{}".format(i))
            for key in signer['privkeys']:
                wrpc.importprivkey(key)
            signed_tx = wrpc.walletprocesspsbt(signer['psbt'])['psbt']
            assert_equal(signed_tx, signer['result'])

        # Combiner test
        for combiner in combiners:
            combined = self.nodes[2].combinepsbt(combiner['combine'])
            assert_equal(combined, combiner['result'])

        # Empty combiner test
        assert_raises_rpc_error(-8, "Parameter 'txs' cannot be empty", self.nodes[0].combinepsbt, [])

        # Finalizer test
        for finalizer in finalizers:
            finalized = self.nodes[2].finalizepsbt(finalizer['finalize'], False)['psbt']
            assert_equal(finalized, finalizer['result'])

        # Extractor test
        for extractor in extractors:
            extracted = self.nodes[2].finalizepsbt(extractor['extract'], True)['hex']
            assert_equal(extracted, extractor['result'])

        # Unload extra wallets
        for i, signer in enumerate(signers):
            self.nodes[2].unloadwallet("wallet{}".format(i))

        # TODO: Re-enable this for segwit v1
        # self.test_utxo_conversion()

        # Test that psbts with p2pkh outputs are created properly
        p2pkh = self.nodes[0].getnewaddress(address_type='legacy')
        psbt = self.nodes[1].walletcreatefundedpsbt([], [{p2pkh : 1}], 0, {"includeWatching" : True}, True)
        self.nodes[0].decodepsbt(psbt['psbt'])

        # Test decoding error: invalid base64
        assert_raises_rpc_error(-22, "TX decode failed invalid base64", self.nodes[0].decodepsbt, ";definitely not base64;")

        # Send to all types of addresses
        addr1 = self.nodes[1].getnewaddress("", "bech32")
        txid1 = self.nodes[0].sendtoaddress(addr1, 11)
        vout1 = find_output(self.nodes[0], txid1, 11)
        addr2 = self.nodes[1].getnewaddress("", "legacy")
        txid2 = self.nodes[0].sendtoaddress(addr2, 11)
        vout2 = find_output(self.nodes[0], txid2, 11)
        addr3 = self.nodes[1].getnewaddress("", "p2sh-segwit")
        txid3 = self.nodes[0].sendtoaddress(addr3, 11)
        vout3 = find_output(self.nodes[0], txid3, 11)
        self.sync_all()

        def test_psbt_input_keys(psbt_input, keys):
            """Check that the psbt input has only the expected keys."""
            assert_equal(set(keys), set(psbt_input.keys()))

        # Create a PSBT. None of the inputs are filled initially
        psbt = self.nodes[1].createpsbt([{"txid":txid1, "vout":vout1},{"txid":txid2, "vout":vout2},{"txid":txid3, "vout":vout3}], {self.nodes[0].getnewaddress():32.999})
        decoded = self.nodes[1].decodepsbt(psbt)
        test_psbt_input_keys(decoded['inputs'][0], [])
        test_psbt_input_keys(decoded['inputs'][1], [])
        test_psbt_input_keys(decoded['inputs'][2], [])

        # Update a PSBT with UTXOs from the node
        # Bech32 inputs should be filled with witness UTXO. Other inputs should not be filled because they are non-witness
        updated = self.nodes[1].utxoupdatepsbt(psbt)
        decoded = self.nodes[1].decodepsbt(updated)
        test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo'])
        test_psbt_input_keys(decoded['inputs'][1], [])
        test_psbt_input_keys(decoded['inputs'][2], [])

        # Try again, now while providing descriptors, making P2SH-segwit work, and causing bip32_derivs and redeem_script to be filled in
        descs = [self.nodes[1].getaddressinfo(addr)['desc'] for addr in [addr1,addr2,addr3]]
        updated = self.nodes[1].utxoupdatepsbt(psbt=psbt, descriptors=descs)
        decoded = self.nodes[1].decodepsbt(updated)
        test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'bip32_derivs'])
        test_psbt_input_keys(decoded['inputs'][1], [])
        test_psbt_input_keys(decoded['inputs'][2], ['witness_utxo', 'bip32_derivs', 'redeem_script'])

        # Two PSBTs with a common input should not be joinable
        psbt1 = self.nodes[1].createpsbt([{"txid":txid1, "vout":vout1}], {self.nodes[0].getnewaddress():Decimal('10.999')})
        assert_raises_rpc_error(-8, "exists in multiple PSBTs", self.nodes[1].joinpsbts, [psbt1, updated])

        # Join two distinct PSBTs
        addr4 = self.nodes[1].getnewaddress("", "p2sh-segwit")
        txid4 = self.nodes[0].sendtoaddress(addr4, 5)
        vout4 = find_output(self.nodes[0], txid4, 5)
        self.nodes[0].generate(6)
        self.sync_all()
        psbt2 = self.nodes[1].createpsbt([{"txid":txid4, "vout":vout4}], {self.nodes[0].getnewaddress():Decimal('4.999')})
        psbt2 = self.nodes[1].walletprocesspsbt(psbt2)['psbt']
        psbt2_decoded = self.nodes[0].decodepsbt(psbt2)
        assert "final_scriptwitness" in psbt2_decoded['inputs'][0] and "final_scriptSig" in psbt2_decoded['inputs'][0]
        joined = self.nodes[0].joinpsbts([psbt, psbt2])
        joined_decoded = self.nodes[0].decodepsbt(joined)
        assert len(joined_decoded['inputs']) == 4 and len(joined_decoded['outputs']) == 2 and "final_scriptwitness" not in joined_decoded['inputs'][3] and "final_scriptSig" not in joined_decoded['inputs'][3]

        # Check that joining shuffles the inputs and outputs
        # 10 attempts should be enough to get a shuffled join
        shuffled = False
        for _ in range(10):
            shuffled_joined = self.nodes[0].joinpsbts([psbt, psbt2])
            shuffled |= joined != shuffled_joined
            if shuffled:
                break
        assert shuffled

        # Newly created PSBT needs UTXOs and updating
        addr = self.nodes[1].getnewaddress("", "p2sh-segwit")
        txid = self.nodes[0].sendtoaddress(addr, 7)
        addrinfo = self.nodes[1].getaddressinfo(addr)
        blockhash = self.nodes[0].generate(6)[0]
        self.sync_all()
        vout = find_output(self.nodes[0], txid, 7, blockhash=blockhash)
        psbt = self.nodes[1].createpsbt([{"txid":txid, "vout":vout}], {self.nodes[0].getnewaddress("", "p2sh-segwit"):Decimal('6.999')})
        analyzed = self.nodes[0].analyzepsbt(psbt)
        assert not analyzed['inputs'][0]['has_utxo'] and not analyzed['inputs'][0]['is_final'] and analyzed['inputs'][0]['next'] == 'updater' and analyzed['next'] == 'updater'

        # After update with wallet, only needs signing
        updated = self.nodes[1].walletprocesspsbt(psbt, False, 'ALL', True)['psbt']
        analyzed = self.nodes[0].analyzepsbt(updated)
        assert analyzed['inputs'][0]['has_utxo'] and not analyzed['inputs'][0]['is_final'] and analyzed['inputs'][0]['next'] == 'signer' and analyzed['next'] == 'signer' and analyzed['inputs'][0]['missing']['signatures'][0] == addrinfo['embedded']['witness_program']

        # Check fee and size things
        assert analyzed['fee'] == Decimal('0.001') and analyzed['estimated_vsize'] == 134 and analyzed['estimated_feerate'] == Decimal('0.00746268')

        # After signing and finalizing, needs extracting
        signed = self.nodes[1].walletprocesspsbt(updated)['psbt']
        analyzed = self.nodes[0].analyzepsbt(signed)
        assert analyzed['inputs'][0]['has_utxo'] and analyzed['inputs'][0]['is_final'] and analyzed['next'] == 'extractor'

        self.log.info("PSBT spending unspendable outputs should have error message and Creator as next")
        analysis = self.nodes[0].analyzepsbt('cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWAEHYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFv8/wADXYP/7//////8JxOh0LR2HAI8AAAAAAAEBIADC6wsAAAAAF2oUt/X69ELjeX2nTof+fZ10l+OyAokDAQcJAwEHEAABAACAAAEBIADC6wsAAAAAF2oUt/X69ELjeX2nTof+fZ10l+OyAokDAQcJAwEHENkMak8AAAAA')
        assert_equal(analysis['next'], 'creator')
        assert_equal(analysis['error'], 'PSBT is not valid. Input 0 spends unspendable output')

        self.log.info("PSBT with invalid values should have error message and Creator as next")
        analysis = self.nodes[0].analyzepsbt('cHNidP8BAHECAAAAAfA00BFgAm6tp86RowwH6BMImQNL5zXUcTT97XoLGz0BAAAAAAD/////AgD5ApUAAAAAFgAUKNw0x8HRctAgmvoevm4u1SbN7XL87QKVAAAAABYAFPck4gF7iL4NL4wtfRAKgQbghiTUAAAAAAABAR8AgIFq49AHABYAFJUDtxf2PHo641HEOBOAIvFMNTr2AAAA')
        assert_equal(analysis['next'], 'creator')
        assert_equal(analysis['error'], 'PSBT is not valid. Input 0 has invalid value')

        self.log.info("PSBT with signed, but not finalized, inputs should have Finalizer as next")
        analysis = self.nodes[0].analyzepsbt('cHNidP8BAHECAAAAAZYezcxdnbXoQCmrD79t/LzDgtUo9ERqixk8wgioAobrAAAAAAD9////AlDDAAAAAAAAFgAUy/UxxZuzZswcmFnN/E9DGSiHLUsuGPUFAAAAABYAFLsH5o0R38wXx+X2cCosTMCZnQ4baAAAAAABAR8A4fUFAAAAABYAFOBI2h5thf3+Lflb2LGCsVSZwsltIgIC/i4dtVARCRWtROG0HHoGcaVklzJUcwo5homgGkSNAnJHMEQCIGx7zKcMIGr7cEES9BR4Kdt/pzPTK3fKWcGyCJXb7MVnAiALOBgqlMH4GbC1HDh/HmylmO54fyEy4lKde7/BT/PWxwEBAwQBAAAAIgYC/i4dtVARCRWtROG0HHoGcaVklzJUcwo5homgGkSNAnIYDwVpQ1QAAIABAACAAAAAgAAAAAAAAAAAAAAiAgL+CIiB59NSCssOJRGiMYQK1chahgAaaJpIXE41Cyir+xgPBWlDVAAAgAEAAIAAAACAAQAAAAAAAAAA')
        assert_equal(analysis['next'], 'finalizer')

        analysis = self.nodes[0].analyzepsbt('cHNidP8BAHECAAAAAfA00BFgAm6tp86RowwH6BMImQNL5zXUcTT97XoLGz0BAAAAAAD/////AgCAgWrj0AcAFgAUKNw0x8HRctAgmvoevm4u1SbN7XL87QKVAAAAABYAFPck4gF7iL4NL4wtfRAKgQbghiTUAAAAAAABAR8A8gUqAQAAABYAFJUDtxf2PHo641HEOBOAIvFMNTr2AAAA')
        assert_equal(analysis['next'], 'creator')
        assert_equal(analysis['error'], 'PSBT is not valid. Output amount invalid')

        analysis = self.nodes[0].analyzepsbt('cHNidP8BAJoCAAAAAkvEW8NnDtdNtDpsmze+Ht2LH35IJcKv00jKAlUs21RrAwAAAAD/////S8Rbw2cO1020OmybN74e3Ysffkglwq/TSMoCVSzbVGsBAAAAAP7///8CwLYClQAAAAAWABSNJKzjaUb3uOxixsvh1GGE3fW7zQD5ApUAAAAAFgAUKNw0x8HRctAgmvoevm4u1SbN7XIAAAAAAAEAnQIAAAACczMa321tVHuN4GKWKRncycI22aX3uXgwSFUKM2orjRsBAAAAAP7///9zMxrfbW1Ue43gYpYpGdzJwjbZpfe5eDBIVQozaiuNGwAAAAAA/v///wIA+QKVAAAAABl2qRT9zXUVA8Ls5iVqynLHe5/vSe1XyYisQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAAAAAQEfQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAA==')
        assert_equal(analysis['next'], 'creator')
        assert_equal(analysis['error'], 'PSBT is not valid. Input 0 specifies invalid prevout')

        assert_raises_rpc_error(-25, 'Inputs missing or spent', self.nodes[0].walletprocesspsbt, 'cHNidP8BAJoCAAAAAkvEW8NnDtdNtDpsmze+Ht2LH35IJcKv00jKAlUs21RrAwAAAAD/////S8Rbw2cO1020OmybN74e3Ysffkglwq/TSMoCVSzbVGsBAAAAAP7///8CwLYClQAAAAAWABSNJKzjaUb3uOxixsvh1GGE3fW7zQD5ApUAAAAAFgAUKNw0x8HRctAgmvoevm4u1SbN7XIAAAAAAAEAnQIAAAACczMa321tVHuN4GKWKRncycI22aX3uXgwSFUKM2orjRsBAAAAAP7///9zMxrfbW1Ue43gYpYpGdzJwjbZpfe5eDBIVQozaiuNGwAAAAAA/v///wIA+QKVAAAAABl2qRT9zXUVA8Ls5iVqynLHe5/vSe1XyYisQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAAAAAQEfQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAA==')
Пример #41
0
def extract_price2uk(number):
    """
    Extracts price from string.
    Formats number in UK format without commas.
    Accepts string with any characters.
    Filters them and returns number in UK format
    >>> extract_price2uk("123,45")
    Decimal('123.45')
    >>> extract_price2uk('1.233,45')
    Decimal('1233.45')
    >>> extract_price2uk('1,233.45')
    Decimal('1233.45')
    """
    if type(number) == unicode:
        number = number.encode('ascii', 'ignore')
    number = re.sub('\s+', '', number)
    m = re.search(r'[\d][\d,.]*[\d]*', number, re.UNICODE)
    if m is None:
        return Decimal(0)
    number = m.group(0)
    # check if number in UK format
    m = re.search(r'^([\d,]+\.{1}[\d]{1,2})$', number, re.UNICODE)
    if not m is None:
        number = m.group(1)
        if number is None:
            number = m.group(2)
        number = number.replace(",", "")
        try:
            return Decimal(number.replace(',', ''))
        except (ValueError, InvalidOperation):
            return Decimal(0)

    # UK format without decimal part
    m = re.search(r'^([\d,]*,[\d]{3})$', number, re.UNICODE)
    if not m is None:
        number = m.group(1)
        if number is None:
            number = m.group(2)
        number = number.replace(",", "")
        try:
            return Decimal(number.replace(',', ''))
        except (ValueError, InvalidOperation):
            return Decimal(0)

    # standard format
    m = re.search(r'^([\d\.\s]+,{1}[\d]{1,2})$', number, re.UNICODE)
    if not m is None:
        number = m.group(1)
        if number is None:
            number = m.group(2)
        number = number.replace(".", "")
        number = number.replace(",", ".")
        try:
            return Decimal(number.replace(',', ''))
        except (ValueError, InvalidOperation):
            return Decimal(0)

    # standard without decimal part
    m = re.search(r'^([\d.\s]*\.[\d]{3})$', number, re.UNICODE)
    if not m is None:
        number = m.group(1)
        if number is None:
            number = m.group(2)
        number = number.replace(".", "")
        number = number.replace(",", ".")
        try:
            return Decimal(number.replace(',', ''))
        except (ValueError, InvalidOperation):
            return Decimal(0)

    # without comma/period
    m = re.search(r'([\d\s]+)', number, re.UNICODE)
    if not m is None:
        number = m.group(0)
        number = number.replace(".", "")
        number = number.replace(",", ".")
        try:
            return Decimal(number.replace(',', ''))
        except (ValueError, InvalidOperation):
            return Decimal(0)

    return Decimal(0)
Пример #42
0
    def test_map_decimal(self, string_series):
        from decimal import Decimal

        result = string_series.map(lambda x: Decimal(str(x)))
        assert result.dtype == np.object_
        assert isinstance(result[0], Decimal)
Пример #43
0
def satoshi_round(amount):
    return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
Пример #44
0
    'domain': ("-D", "List of addresses"),
    'memo': ("-m", "Description of the request"),
    'expiration': (None, "Time in seconds"),
    'timeout': (None, "Timeout in seconds"),
    'force':
    (None,
     "Create new address beyond gap limit, if no more addresses are available."
     ),
    'pending': (None, "Show only pending requests."),
    'expired': (None, "Show only expired requests."),
    'paid': (None, "Show only paid requests."),
}

# don't use floats because of rounding errors
from .transaction import tx_from_str
json_loads = lambda x: json.loads(x, parse_float=lambda x: str(Decimal(x)))
arg_types = {
    'num': int,
    'nbits': int,
    'imax': int,
    'tx': tx_from_str,
    'pubkeys': json_loads,
    'jsontx': json_loads,
    'inputs': json_loads,
    'outputs': json_loads,
    'fee': lambda x: str(Decimal(x)) if x is not None else None,
    'amount': lambda x: str(Decimal(x)) if x != '!' else '!',
    'locktime': int,
}

config_variables = {
Пример #45
0
 def times_scalar(self, c):
     new_coordinate = [Decimal(c) * x for x in self.coordinates]
     return Vector(new_coordinate)
Пример #46
0
    expected_comprehension="a",
    expected_types={},
)

CASE_LIST_INT = TypeExpressionTest(
    type_expression=List[int],
    serialized_data=[1, 2, 3, 4],
    expected_result=[1, 2, 3, 4],
    expected_comprehension="[b for b in a]",
    expected_types={},
)

CASE_LIST_DECIMAL = TypeExpressionTest(
    type_expression=List[Decimal],
    serialized_data=[
        str(Decimal("1.12")),
        str(Decimal("2.23")),
        str(Decimal("3.34")),
        str(Decimal("4.45")),
    ],
    expected_result=[
        Decimal("1.12"),
        Decimal("2.23"),
        Decimal("3.34"),
        Decimal("4.45"),
    ],
    expected_comprehension="[_Decimal_(b) for b in a]",
    expected_types={NodeType.DECIMAL: {Decimal}},
)

CASE_MAPPING_KEY_DATETIME_VALUE_OPTIONAL_LIST_DATETIME = TypeExpressionTest(
Пример #47
0
def parse_coinbase(data_row, parser, fiat_values):
    (spot_price_ccy, subtotal, total_ccy, fees) = fiat_values
    row_dict = data_row.row_dict

    if row_dict['Transaction Type'] == "Receive":
        if "Coinbase Referral" in row_dict['Notes']:
            # We can calculate the exact buy_value from the spot price
            data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_GIFT_RECEIVED,
                                 data_row.timestamp,
                                 buy_quantity=row_dict['Quantity Transacted'],
                                 buy_asset=row_dict['Asset'],
                                 buy_value=spot_price_ccy * \
                                           Decimal(row_dict['Quantity Transacted']),
                                 wallet=WALLET)
        else:
            data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_DEPOSIT,
                                                     data_row.timestamp,
                                                     buy_quantity=row_dict['Quantity Transacted'],
                                                     buy_asset=row_dict['Asset'],
                                                     wallet=WALLET)
    elif row_dict['Transaction Type'] in ("Coinbase Earn", "Rewards Income"):
        data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_INCOME,
                                                 data_row.timestamp,
                                                 buy_quantity=row_dict['Quantity Transacted'],
                                                 buy_asset=row_dict['Asset'],
                                                 buy_value=total_ccy,
                                                 wallet=WALLET)
    elif row_dict['Transaction Type'] == "Send":
        data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_WITHDRAWAL,
                                                 data_row.timestamp,
                                                 sell_quantity=row_dict['Quantity Transacted'],
                                                 sell_asset=row_dict['Asset'],
                                                 wallet=WALLET)
    elif row_dict['Transaction Type'] == "Buy":
        currency = get_currency(row_dict['Notes'])
        if currency is None:
            raise UnexpectedContentError(parser.in_header.index('Notes'), 'Notes',
                                         row_dict['Notes'])

        if config.coinbase_zero_fees_are_gifts and Decimal(fees) == 0:
            # Zero fees "may" indicate an early referral reward, or airdrop
            data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_GIFT_RECEIVED,
                                                     data_row.timestamp,
                                                     buy_quantity=row_dict['Quantity Transacted'],
                                                     buy_asset=row_dict['Asset'],
                                                     buy_value=total_ccy if total_ccy > 0 else None,
                                                     wallet=WALLET)
        else:
            data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_TRADE,
                                                     data_row.timestamp,
                                                     buy_quantity=row_dict['Quantity Transacted'],
                                                     buy_asset=row_dict['Asset'],
                                                     sell_quantity=subtotal,
                                                     sell_asset=currency,
                                                     fee_quantity=fees,
                                                     fee_asset=currency,
                                                     wallet=WALLET)
    elif row_dict['Transaction Type'] == "Sell":
        currency = get_currency(row_dict['Notes'])
        if currency is None:
            raise UnexpectedContentError(parser.in_header.index('Notes'), 'Notes',
                                         row_dict['Notes'])

        data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_TRADE,
                                                 data_row.timestamp,
                                                 buy_quantity=subtotal,
                                                 buy_asset=currency,
                                                 sell_quantity=row_dict['Quantity Transacted'],
                                                 sell_asset=row_dict['Asset'],
                                                 fee_quantity=fees,
                                                 fee_asset=currency,
                                                 wallet=WALLET)
    elif row_dict['Transaction Type'] == "Convert":
        convert_info = get_convert_info(row_dict['Notes'])
        if convert_info is None:
            raise UnexpectedContentError(parser.in_header.index('Notes'), 'Notes',
                                         row_dict['Notes'])

        buy_quantity = convert_info[2]
        buy_asset = convert_info[3]
        data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_TRADE,
                                                 data_row.timestamp,
                                                 buy_quantity=buy_quantity,
                                                 buy_asset=buy_asset,
                                                 buy_value=total_ccy,
                                                 sell_quantity=row_dict['Quantity Transacted'],
                                                 sell_asset=row_dict['Asset'],
                                                 sell_value=total_ccy,
                                                 wallet=WALLET)

    else:
        raise UnexpectedTypeError(parser.in_header.index('Transaction Type'), 'Transaction Type',
                                  row_dict['Transaction Type'])
Пример #48
0
def check_json_precision():
    """Make sure json library being used does not lose precision converting BTC values"""
    n = Decimal("20000000.00000003")
    satoshis = int(json.loads(json.dumps(float(n))) * 1.0e8)
    if satoshis != 2000000000000003:
        raise RuntimeError("JSON encode/decode loses precision")
Пример #49
0

first_unspent = rpc_connection.listunspent(0)[-1]

print(first_unspent)

address = first_unspent.get("address")
scriptPubKey = first_unspent.get("scriptPubKey")
redeemScript = first_unspent.get("redeemScript")
txid = first_unspent.get("txid")
vout = first_unspent.get("vout")

print(txid)
print(vout)

first_unspent_amount = Decimal(first_unspent.get("amount"))

print(first_unspent_amount)
raw_change_address = rpc_connection.getrawchangeaddress()
new_bitcoin_address = rpc_connection.getnewaddress()

print(raw_change_address)
print(new_bitcoin_address)

fee_obj = rpc_connection.estimatesmartfee(6)
fee = fee_obj.get("feerate")

print(fee)


send_amount = first_unspent_amount / 2
Пример #50
0
 def area_of_triangle_with(self, v):
     return self.area_of_parallelogram_with(v) / Decimal('2.0')
def lambda_handler(event, context):
    
    url = 'https://voyagesarabais.com/recherche-sud/getpricedetails?search%5Bgateway%5D=YUL&search%5BdateDep%5D=2019-12-15&search%5Bduration%5D=7day%2C8day&search%5BdestDep%5D=o&search%5BnoHotel%5D=p7&search%5Broom1%5D=a%3A4%3A%7Bi%3A0%3Bs%3A2%3A%2240%22%3Bi%3A1%3Bs%3A2%3A%2240%22%3Bi%3A2%3Bs%3A1%3A%223%22%3Bi%3A3%3Bs%3A1%3A%221%22%3B%7D&search%5Broom2%5D=&search%5Broom3%5D=&search%5Broom4%5D=&search%5Broom5%5D=&search%5Broom6%5D=&search%5Bflex%5D=N&search%5Bflexhigh%5D=3&search%5Bflexlow%5D=3&search%5Broomcallgroup%5D=%5B%7B%22_priority%22%3A9%2C%22nb_rooms%22%3A1%2C%22nb_adults%22%3A2%2C%22non_adults%22%3A%5B%223%22%2C%221%22%5D%7D%5D&search%5Bpricemax%5D=9000&search%5Bpricemin%5D=1&search%5Ballinclusive%5D=Y&search%5Bbeach%5D=&search%5Bcasino%5D=&search%5Bfamily%5D=&search%5Bgolf%5D=&search%5Bkitchenette%5D=&search%5Boceanview%5D=&search%5Bminiclub%5D=&search%5Bspa%5D=&search%5Bwedding%5D=&search%5Badultonly%5D=&search%5Bnoextrasingle%5D=&search%5Bvilla%5D=&search%5Bstar%5D=4.5&search%5Bstarmax%5D=4.5&search%5Bdirectflight%5D=&search%5Btourtodisplay%5D=CAH%2CVAT%2CVAC%2CVAX%2CSGN%2CSQV%2CSWG%2CWJV&search%5Buuid%5D=&search%5BnbRoomsMax%5D=&search%5BhotelDistanceMax%5D='

    payload = 'data=QXjaDVS1EqNQAPyXaymCS4l7cL1cAQQn8ILD11%2F6ndlZ%2FfMX%2FufEXTaHeV6sCyracChEFTl8XHzw9NfD8TjxcBJOrgXgabDpEkZOeyGaNsfYlfsXoxaj57LBWgZjpB2mpeDKsJ0iUmI5VVjv9eCeA34db0A8ASRklG9DJjZAVk8j%2BK58ctfscX7FxXppW62OhAMznyYwpeGqU9FoU%2F71SDiO7fk5Dz99S3CAd5RDB9lKTvzmSahBld5gdaz9vfedPConEhM4dpuBiIxpZ6fKZK7O1BDnBvU9Ba%2FHZJXiRNuFCNhRlvZh1lH4WrciCbh5GUW8r4vsjq6xDRJzTvsb3EGJM%2BplJMNkBcma09TrMezjOqFNtOCZ3EHBE8rwpbzA%2Bnp43SKN3No4fVcGdg1hSW1er0e8zHKV7qNEleUPVGcJ4YniN6lPWIA%2BfixcisbTUpO8HgR78ue3i0dZlwJXGyhYhxfWoz5wCrQL5JbnZadk2pILWEdT4RKiXbKcxemTi4mF7paMniWP190lJHXy8eZgV7QqaTnvx%2BwQYGNWsd5jPomwNojiNgn3zh%2B1E2XIxO7ri%2FfN7PXIehG2oplT9oHbTGqkNtPKtiQq9UsjliPEktUIbyc0%2Be8RqapxzPExGO%2BP8Qts0dbCnm7UJ3A15plV51xQq1Y6d07xJjZ4BhGiIHKw9uosLjWpHmidnaEsg%2Fle4JjPGvaZT3tgFAS6cjix2u53EIB4JwwyuGLJSxGCYa8HTz7Tm8WL741X0NfeAcIkpt6ssUJHChKkaf96kAMEG0PDxHs%2B7wDQs%2F2FQgVRsDful59Uhdw7UAWKp4yiQU25FNUlpGoG%2F1nlZGD7lDW2fb7RviM%2FQjpny6Hcxmd6JoeYuHtGOa6VdW3dcMVAxir5FXtwqb2fog0PfNydAw9EuBQwiAbzivCMaLJTr2f%2BXt4SMOadF6fZ29rn66FBIYemXUNzpHDqUoX4FlcaXO9ucgZAisAS66Mbh5xeEK7V0r33Z8oMzAnFHUeen8hoDtq2ahi3JY%2FQC5DqhEiB0eRNkC7bGPaGKXIAoq%2F1ToN4sHN8BpgKd56efidkDlK%2FyJtTid7itoGQUcLMrT0feaY455Znrfb28az3t9C8B9k63ya8BRcaX3QMkDIvsQHxciv33ROC4cA3WhqqcuUkPxRSuz9xACrzlEvXLM4QP0qBFEOvB7qeKyBXqppLE1DFLEPhc0zRyiWY30YwlgSpcQhzmmifBd8wXgLAYpouOFpYn%2BTqDEweseIKO3G2c3gbFJC5yOPGgTVLBsG7KYk%2BkCJpEW984kihzE6lTENZ32CHseFA%2FXCTZUG5FZ3M12VmtH2hKXC1IZ2UAQ4foyB1Qdi35QQJv9Ef235UyPN4c%2FeOeKR9eIlGlL9GiWhogoOEpUnE%2BDdTnKQXFWwgRRHGNXaonLog6ZNhoLCluUWOc8j6a%2BZ793ZojmWm39gkBnx0YWPFstDXoQSkIsIlwr4oN%2F8%2BhfU6N%2F%2Bd0J%2F%2Fb5zoDz0%3D&type=packageplus'

    headers = {
    'Cookie': 'Cookie: _gcl_au=1.1.596656575.1560126807; _ga=GA1.2.1347033583.1560126807; _fbp=fb.1.1560126807161.1014257493; _gaexp=GAX1.2.NFE8cllqRy-hy2p_zsZ_9A.18143.0; G_ENABLED_IDPS=google; is_all_inclusive_checked=1; PHPSESSID=0odjk0bsqoalhh20ijg3hgcqs2; _hjid=d29cb0cd-017e-4453-a112-b8ae863dbb89; _gid=GA1.2.1378798265.1565464684; _gac_UA-6397631-1=1.1565464692.CjwKCAjw1rnqBRAAEiwAr29II9bpU1twn6ZPzisvGTap3gofl973SwBnRO6CkYdpJF4F3qEYN9FTDBoCPRwQAvD_BwE; _gat_UA-6397631-1=1',
    'Origin': 'https://voyagesarabais.com',
    'Accept-Encoding': 'gzip, deflate, br' ,
    'Accept-Language': 'en-US,en;q=0.9,fr;q=0.8' ,
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' ,
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' ,
    'Accept': '*/*' ,
    'Referer': 'https://voyagesarabais.com/recherche-sud?gateway=YUL&dateDep=2019-12-15&duration=7day,8day&destDep=o&noHotel=p7&allinclusive=Y&beach=&casino=&family=&golf=&kitchenette=&oceanview=&miniclub=&spa=&weeding=&adultonly=&noextrasingle=&villa=&directflight=&tourtodisplay=CAH,VAT,VAC,VAX,SGN,SQV,SWG,WJV&uuid=&nbRoomsMax=&hotelDistanceMax=&star=4.5&starmax=4.5&pricemin=1&pricemax=9000&flex=N&&bedrooms[0][0]=40&bedrooms[0][1]=40&bedrooms[0][2]=3&bedrooms[0][3]=1',
    'X-Requested-With': 'XMLHttpRequest',
    'Connection': 'keep-alive' 
    }

    r = requests.post(url, data=payload, headers=headers)
    rr = json.loads(r.text)
    
    #We sometime get cookies denied, so we have to update the data and cookies above.
    if 'totalprice' not in rr.keys():

        SUBJECT = "Voyage en Rabais - DATA UNAVAILABLE"
        BODY_TEXT = ( "Update the key bastard!")
        
        
        
        client = boto3.client('ses',region_name=AWS_REGION)
        
        # Try to send the email.
        try:
            #Provide the contents of the email.
            response = client.send_email(
                Destination={
                    'ToAddresses': [
                        RECIPIENT,
                    ],
                },
                Message={
                    'Body': {
                        'Text': {
                            'Charset': CHARSET,
                            'Data': BODY_TEXT,
                        },
                    },
                    'Subject': {
                        'Charset': CHARSET,
                        'Data': SUBJECT,
                    },
                },
                Source=SENDER,
            )
        except ClientError as e:
            print(e.response['Error']['Message'])
        else:
            print("Email sent! Message ID:"),
            print(response['MessageId'])
        
        return(-1)
    
    #get pricing
    totalPrice = rr['totalprice']
    dd = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    
    #load it into dynamodb
    table.put_item(
    Item={
        'time': dd,
        'total_price': Decimal(round(totalPrice, 2))
        })
    
    
    # Store it into a S3 file
    string = 'time,total_price\n{},{}'.format(dd, Decimal(round(totalPrice, 2)))
    encoded_string = string.encode("utf-8")

    bucket_name = "trip-price"
    file_name = datetime.datetime.now().strftime('%s')+'.csv'
    
    s3_path = "data/" + file_name

    s3 = boto3.resource("s3")
    s3.Bucket(bucket_name).put_object(Key=s3_path, Body=encoded_string)
    
    # If price goes below 4000 I want a mail
    if Decimal(round(totalPrice, 2)) < 4000:
        
        SUBJECT = "Voyage en Rabais !!"
        BODY_TEXT = ( "Le prix du voyage est de: " + str(int(totalPrice)) + "$")

        # Create a new SES resource and specify a region.
        client = boto3.client('ses',region_name=AWS_REGION)
        
        # Try to send the email.
        try:
            #Provide the contents of the email.
            response = client.send_email(
                Destination={
                    'ToAddresses': [
                        RECIPIENT,
                    ],
                },
                Message={
                    'Body': {
                        'Text': {
                            'Charset': CHARSET,
                            'Data': BODY_TEXT,
                        },
                    },
                    'Subject': {
                        'Charset': CHARSET,
                        'Data': SUBJECT,
                    },
                },
                Source=SENDER,
            )
        # Display an error if something goes wrong.	
        except ClientError as e:
            print(e.response['Error']['Message'])
        else:
            print("Email sent! Message ID:"),
            print(response['MessageId'])

    return str(Decimal(totalPrice))
Пример #52
0
def parse_coinbase_transactions(data_row, _parser, **_kwargs):
    row_dict = data_row.row_dict
    data_row.timestamp = DataParser.parse_timestamp(row_dict['Timestamp'])

    if data_row.row[21] != "":
        # Hash so must be external crypto deposit or withdrawal
        if Decimal(row_dict['Amount']) < 0:
            data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_WITHDRAWAL,
                                                     data_row.timestamp,
                                                     sell_quantity=abs(Decimal(row_dict['Amount'])),
                                                     sell_asset=row_dict['Currency'],
                                                     wallet=WALLET)
        else:
            data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_DEPOSIT,
                                                     data_row.timestamp,
                                                     buy_quantity=row_dict['Amount'],
                                                     buy_asset=row_dict['Currency'],
                                                     wallet=WALLET)
    elif row_dict['Transfer ID'] != "":
        # Transfer ID so could be a trade or external fiat deposit/withdrawal
        if row_dict['Currency'] != row_dict['Transfer Total Currency']:
            # Currencies are different so must be a trade
            if Decimal(row_dict['Amount']) < 0:
                data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_TRADE,
                                                 data_row.timestamp,
                                                 buy_quantity= \
                                                     Decimal(row_dict['Transfer Total']) + \
                                                     Decimal(row_dict['Transfer Fee']),
                                                 buy_asset=row_dict['Transfer Total Currency'],
                                                 sell_quantity=abs(Decimal(row_dict['Amount'])),
                                                 sell_asset=row_dict['Currency'],
                                                 fee_quantity=row_dict['Transfer Fee'],
                                                 fee_asset=row_dict['Transfer Fee Currency'],
                                                 wallet=WALLET)
            else:
                data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_TRADE,
                                                     data_row.timestamp,
                                                     buy_quantity=row_dict['Amount'],
                                                     buy_asset=row_dict['Currency'],
                                                     sell_quantity=
                                                         Decimal(row_dict['Transfer Total']) - \
                                                         Decimal(row_dict['Transfer Fee']),
                                                     sell_asset=row_dict['Transfer Total Currency'],
                                                     fee_quantity=row_dict['Transfer Fee'],
                                                     fee_asset=row_dict['Transfer Fee Currency'],
                                                     wallet=WALLET)
        else:
            if Decimal(row_dict['Amount']) < 0:
                data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_WITHDRAWAL,
                                                     data_row.timestamp,
                                                     sell_quantity=row_dict['Transfer Total'],
                                                     sell_asset=row_dict['Currency'],
                                                     fee_quantity=row_dict['Transfer Fee'],
                                                     fee_asset=row_dict['Transfer Fee Currency'],
                                                     wallet=WALLET)
            else:
                data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_DEPOSIT,
                                                     data_row.timestamp,
                                                     buy_quantity=row_dict['Transfer Total'],
                                                     buy_asset=row_dict['Currency'],
                                                     fee_quantity=row_dict['Transfer Fee'],
                                                     fee_asset=row_dict['Transfer Fee Currency'],
                                                     wallet=WALLET)
    else:
        # Could be a referral bonus or deposit/withdrawal to/from Coinbase Pro
        if row_dict['Notes'] != "" and row_dict['Currency'] == "BTC":
            # Bonus is always in BTC
            data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_GIFT_RECEIVED,
                                                     data_row.timestamp,
                                                     buy_quantity=row_dict['Amount'],
                                                     buy_asset=row_dict['Currency'],
                                                     wallet=WALLET)
        elif row_dict['Notes'] != "" and row_dict['Currency'] != "BTC":
            # Special case, flag as duplicate entry, trade will be in BTC Wallet Transactions Report
            if Decimal(row_dict['Amount']) < 0:
                data_row.t_record = TransactionOutRecord(DUPLICATE,
                                                     data_row.timestamp,
                                                     sell_quantity=abs(Decimal(row_dict['Amount'])),
                                                     sell_asset=row_dict['Currency'],
                                                     wallet=WALLET)
            else:
                data_row.t_record = TransactionOutRecord(DUPLICATE,
                                                         data_row.timestamp,
                                                         buy_quantity=row_dict['Amount'],
                                                         buy_asset=row_dict['Currency'],
                                                         wallet=WALLET)
        elif Decimal(row_dict['Amount']) < 0:
            data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_WITHDRAWAL,
                                                     data_row.timestamp,
                                                     sell_quantity=abs(Decimal(row_dict['Amount'])),
                                                     sell_asset=row_dict['Currency'],
                                                     wallet=WALLET)
        else:
            data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_DEPOSIT,
                                                     data_row.timestamp,
                                                     buy_quantity=row_dict['Amount'],
                                                     buy_asset=row_dict['Currency'],
                                                     wallet=WALLET)
Пример #53
0
class ImageInfo:
    DPI_PREC = Decimal('1.000')

    def __init__(self, *, name='', pdfimage=None, inline=None, shorthand=None):

        self._name = str(name)
        self._shorthand = shorthand

        if inline is not None:
            self._origin = 'inline'
            pim = inline.iimage
        elif pdfimage is not None:
            self._origin = 'xobject'
            pim = pikepdf.PdfImage(pdfimage)
        self._width = pim.width
        self._height = pim.height

        # If /ImageMask is true, then this image is a stencil mask
        # (Images that draw with this stencil mask will have a reference to
        # it in their /Mask, but we don't actually need that information)
        if pim.image_mask:
            self._type = 'stencil'
        else:
            self._type = 'image'

        self._bpc = int(pim.bits_per_component)
        try:
            self._enc = FRIENDLY_ENCODING.get(pim.filters[0], 'image')
        except IndexError:
            self._enc = '?'

        try:
            self._color = FRIENDLY_COLORSPACE.get(pim.colorspace, '?')
        except NotImplementedError:
            self._color = '?'
        if self._enc == Encoding.jpeg2000:
            self._color = Colorspace.jpeg2000

        self._comp = FRIENDLY_COMP.get(self._color, '?')

        # Bit of a hack... infer grayscale if component count is uncertain
        # but encoding must be monochrome. This happens if a monochrome image
        # has an ICC profile attached. Better solution would be to examine
        # the ICC profile.
        if self._comp == '?' and self._enc in (Encoding.ccitt, 'jbig2'):
            self._comp = FRIENDLY_COMP[Colorspace.gray]

    @property
    def name(self):
        return self._name

    @property
    def type_(self):
        return self._type

    @property
    def width(self):
        return self._width

    @property
    def height(self):
        return self._height

    @property
    def bpc(self):
        return self._bpc

    @property
    def color(self):
        return self._color

    @property
    def comp(self):
        return self._comp

    @property
    def enc(self):
        return self._enc

    @property
    def xres(self):
        return _get_dpi(self._shorthand, (self._width, self._height))[0]

    @property
    def yres(self):
        return _get_dpi(self._shorthand, (self._width, self._height))[1]

    def __repr__(self):
        class_locals = {
            attr: getattr(self, attr, None)
            for attr in dir(self) if not attr.startswith('_')
        }
        return ("<ImageInfo '{name}' {type_} {width}x{height} {color} "
                "{comp} {bpc} {enc} {xres}x{yres}>").format(**class_locals)
Пример #54
0
    def run_test(self):
        self.log.info('prepare some coins for multiple *rawtransaction commands')
        self.nodes[2].generate(1)
        self.sync_all()
        self.nodes[0].generate(101)
        self.sync_all()
        self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5)
        self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0)
        self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0)
        self.sync_all()
        self.nodes[0].generate(5)
        self.sync_all()

        self.log.info('Test getrawtransaction on genesis block coinbase returns an error')
        block = self.nodes[0].getblock(self.nodes[0].getblockhash(0))
        assert_raises_rpc_error(-5, "The genesis block coinbase is not considered an ordinary transaction", self.nodes[0].getrawtransaction, block['merkleroot'])

        self.log.info('Check parameter types and required parameters of createrawtransaction')
        # Test `createrawtransaction` required parameters
        assert_raises_rpc_error(-1, "createrawtransaction", self.nodes[0].createrawtransaction)
        assert_raises_rpc_error(-1, "createrawtransaction", self.nodes[0].createrawtransaction, [])

        # Test `createrawtransaction` invalid extra parameters
        assert_raises_rpc_error(-1, "createrawtransaction", self.nodes[0].createrawtransaction, [], {}, 0, False, 'foo')

        # Test `createrawtransaction` invalid `inputs`
        txid = '1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000'
        assert_raises_rpc_error(-3, "Expected type array", self.nodes[0].createrawtransaction, 'foo', {})
        assert_raises_rpc_error(-1, "JSON value is not an object as expected", self.nodes[0].createrawtransaction, ['foo'], {})
        assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].createrawtransaction, [{}], {})
        assert_raises_rpc_error(-8, "txid must be of length 64 (not 3, for 'foo')", self.nodes[0].createrawtransaction, [{'txid': 'foo'}], {})
        assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844')", self.nodes[0].createrawtransaction, [{'txid': 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844'}], {})
        assert_raises_rpc_error(-8, "Invalid parameter, missing vout key", self.nodes[0].createrawtransaction, [{'txid': txid}], {})
        assert_raises_rpc_error(-8, "Invalid parameter, missing vout key", self.nodes[0].createrawtransaction, [{'txid': txid, 'vout': 'foo'}], {})
        assert_raises_rpc_error(-8, "Invalid parameter, vout must be positive", self.nodes[0].createrawtransaction, [{'txid': txid, 'vout': -1}], {})
        assert_raises_rpc_error(-8, "Invalid parameter, sequence number is out of range", self.nodes[0].createrawtransaction, [{'txid': txid, 'vout': 0, 'sequence': -1}], {})

        # Test `createrawtransaction` invalid `outputs`
        address = self.nodes[0].getnewaddress()
        address2 = self.nodes[0].getnewaddress()
        assert_raises_rpc_error(-1, "JSON value is not an array as expected", self.nodes[0].createrawtransaction, [], 'foo')
        self.nodes[0].createrawtransaction(inputs=[], outputs={})  # Should not throw for backwards compatibility
        self.nodes[0].createrawtransaction(inputs=[], outputs=[])
        assert_raises_rpc_error(-8, "Data must be hexadecimal string", self.nodes[0].createrawtransaction, [], {'data': 'foo'})
        assert_raises_rpc_error(-5, "Invalid CounosH address", self.nodes[0].createrawtransaction, [], {'foo': 0})
        assert_raises_rpc_error(-3, "Invalid amount", self.nodes[0].createrawtransaction, [], {address: 'foo'})
        assert_raises_rpc_error(-3, "Amount out of range", self.nodes[0].createrawtransaction, [], {address: -1})
        assert_raises_rpc_error(-8, "Invalid parameter, duplicated address: %s" % address, self.nodes[0].createrawtransaction, [], multidict([(address, 1), (address, 1)]))
        assert_raises_rpc_error(-8, "Invalid parameter, duplicated address: %s" % address, self.nodes[0].createrawtransaction, [], [{address: 1}, {address: 1}])
        assert_raises_rpc_error(-8, "Invalid parameter, duplicate key: data", self.nodes[0].createrawtransaction, [], [{"data": 'aa'}, {"data": "bb"}])
        assert_raises_rpc_error(-8, "Invalid parameter, duplicate key: data", self.nodes[0].createrawtransaction, [], multidict([("data", 'aa'), ("data", "bb")]))
        assert_raises_rpc_error(-8, "Invalid parameter, key-value pair must contain exactly one key", self.nodes[0].createrawtransaction, [], [{'a': 1, 'b': 2}])
        assert_raises_rpc_error(-8, "Invalid parameter, key-value pair not an object as expected", self.nodes[0].createrawtransaction, [], [['key-value pair1'], ['2']])

        # Test `createrawtransaction` invalid `locktime`
        assert_raises_rpc_error(-3, "Expected type number", self.nodes[0].createrawtransaction, [], {}, 'foo')
        assert_raises_rpc_error(-8, "Invalid parameter, locktime out of range", self.nodes[0].createrawtransaction, [], {}, -1)
        assert_raises_rpc_error(-8, "Invalid parameter, locktime out of range", self.nodes[0].createrawtransaction, [], {}, 4294967296)

        # Test `createrawtransaction` invalid `replaceable`
        assert_raises_rpc_error(-3, "Expected type bool", self.nodes[0].createrawtransaction, [], {}, 0, 'foo')

        self.log.info('Check that createrawtransaction accepts an array and object as outputs')
        tx = CTransaction()
        # One output
        tx.deserialize(BytesIO(hex_str_to_bytes(self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs={address: 99}))))
        assert_equal(len(tx.vout), 1)
        assert_equal(
            tx.serialize().hex(),
            self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs=[{address: 99}]),
        )
        # Two outputs
        tx.deserialize(BytesIO(hex_str_to_bytes(self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs=OrderedDict([(address, 99), (address2, 99)])))))
        assert_equal(len(tx.vout), 2)
        assert_equal(
            tx.serialize().hex(),
            self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs=[{address: 99}, {address2: 99}]),
        )
        # Multiple mixed outputs
        tx.deserialize(BytesIO(hex_str_to_bytes(self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs=multidict([(address, 99), (address2, 99), ('data', '99')])))))
        assert_equal(len(tx.vout), 3)
        assert_equal(
            tx.serialize().hex(),
            self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs=[{address: 99}, {address2: 99}, {'data': '99'}]),
        )

        for type in ["bech32", "p2sh-segwit", "legacy"]:
            addr = self.nodes[0].getnewaddress("", type)
            addrinfo = self.nodes[0].getaddressinfo(addr)
            pubkey = addrinfo["scriptPubKey"]

            self.log.info('sendrawtransaction with missing prevtx info (%s)' %(type))

            # Test `signrawtransactionwithwallet` invalid `prevtxs`
            inputs  = [ {'txid' : txid, 'vout' : 3, 'sequence' : 1000}]
            outputs = { self.nodes[0].getnewaddress() : 1 }
            rawtx   = self.nodes[0].createrawtransaction(inputs, outputs)

            prevtx = dict(txid=txid, scriptPubKey=pubkey, vout=3, amount=1)
            succ = self.nodes[0].signrawtransactionwithwallet(rawtx, [prevtx])
            assert succ["complete"]
            if type == "legacy":
                del prevtx["amount"]
                succ = self.nodes[0].signrawtransactionwithwallet(rawtx, [prevtx])
                assert succ["complete"]

            if type != "legacy":
                assert_raises_rpc_error(-3, "Missing amount", self.nodes[0].signrawtransactionwithwallet, rawtx, [
                    {
                        "txid": txid,
                        "scriptPubKey": pubkey,
                        "vout": 3,
                    }
                ])

            assert_raises_rpc_error(-3, "Missing vout", self.nodes[0].signrawtransactionwithwallet, rawtx, [
                {
                    "txid": txid,
                    "scriptPubKey": pubkey,
                    "amount": 1,
                }
            ])
            assert_raises_rpc_error(-3, "Missing txid", self.nodes[0].signrawtransactionwithwallet, rawtx, [
                {
                    "scriptPubKey": pubkey,
                    "vout": 3,
                    "amount": 1,
                }
            ])
            assert_raises_rpc_error(-3, "Missing scriptPubKey", self.nodes[0].signrawtransactionwithwallet, rawtx, [
                {
                    "txid": txid,
                    "vout": 3,
                    "amount": 1
                }
            ])

        #########################################
        # sendrawtransaction with missing input #
        #########################################

        self.log.info('sendrawtransaction with missing input')
        inputs  = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1}] #won't exists
        outputs = { self.nodes[0].getnewaddress() : 4.998 }
        rawtx   = self.nodes[2].createrawtransaction(inputs, outputs)
        rawtx   = self.nodes[2].signrawtransactionwithwallet(rawtx)

        # This will raise an exception since there are missing inputs
        assert_raises_rpc_error(-25, "bad-txns-inputs-missingorspent", self.nodes[2].sendrawtransaction, rawtx['hex'])

        #####################################
        # getrawtransaction with block hash #
        #####################################

        # make a tx by sending then generate 2 blocks; block1 has the tx in it
        tx = self.nodes[2].sendtoaddress(self.nodes[1].getnewaddress(), 1)
        block1, block2 = self.nodes[2].generate(2)
        self.sync_all()
        # We should be able to get the raw transaction by providing the correct block
        gottx = self.nodes[0].getrawtransaction(tx, True, block1)
        assert_equal(gottx['txid'], tx)
        assert_equal(gottx['in_active_chain'], True)
        # We should not have the 'in_active_chain' flag when we don't provide a block
        gottx = self.nodes[0].getrawtransaction(tx, True)
        assert_equal(gottx['txid'], tx)
        assert 'in_active_chain' not in gottx
        # We should not get the tx if we provide an unrelated block
        assert_raises_rpc_error(-5, "No such transaction found", self.nodes[0].getrawtransaction, tx, True, block2)
        # An invalid block hash should raise the correct errors
        assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].getrawtransaction, tx, True, True)
        assert_raises_rpc_error(-8, "parameter 3 must be of length 64 (not 6, for 'foobar')", self.nodes[0].getrawtransaction, tx, True, "foobar")
        assert_raises_rpc_error(-8, "parameter 3 must be of length 64 (not 8, for 'abcd1234')", self.nodes[0].getrawtransaction, tx, True, "abcd1234")
        assert_raises_rpc_error(-8, "parameter 3 must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[0].getrawtransaction, tx, True, "ZZZ0000000000000000000000000000000000000000000000000000000000000")
        assert_raises_rpc_error(-5, "Block hash not found", self.nodes[0].getrawtransaction, tx, True, "0000000000000000000000000000000000000000000000000000000000000000")
        # Undo the blocks and check in_active_chain
        self.nodes[0].invalidateblock(block1)
        gottx = self.nodes[0].getrawtransaction(txid=tx, verbose=True, blockhash=block1)
        assert_equal(gottx['in_active_chain'], False)
        self.nodes[0].reconsiderblock(block1)
        assert_equal(self.nodes[0].getbestblockhash(), block2)

        #########################
        # RAW TX MULTISIG TESTS #
        #########################
        # 2of2 test
        addr1 = self.nodes[2].getnewaddress()
        addr2 = self.nodes[2].getnewaddress()

        addr1Obj = self.nodes[2].getaddressinfo(addr1)
        addr2Obj = self.nodes[2].getaddressinfo(addr2)

        # Tests for createmultisig and addmultisigaddress
        assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, ["01020304"])
        self.nodes[0].createmultisig(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) # createmultisig can only take public keys
        assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 2, [addr1Obj['pubkey'], addr1]) # addmultisigaddress can take both pubkeys and addresses so long as they are in the wallet, which is tested here.

        mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr1])['address']

        #use balance deltas instead of absolute values
        bal = self.nodes[2].getbalance()

        # send 1.2 CCH to msig adr
        txId = self.nodes[0].sendtoaddress(mSigObj, 1.2)
        self.sync_all()
        self.nodes[0].generate(1)
        self.sync_all()
        assert_equal(self.nodes[2].getbalance(), bal+Decimal('1.20000000')) #node2 has both keys of the 2of2 ms addr., tx should affect the balance


        # 2of3 test from different nodes
        bal = self.nodes[2].getbalance()
        addr1 = self.nodes[1].getnewaddress()
        addr2 = self.nodes[2].getnewaddress()
        addr3 = self.nodes[2].getnewaddress()

        addr1Obj = self.nodes[1].getaddressinfo(addr1)
        addr2Obj = self.nodes[2].getaddressinfo(addr2)
        addr3Obj = self.nodes[2].getaddressinfo(addr3)

        mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']])['address']

        txId = self.nodes[0].sendtoaddress(mSigObj, 2.2)
        decTx = self.nodes[0].gettransaction(txId)
        rawTx = self.nodes[0].decoderawtransaction(decTx['hex'])
        self.sync_all()
        self.nodes[0].generate(1)
        self.sync_all()

        #THIS IS AN INCOMPLETE FEATURE
        #NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND COUNT AT BALANCE CALCULATION
        assert_equal(self.nodes[2].getbalance(), bal) #for now, assume the funds of a 2of3 multisig tx are not marked as spendable

        txDetails = self.nodes[0].gettransaction(txId, True)
        rawTx = self.nodes[0].decoderawtransaction(txDetails['hex'])
        vout = next(o for o in rawTx['vout'] if o['value'] == Decimal('2.20000000'))

        bal = self.nodes[0].getbalance()
        inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "amount" : vout['value']}]
        outputs = { self.nodes[0].getnewaddress() : 2.19 }
        rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
        rawTxPartialSigned = self.nodes[1].signrawtransactionwithwallet(rawTx, inputs)
        assert_equal(rawTxPartialSigned['complete'], False) #node1 only has one key, can't comp. sign the tx

        rawTxSigned = self.nodes[2].signrawtransactionwithwallet(rawTx, inputs)
        assert_equal(rawTxSigned['complete'], True) #node2 can sign the tx compl., own two of three keys
        self.nodes[2].sendrawtransaction(rawTxSigned['hex'])
        rawTx = self.nodes[0].decoderawtransaction(rawTxSigned['hex'])
        self.sync_all()
        self.nodes[0].generate(1)
        self.sync_all()
        assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx

        # 2of2 test for combining transactions
        bal = self.nodes[2].getbalance()
        addr1 = self.nodes[1].getnewaddress()
        addr2 = self.nodes[2].getnewaddress()

        addr1Obj = self.nodes[1].getaddressinfo(addr1)
        addr2Obj = self.nodes[2].getaddressinfo(addr2)

        self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
        mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
        mSigObjValid = self.nodes[2].getaddressinfo(mSigObj)

        txId = self.nodes[0].sendtoaddress(mSigObj, 2.2)
        decTx = self.nodes[0].gettransaction(txId)
        rawTx2 = self.nodes[0].decoderawtransaction(decTx['hex'])
        self.sync_all()
        self.nodes[0].generate(1)
        self.sync_all()

        assert_equal(self.nodes[2].getbalance(), bal) # the funds of a 2of2 multisig tx should not be marked as spendable

        txDetails = self.nodes[0].gettransaction(txId, True)
        rawTx2 = self.nodes[0].decoderawtransaction(txDetails['hex'])
        vout = next(o for o in rawTx2['vout'] if o['value'] == Decimal('2.20000000'))

        bal = self.nodes[0].getbalance()
        inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "redeemScript" : mSigObjValid['hex'], "amount" : vout['value']}]
        outputs = { self.nodes[0].getnewaddress() : 2.19 }
        rawTx2 = self.nodes[2].createrawtransaction(inputs, outputs)
        rawTxPartialSigned1 = self.nodes[1].signrawtransactionwithwallet(rawTx2, inputs)
        self.log.debug(rawTxPartialSigned1)
        assert_equal(rawTxPartialSigned1['complete'], False) #node1 only has one key, can't comp. sign the tx

        rawTxPartialSigned2 = self.nodes[2].signrawtransactionwithwallet(rawTx2, inputs)
        self.log.debug(rawTxPartialSigned2)
        assert_equal(rawTxPartialSigned2['complete'], False) #node2 only has one key, can't comp. sign the tx
        rawTxComb = self.nodes[2].combinerawtransaction([rawTxPartialSigned1['hex'], rawTxPartialSigned2['hex']])
        self.log.debug(rawTxComb)
        self.nodes[2].sendrawtransaction(rawTxComb)
        rawTx2 = self.nodes[0].decoderawtransaction(rawTxComb)
        self.sync_all()
        self.nodes[0].generate(1)
        self.sync_all()
        assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx

        # decoderawtransaction tests
        # witness transaction
        encrawtx = "010000000001010000000000000072c1a6a246ae63f74f931e8365e15a089c68d61900000000000000000000ffffffff0100e1f50500000000000102616100000000"
        decrawtx = self.nodes[0].decoderawtransaction(encrawtx, True) # decode as witness transaction
        assert_equal(decrawtx['vout'][0]['value'], Decimal('1.00000000'))
        assert_raises_rpc_error(-22, 'TX decode failed', self.nodes[0].decoderawtransaction, encrawtx, False) # force decode as non-witness transaction
        # non-witness transaction
        encrawtx = "01000000010000000000000072c1a6a246ae63f74f931e8365e15a089c68d61900000000000000000000ffffffff0100e1f505000000000000000000"
        decrawtx = self.nodes[0].decoderawtransaction(encrawtx, False) # decode as non-witness transaction
        assert_equal(decrawtx['vout'][0]['value'], Decimal('1.00000000'))

        # getrawtransaction tests
        # 1. valid parameters - only supply txid
        txId = rawTx["txid"]
        assert_equal(self.nodes[0].getrawtransaction(txId), rawTxSigned['hex'])

        # 2. valid parameters - supply txid and 0 for non-verbose
        assert_equal(self.nodes[0].getrawtransaction(txId, 0), rawTxSigned['hex'])

        # 3. valid parameters - supply txid and False for non-verbose
        assert_equal(self.nodes[0].getrawtransaction(txId, False), rawTxSigned['hex'])

        # 4. valid parameters - supply txid and 1 for verbose.
        # We only check the "hex" field of the output so we don't need to update this test every time the output format changes.
        assert_equal(self.nodes[0].getrawtransaction(txId, 1)["hex"], rawTxSigned['hex'])

        # 5. valid parameters - supply txid and True for non-verbose
        assert_equal(self.nodes[0].getrawtransaction(txId, True)["hex"], rawTxSigned['hex'])

        # 6. invalid parameters - supply txid and string "Flase"
        assert_raises_rpc_error(-1, "not a boolean", self.nodes[0].getrawtransaction, txId, "Flase")

        # 7. invalid parameters - supply txid and empty array
        assert_raises_rpc_error(-1, "not a boolean", self.nodes[0].getrawtransaction, txId, [])

        # 8. invalid parameters - supply txid and empty dict
        assert_raises_rpc_error(-1, "not a boolean", self.nodes[0].getrawtransaction, txId, {})

        inputs  = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 1000}]
        outputs = { self.nodes[0].getnewaddress() : 1 }
        rawtx   = self.nodes[0].createrawtransaction(inputs, outputs)
        decrawtx= self.nodes[0].decoderawtransaction(rawtx)
        assert_equal(decrawtx['vin'][0]['sequence'], 1000)

        # 9. invalid parameters - sequence number out of range
        inputs  = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : -1}]
        outputs = { self.nodes[0].getnewaddress() : 1 }
        assert_raises_rpc_error(-8, 'Invalid parameter, sequence number is out of range', self.nodes[0].createrawtransaction, inputs, outputs)

        # 10. invalid parameters - sequence number out of range
        inputs  = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 4294967296}]
        outputs = { self.nodes[0].getnewaddress() : 1 }
        assert_raises_rpc_error(-8, 'Invalid parameter, sequence number is out of range', self.nodes[0].createrawtransaction, inputs, outputs)

        inputs  = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 4294967294}]
        outputs = { self.nodes[0].getnewaddress() : 1 }
        rawtx   = self.nodes[0].createrawtransaction(inputs, outputs)
        decrawtx= self.nodes[0].decoderawtransaction(rawtx)
        assert_equal(decrawtx['vin'][0]['sequence'], 4294967294)

        ####################################
        # TRANSACTION VERSION NUMBER TESTS #
        ####################################

        # Test the minimum transaction version number that fits in a signed 32-bit integer.
        tx = CTransaction()
        tx.nVersion = -0x80000000
        rawtx = ToHex(tx)
        decrawtx = self.nodes[0].decoderawtransaction(rawtx)
        assert_equal(decrawtx['version'], -0x80000000)

        # Test the maximum transaction version number that fits in a signed 32-bit integer.
        tx = CTransaction()
        tx.nVersion = 0x7fffffff
        rawtx = ToHex(tx)
        decrawtx = self.nodes[0].decoderawtransaction(rawtx)
        assert_equal(decrawtx['version'], 0x7fffffff)

        self.log.info('sendrawtransaction/testmempoolaccept with maxfeerate')

        # Test a transaction with a small fee.
        txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0)
        rawTx = self.nodes[0].getrawtransaction(txId, True)
        vout = next(o for o in rawTx['vout'] if o['value'] == Decimal('1.00000000'))

        self.sync_all()
        inputs = [{ "txid" : txId, "vout" : vout['n'] }]
        # Fee 10,000 satoshis, (1 - (10000 sat * 0.00000001 CCH/sat)) = 0.9999
        outputs = { self.nodes[0].getnewaddress() : Decimal("0.99990000") }
        rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
        rawTxSigned = self.nodes[2].signrawtransactionwithwallet(rawTx)
        assert_equal(rawTxSigned['complete'], True)
        # Fee 10,000 satoshis, ~100 b transaction, fee rate should land around 100 sat/byte = 0.00100000 CCH/kB
        # Thus, testmempoolaccept should reject
        testres = self.nodes[2].testmempoolaccept([rawTxSigned['hex']], 0.00001000)[0]
        assert_equal(testres['allowed'], False)
        assert_equal(testres['reject-reason'], 'absurdly-high-fee')
        # and sendrawtransaction should throw
        assert_raises_rpc_error(-26, "absurdly-high-fee", self.nodes[2].sendrawtransaction, rawTxSigned['hex'], 0.00001000)
        # and the following calls should both succeed
        testres = self.nodes[2].testmempoolaccept(rawtxs=[rawTxSigned['hex']])[0]
        assert_equal(testres['allowed'], True)
        self.nodes[2].sendrawtransaction(hexstring=rawTxSigned['hex'])

        # Test a transaction with a large fee.
        txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0)
        rawTx = self.nodes[0].getrawtransaction(txId, True)
        vout = next(o for o in rawTx['vout'] if o['value'] == Decimal('1.00000000'))

        self.sync_all()
        inputs = [{ "txid" : txId, "vout" : vout['n'] }]
        # Fee 2,000,000 satoshis, (1 - (2000000 sat * 0.00000001 CCH/sat)) = 0.98
        outputs = { self.nodes[0].getnewaddress() : Decimal("0.98000000") }
        rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
        rawTxSigned = self.nodes[2].signrawtransactionwithwallet(rawTx)
        assert_equal(rawTxSigned['complete'], True)
        # Fee 2,000,000 satoshis, ~100 b transaction, fee rate should land around 20,000 sat/byte = 0.20000000 CCH/kB
        # Thus, testmempoolaccept should reject
        testres = self.nodes[2].testmempoolaccept([rawTxSigned['hex']])[0]
        assert_equal(testres['allowed'], False)
        assert_equal(testres['reject-reason'], 'absurdly-high-fee')
        # and sendrawtransaction should throw
        assert_raises_rpc_error(-26, "absurdly-high-fee", self.nodes[2].sendrawtransaction, rawTxSigned['hex'])
        # and the following calls should both succeed
        testres = self.nodes[2].testmempoolaccept(rawtxs=[rawTxSigned['hex']], maxfeerate='0.20000000')[0]
        assert_equal(testres['allowed'], True)
        self.nodes[2].sendrawtransaction(hexstring=rawTxSigned['hex'], maxfeerate='0.20000000')
Пример #55
0
	def setCODPaymentMethod(self, CODextracost):
		self.cod_charge = Decimal(CODextracost*float(self.calculated_price))
		self.final_price += self.cod_charge
		self.save()
Пример #56
0
	def _get_taxable_total(self):
		total = Decimal("0.0")
		for li in self.lineitems.all():
			if li.taxable:
				total += li.total
		return total.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
Пример #57
0
    def test_can_insert_model_with_all_column_types(self):
        """
        Test for inserting all column types into a Model

        test_can_insert_model_with_all_column_types tests that each cqlengine column type can be inserted into a Model.
        It first creates a Model that has each cqlengine column type. It then creates a Model instance where all the fields
        have corresponding data, which performs the insert into the Cassandra table.
        Finally, it verifies that each column read from the Model from Cassandra is the same as the input parameters.

        @since 2.6.0
        @jira_ticket PYTHON-246
        @expected_result The Model is inserted with each column type, and the resulting read yields proper data for each column.

        @test_category data_types:primitive
        """
        class AllDatatypesModel(Model):
            id = columns.Integer(primary_key=True)
            a = columns.Ascii()
            b = columns.BigInt()
            c = columns.Blob()
            d = columns.Boolean()
            e = columns.DateTime()
            f = columns.Decimal()
            g = columns.Double()
            h = columns.Float()
            i = columns.Inet()
            j = columns.Integer()
            k = columns.Text()
            l = columns.TimeUUID()
            m = columns.UUID()
            n = columns.VarInt()
            o = columns.Duration()

        sync_table(AllDatatypesModel)

        input = [
            'ascii', 2**63 - 1,
            bytearray(b'hello world'), True,
            datetime.utcfromtimestamp(872835240),
            Decimal('12.3E+7'), 2.39, 3.4028234663852886e+38,
            '123.123.123.123', 2147483647, 'text',
            UUID('FE2B4360-28C6-11E2-81C1-0800200C9A66'),
            UUID('067e6162-3b6f-4ae2-a171-2470b63dff00'),
            int(str(2147483647) + '000')
        ]

        AllDatatypesModel.create(
            id=0,
            a='ascii',
            b=2**63 - 1,
            c=bytearray(b'hello world'),
            d=True,
            e=datetime.utcfromtimestamp(872835240),
            f=Decimal('12.3E+7'),
            g=2.39,
            h=3.4028234663852886e+38,
            i='123.123.123.123',
            j=2147483647,
            k='text',
            l=UUID('FE2B4360-28C6-11E2-81C1-0800200C9A66'),
            m=UUID('067e6162-3b6f-4ae2-a171-2470b63dff00'),
            n=int(str(2147483647) + '000'),
            o=Duration(2, 3, 4))

        self.assertEqual(1, AllDatatypesModel.objects.count())
        output = AllDatatypesModel.objects.first()

        for i, i_char in enumerate(range(ord('a'), ord('a') + 14)):
            self.assertEqual(input[i], output[chr(i_char)])
Пример #58
0
	def _get_sub_total(self):
		total = Decimal("0.0")
		for li in self.lineitems.all():
				total += Decimal(li.unit_price * li.quantity)
		return total.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
Пример #59
0
except ValueError:
    print("Please try again with a numeral input")

s0input = input("Input initial infected population: ")
try:
    I0 = int(s0input)
except ValueError:
    print("Please try again with a numeral input")

S0 = N - I0

k0input = input(
    "What is your first guess for infection rate? (Usually a decimal from 0 to 10) "
)
try:
    k0 = Decimal(k0input)
    print("Accepted")
except ValueError:
    print("Please try again with a numeral input")

tinput = input(
    "Input a timepoint at which you would like to predict the total infected population: "
)
try:
    timepoint = int(tinput)
    print(
        "Accepted. Calculating total infected population and adjusted infection rate... "
    )
except ValueError:
    print("Please try again with a numeral input")
Пример #60
0
    def report_to_list(self, queryset, display_fields, user=None, property_filters=[], preview=False):
        """ Create list from a report with all data filtering.
        queryset: initial queryset to generate results
        display_fields: list of field references or DisplayField models
        user: requesting user. If left as None - there will be no permission check
        property_filters: ???
        preview: return only first 50 rows
        Returns list, message in case of issues.
        """
        model_class = queryset.model

        def can_change_or_view(model):
            """ Return True iff `user` has either change or view permission
            for `model`. """
            if user is None:
                return True
            model_name = model._meta.model_name
            app_label = model._meta.app_label
            can_change = user.has_perm(app_label + '.change_' + model_name)
            can_view = user.has_perm(app_label + '.view_' + model_name)

            return can_change or can_view

        if not can_change_or_view(model_class):
            return [], 'Permission Denied'

        if isinstance(display_fields, list):
            # Convert list of strings to DisplayField objects.

            new_display_fields = []

            for display_field in display_fields:
                field_list = display_field.split('__')
                field = field_list[-1]
                path = '__'.join(field_list[:-1])

                if path:
                    path += '__'  # Legacy format to append a __ here.

                new_model = get_model_from_path_string(model_class, path)
                model_field = new_model._meta.get_field_by_name(field)[0]
                choices = model_field.choices
                new_display_fields.append(DisplayField(
                    path, '', field, '', '', None, None, choices, ''
                ))

            display_fields = new_display_fields

        # Build group-by field list.

        group = [df.path + df.field for df in display_fields if df.group]

        # To support group-by with multiple fields, we turn all the other
        # fields into aggregations. The default aggregation is `Max`.

        if group:
            for field in display_fields:
                if (not field.group) and (not field.aggregate):
                    field.aggregate = 'Max'

        message = ""
        objects = self.add_aggregates(queryset, display_fields)

        # Display Values

        display_field_paths = []
        property_list = {}
        custom_list = {}
        display_totals = {}

        for i, display_field in enumerate(display_fields):
            model = get_model_from_path_string(model_class, display_field.path)

            if display_field.field_type == "Invalid":
                continue

            if not model or can_change_or_view(model):
                display_field_key = display_field.path + display_field.field

                if display_field.field_type == "Property":
                    property_list[i] = display_field_key
                elif display_field.field_type == "Custom Field":
                    custom_list[i] = display_field_key
                elif display_field.aggregate == "Avg":
                    display_field_key += '__avg'
                elif display_field.aggregate == "Max":
                    display_field_key += '__max'
                elif display_field.aggregate == "Min":
                    display_field_key += '__min'
                elif display_field.aggregate == "Count":
                    display_field_key += '__count'
                elif display_field.aggregate == "Sum":
                    display_field_key += '__sum'

                if display_field.field_type not in ('Property', 'Custom Field'):
                    display_field_paths.append(display_field_key)

                if display_field.total:
                    display_totals[display_field_key] = Decimal(0)

            else:
                message += 'Error: Permission denied on access to {0}.'.format(
                    display_field.name
                )

        def increment_total(display_field_key, val):
            """ Increment display total by `val` if given `display_field_key` in
            `display_totals`.
            """
            if display_field_key in display_totals:
                if isinstance(val, bool):
                    # True: 1, False: 0
                    display_totals[display_field_key] += Decimal(val)
                elif isinstance(val, Number):
                    display_totals[display_field_key] += Decimal(str(val))
                elif val:
                    display_totals[display_field_key] += Decimal(1)

        # Select pk for primary and m2m relations in order to retrieve objects
        # for adding properties to report rows. Group-by queries do not support
        # Property nor Custom Field filters.

        if not group:
            display_field_paths.insert(0, 'pk')

            m2m_relations = []
            for position, property_path in property_list.items():
                property_root = property_path.split('__')[0]
                root_class = model_class

                try:
                    property_root_class = getattr(root_class, property_root)
                except AttributeError:  # django-hstore schema compatibility
                    continue

                if type(property_root_class) == ManyToManyDescriptor:
                    display_field_paths.insert(1, '%s__pk' % property_root)
                    m2m_relations.append(property_root)

        if group:
            values = objects.values(*group)
            values = self.add_aggregates(values, display_fields)
            filtered_report_rows = [
                [row[field] for field in display_field_paths]
                for row in values
            ]
            for row in filtered_report_rows:
                for pos, field in enumerate(display_field_paths):
                    increment_total(field, row[pos])
        else:
            filtered_report_rows = []
            values_and_properties_list = []

            values_list = objects.values_list(*display_field_paths)

            for row in values_list:
                row = list(row)
                values_and_properties_list.append(row[1:])
                obj = None  # we will get this only if needed for more complex processing
                # related_objects
                remove_row = False
                # filter properties (remove rows with excluded properties)
                for property_filter in property_filters:
                    if not obj:
                        obj = model_class.objects.get(pk=row.pop(0))
                    root_relation = property_filter.path.split('__')[0]
                    if root_relation in m2m_relations:
                        pk = row[0]
                        if pk is not None:
                            # a related object exists
                            m2m_obj = getattr(obj, root_relation).get(pk=pk)
                            val = reduce(getattr, [property_filter.field], m2m_obj)
                        else:
                            val = None
                    else:
                        if property_filter.field_type == 'Custom Field':
                            for relation in property_filter.path.split('__'):
                                if hasattr(obj, root_relation):
                                    obj = getattr(obj, root_relation)
                            val = obj.get_custom_value(property_filter.field)
                        else:
                            val = reduce(getattr, (property_filter.path + property_filter.field).split('__'), obj)
                    if property_filter.filter_property(val):
                        remove_row = True
                        values_and_properties_list.pop()
                        break
                if not remove_row:
                    for i, field in enumerate(display_field_paths[1:]):
                        increment_total(field, row[i + 1])

                    for position, display_property in property_list.items():
                        if not obj:
                            obj = model_class.objects.get(pk=row.pop(0))
                        relations = display_property.split('__')
                        root_relation = relations[0]
                        if root_relation in m2m_relations:
                            pk = row.pop(0)
                            if pk is not None:
                                # a related object exists
                                m2m_obj = getattr(obj, root_relation).get(pk=pk)
                                val = reduce(getattr, relations[1:], m2m_obj)
                            else:
                                val = None
                        else:
                            # Could error if a related field doesn't exist
                            try:
                                val = reduce(getattr, relations, obj)
                            except AttributeError:
                                val = None
                        values_and_properties_list[-1].insert(position, val)
                        increment_total(display_property, val)

                    for position, display_custom in custom_list.items():
                        if not obj:
                            obj = model_class.objects.get(pk=row.pop(0))
                        val = obj.get_custom_value(display_custom)
                        values_and_properties_list[-1].insert(position, val)
                        increment_total(display_custom, val)

                    filtered_report_rows.append(values_and_properties_list[-1])

                if preview and len(filtered_report_rows) == 50:
                    break

        # Sort results if requested.

        if hasattr(display_fields, 'filter'):
            defaults = {
                None: text_type,
                datetime.date: lambda: datetime.date(datetime.MINYEAR, 1, 1),
                datetime.datetime: lambda: datetime.datetime(datetime.MINYEAR, 1, 1),
            }

            # Order sort fields in reverse order so that ascending, descending
            # sort orders work together (based on Python's stable sort). See
            # http://stackoverflow.com/questions/6666748/ for details.

            sort_fields = display_fields.filter(sort__gt=0).order_by('-sort')
            sort_values = sort_fields.values_list('position', 'sort_reverse')

            for pos, reverse in sort_values:
                column = (row[pos] for row in filtered_report_rows)
                type_col = (type(val) for val in column if val is not None)
                field_type = next(type_col, None)
                default = defaults.get(field_type, field_type)()

                filtered_report_rows = sorted(
                    filtered_report_rows,
                    key=lambda row: self.sort_helper(row[pos], default),
                    reverse=reverse,
                )

        values_and_properties_list = filtered_report_rows

        # Build mapping from display field position to choices list.

        choice_lists = {}
        for df in display_fields:
            if df.choices and hasattr(df, 'choices_dict'):
                df_choices = df.choices_dict
                # Insert blank and None as valid choices.
                df_choices[''] = ''
                df_choices[None] = ''
                choice_lists[df.position] = df_choices

        # Build mapping from display field position to format.

        display_formats = {}

        for df in display_fields:
            if hasattr(df, 'display_format') and df.display_format:
                display_formats[df.position] = df.display_format

        def formatter(value, style):
            # Convert value to Decimal to apply numeric formats.
            try:
                value = Decimal(value)
            except Exception:
                pass

            try:
                return style.string.format(value)
            except ValueError:
                return value

        # Iterate rows and convert values by choice lists and field formats.

        final_list = []

        for row in values_and_properties_list:
            row = list(row)

            for position, choice_list in choice_lists.items():
                try:
                    row[position] = text_type(choice_list[row[position]])
                except Exception:
                    row[position] = text_type(row[position])

            for pos, style in display_formats.items():
                row[pos] = formatter(row[pos], style)

            final_list.append(row)

        values_and_properties_list = final_list

        if display_totals:
            display_totals_row = []

            fields_and_properties = list(display_field_paths[0 if group else 1:])

            for position, value in property_list.items():
                fields_and_properties.insert(position, value)

            for field in fields_and_properties:
                display_totals_row.append(display_totals.get(field, ''))

            # Add formatting to display totals.

            for pos, style in display_formats.items():
                display_totals_row[pos] = formatter(display_totals_row[pos], style)

            values_and_properties_list.append(
                ['TOTALS'] + (len(fields_and_properties) - 1) * ['']
            )
            values_and_properties_list.append(display_totals_row)

        return values_and_properties_list, message