def report(): kwargs = get_report_params() date_resolution_from = kwargs.get("date_resolution_from") date_resolution_to = kwargs.get("date_resolution_to") if date_resolution_from and date_resolution_to: date_from = date_resolution_from date_to = date_resolution_to + timedelta(days=1) data_success_filters = query_payment_report_success( resolution_exists=True, resolution_date_from=date_from, resolution_date_to=date_to, ) data_failed_filters = query_payment_report_failed( message_ids_include=PAYMENTS_FAILED_MESSAGE_ID_LIST, message_ids_exclude=PAYMENTS_NOT_FAILED_MESSAGE_ID_LIST, message_ids_date_from=date_from, message_ids_date_to=date_to, ) filters = query_combined_or( [data_success_filters, data_failed_filters]) data = get_payment_results(filters)["results"] rows = get_report(data, total=True) else: date = get_now() - timedelta(days=1) return redirect( url_for("payments_views.report", date_resolution_from=date.strftime("%Y-%m-%d"), date_resolution_to=date.strftime("%Y-%m-%d"))) return render_template("payments/payment_report.html", rows=rows, **kwargs)
def test_process_handler(self, process_tender): tender = { "id": "qwa", "dateModified": get_now().isoformat(), "procurementMethodType": "aboveThresholdUA" } payments_tender_handler(tender) process_tender.delay.assert_called_with(tender_id="qwa")
def build_receipt_request(task, tenderID, lot_index, identifier, name): now = get_now() c_doc_count = get_monthly_increment_id(task, now.date()) if len("{:d}".format(c_doc_count)) > 6: logger.critical("Month doc count doesn't fit 6 signs") # I don't really expect this to happen filename = "{authority}{identifier}{c_doc}{c_doc_sub}{c_doc_ver:02d}{c_doc_stan}{c_doc_type}" \ "{env_number:d}{c_doc_count:06d}" \ "{period_type}{period_month:02d}{period_year}{authority}.xml".format( authority="2659", identifier="0" * (10 - len(FISCAL_SENDER_TIN)) + FISCAL_SENDER_TIN, c_doc="J16", # J17 for response c_doc_sub="031", c_doc_ver=REQUEST_DOC_VERSION, c_doc_stan="1", c_doc_type="00", env_number=FISCAL_BOT_ENV_NUMBER, c_doc_count=c_doc_count, period_type="1", period_month=now.month, period_year=now.year, ) template = TEMPLATES.get_template('request.xml') is_legal = len(identifier) == 8 and identifier.isdigit() context = dict( sender_tin=FISCAL_SENDER_TIN, sender_name=FISCAL_SENDER_NAME, sender_sti=FISCAL_SENDER_STI, tenderID=tenderID, lot_index=lot_index, identifier=identifier, name=name, c_doc_ver=REQUEST_DOC_VERSION, c_doc_count=c_doc_count, h_num=get_daily_increment_id(task, now.date()), now=now, is_physical=not is_legal, ) if context["is_physical"]: name_parts = name.strip().split(" ") if len(name_parts) > 0: context["last_name"] = name_parts[0] if len(name_parts) > 1: context["first_name"] = name_parts[1] if len(name_parts) > 2: context["patronymic"] = name_parts[2] content = template.render(context).encode('windows-1251', errors='ignore') return filename, content
def test_process_handler_for_non_complaint_procedures( self, process_tender): non_complaint_procedures = [ 'belowThreshold', 'reporting', 'closeFrameworkAgreementSelectionUA' ] for pmt in non_complaint_procedures: tender = { "id": "qwa", "dateModified": get_now().isoformat(), "procurementMethodType": pmt } payments_tender_handler(tender) self.assertEqual(len(process_tender.delay.mock_calls), 0)
def payment_stats(): report_kwargs = get_report_params() search_kwargs = get_payment_search_params() resolution_date_from = report_kwargs.get("date_resolution_from") resolution_date_to = report_kwargs.get("date_resolution_to") payment_date_from = search_kwargs.get("payment_date_from") payment_date_to = search_kwargs.get("payment_date_to") if payment_date_from and payment_date_to: date_from = resolution_date_from date_to = resolution_date_to + timedelta( days=1) if resolution_date_to else None filters = query_payment_results(date_from, date_to, **search_kwargs) data = get_payment_stats(filters) counts = data["counts"] min_date = parse_dt_string(RELEASE_2020_04_19).date() max_date = get_now().date() return render_template("payments/payment_stats.html", counts=counts, min_date=min_date, max_date=max_date, **search_kwargs, **report_kwargs) else: date_from = get_now() - timedelta(days=30) date_to = get_now() return redirect( url_for("payments_views.payment_stats", date_oper_from=date_from.strftime("%Y-%m-%d"), date_oper_to=date_to.strftime("%Y-%m-%d")))
def request_org_catalog(self): document = render_catalog_xml(dict(catalog_id="RefOrgs")) message_id = uuid4().hex # sign document sign = sign_data(self, document) # send request send_request(self, document, sign=sign, message_id=message_id, method_name="GetRef") expected_response_time = get_now() + timedelta(seconds=3 * 60) receive_org_catalog.apply_async( eta=expected_response_time, # requests earlier return 500 status code kwargs=dict(message_id=message_id, ))
def send_transactions_results(self, transactions_statuses, transactions_data, message_id): successful_trans_quantity = transactions_statuses.count(True) transactions_quantity = len(transactions_data) if successful_trans_quantity == 0: status_id = -1 # no records processed elif successful_trans_quantity < transactions_quantity: status_id = 1 # some records are successfully processed elif successful_trans_quantity == transactions_quantity: status_id = 0 # all records are successfully processed else: raise TransactionsQuantityServerErrorHTTPException() transactions_values_sum = float( sum([Decimal(str(trans['doc_sq'])) for trans in transactions_data])) xml_document = render_transactions_confirmation_xml( register_id=str(message_id), status_id=str(status_id), date=get_now().isoformat(), rec_count=str(successful_trans_quantity), reg_sum=str(transactions_values_sum)) sign = sign_data(self, xml_document) # sending changes message_id = uuid4().hex first_contract_id = transactions_data[0]['id_contract'] logger.info( f'ConfirmPRTrans requested data for {first_contract_id} contract: {xml_document}', extra={"MESSAGE_ID": "CONFIRM_PR_TRANS_REQUESTED_DATA"}) send_request(self, xml_document, sign, message_id, method_name="ConfirmPRTrans") logger.info( f"PRTrans confirmation xml for {first_contract_id} contract has been successful sent", extra={"MESSAGE_ID": "CONFIRM_PR_TRANS_SUCCESS_STATUS"})
def check_for_response_file(self, request_data, supplier, request_time, requests_reties): days_passed = working_days_count_since(request_time, working_weekends_enabled=True) if days_passed > WORKING_DAYS_BEFORE_REQUEST_AGAIN: if requests_reties < REQUEST_MAX_RETRIES: prepare_receipt_request.delay(supplier=supplier, requests_reties=requests_reties + 1) logger.warning( "Request retry scheduled", extra={"MESSAGE_ID": "FISCAL_REQUEST_RETRY_SCHEDULED"}) else: logger.warning("Additional requests number {} exceeded".format( REQUEST_MAX_RETRIES), extra={"MESSAGE_ID": "FISCAL_REQUEST_RETRY_EXCEED"}) else: try: response = requests.post( '{}/cabinet/public/api/exchange/kvt_by_id'.format( FISCAL_API_HOST), timeout=(CONNECT_TIMEOUT, READ_TIMEOUT), proxies=FISCAL_API_PROXIES, data=request_data) except RETRY_REQUESTS_EXCEPTIONS as e: logger.exception( e, extra={"MESSAGE_ID": "FISCAL_API_CHECK_RESPONSE_ERROR"}) raise self.retry(exc=e) else: if response.status_code != 200: logger.error( "Unsuccessful status code: {} {}".format( response.status_code, response.text), extra={"MESSAGE_ID": "FISCAL_API_CHECK_RESPONSE_ERROR"}) self.retry(countdown=response.headers.get( 'Retry-After', DEFAULT_RETRY_AFTER)) else: data = response.json() kvt_list = data.get("kvtList") or [] if data.get("status") != "OK" or not any( kv.get("finalKvt") for kv in kvt_list): for kv in kvt_list: # strip file content for logger if isinstance(kv, dict) and "kvtBase64" in kv: kv["kvtBase64"] = "{}...".format( kv["kvtBase64"][:10]) logger.warning("Unsuccessful: {}".format(data), extra={ "MESSAGE_ID": "FISCAL_API_CHECK_UNSUCCESSFUL_RESPONSE" }) # schedule next check on work time eta = get_working_datetime( get_now() + timedelta(seconds=60 * 60), custom_wd=WORKING_TIME, working_weekends_enabled=True, ) raise self.retry(eta=eta) else: for kvt in data["kvtList"]: if kvt["finalKvt"]: decode_and_save_data.delay(kvt["kvtFname"], kvt["kvtBase64"], supplier["tender_id"], supplier["award_id"]) logger.info( "Found kvt file: {}".format({ k: v for k, v in kvt.items() if k != "kvtBase64" }), extra={"MESSAGE_ID": "FISCAL_API_KVT_FOUND"})
def send_request_receipt(self, request_data, filename, supplier, requests_reties): task_args = supplier, requests_reties data = get_task_result(self, task_args) if data is None: try: response = requests.post( '{}/cabinet/public/api/exchange/report'.format( FISCAL_API_HOST), proxies=FISCAL_API_PROXIES, json=[{ 'contentBase64': request_data, 'fname': filename }]) except RETRY_REQUESTS_EXCEPTIONS as e: logger.exception( e, extra={"MESSAGE_ID": "FISCAL_API_POST_REQUEST_ERROR"}) raise self.retry(exc=e) else: if response.status_code != 200: logger.error( "Unsuccessful status code: {} {}".format( response.status_code, response.text), extra={"MESSAGE_ID": "FISCAL_API_POST_REQUEST_ERROR"}) self.retry(countdown=response.headers.get( 'Retry-After', DEFAULT_RETRY_AFTER)) else: data = response.json() if data["status"] != "OK": logger.error( "Getting receipt failed: {} {}".format( response.status_code, response.text), extra={"MESSAGE_ID": "FISCAL_API_POST_REQUEST_ERROR"}) return else: uid = save_task_result(self, data, task_args) logger.info( "Receipt requested successfully: {} {} {}; saved result: {}" .format(response.status_code, data["id"], data["kvt1Fname"], uid), extra={ "MESSAGE_ID": "FISCAL_API_POST_REQUEST_SUCCESS" }) decode_and_save_data.apply_async(kwargs=dict( name=data["kvt1Fname"], data=data["kvt1Base64"], tender_id=supplier["tender_id"], award_id=supplier["award_id"], )) # response check should be after an hour # also later we will need to know how many working days have passed since now including this # one (if it's a working day) now = get_now() check_response_time = get_working_datetime(now + timedelta(seconds=60 * 60), custom_wd=WORKING_TIME, working_weekends_enabled=True) prepare_check_request.apply_async(eta=check_response_time, kwargs=dict( uid=data["id"], supplier=supplier, request_time=now, requests_reties=requests_reties, )) logger.info("Fiscal receipt check of {} scheduled at {}".format( data["id"], check_response_time), extra={"MESSAGE_ID": "FISCAL_API_CHECK_SCHEDULE"})
def payments_tender_handler(tender, **kwargs): delta = get_now() - parse_dt_string(tender['dateModified']) if delta < timedelta(days=PAYMENTS_SKIP_TENDER_DAYS): if tender.get('procurementMethodType') not in non_complaint_procedures: process_tender.delay(tender_id=tender['id'])