Ejemplo n.º 1
0
class Unittest(unittest.TestCase):
    def setUp(self):
        self.tools = Tools()

    def test_get_utc_epoch(self):
        date = '13.04.2018 13:40'
        result = self.tools.get_utc_epoch(date)
        self.assertEqual(1523608800000, result)

    def test_get_utc_epoch_none(self):
        date = None
        result = self.tools.get_utc_epoch(date)
        self.assertIsNone(result)
Ejemplo n.º 2
0
class Unittest(unittest.TestCase):
    def setUp(self):
        self.tools = Tools()

    def test_get_utc_epoch(self):
        date = '14.05.2018'
        result = self.tools.get_utc_epoch(date)
        self.assertEqual(1526256000000, result)
Ejemplo n.º 3
0
class Mapper:
    """
    Класс-маппер (перевод из обработанных данных в модель для отправки в менеджер очередей RabbitMQ)
    """
    def __init__(self):
        self.tools = Tools()

    @staticmethod
    def get_organisations_search(lot, org):
        """на roseltorg.ru кпп не указано"""
        return lot['customer'] if lot['customer'] else ''

    @staticmethod
    def get_customer_model_list(lot, org):
        return [{
            'guid': None,
            'name': lot['customer'] if lot['customer'] else org['name'],
            'region': int(org['region']) if org['region'] else None
        }]

    @staticmethod
    def get_global_search(item, lot):
        return '{} {} {} {}'.format(
            item['number'],
            item['name'] if item['name'] else '',
            lot['customer'] if lot['customer'] else '',
            item['type'] if item['type'] else ''
        )

    @staticmethod
    def get_tender_search(item, lot):
        return '{} {} {}'.format(
            item['number'] if item['number'] else '',
            item['name'] if item['name'] else lot['name'],
            lot['customer'] if lot['customer'] else ''
        )

    def get_attachments(self, files):
        attachments = []
        for file in files:
            attachments.append({
                'displayName': file['display_name'],
                'href': file['url'],
                'publicationDateTime': self.tools.get_utc_epoch(
                    file['publication_date'][0], file['publication_date'][1]),
                'realName': file['real_name'],
                'size': None
            })
        return attachments

    def map(self, item, multilot, org, attachments, lot, tender_lot_id):
        """
        Функция маппинга итоговой модели
        """

        model = {
            # Идентификатор тендера (Тендер+Лот)
            # Для каждого лота в тендере создается отдельная модель
            'id': tender_lot_id,
            # Массив заказчиков
            # [{
            #   guid = идентификатор организации (str/None),
            #   name = название организации (str),
            #   region = регион организации (int/None),
            # }]
            'customers': self.get_customer_model_list(lot, org),
            # массив документов
            'attachments': self.get_attachments(attachments),
            'globalSearch': self.get_global_search(item, lot),
            'guaranteeApp': lot['guarantee_app'],
            'href': item['link'],
            'json': None,
            # Максимальная (начальная) цена тендера
            'maxPrice': lot['price'],
            'multilot': multilot,
            'number': item['number'],
            # Массив ОКПД (если присутствует) ex. ['11.11', '20.2']
            'okdp': [],
            # Массив ОКПД2 (если присутствует)
            'okpd': [],
            # Массив ОКДП (если присутствует)
            'okpd2': [i.split()[0] for i in lot['okpd2']] if lot['okpd2'] else [],
            'orderName': item['name'],
            'organisationsSearch': self.get_organisations_search(lot, org),
            'placingWay': self.get_placingway(item['type']),
            'platform': {
                'href': 'https://etpgpb.ru/',
                'name': 'ЭТП ГПБ',
            },
            # Дата публикации тендера UNIX EPOCH (UTC)
            'publicationDateTime': self.tools.get_utc_epoch(lot['publication_date'][0], lot['publication_date'][1]),
            'region': int(org['region']) if org['region'] else None,
            # Дата окончания подачи заявок UNIX EPOCH (UTC)
            'submissionCloseDateTime': self.tools.get_utc_epoch(
                lot['sub_close_date'][0], lot['sub_close_date'][1]) if lot['sub_close_date'] else None,
            # Дата начала подачи заявок UNIX EPOCH (UTC)
            'submissionStartDateTime': self.tools.get_utc_epoch(lot['publication_date'][0], lot['publication_date'][1]),
            'tenderSearch': self.get_tender_search(item, lot),
            # Дата маппинга модели в UNIX EPOCH (UTC) (milliseconds)
            'timestamp': self.tools.get_utc(),
            'status': self.get_status(lot['status']),
            # Версия извещения
            # Если на площадке нет версии, то ставить 1
            'version': 1,
            'kind': 0,
            'type': 18,
            'ktru': ["string"],
            "modification": {
                'modDateTime': '',
                'reason': ''
            },
            'futureNumber': 'string',
            'scoringDateTime': 'long',
            'biddingDateTime': 'long',
            'preference': [],
            'group': None,
        }

        model['json'] = self.get_json(
            model,
            lot,
            org
        )
        return model

    def get_placingway(self, org_form):
        """
        Получение способа определения поставщика
        т.к. на площадке присутствуют не все виды, то
        задействованы только присутствующие
        #     Открытый конкурс = 1,
        #     Открытый аукцион = 2,
        #     Открытый аукцион в электронной форме = 3,
        #     Запрос котировок = 4,
        #     Предварительный отбор = 5,
        #     Закупка у единственного поставщика (подрядчика, исполнителя) = 6,
        #     Конкурс с ограниченным участием = 7,
        #     Двухэтапный конкурс = 8,
        #     Закрытый конкурс = 9,
        #     Закрытый конкурс с ограниченным участием = 10,
        #     Закрытый двухэтапный конкурс = 11,
        #     Закрытый аукцион = 12,
        #     Запрос котировок без размещения извещения = 13,
        #     Запрос предложений = 14,
        #     Электронный аукцион = 15,
        #     Иной многолотовый способ = 16,
        #     Сообщение о заинтересованности в проведении открытого конкурса = 17,
        #     Иной однолотовый способ = 18
        """

        if org_form in ['Аукцион на повышение', 'Аукцион на понижение']:
            return 15
        elif org_form in ['Запрос предложений']:
            return 14
        elif org_form in ['Запрос цен']:
            return 16
        elif org_form in ['Попозиционные торги']:
            return 18
        elif org_form in ['Запрос котировок']:
            return 4
        elif org_form in ['Предварительный отбор']:
            return 5
        elif org_form in ['Конкурс']:
            return 1
        elif org_form in ['Открытая тендерная закупка в электронной форме']:
            return 16
        else:
            return 5000

    @staticmethod
    def get_status(string):
        """
        Получения статуса тендера
        при изменении статуса тендер должен отсылаться в RabbitMQ
        #   Без статуса = 0,
        #   Опубликован = 1,
        #   На рассмотрении комиссии = 2,
        #   Закрыт = 3,
        #   Отменен = 4,
        #   Приостановлен = 5,
        #   Исполнение завершено = 6,
        #   Исполняется = 7,
        #   Приостановлено определение поставщика = 8
        т.к. на площадке присутствуют не все виды, то 
        задействованы только присутствующие

            status[
            , , , , , , , ]
        """

        if string is None or string.strip() == '':
            return 0
        elif string in ['Прием заявок на участие', ]:
            return 1
        elif string in ['Подведение итогов', 'Вскрытие конвертов', 'Рассмотрение первых частей заявок']:
            return 2
        elif string in ['Заключение договора', 'Проведение аукциона']:
            return 7
        elif string in ['Архив']:
            return 3
        elif string == 'Процедура отменена':
            return 4

    @staticmethod
    def get_currency_mod(lot_currency):
        if lot_currency == 'RUB':
            return Modification.CurRUB
        elif lot_currency == 'USD':
            return Modification.CurUSD
        elif lot_currency == 'EUR':
            return Modification.CurEUR

    def get_json(self, model, lot, org):
        """
        Получение модели для рендера
        Использует sharedmodel модуль

        В данной модели обязательно присутствие:
        * general - основная информация
        * customer - заказчик

        В данной модели должно быть как можно больше информации о тендере
        (сроки поставки, вскрытия конвертов итп)

        """
        return Root()\
            .add_customer(
                Customer().set_properties(
                    max_price=model['maxPrice'],
                    guarantee_app=model['guaranteeApp'],
                    guarantee_contract=None,
                    customer_guid=model['customers'][0]['guid'],
                    customer_name=model['customers'][0]['name']
                )
            ).add_category(
                lambda c: c.set_properties(
                    name='ObjectInfo',
                    displayName='Информация об объекте закупки',
                ).add_table(
                    lambda t: t.set_properties(
                        name='Objects',
                        displayName='Объекты закупки'
                    ).set_header(
                        lambda th: th.add_cells([
                            Head(name='Name', displayName='Наименования товара, работы, услуги'),
                            Head(name='Count', displayName='Количество')
                        ])
                    ).add_rows(
                        [element for element in enumerate(lot['positions'], start=1)],
                        lambda el, row: row.add_cells([
                            Cell(
                                name='Name',
                                type=FieldType.String,
                                value=el[1].get('name').strip('"'),
                                modifications=[]
                            ),
                            Cell(
                                name='Count',
                                type=FieldType.String,
                                value=el[1].get('quantity'),
                                modifications=[]
                            )
                        ])
                    )
                )
            ).add_category(
                lambda c: c.set_properties(
                    name='procedureInfo',
                    displayName='Порядок размещения заказа',
                    modifications=[]
                ).add_field(
                    Field(
                        name='PublicationtDateTime',
                        displayName='Дата публикации',
                        value=model['publicationDateTime'],
                        type=FieldType.DateTime,
                        modifications=[Modification.Calendar]
                    )
                ).add_field(
                    Field(
                        name='AcceptOrderEndDateTime',
                        displayName='Дата и время окончания срока приема заявок',
                        value=model['submissionCloseDateTime'],
                        type=FieldType.DateTime,
                        modifications=[Modification.Calendar]
                    )
                ).add_field(
                    Field(
                        name='ScoringStartDateTime',
                        displayName='Дата и время вскрытия заявок',
                        value=self.tools.get_utc_epoch(
                            lot['order_view_date'][0], lot['order_view_date'][1]) if lot['order_view_date'] else None,
                        type=FieldType.DateTime,
                        modifications=[]
                    )
                ).add_field(        #
                    Field(
                        name='ScoringEndDateTime',
                        displayName='Дата подведения итогов',
                        value=self.tools.get_utc_epoch(
                            lot['scoring_date'][0], lot['scoring_date'][1]) if lot['scoring_date'] else None,
                        type=FieldType.DateTime,
                        modifications=[]
                    )
                ).add_field(
                    Field(
                        name='TradeDateTime',
                        displayName='Дата проведения торгов',
                        value=self.tools.get_utc_epoch(
                            lot['trade_date'][0], lot['trade_date'][1]) if lot['trade_date'] else None,
                        type=FieldType.Date,
                        modifications=[]
                    )
                )
            ).add_category(
                lambda c: c.set_properties(
                    name='Contacts',
                    displayName='Контактная информация',
                    modifications=[]
                ).add_field(Field(
                    name='Organization',
                    displayName='Организация',
                    value=org['name'],
                    type=FieldType.String,
                    modifications=[]
                    )
                ).add_field(Field(
                    name='ActualAddress',
                    displayName='Фактический адрес',
                    value=org['actual_address'],
                    type=FieldType.String,
                    modifications=[]
                    )
                ).add_field(Field(
                    name='PostAddress',
                    displayName='Почтовый адрес',
                    value=org['post_address'],
                    type=FieldType.String,
                    modifications=[]
                    )
                ).add_array(
                    lambda ar: ar.set_properties(
                        name='Contacts',
                        displayName='Контакты',
                        modifications=[Modification.HiddenLabel]
                    ).add_field(Field(
                        name='FIO',
                        displayName='ФИО',
                        value=org['fio'],
                        type=FieldType.String,
                        modifications=[Modification.HiddenLabel]
                        )
                    ).add_field(Field(
                        name='Phone',
                        displayName='Телефон',
                        value=org['phone'],
                        type=FieldType.String,
                        modifications=[]
                        )
                    ).add_field(Field(
                        name='Email',
                        displayName='Электронная почта',
                        value=org['email'],
                        type=FieldType.String,
                        modifications=[Modification.Email]
                        )
                    )
                )
            ).add_general(
                lambda f: f.set_properties(
                    name='Quantity',
                    displayName='Количество поставляемого товара/объем выполняемых работ/оказываемых услуг',
                    value=lot['quantity'],
                    type=FieldType.String,
                    modifications=[]
                )
            ).add_general(
                lambda f: f.set_properties(
                    name='deliveryPlace',
                    displayName='Место поставки товаров оказания услуг',
                    value=lot['delivery_place'] if lot['delivery_place'] else '',
                    type=FieldType.String,
                    modifications=[]
                )
            ).add_general(
                lambda f: f.set_properties(
                    name='PaymentTerms',
                    displayName='Условия оплаты и поставки товаров/выполнения работ/оказания услуг',
                    value=lot['payment_terms'] if lot['payment_terms'] else '',
                    type=FieldType.String,
                    modifications=[]
                )
            ).to_json()
