Ejemplo n.º 1
0
    def approve_bids_information(self):
        if self.current_stage in self._bids_data:
            LOGGER.info(
                "Current stage bids {}".format(self._bids_data[self.current_stage]),
                extra={"JOURNAL_REQUEST_ID": self.request_id}
            )

            bid_info = get_latest_bid_for_bidder(
                self._bids_data[self.current_stage],
                self.auction_document["stages"][self.current_stage]['bidder_id']
            )
            if bid_info['yearlyPaymentsPercentage'] == -0.01:
                LOGGER.info(
                    "Latest bid is bid cancellation: {}".format(bid_info),
                    extra={"JOURNAL_REQUEST_ID": self.request_id,
                           "MESSAGE_ID": AUCTION_WORKER_BIDS_LATEST_BID_CANCELLATION}
                )
                return False
            bid_info = {key: bid_info[key] for key in BIDS_KEYS_FOR_COPY}
            bid_info["bidder_name"] = self.mapping[bid_info['bidder_id']]
            bid_info['amount'] = bid_info['amount']
            if self.features:
                bid_info['amount_features'] = Fraction(bid_info['amount']) * self.bidders_coeficient[bid_info['bidder_id']]
            self.auction_document["stages"][self.current_stage] = prepare_bids_stage(
                self.auction_document["stages"][self.current_stage],
                bid_info
            )
            self.auction_document["stages"][self.current_stage]["changed"] = True

            return True
        else:
            return False
Ejemplo n.º 2
0
    def end_sealedbid(self, stage):
        with utils.update_auction_document(self):

            self._end_sealedbid.set()
            while not self.bids_queue.empty():
                LOGGER.info("Waiting for bids to process")
                sleep(0.1)
            LOGGER.info("Done processing bids queue")
            if len(self._bids_data.keys()) < 2:
                LOGGER.info("No bids on sealedbid phase. end auction")
                self.end_auction()
                return

            all_bids = deepcopy(self._bids_data)
            minimal_bids = []
            max_bid = {'amount': 0}  # init sealedbid winner bid
            for bid_id in all_bids.keys():
                bid = get_latest_bid_for_bidder(all_bids[bid_id], bid_id)
                bid['bidder_name'] = self.mapping[bid['bidder_id']]
                minimal_bids.append(utils.prepare_results_stage(**bid))
                # find a winner
                max_bid = max([max_bid, bid], key=lambda bid: bid['amount'])
            minimal_bids = sorting_by_amount(minimal_bids)
            self.auction_document['results'] = minimal_bids
            # save winner to stages in auction_document
            max_bid['sealedbid_winner'] = True
            self.auction_document['stages'][
                self.auction_document['current_stage']].update(
                    utils.prepare_results_stage(**max_bid))
            run_time = utils.update_stage(self)
            self.approve_audit_info_on_sealedbid(run_time)
            self.auction_document['current_phase'] = PREBESTBID
def post_results_data(self, with_auctions_results=True):
    patch_data = {'data': {'bids': list(self._auction_data['data']['bids'])}}
    if with_auctions_results:
        for bid_index, bid in enumerate(self._auction_data['data']['bids']):
            if bid.get('status', 'active') == 'active':
                for lot_index, lot_bid in enumerate(bid['lotValues']):
                    if lot_bid['relatedLot'] == self.lot_id and lot_bid.get(
                            'status', 'active') == 'active':
                        auction_bid_info = get_latest_bid_for_bidder(
                            self.auction_document["results"], bid["id"])
                        patch_data['data']['bids'][bid_index]['lotValues'][
                            lot_index]["value"]["amount"] = auction_bid_info[
                                "amount"]
                        patch_data['data']['bids'][bid_index]['lotValues'][
                            lot_index]["date"] = auction_bid_info["time"]
                        break

    logger.info("Approved data: {}".format(patch_data),
                extra={
                    "JOURNAL_REQUEST_ID": self.request_id,
                    "MESSAGE_ID": AUCTION_WORKER_API_APPROVED_DATA
                })
    results = make_request(self.tender_url + '/auction/{}'.format(self.lot_id),
                           data=patch_data,
                           user=self.worker_defaults["TENDERS_API_TOKEN"],
                           method='post',
                           request_id=self.request_id,
                           session=self.session)
    return results
