示例#1
0
    def wrapper(*args, **kwargs):
        try:
            result = func(*args, **kwargs)
            if result.get('error'):
                msg = f'Ошибка при открытии порта: {result}'
                _msg = f'{result.get("description_error", "")} {result.get("message", "")}'

                raise CashboxException(data=_msg, to_logging=msg)
                # raise CashboxException(data=msg)
            if result.get('status_printer_error_code'):
                if result['status_printer_error_code'] > 0:
                    code = result['status_printer_error_code']
                    err_msg = result['status_printer_message']
                    msg = f'Ошибка фискального регистратора: ' \
                          f'Код: {code} Сообщение: {err_msg}'
                    raise CashboxException(data=msg, to_logging=f'Ошибка фискальника {result}')
            return result

        except CashboxException as c_exc:
            msg = f'Фискальный регистратор не смог ' \
                  f'выполнить функцию ({func.__name__}) ' \
                  f'Тип ошибки: {c_exc.__class__.__name__} ' \
                  f'Описание: {str(c_exc)}'
            to_log = c_exc.to_logging if c_exc.to_logging else msg
            raise CashboxException(data=msg, to_logging=to_log)
        except Exception as exc:
            msg = f'Фискальный регистратор не смог ' \
                  f'выполнить функцию ({func.__name__}) ' \
                  f'Тип ошибки: {exc.__class__.__name__} ' \
                  f'Описание: {str(exc)}'
            raise CashboxException(data=msg)
示例#2
0
 async def wrapper(*args, **kwargs):
     msg = 'Смена в фискальном регистраторе'
     if not _is_fiscal_shift_opened(kwargs):
         if err_if_closed:
             raise CashboxException(data=msg + ' уже закрыта')
         else:
             return await func(*args, **kwargs)
     else:
         raise CashboxException(data=msg + ' еще открыта')
示例#3
0
async def return_order(*args, **kwargs):
    req_data, kkt_info = kwargs['valid_schema_data'], kwargs[
        'opened_port_info']

    cashier_name = req_data['cashier_name']
    cashier_id = req_data['cashier_id']
    order_uuid = req_data['internal_order_uuid']
    doc_type = DocumentTypes.RETURN.value
    cashbox = Cashbox.box()
    order = Order.objects(clientOrderID=order_uuid).first()

    if not order:
        msg = 'Нет такого заказа'
        raise CashboxException(data=msg)

    if order.returned:
        msg = 'Этот заказ уже был возвращен'
        raise CashboxException(data=msg)

    order_dict = OrderSchema().dump(order).data
    kkt_kwargs = {
        'cashier_name': cashier_name,
        'document_type': doc_type,
        'payment_type': order_dict['payType'],
        'wares': order_dict['wares'],
        'amount_entered': order_dict['amount_with_discount'],
        'pay_link': order_dict['payLink'],
        'order_prefix': order_dict['order_prefix']
    }

    canceled_order = KKTDevice.handle_order(**kkt_kwargs)

    if PaymentChoices.CASH.value == kkt_kwargs['payment_type']:
        cashbox.update_shift_money_counter(DocumentTypes.RETURN,
                                           order_dict['amount_with_discount'])

    order.returned = True
    order.return_cashier_name = cashier_name
    order.return_cashier_id = cashier_id
    order.return_date = canceled_order['datetime']
    order.save().reload()

    to_paygate = PaygateOrderSchema(
        only=['clientOrderID', 'cashID', 'checkNumber']).dump(order).data
    to_paygate.update({'creation_date': canceled_order['datetime']})
    to_paygate.update({'proj': cashbox.project_number})
    to_paygate.update({'url': PaygateURLs.cancel_order})
    cashbox.save_paygate_data_for_send(to_paygate)
    return {}
示例#4
0
async def make_request(url: str, method: str, data, do_raise=True):
    try:
        async with ClientSession() as session:
            async with session.request(method, url, json=data) as result:
                if result.status >= 400:
                    if not do_raise:
                        return
                    err = await result.text()
                    raise CashboxException(data=err)
                return await result.json()
        # result = await app.aiohttp_requests.request(method, url, json=data)
    except ClientError as exc:
        if do_raise:
            msg = f'Класс ошибки: {exc.__class__}; Детали ошибки: {str(exc)}'
            raise CashboxException(data=msg)
        else:
            return
示例#5
0
def create_user(**kwargs):
    data = kwargs['valid_schema_data']
    if is_user_exist(data['login']):
        msg = f'Этот пользователь с таким логином ( {data["login"]} ) уже существует'
        raise CashboxException(data=msg, to_logging=msg)
    hash_password_if_exist(data)
    lowercase_login(data)
    return Users(**data).save()