Ejemplo n.º 4
0
class Http():
    def __init__(self):
        cfg = configparse()
        self.parser = Parser()
        cfg_mongo = cfg['mongodb']
        self.repository = MongoRepository(cfg_mongo['host'], cfg_mongo['port'],
                                          cfg_mongo['database'],
                                          cfg_mongo['collection'])
        self.tools = Tools()

    def get_page_list(self, starturl):
        Startpage = []
        index = requests.get(starturl)
        y = 0
        x = 0
        while True:
            Startpage.append(starturl)
            print("add page", x)
            x = x + 1
            for href in Selector(index.text).css(
                    '.pagination ul :last-child a::attr(href)').extract():
                url = urljoin(index.url, href)
                sel = Selector(requests.get(url).text)
            if url == starturl:
                break
            else:
                starturl = url
                index = requests.get(starturl)
        return Startpage

    def get_special_tender_list(self, starturl):
        SpecialTenderInfo = set()
        index = requests.get(starturl)
        for href in Selector(
                index.text).css('.purchase-title a::attr(href)').extract():
            url = urljoin(index.url, href)
            sel = Selector(requests.get(url).text)

            id = sel.css(' .purchase-single-head span::text').extract_first()
            title = handler(
                sel.css(' .purchase-single-head h2').extract_first())

            if self.parser.special_search(title) is not None:
                SpecialTenderInfo.add(id)
        return list(SpecialTenderInfo)

    def get_tender_list(self, starturl, status, time):
        """Возвращает списком c данными для тендеров"""

        TenderInfo = set()

        index = requests.get(starturl)
        for href in Selector(
                index.text).css('.purchase-title a::attr(href)').extract():
            url = urljoin(index.url, href)
            sel = Selector(requests.get(url).text)

            id = sel.css(' .purchase-single-head span::text').extract_first()
            dbmodel = self.repository.get_one('{}'.format(id))
            info = handler(
                sel.css('.purchase-single-head .purchase-single-info::text').
                extract_first())
            tm = info[info.find("|") + 20:info.rfind("|") - 1]
            #Проверка с базой в середине функции, мне казалось,что брейк просто бы остановил цикл в колекте продолжилось бы выполнение, тут сравнение со временем можно регулировать, накинуть дни например
            if dbmodel is not None and dbmodel['_id'] == id and dbmodel[
                    'status'] == status and dbmodel[
                        'time'] == self.tools.get_utc_epoch(tm) and (
                            time is not None and
                            (self.tools.get_utc_epoch(tm)) < time):
                sys.exit(0)
            if dbmodel is not None and dbmodel['_id'] == id and dbmodel[
                    'status'] == status and dbmodel[
                        'time'] == self.tools.get_utc_epoch(tm):
                print("Coincidence? I don't think so ...")
                continue

            title = handler(
                sel.css(' .purchase-single-head h2').extract_first())
            organization = sel.css(
                ' .purchase-single-filters a::text').extract_first()
            TenderInfo.add((
                id,
                href,
                title[title.find("]") + 2:],
                organization,
                tm,
                info[info.find("|") - 12:info.find("|")],
            ))

        a = list(TenderInfo)
        return a

    def get_tender_mindate(self, url):
        index = requests.get(url)
        for href in Selector(
                index.text).css('.purchase-title a::attr(href)').extract():
            url = urljoin(index.url, href)
            sel = Selector(requests.get(url).text)
            info = handler(
                sel.css('.purchase-single-head .purchase-single-info::text').
                extract_first())
            a = info[info.find("|") + 20:info.rfind("|") - 1]
            #Неполучилось воспользщоваться функцией из Tools, поэтому скопировал (ಥ﹏ಥ)
            date = datetime.strptime(
                a.replace('\n', '').replace('\t', '').replace('\r',
                                                              '').strip(),
                '%d.%m.%Y')
            ep_time = (date - datetime(1970, 1, 1)).total_seconds() * 1000
            break
        return int(ep_time)

    def get_tender_contacts(self, tender_number):
        """Возвращает HTML документ с контактами для тендера"""
        starturl = 'http://tenders.polyusgold.com/purchases/{}'.format(
            tender_number)
        sel = Selector(requests.get(starturl).text)

        a = sel.css(' .purchase-single-body').extract_first()
        return a

    def get_tender_lots(self, tender_id, tender_number, token):
        """Возвращает JSON со списком лотов для тендера"""
        url = 'https://zakupki.ugmk.com/Tenders/LoadLots/{}'.format(tender_id)
        headers = {
            'Accept':
            'application/json, text/javascript, */*; q=0.01',
            'Accept-Encoding':
            'gzip, deflate, br',
            'Accept-Language':
            'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
            'Cache-Control':
            'no-cache',
            'Connection':
            'keep-alive',
            'Content-Type':
            'application/x-www-form-urlencoded; charset=UTF-8',
            'Cookie':
            'ASP.NET_SessionId=vvselgjio1azsx5igfremgcb; __RequestVerificationToken_Lw__={}'
            .format(token),
            'Host':
            'zakupki.ugmk.com',
            'Origin':
            'https://zakupki.ugmk.com',
            'Pragma':
            'no-cache',
            'Referer':
            'https://zakupki.ugmk.com/Tender/{}'.format(tender_number),
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
            'X-Requested-With':
            'XMLHttpRequest'
        }
        data = {
            'offset': 0,
            'limit': 1000,
            'sortColumn': None,
            'sortAsc': False,
            '__RequestVerificationToken': token
        }

        r = requests.post(url, data, headers=headers)
        return r.json()['Rows']

    def get_tender_data(self, tender_number):
        """Возвращает HTML документ с данными тендера"""
        url = 'http://tenders.polyusgold.com/purchases/{}'.format(
            tender_number)
        r = requests.get(url)
        return r.text

    def get_tender_documents(self, tender_number):
        """Получение HTML с документами тендера"""
        #TenderInfo = set()
        starturl = 'http://tenders.polyusgold.com/purchases/{}'.format(
            tender_number)
        sel = Selector(requests.get(starturl).text)

        a = sel.css(' .purchase-single-docs ul').extract_first()

        return a

    def get_lot_data(self, lot_url, tender_number, token):
        """Возвращает HTML с данными для лота"""
        url = 'https://zakupki.ugmk.com{}'.format(lot_url)
        headers = {
            'Accept':
            'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'Accept-Encoding':
            'gzip, deflate, br',
            'Accept-Language':
            'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
            'Cache-Control':
            'no-cache',
            'Connection':
            'keep-alive',
            'Cookie':
            'ASP.NET_SessionId=vvselgjio1azsx5igfremgcb; __RequestVerificationToken_Lw__={}'
            .format(token),
            'Host':
            'zakupki.ugmk.com',
            'Pragma':
            'no-cache',
            'Referer':
            'https://zakupki.ugmk.com/Tender/{}'.format(tender_number),
            'Upgrade-Insecure-Requests':
            '1',
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
        }

        r = requests.get(url, headers=headers)
        return r.text

    def get_lot_documents(self, entity_id, lot_url, token):
        url = 'https://zakupki.ugmk.com/Documents/List?entityTypeCode=TenderLot&entityUid={}'.format(
            entity_id)
        headers = {
            'Accept': '*/*',
            'Accept-Encoding': 'gzip, deflate, br',
            'Accept-Language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'Cookie':
            'ASP.NET_SessionId=vvselgjio1azsx5igfremgcb; __RequestVerificationToken_Lw__=K3dfzSt3g/2sa7vr2mJqfDTCyXcqWyLBvjQ7Omjx2Alt6sT63z9CQ43PEsPx7cPND1LSl1GmDQ+MlQX806uU7WV3Sm00gdhatsjwNQXDDe7KnvzYWnAiDNTAr28sZSElM/4l7PBVnzo2tOM6SfQY7mPkdS2hE0G5AckN1/mudaA=',
            'Host': 'zakupki.ugmk.com',
            'Origin': 'https://zakupki.ugmk.com',
            'Pragma': 'no-cache',
            'Referer': 'https://zakupki.ugmk.com{}'.format(lot_url),
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
            'X-Requested-With': 'XMLHttpRequest'
        }
        data = {'__RequestVerificationToken': token}
        r = requests.post(url, data, headers=headers)
        return r.text

    def get_lot_stages(self, lot_uid, lot_url, token):
        url = 'https://zakupki.ugmk.com/Tenders/LoadNotices?lotUId={}'.format(
            lot_uid)
        headers = {
            'Accept':
            'application/json, text/javascript, */*; q=0.01',
            'Accept-Encoding':
            'gzip, deflate, br',
            'Accept-Language':
            'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
            'Cache-Control':
            'no-cache',
            'Connection':
            'keep-alive',
            'Content-Type':
            'application/x-www-form-urlencoded; charset=UTF-8',
            'Cookie':
            'SP.NET_SessionId=vvselgjio1azsx5igfremgcb; __RequestVerificationToken_Lw__={}'
            .format(token),
            'Host':
            'zakupki.ugmk.com',
            'Origin':
            'https://zakupki.ugmk.com',
            'Pragma':
            'no-cache',
            'Referer':
            'https://zakupki.ugmk.com/{}'.format(lot_url),
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
            'X-Requested-With':
            'XMLHttpRequest'
        }
        data = {
            'offset': 0,
            'limit': 1000,
            'sortColumn': None,
            'sortAsc': False,
            '__RequestVerificationToken': token
        }

        r = requests.post(url, data, headers=headers)
        return r.json()

    def get_organization_page(self, company_id, token):
        url = 'https://zakupki.ugmk.com/Companies/Details/{}'.format(
            company_id)
        headers = {
            'Accept':
            'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'Accept-Encoding':
            'gzip, deflate, br',
            'Accept-Language':
            'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
            'Cache-Control':
            'no-cache',
            'Connection':
            'keep-alive',
            'Cookie':
            'ASP.NET_SessionId=vvselgjio1azsx5igfremgcb; __RequestVerificationToken_Lw__={}'
            .format(token),
            'Host':
            'zakupki.ugmk.com',
            'Pragma':
            'no-cache',
            'Referer':
            'https://zakupki.ugmk.com/Tender/T-000001749',
            'Upgrade-Insecure-Requests':
            '1',
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
        }
        r = requests.get(url, headers=headers)
        return r.text

    def get_organization(self, name, inn, kpp):
        url = 'http://organizationHost/organization?inn={}&kpp={}&name={}'.format(
            inn, kpp, name)
        # r = requests.get(url)
        # return r.json()
        # заглушка
        if name is None:
            return None
        return {'guid': None, 'name': name, 'region': None}

    def get_stages_list(self, lot_uid, lot_url, token):
        url = 'https://zakupki.ugmk.com/Tenders/LoadNotices?lotUId={}'.format(
            lot_uid)
        headers = {
            'Accept':
            'application/json, text/javascript, */*; q=0.01',
            'Accept-Encoding':
            'gzip, deflate, br',
            'Accept-Language':
            'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
            'Cache-Control':
            'no-cache',
            'Connection':
            'keep-alive',
            'Content-Type':
            'application/x-www-form-urlencoded; charset=UTF-8',
            'Cookie':
            'ASP.NET_SessionId=vvselgjio1azsx5igfremgcb; __RequestVerificationToken_Lw__={}'
            .format(token),
            'Host':
            'zakupki.ugmk.com',
            'Origin':
            'https://zakupki.ugmk.com',
            'Pragma':
            'no-cache',
            'Referer':
            'https://zakupki.ugmk.com{}'.format(lot_url),
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
            'X-Requested-With':
            'XMLHttpRequest'
        }
        data = {
            'offset': 0,
            'limit': 1000,
            'sortColumn': None,
            'sortAsc': False,
            '__RequestVerificationToken': token
        }
        r = requests.post(url, data, headers=headers)
        return r.json()['Rows']
