def test_atol_report_unrecoverable_errors(status, params, set_atol_token): atol = AtolAPI() set_atol_token('12345') payment_uuid = str(uuid4()) responses.add(responses.GET, ATOL_BASE_URL + '/ATOL-ProdTest-1/report/%s' % payment_uuid, status=status, **params) with pytest.raises(AtolUnrecoverableError): atol.report(payment_uuid)
def atol_receive_receipt_report(self, receipt_id): """ Attempt to retrieve a receipt report for given receipt_id If received an unrecoverable error, then stop any further attempts to receive the report """ atol = AtolAPI() Receipt = apps.get_model('atol', 'Receipt') receipt = Receipt.objects.get(id=receipt_id) if not receipt.uuid: logger.error('receipt %s does not have a uuid', receipt.id) return if receipt.status not in [ReceiptStatus.initiated, ReceiptStatus.retried]: logger.error('receipt %s has invalid status: %s', receipt.uuid, receipt.status) return try: report = atol.report(receipt.uuid) except AtolUnrecoverableError as exc: logger.error('unable to fetch report for receipt %s due to %s', receipt.id, exc, exc_info=True) receipt.declare_failed() except AtolReceiptNotProcessed as exc: logger.warning('unable to fetch report for receipt %s due to %s', receipt.id, exc, exc_info=True) logger.info('repeat receipt registration: id %s; old internal_uuid %s', receipt.id, receipt.internal_uuid) with transaction.atomic(): receipt.internal_uuid = uuid4() receipt.status = ReceiptStatus.retried receipt.save(update_fields=['internal_uuid', 'status']) transaction.on_commit(lambda: atol_create_receipt.apply_async( args=(receipt.id, ), countdown=60)) except Exception as exc: logger.warning('failed to fetch report for receipt %s due to %s', receipt.id, exc, exc_info=True) try: countdown = 60 * int(math.exp(self.request.retries)) logger.info( 'retrying to receive receipt %s with countdown %s due to %s', receipt.id, countdown, exc) self.retry(countdown=countdown) except MaxRetriesExceededError: logger.error('run out of attempts to create receipt %s due to %s', receipt.id, exc) receipt.declare_failed() else: with transaction.atomic(): receipt.receive(content=report.data)
def atol_receive_receipt_report(self, receipt_id): """ Attempt to retrieve a receipt report for given receipt_id If received an unrecoverable error, then stop any further attempts to receive the report """ atol = AtolAPI() Receipt = apps.get_model('atol', 'Receipt') receipt = Receipt.objects.get(id=receipt_id) if not receipt.uuid: logger.error('receipt %s does not have a uuid', receipt.id) return if receipt.status != ReceiptStatus.initiated: logger.error('receipt %s has invalid status: %s', receipt.uuid, receipt.status) return try: report = atol.report(receipt.uuid) except AtolUnrecoverableError as exc: logger.error('unable to fetch report for receipt %s due to %s', receipt.uuid, exc, exc_info=True) receipt.declare_failed() return except Exception as exc: logger.warning('failed to fetch report for receipt %s due to %s', receipt_id, exc, exc_info=True) try: countdown = 60 * int(math.exp(self.request.retries)) logger.info( 'retrying to receive receipt %s with countdown %s due to %s', receipt.id, countdown, exc) self.retry(countdown=countdown) except MaxRetriesExceededError: logger.error('run out of attempts to create receipt %s due to %s', receipt.id, exc) receipt.declare_failed() else: with transaction.atomic(): receipt.receive(content=report.data)
def test_atol_create_receipt_workflow(): uid = '973f3bef-1c39-40c9-abd0-33a91ab005ca' # get Token data = { 'code': 1, 'text': None, 'token': '84a50b3a6207421aba46834d650b42a0' } url = ATOL_BASE_URL + '/getToken' responses.add(responses.POST, url, status=200, json=data) # sell data = { 'uuid': uid, 'timestamp': '13.07.2017 18:32:49', 'status': 'wait', 'error': None } url = ATOL_BASE_URL + '/ATOL-ProdTest-1/sell' responses.add(responses.POST, url, status=200, json=data) # report error data = { 'uuid': uid, 'timestamp': '13.07.2017 18:32:49', 'status': 'wait', 'error': { 'error_id': 'e710f5de-0b20-47de-8ae8-d193016c5a4e', 'code': 34, 'text': 'Нет информации, попробуйте позднее', 'type': 'system' }, 'payload': None } url = ATOL_BASE_URL + '/ATOL-ProdTest-1/report/' + uid responses.add(responses.GET, url, status=200, json=data) # report ok data = { 'uuid': uid, 'error': None, 'status': 'done', 'payload': { 'total': 199.99, 'fns_site': 'www.nalog.ru', 'fn_number': '9999078900003780', 'shift_number': 114, 'receipt_datetime': '13.07.2017 18:32:00', 'fiscal_receipt_number': 1412, 'fiscal_document_number': 50066, 'ecr_registration_number': '1029384756033729', 'fiscal_document_attribute': 2649836604 }, 'timestamp': '13.07.2017 18:32:50', 'group_code': 'ATOL-ProdTest-1', 'daemon_code': 'prod-agent-1', 'device_code': 'KSR13.11-3-1', 'external_id': 'TRF20801_1', 'callback_url': '', } url = ATOL_BASE_URL + '/ATOL-ProdTest-1/report/' + uid responses.add(responses.GET, url, status=200, json=data) # sell error data = { 'uuid': uid, 'timestamp': '13.07.2017 18:32:50', 'status': 'fail', 'error': { 'error_id': '01b46c9d-f829-4ecf-b07c-7b096d0b985e', 'code': 33, 'text': 'В системе существует чек с external_id : ec0ce0c6-7a31-4f45-b94f-a1442be3bb9c ' 'и group_code: ATOL-ProdTest-1', 'type': 'system', } } url = ATOL_BASE_URL + '/ATOL-ProdTest-1/sell' responses.add(responses.POST, url, status=200, json=data) atol = AtolAPI() now = datetime(2017, 11, 22, 10, 47, 32) payment_uuid = str(uuid4()) sell_params = dict(timestamp=now, transaction_uuid=payment_uuid, purchase_name=u'Стандартная подписка на 1 месяц', purchase_price='199.99', user_email='*****@*****.**', user_phone='+75551234567') receipt = atol.sell(**sell_params) assert receipt.uuid == '973f3bef-1c39-40c9-abd0-33a91ab005ca' assert receipt.data['status'] == 'wait' # report is not ready yet with pytest.raises(AtolRecoverableError): atol.report(receipt.uuid) report = atol.report(receipt.uuid) assert report.data['group_code'] == 'ATOL-ProdTest-1' assert report.data['status'] == 'done' assert report.data['payload']['total'] == 199.99 # another celery worker somehow requested the same payment receipt double_receipt = atol.sell(**sell_params) assert double_receipt.uuid == '973f3bef-1c39-40c9-abd0-33a91ab005ca' assert double_receipt.data['status'] == 'fail'