Beispiel #1
0
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)
Beispiel #2
0
 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")
Beispiel #3
0
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
Beispiel #4
0
 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)
Beispiel #5
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")))
Beispiel #6
0
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, ))
Beispiel #7
0
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"})
Beispiel #8
0
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"})
Beispiel #9
0
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"})
Beispiel #10
0
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'])