Ejemplo n.º 5
0
class Mapper():
    def __init__(self):
        self.tools = Tools()

    def map_short(self, model):
        return {
            '_id': model['_id'],
            'status': model['status'],
        }

    def map_participant(self, participant):
        return {
            'admitted': True,
            'evolveDateTime': None,
            'guid': participant['guid'],
            'name': participant['name'],
            'price': None,
            'region': participant['region'],
            'rejectionCodes': [],
            'winner':
            True  # потому что на этой площадке из участников показывается только победитель
        }

    def map(self, item, item1, item2, item3, item4, item5, multilot,
            attachments, customer, contacts, s):
        customer_search = '' if customer is None else '{} {}'.format(
            customer.get('name'), customer.get('region'))
        #participant_search = '' if participant is None else '{} {}'.format(participant.get('guid'), participant.get('name'))
        okpd = []
        okpd2 = []
        okdp = []
        ktru = []
        #print([customer][0]['name'])
        model = {
            '_id':
            '{}'.format(item),
            'customers': [] if customer is None else [customer],
            #'participants': [] if participant is None else [self.map_participant(participant)],
            'type':
            30,  #change
            'timestamp':
            self.tools.get_utc(),
            'number':
            item,
            'group':
            item,
            'kind':
            0,
            'orderName':
            item2,
            'maxPrice':
            None,
            'submissionCloseDateTime':
            self.tools.get_utc_epoch(item4),
            'submissionStartDateTime':
            None,
            'publicationDateTime':
            self.tools.get_utc_epoch(item5),
            'guaranteeApp':
            None,
            'guaranteeContract':
            None,
            'preference': [],
            'placingWay':
            5000,
            'region':
            customer.get('region') if customer is not None else None,
            'okpd':
            okpd,
            'okpd2':
            okpd2,
            'okdp':
            okdp,
            'ktru':
            ktru,
            'prepayment':
            None,
            'organisationsSearch':
            '{}'.format(customer_search).strip(),
            'tenderSearch':
            '{} {} {}'.format(item, item2, customer.get('name')),
            'globalSearch':
            '{} {} {} {}'.format(okdp, okpd, okpd2,
                                 (item, item2, customer.get('name'))),
            'version':
            1,  # версия тендера если есть изменения????????
            'multiLot':
            multilot,
            'json':
            None,
            'attachments':
            attachments,
            'platform': {
                'href': "http://tenders.polyusgold.com/",
                'name': "«ПАО Полюс»",
            },
            'href':
            'http://tenders.polyusgold.com/purchases/{}'.format(item1),
            'modification':
            None,  #???????
            'futureNumber':
            None,  #??????
            "guid":
            '{}'.format(customer.get('guid')),  #????????
            'scoringDateTime':
            None,
            'biddingDateTime':
            None,
            'status':
            s  #self.get_status(item['LotStatusName'])
        }
        json = self.get_json(model, contacts, item3)
        model.update({'json': json})
        return model

    def get_placingway(self, placingway, org_form):
        if placingway == 'Аукцион' and org_form == 'Закрытая':
            return 12
        elif placingway == 'Аукцион' and org_form == 'Открытая':
            return 2
        elif placingway == 'Конкурс' and org_form == 'Закрытая':
            return 9
        elif placingway == 'Конкурс' and org_form == 'Открытая':
            return 1
        elif placingway == 'Запрос цен' and org_form == 'Закрытая':
            return 4
        elif placingway == 'Запрос цен' and org_form == 'Открытая':
            return 4
        else:
            return 0

        # fortyfour = {
        #     "Открытый конкурс": 1,
        #     "Открытый аукцион": 2,
        #     "Открытый аукцион в электронной форме": 3,
        #     "Запрос котировок": 4,
        #     "Предварительный отбор": 5,
        #     "Закупка у единственного поставщика (подрядчика, исполнителя)": 6,
        #     "Конкурс с ограниченным участием": 7,
        #     "Двухэтапный конкурс": 8,
        #     "Закрытый конкурс": 9,
        #     "Закрытый конкурс с ограниченным участием": 10,
        #     "Закрытый двухэтапный конкурс": 11,
        #     "Закрытый аукцион": 12,
        #     "Запрос котировок без размещения извещения": 13,
        #     "Запрос предложений": 14,
        #     "Электронный аукцион": 15,
        #     "Иной многолотовый способ": 16,
        #     "Сообщение о заинтересованности в проведении открытого конкурса": 17,
        #     "Иной однолотовый способ": 18
        # }

    def get_status(self, string):
        if string is None or string.strip() == '':
            return 0

        #elif string == 'Опубликовано':
        #   return 1
        #elif string == 'Прием заявок':
        #   return 2
        elif string:
            return 2
        elif string == 'Проведена':
            return 3
        #elif string == 'Завершен':
        #    return 7
        #elif string == 'Не состоялся с выбором победителя' or string == 'Отменен':
        #    return 4
        #elif string == 'Договор завершен':
        #    return 6
        #elif string == 'Не состоялся' \
        #        or string == 'Не состоялся с заключением договора' \
        #        or string == 'Не состоялся без заключения договора':
        #    return 5
        #elif string == 'Заменен новой версией':
        #    return 0

        # Без статуса
        # None = 0,
        # Опубликован
        # Active = 1,
        # На рассмотрении комиссии
        # Commission = 2,
        # Закрыт
        # Closed = 3,
        # Отменен
        # Cancel = 4,
        # Приостановлен
        # Abandoned = 5,
        # Исполнение завершено
        # Played = 6,
        # Исполняется
        # Playing = 7,
        # Приостановлено определение поставщика
        # Suspended = 8

    def get_json(self, model, contacts, organization):
        return Root() \
            .add_general(
            Field(
                name="MaxPrice",
                type=FieldType.Price,
                value=model['maxPrice'],
                displayName="Цена контракта"
              )
             ) \
            .add_customer(
            Customer().set_properties(
                max_price=None,
                guarantee_app=None,
                guarantee_contract=None,
                customer_guid=model['customers'][0]['guid'],
                customer_name=model['customers'][0]['name']
            )
            ) \
            .add_category(
             lambda c: c.set_properties(
                name='ProcedureInfo',
                displayName='Порядок размещения заказа'
            ).add_field(Field(
                name='AcceptOrderEndDateTime',
                displayName='Дата окончания приема заявок',
                value=model['submissionCloseDateTime'],
                type=FieldType.DateTime,
                modifications=[Modification.Calendar]
              ))
            ) \
            .add_category(
            lambda c: c.set_properties(
                name='Contacts',
                displayName='Контактная информация'
            ).add_field(Field(
                name='Organization',
                displayName='Организация',
                value=organization,
                type=FieldType.String
            )).add_array(
                lambda ar: ar.set_properties(
                    name='Contacts',
                    displayName='Контакты',
                    modifications=[Modification.HiddenLabel]
                ).add_field(Field(
                    name='FIO',
                    displayName='ФИО',
                    value=contacts[0]['name'],
                    type=FieldType.String,
                    modifications=[Modification.HiddenLabel]
                )).add_field(Field(
                    name='Phone',
                    displayName='Телефон',
                    value=contacts[0]['phone'],
                    type=FieldType.String,
                    modifications=[]
                )).add_field(Field(
                    name='Email',
                    displayName='Электронная почта',
                    value=contacts[0]['email'],
                    type=FieldType.String,
                    modifications=[]
                ))
            )
           ) \
            .to_json()