示例#6
0
async def request_to_paygate(url: str,
                             method: str,
                             data: Dict,
                             do_raise_if_500=True) -> Dict:
    content = await make_request(url, method, data)
    if content['statusCode'] != 200:
        msg = f'Paygate вернул код ответа 500. Сообщение: {content["errorMessage"]}'
        if do_raise_if_500:
            raise CashboxException(data=msg)
    return content
示例#7
0
def get_model_by_id_or_raise(model,
                             model_id,
                             include_nested=False,
                             nested_deep=1):
    try:
        if include_nested:
            return model.objects.get(id=model_id).select_related(
                max_depth=nested_deep)
        else:
            return model.objects.no_dereference().get(id=model_id)
    except (DoesNotExist, ValidationError):
        msg = f'No such element with id of ({model_id})'
        raise CashboxException(data=msg, to_logging=msg)
示例#8
0
        async def wrapper(*args, **kwargs):
            cb = Cashbox.box()
            is_opened_fiscal_shift = kwargs['opened_port_info'][
                'is_open_shift']
            current_fiscal_shift_number = kwargs['opened_port_info'][
                'shift_number']
            actual_fiscal_device_number = kwargs['opened_port_info'][
                'fn_number']
            current_fiscal_device_number_in_db = cb.cash_id
            current_shift_in_db = cb.current_opened_shift

            if current_fiscal_device_number_in_db != actual_fiscal_device_number:
                raise CashboxException(data=ERR_IF_FISCAL_ID_NOT_SYNCED)
            if skip_shift_check:
                return await func(*args, **kwargs)
            if is_opened_fiscal_shift:
                if current_shift_in_db:
                    check_current_shift_is_expired(current_shift_in_db)
                    if current_shift_in_db.shiftNumber != current_fiscal_shift_number:
                        raise CashboxException(
                            data=ERR_SHIFT_NUMBER_NOT_SYNCED)
                else:
                    # Экстренное закрытие смены
                    urgent_close_shift(current_fiscal_device_number_in_db, cb)
                    KKTDevice.force_close_shift()
                    msg = f'{ERR_FISCAL_SHIFT_OPENED_BUT_NOT_IN_DB}. ' \
                          f'Смена закрыта принудительно. ' \
                          f'Теперь откройте смену'
                    raise CashboxException(data=msg)
            else:
                if current_shift_in_db:
                    # Экстренное закрытие смены
                    urgent_close_shift(current_fiscal_device_number_in_db, cb)
                    cb.current_opened_shift = None
                    cb.save()
                    raise CashboxException(
                        data=ERR_DB_SHIFT_OPENED_BUT_NOT_IN_FISCAL)
            return await func(*args, **kwargs)
示例#9
0
    def handle_order(*args, **kwargs):
        cashier = kwargs['cashier_name'] or DEFAULT_CASHIER_NAME
        p_type = kwargs['payment_type']
        d_type = kwargs['document_type']
        order_number = kwargs.get('order_number', 0)
        wares = kwargs['wares']
        money_given = kwargs.get('amount_entered', 0)
        pay_link = kwargs.get('pay_link', '')
        pref = kwargs.get('order_prefix', '')
        order_number += 1
        print('orderr number -> ', order_number, 'pay_link ', pay_link)
        text = f"\n\n\n--------------------------------------------\n" \
               f"(font-style=BIG_BOLD)     НОМЕР ЗАКАЗА: (font-style=BIG_BOLD){pref}{order_number}" \
               f"\n --------------------------------------------\n\n"
        result = real_kkt.new_transaction(
            cashier=cashier, payment_type=p_type, doc_type=d_type,
            wares=copy.copy(wares), amount=money_given, rrn=pay_link,
            # order_prefix=pref,
            print_strings=text if d_type == DocumentTypes.PAYMENT else ''
        )

        if result['error']:
            msg = f'Ошибка во время транзакции: {result["message"]}'
            raise CashboxException(data=msg, to_logging=msg + f'\nИнформация: {result}')

        from pprint import pprint as pp
        print('FROM FISKALNIK')
        pp(result)

        info = {}
        transaction_sum = round_half_down(result['transaction_sum'] - result['discount_sum'], 2)
        info['cashier_name'] = result['cashier']
        info['datetime'] = result['datetime']
        info['doc_number'] = result['doc_number']
        # При наличном платеже с пирита приходит transaction_sum без округления в меньшую сторону,
        # и пока можно оставить строчку ниже без изменений
        info['total_without_discount'] = round_half_down(result['transaction_sum'], 2)

        info['transaction_sum'] = transaction_sum
        # info['check_number'] = result['check_number']
        info['check_number'] = str(int(str(result['check_number']).rsplit('.', maxsplit=1)[-1]))
        info['order_num'] = order_number
        info['rrn'] = result.get('rrn', '')
        info['pan_card'] = result.get('pan_card', '')
        info['cardholder_name'] = result.get('cardholder_name', '')
        return info