Ejemplo n.º 4
0
    def _post_results_data(self, external_data, db_document):
        """
        :param auction_data: data from api
        :param auction_document: data from auction module couchdb
        :return: response from api where data is posted
        """
        request_id = generate_request_id()
        result_bids = deepcopy(db_document["results"])
        posted_result_data = deepcopy(external_data["data"]["bids"])

        for index, bid_info in enumerate(external_data["data"]["bids"]):
            if bid_info.get('status', 'active') == 'active':
                auction_bid_info = get_latest_bid_for_bidder(
                    result_bids, bid_info["id"])
                posted_result_data[index]["value"][
                    "amount"] = auction_bid_info["amount"]
                posted_result_data[index]["date"] = auction_bid_info["time"]

        data = {'data': {'bids': posted_result_data}}
        LOGGER.info("Approved data: {}".format(data),
                    extra={
                        "JOURNAL_REQUEST_ID": request_id,
                        "MESSAGE_ID": AUCTION_WORKER_API_APPROVED_DATA
                    })
        return make_request(self.api_url + '/auction',
                            data=data,
                            user=self.api_token,
                            method='post',
                            request_id=request_id,
                            session=self.session)
def post_results_data(self, with_auctions_results=True):

    if with_auctions_results:
        all_bids = self.auction_document["results"]
        for index, bid_info in enumerate(self._auction_data["data"]["bids"]):
            if bid_info.get('status', 'active') == 'active':
                auction_bid_info = get_latest_bid_for_bidder(
                    all_bids, bid_info["id"])
                self._auction_data["data"]["bids"][index]["value"]["amount"] =\
                    auction_bid_info["amount"]
                self._auction_data["data"]["bids"][index]["date"] =\
                    auction_bid_info["time"]

    data = {'data': {'bids': self._auction_data["data"]['bids']}}
    LOGGER.info("Approved data: {}".format(data),
                extra={
                    "JOURNAL_REQUEST_ID": self.request_id,
                    "MESSAGE_ID": AUCTION_WORKER_API_APPROVED_DATA
                })
    return make_request(self.tender_url + '/auction',
                        data=data,
                        user=self.worker_defaults["resource_api_token"],
                        method='post',
                        request_id=self.request_id,
                        session=self.session)
Ejemplo n.º 6
0
    def start_auction(self, switch_to_round=None):
        self.generate_request_id()
        self.audit['timeline']['auction_start']['time'] = datetime.now(
            tzlocal()).isoformat()
        LOGGER.info('---------------- Start auction ----------------',
                    extra={
                        "JOURNAL_REQUEST_ID": self.request_id,
                        "MESSAGE_ID": AUCTION_WORKER_SERVICE_START_AUCTION
                    })
        self.get_auction_info()
        self.get_auction_document()
        # Initital Bids
        bids = deepcopy(self.bidders_data)
        self.auction_document["initial_bids"] = []
        bids_info = sorting_start_bids_by_amount(bids, features=self.features)
        for index, bid in enumerate(bids_info):
            amount = bid["value"]["amount"]
            audit_info = {
                "bidder": bid["id"],
                "date": bid["date"],
                "amount": amount
            }
            if self.features:
                amount_features = cooking(amount, self.features,
                                          self.bidders_features[bid["id"]])
                coeficient = self.bidders_coeficient[bid["id"]]
                audit_info["amount_features"] = str(amount_features)
                audit_info["coeficient"] = str(coeficient)
            else:
                coeficient = None
                amount_features = None

            self.audit['timeline']['auction_start']['initial_bids'].append(
                audit_info)
            self.auction_document["initial_bids"].append(
                prepare_initial_bid_stage(
                    time=bid["date"] if "date" in bid else self.startDate,
                    bidder_id=bid["id"],
                    bidder_name=self.mapping[bid["id"]],
                    amount=amount,
                    coeficient=coeficient,
                    amount_features=amount_features))
        if isinstance(switch_to_round, int):
            self.auction_document["current_stage"] = switch_to_round
        else:
            self.auction_document["current_stage"] = 0

        all_bids = deepcopy(self.auction_document["initial_bids"])
        minimal_bids = []
        for bid_info in self.bidders_data:
            minimal_bids.append(
                get_latest_bid_for_bidder(all_bids, str(bid_info['id'])))

        minimal_bids = self.filter_bids_keys(sorting_by_amount(minimal_bids))
        self.update_future_bidding_orders(minimal_bids)
        self.save_auction_document()
def prepare_auction_results(auction, bids_data):
    all_bids = deepcopy(bids_data)
    max_bids = []
    for bid_id in all_bids.keys():
        bid = get_latest_bid_for_bidder(all_bids[bid_id], bid_id)
        bid['bidder_name'] = auction.mapping[bid['bidder_id']]
        max_bids.append(
            prepare_results_stage(**bid)
        )
    return sorting_by_amount(max_bids)