示例#10
0
 def wrapper(*args, **kwargs):
     try:
         result = func(*args, **kwargs)
         return result
     except Exception as exc:
         msg = f'Фискальный регистратор не смог ' \
               f'выполнить функцию ({func.__name__}) ' \
               f'Тип ошибки: {exc.__class__.__name__} ' \
               f'Описание: {str(exc)}'
         # pp(exc_info()[2])
         # print_tb(exc_info()[2], 20)
         print(''.join(
             traceback.format_exception(etype=type(exc),
                                        value=exc,
                                        tb=exc.__traceback__)))
         Spark115f.kkt_object.DeinitDevice()
         raise CashboxException(data=msg)
示例#11
0
async def init_cashbox(*args, **kwargs):
    """ Первоначальная инициализация кассы. """

    result = kwargs['opened_port_info']
    shop_num, cash_id, sys_id = (CS['shopNumber'], result.get('fn_number'),
                                 System.get_sys_id())

    if not cash_id:
        err = 'Ошибка: Не удалось получить из ККТ fn_number'
        raise CashboxException(data=err)

    # # proj - номер системы, с которой происходит запрос
    obj = {'shop': shop_num, 'cashID': cash_id, 'systemID': sys_id, 'proj': 1}
    print('request to paygate -> ', obj)
    paygate_content = await request_to_paygate(
        CS['paygateAddress'] + PaygateURLs.register_cash, 'post', obj)
    print('response from paygate', paygate_content)
    cash_num = paygate_content.get('cashNumber')

    cashbox = Cashbox.objects(cash_id=cash_id, cash_number=cash_num).first()
    Cashbox.set_all_inactive()
    if cashbox:
        cashbox.reload()
        cashbox.activation_date = result['datetime']
        cashbox.is_active = True
        cashbox.save().reload()
        print('is cashbox active right now? ', cashbox.is_active)
    else:
        cashbox = Cashbox()
        cashbox.creation_date = result['datetime']
        cashbox.shop = CS['shopNumber']
        cashbox.cash_number = cash_num
        cashbox.cash_name = CS['cashName']
        cashbox.cash_id = cash_id
        cashbox.project_number = obj['proj']
        cashbox.save().reload()
示例#12
0
async def partial_return(*args, **kwargs):
    cashbox = Cashbox.box()
    kkt_info = kwargs['opened_port_info']
    data = kwargs['valid_schema_data']
    order_id = data['internal_order_uuid']
    doc_type = DocumentTypes.RETURN.value
    data_for_checkstatus = {
        'proj': cashbox.project_number,
        'clientOrderID': order_id
    }
    checkstatus_url = CS['paygateAddress'] + PaygateURLs.check_order_status
    return_part_url = CS['paygateAddress'] + PaygateURLs.refund_part
    checkstatus = await request_to_paygate(checkstatus_url, 'POST',
                                           data_for_checkstatus)

    # print('| chekstatus response -> ', checkstatus)

    if checkstatus['orderStatus'] == 'cancelled':
        msg = 'Этот заказ уже был отменён'
        to_log = msg + f'\nОтвет с платежного шлюза: {checkstatus}'
        raise CashboxException(data=msg, to_logging=to_log)

    valid_sum = checkstatus['confirmedSum']

    _wares = []
    total_wares_sum = 0

    for ware in data['wares']:
        total_wares_sum += ware['priceDiscount'] * ware['quantity']
        _wares.append({
            'name': ware['name'],
            'price': ware['priceDiscount'],
            'priceDiscount': ware['priceDiscount'],
            'barcode': ware['barcode'],
            'tax_number': ware['tax_number'],
            'quantity': ware['quantity'],
            'discount': 0,
            'posNumber': ware['posNumber']
        })
    total_wares_sum = round_half_down(total_wares_sum, 2)

    # print('total wares sum ', total_wares_sum, 'valid sum ', valid_sum)
    if total_wares_sum > valid_sum:
        msg = 'Сумма переданых товаров превышает оставшуюся сумму заказа!'
        to_log = msg + f'\nСумма товаров: {total_wares_sum} \nСумма заказа в paygate: {valid_sum}'
        raise CashboxException(data=msg, to_logging=to_log)

    to_kkt = {
        'total_wares_sum': total_wares_sum,
        'cashier_name': data['cashier_name'],
        'payment_type': data['payment_type'],
        'document_type': doc_type,
        'amount_entered': data['total_price_with_discount'],
        'pay_link': data['payment_link'],
        'wares': _wares
    }

    result = KKTDevice.handle_order(**to_kkt)

    # pp('formatted info!!!')
    # pp(result)

    to_paygate = {
        'clientOrderID': order_id,
        'proj': cashbox.project_number,
        'wares': _wares,
        'checkNumber': int(result['check_number']),
        'cashID': kkt_info['fn_number'],
        'refundAmount': result['transaction_sum']
    }

    try:
        content = await request_to_paygate(return_part_url, 'POST', to_paygate)
    except CashboxException as exc:
        to_kkt['document_type'] = DocumentTypes.PAYMENT.value
        # TODO: Что-нибудь придумать с этим кейсом. Пока что это не работает должным образом
        KKTDevice.handle_order(**to_kkt)
        raise CashboxException(data=exc.data['errors'], to_logging=exc.data)

    # print('| refund_part response -> ', content)

    return {'actual_order_price': content.get('confirmedSum', 0)}