def post_results_data(auction, with_auctions_results=True):
    """TODO: make me work"""
    def generate_value(bid_info):
        auction_bid = bid_info['amount'] if str(bid_info['amount']) != '-1'\
                else None
        value = auction.auction_document['value']
        return {
            "amount": str(auction_bid),
            "currency": value.get('currency'),
            "valueAddedTaxIncluded": value.get('valueAddedTaxIncluded')
        }

    info = auction.get_auction_info()
    bids = info['data'].get("bids", [])
    if with_auctions_results:
        for bid_info in bids:
            if bid_info.get('status', 'active') == 'active':
                bidder_id = bid_info.get('bidder_id', bid_info.get('id', ''))
                if bidder_id:
                    try:
                        bid = get_latest_bid_for_bidder(
                            auction.auction_document['results'],
                            bidder_id
                        )
                    except IndexError:
                        bid = ''
                    if bid:
                        bid_info['value'] = generate_value(bid)
                        bid_info['date'] = bid['time']
    data = {'data': {'bids': bids}}
    LOGGER.info(
        "Approved data: {}".format(data),
        extra={"JOURNAL_REQUEST_ID": auction.request_id,
               "MESSAGE_ID": AUCTION_WORKER_API_APPROVED_DATA}
    )
    if not auction.debug:
        return make_request(
            auction.tender_url + '/auction', data=data,
            user=auction.worker_defaults["resource_api_token"],
            method='post',
            request_id=auction.request_id,
            session=auction.session
        )
    LOGGER.info(
        "Making request to api with params {}".format(
        dict(method="post",
             url=auction.tender_url + '/auction',
             data=data)))
    return data
Ejemplo n.º 9
0
    def end_bids_stage(self, switch_to_round=None):
        self.generate_request_id()
        self.bids_actions.acquire()
        self.get_auction_document()
        LOGGER.info(
            '---------------- End Bids Stage ----------------',
            extra={"JOURNAL_REQUEST_ID": self.request_id,
                   "MESSAGE_ID": AUCTION_WORKER_SERVICE_END_BID_STAGE}
        )

        self.current_round = self.get_round_number(
            self.auction_document["current_stage"]
        )
        self.current_stage = self.auction_document["current_stage"]

        if self.approve_bids_information():
            LOGGER.info("Approved bid on current stage")
            start_stage, end_stage = self.get_round_stages(self.current_round)
            all_bids = deepcopy(
                self.auction_document["stages"][start_stage:end_stage]
            )
            minimal_bids = []
            for bid_info in self.bidders_data:
                minimal_bids.append(
                    get_latest_bid_for_bidder(all_bids, bid_info['id'])
                )
            minimal_bids = self.filter_bids_keys(
                sorting_by_amount(minimal_bids, reverse=False)
            )
            self.update_future_bidding_orders(minimal_bids)

        self.approve_audit_info_on_bid_stage()

        if isinstance(switch_to_round, int):
            self.auction_document["current_stage"] = switch_to_round
        else:
            self.auction_document["current_stage"] += 1

        LOGGER.info('---------------- Start stage {0} ----------------'.format(
            self.auction_document["current_stage"]),
            extra={"JOURNAL_REQUEST_ID": self.request_id,
                   "MESSAGE_ID": AUCTION_WORKER_SERVICE_START_STAGE}
        )
        self.save_auction_document()
        if self.auction_document["stages"][self.auction_document["current_stage"]]['type'] == 'pre_announcement':
            self.end_auction()
        self.bids_actions.release()
        if self.auction_document["current_stage"] == (len(self.auction_document["stages"]) - 1):
            self._end_auction_event.set()
Ejemplo n.º 10
0
    def end_bestbid(self, stage):
        with utils.update_auction_document(self):

            all_bids = deepcopy(self._bids_data)
            minimal_bids = []

            for bid_id in all_bids.keys():
                bid = get_latest_bid_for_bidder(all_bids[bid_id], bid_id)
                bid['bidder_name'] = self.mapping[bid['bidder_id']]
                minimal_bids.append(utils.prepare_results_stage(**bid))
            minimal_bids = sorting_by_amount(minimal_bids)

            self.auction_document['results'] = minimal_bids
            run_time = utils.update_stage(self)
            self.approve_audit_info_on_bestbid(run_time)
        self.end_auction()
Ejemplo n.º 11
0
def post_results_data(auction, with_auctions_results=True):
    """TODO: make me work"""
    if with_auctions_results:
        for index, bid_info in enumerate(
                auction._auction_data["data"]["bids"]):
            if bid_info.get('status', 'active') == 'active':
                bidder_id = bid_info.get('bidder_id', bid_info.get('id', ''))
                if bidder_id:
                    try:
                        bid = get_latest_bid_for_bidder(
                            auction.auction_document['results'], bidder_id)
                    except IndexError:
                        bid = ''
                    if bid:
                        auction._auction_data["data"]["bids"][index]["value"][
                            "amount"] = bid['amount']
                        auction._auction_data["data"]["bids"][index][
                            "date"] = bid['time']
    data = {'data': {'bids': auction._auction_data["data"]['bids']}}
    LOGGER.info("Approved data: {}".format(data),
                extra={
                    "JOURNAL_REQUEST_ID": auction.request_id,
                    "MESSAGE_ID": AUCTION_WORKER_API_APPROVED_DATA
                })
    if not auction.debug:
        return make_request(auction.tender_url + '/auction',
                            data=data,
                            user=auction.worker_defaults["resource_api_token"],
                            method='post',
                            request_id=auction.request_id,
                            session=auction.session)
    else:
        LOGGER.info("Making request to api with params {}".format(
            dict(method="post", url=auction.tender_url + '/auction',
                 data=data)))
        return data
Ejemplo n.º 12
0
    def prepare_auction_stages_fast_forward(self):
        self.auction_document['auction_type'] = 'meat' if self.features else 'default'
        bids = deepcopy(self.bidders_data)
        self.auction_document["initial_bids"] = []
        bids_info = sorting_start_bids_by_amount(bids, features=self.features, reverse=False)
        for index, bid in enumerate(bids_info):
            amount = bid["value"]["amountPerformance"]
            annualCostsReduction = bid["value"]["annualCostsReduction"]
            if self.features:
                amount_features = cooking(
                    amount,
                    self.features, self.bidders_features[bid["id"]],
                    reverse=True
                )
                coeficient = self.bidders_coeficient[bid["id"]]

            else:
                coeficient = None
                amount_features = None
            initial_bid_stage = prepare_initial_bid_stage(
                time=bid["date"] if "date" in bid else self.startDate,
                bidder_id=bid["id"],
                bidder_name=self.mapping[bid["id"]],
                amount=amount,
                coeficient=coeficient,
                amount_features=amount_features,
                annualCostsReduction=annualCostsReduction,
                yearlyPaymentsPercentage=bid["value"]["yearlyPaymentsPercentage"],
                contractDurationDays=bid["value"]["contractDuration"].get("days", None),
                contractDurationYears=bid["value"]["contractDuration"].get("years", None)
            )
            self.auction_document["initial_bids"].append(
                initial_bid_stage
            )
        self.auction_document['stages'] = []
        next_stage_timedelta = datetime.now(tzlocal())
        for round_id in xrange(ROUNDS):
            # Schedule PAUSE Stage
            pause_stage = prepare_service_stage(
                start=next_stage_timedelta.isoformat(),
                stage="pause"
            )
            self.auction_document['stages'].append(pause_stage)
            # Schedule BIDS Stages
            for index in xrange(self.bidders_count):
                bid_stage = prepare_bids_stage({
                    'start': next_stage_timedelta.isoformat(),
                    'bidder_id': '',
                    'bidder_name': '',
                    'amount': '0',
                    "contractDurationDays": "0",
                    "contractDurationYears": "0",
                    "yearlyPaymentsPercentage": "0",
                    'time': '',
                })
                self.auction_document['stages'].append(bid_stage)
                next_stage_timedelta += timedelta(seconds=BIDS_SECONDS)

        self.auction_document['stages'].append(
            prepare_service_stage(
                start=next_stage_timedelta.isoformat(),
                type="pre_announcement"
            )
        )
        self.auction_document['stages'].append(
            prepare_service_stage(
                start="",
                type="announcement"
            )
        )
        all_bids = deepcopy(self.auction_document["initial_bids"])
        minimal_bids = []
        for bid_info in self.bidders_data:
            minimal_bids.append(get_latest_bid_for_bidder(
                all_bids, str(bid_info['id'])
            ))

        minimal_bids = self.filter_bids_keys(sorting_by_amount(minimal_bids, reverse=False))
        self.update_future_bidding_orders(minimal_bids)

        self.auction_document['endDate'] = next_stage_timedelta.isoformat()
        self.auction_document["current_stage"] = len(self.auction_document["stages"]) - 2