示例#13
0
async def create_order(*args, **kwargs):
    cashbox = Cashbox.box()
    # raise CashboxException(data='Holy Shield')
    if not cashbox.cash_character:
        msg = 'Символ кассы отсутствует. Зарегистрируйте'
        raise CashboxException(data=msg)

    req_data, kkt_info = kwargs['valid_schema_data'], kwargs[
        'opened_port_info']
    cashier_name = req_data['cashier_name']
    cashier_id = req_data['cashier_id']
    payment_type = req_data['payment_type']
    document_type = DocumentTypes.PAYMENT.value
    amount_entered = req_data['amount_entered']
    wares = req_data['wares']
    character = cashbox.cash_character
    real_money = False
    order_prefix = f'{character}-'
    order_number = cashbox.get_shift_order_number()

    if payment_type == PaymentChoices.CASH:
        wares = find_and_modify_one_ware_with_discount(wares)
        real_money = True
    elif payment_type == PaymentChoices.NON_CASH:
        amount_entered = 0

    wares = _build_wares(wares)

    kkt_kwargs = {
        'cashier_name': cashier_name,
        'payment_type': payment_type,
        'document_type': document_type,
        'order_prefix': order_prefix,
        'order_number': order_number,
        'amount_entered': amount_entered,
        'wares': wares
    }
    created_order = KKTDevice.handle_order(**kkt_kwargs)

    cashbox.modify_shift_order_number()
    data_to_db = {
        'cashier_name': created_order['cashier_name'],
        'cashier_id': cashier_id,
        'clientOrderID': generate_internal_order_id(),
        'amount': created_order['total_without_discount'],
        'amount_with_discount': created_order['transaction_sum'],
        'creation_date': created_order['datetime'],
        'cashID': cashbox.cash_id,
        'checkNumber': get_cheque_number(created_order['check_number']),
        'order_number': created_order['order_num'],
        'doc_number': created_order['doc_number'],
        'cardHolder': created_order.get('cardholder_name', ''),
        'pan': created_order.get('pan_card', ''),
        'payLink': created_order.get('rrn', ''),
        'payType': payment_type,
        'paid': 1,
    }

    if real_money:
        cashbox.update_shift_money_counter(DocumentTypes.PAYMENT,
                                           created_order['transaction_sum'])

    # data_to_db.update({'wares': _build_wares(wares)})
    order, errs = OrderSchema().load({**kkt_kwargs, **data_to_db})
    pp(errs)
    to_paygate, _errs = PaygateOrderSchema().dump(order)
    to_paygate.update({'amount': data_to_db['amount_with_discount']})
    to_paygate.update({'proj': cashbox.project_number})
    to_paygate.update({'url': PaygateURLs.new_order})

    pp('to paygate')
    pp(to_paygate)
    cashbox.add_order(order)
    cashbox.save_paygate_data_for_send(to_paygate)

    to_print = {
        'pref': order_prefix,
        'num': data_to_db['order_number'],
        'wares': wares
    }
    await print_to_secondary_printer(to_print)

    to_response, errs = ConvertToResponseCreateOrder().load({
        'device_id':
        System.get_sys_id(),
        **kkt_kwargs,
        **data_to_db
    })
    return to_response
示例#14
0
def check_current_shift_is_expired(curr_shift):
    is_expired = (datetime.now() -
                  timedelta(hours=24)) > curr_shift.creation_date
    if is_expired:
        raise CashboxException(data=ERR_MSG_SHIFT_IS_EXPIRED)