예제 #1
0
 def _add_assets_to_lot(self, lot):
     result, patched_assets = self.patch_assets(
         lot,
         get_next_status(NEXT_STATUS_CHANGE, 'asset', lot['status'], 'pre'),
         lot['id'])
     if result is False:
         if patched_assets:
             logger.info("Assets {} will be repatched to 'pending'".format(
                 patched_assets))
             result, _ = self.patch_assets({'assets': patched_assets},
                                           get_next_status(
                                               NEXT_STATUS_CHANGE, 'asset',
                                               lot['status'], 'fail'))
             if result is False:
                 log_broken_lot(
                     self.db, logger, self.errors_doc, lot,
                     'patching assets to {}'.format(
                         get_next_status(NEXT_STATUS_CHANGE, 'asset',
                                         lot['status'], 'pre')))
     else:
         result, _ = self.patch_assets(
             lot,
             get_next_status(NEXT_STATUS_CHANGE, 'asset', lot['status'],
                             'finish'), lot['id'])
         if result is False:
             logger.info("Assets {} will be repatched to 'pending'".format(
                 lot['assets']))
             result, _ = self.patch_assets(
                 lot,
                 get_next_status(NEXT_STATUS_CHANGE, 'asset', lot['status'],
                                 'fail'))
             if result is False:
                 log_broken_lot(self.db, logger, self.errors_doc, lot,
                                'patching assets to active')
         else:
             asset = self.assets_client.get_asset(lot['assets'][0]).data
             asset_decision = deepcopy(asset['decisions'][0])
             asset_decision['relatedItem'] = asset['id']
             to_patch = {
                 l_key: asset.get(a_key)
                 for a_key, l_key in KEYS_FOR_LOKI_PATCH.items()
             }
             to_patch['decisions'] = [lot['decisions'][0], asset_decision]
             result = self.patch_lot(
                 lot,
                 get_next_status(NEXT_STATUS_CHANGE, 'lot', lot['status'],
                                 'finish'), to_patch)
             if result is False:
                 log_broken_lot(self.db, logger, self.errors_doc, lot,
                                'patching lot to active.salable')
예제 #2
0
 def _add_assets_to_lot(self, lot):
     result, patched_assets = self.patch_assets(
         lot,
         get_next_status(NEXT_STATUS_CHANGE, 'asset', lot['status'], 'pre'),
         lot['id'])
     if result is False:
         if patched_assets:
             logger.info("Assets {} will be repatched to 'pending'".format(
                 patched_assets))
             result, _ = self.patch_assets({'assets': patched_assets},
                                           get_next_status(
                                               NEXT_STATUS_CHANGE, 'asset',
                                               lot['status'], 'fail'))
             if result is False:
                 log_broken_lot(
                     self.db, logger, self.errors_doc, lot,
                     'patching assets to {}'.format(
                         get_next_status(NEXT_STATUS_CHANGE, 'asset',
                                         lot['status'], 'pre')))
         return False
     else:
         result, _ = self.patch_assets(
             lot,
             get_next_status(NEXT_STATUS_CHANGE, 'asset', lot['status'],
                             'finish'), lot['id'])
         if result is False:
             logger.info("Assets {} will be repatched to 'pending'".format(
                 lot['assets']))
             result, _ = self.patch_assets(
                 lot,
                 get_next_status(NEXT_STATUS_CHANGE, 'asset', lot['status'],
                                 'fail'))
             if result is False:
                 log_broken_lot(self.db, logger, self.errors_doc, lot,
                                'patching assets to active')
             return False
         else:
             result = self.patch_lot(
                 lot,
                 get_next_status(NEXT_STATUS_CHANGE, 'lot', lot['status'],
                                 'finish'),
             )
             if result is False:
                 log_broken_lot(self.db, logger, self.errors_doc, lot,
                                'patching Lot to active.salable')
                 return False
             return True
    def process_lots(self, lot):
        """
        Performs the main processing of the lot. Checks the availability
        of a given lot and assets united by this lot and switches their
        statuses to required ones.

        Lot considered as available, if it is in status 'verification'
        or 'pending.dissolution'. If this condition is not satisfied,
        lot will be skipped. Assets considered as available, if all of
        them are in status 'pending'. If this condition is not satisfied,
        lot status will be switched to 'pending'.

        In case lot is in status 'pending.dissolution', switches assets statuses
        to 'pending', sets None as value of asset field 'relatedLot' and switch lot
        status to 'dissolved'. In case processed lot is in status 'verification', at
        first, switches assets statuses to 'verification' and sets lot id as
        'relatedLot' field value and after that switches to 'active' status. If all
        PATCH requests were successful, switches lot to status 'active.salable'

        In case error occurs during switching assets statuses, tries to switch
        assets, which were patched successfully, back to status 'pending'. If
        error occurs during this patch as well, lot will be marked as broken
        and added to db document, specified in configuration file.

        If error occurs during switching lot status to 'active.salable', this lot
        will be considered as broken as well and added to db document, specified
        in configuration file.

        Args:
            lot: dictionary which contains some fields of lot
                 document from db: id, rev, status, assets, lotID.
        Returns:
            None
        """
        lot_available = self.check_lot(lot)
        if not lot_available:
            logger.info("Skipping Lot {}".format(lot['id']),
                        extra={'MESSAGE_ID': 'skip_lot'})
            return
        logger.info("Processing Lot {} in status {}".format(
            lot['id'], lot['status']),
                    extra={'MESSAGE_ID': 'process_loki_lot'})
        if lot['status'] in ['verification']:
            try:
                assets_available = self.check_assets(lot)
            except RequestFailed:
                logger.info(
                    "Due to fail in getting assets, Lot {} is skipped".format(
                        lot['id']))
            else:
                if assets_available:
                    result = self._add_assets_to_lot(lot)
                    if result:
                        self.lots_mapping.put(lot['id'], True)
                else:
                    self.patch_lot(
                        lot,
                        get_next_status(NEXT_STATUS_CHANGE, 'lot',
                                        lot['status'], 'fail'))
        elif lot['status'] == 'active.salable':
            if self.check_assets(lot, 'active'):
                is_all_auction_valid = all([
                    a['status'] in HANDLED_AUCTION_STATUSES
                    for a in lot['auctions']
                ])
                if is_all_auction_valid and self.check_previous_auction(lot):
                    result = self._create_auction(lot)
                    if result:
                        auction, lot_auction_id = result
                        data = {
                            'auctionID': auction['data']['auctionID'],
                            'status': 'active',
                            'relatedProcessID': auction['data']['id']
                        }
                        self._patch_auction(data, lot['id'], lot_auction_id)
                        self.lots_mapping.put(lot['id'], True)
                    elif result is False:
                        self._process_lot_and_assets(lot, 'composing',
                                                     'pending')
        else:
            result = self._process_lot_and_assets(
                lot,
                get_next_status(NEXT_STATUS_CHANGE, 'lot', lot['status'],
                                'finish'),
                get_next_status(NEXT_STATUS_CHANGE, 'asset', lot['status'],
                                'finish'))
            if result:

                if get_next_status(NEXT_STATUS_CHANGE, 'asset', lot['status'],
                                   'finish') == 'pending':
                    # Remove related processes with lot type from asset that switched in pending status
                    asset = self.assets_client.get_asset(
                        lot['relatedProcesses'][0]['relatedProcessID']).data
                    related_processes = [
                        rP for rP in asset.get('relatedProcesses', [])
                        if rP['type'] == 'lot'
                        and rP['relatedProcessID'] == lot['id']
                    ]

                    for rp in related_processes:
                        rp['asset_parent'] = asset['id']

                    self.clean_asset_related_processes(related_processes)

                self.lots_mapping.put(lot['id'], True)
    def _add_assets_to_lot(self, lot):
        result, patched_assets = self.patch_assets(
            lot,
            get_next_status(NEXT_STATUS_CHANGE, 'asset', lot['status'], 'pre'),
        )

        if result is False:
            if patched_assets:
                logger.info("Assets {} will be repatched to 'pending'".format(
                    patched_assets))
                result, _ = self.patch_assets({'assets': patched_assets},
                                              get_next_status(
                                                  NEXT_STATUS_CHANGE, 'asset',
                                                  lot['status'], 'fail'))
                if result is False:
                    log_broken_lot(
                        self.db, logger, self.errors_doc, lot,
                        'patching assets to {}'.format(
                            get_next_status(NEXT_STATUS_CHANGE, 'asset',
                                            lot['status'], 'pre')))
            return False
        else:
            result, asset_added_rPs = self.add_related_process_to_assets(lot)
            if not result and asset_added_rPs:
                self.clean_asset_related_processes(asset_added_rPs)
                self.patch_assets(lot, 'pending')
                return False
            elif not result:
                self.patch_assets(lot, 'pending')
                return False

            result, _ = self.patch_assets(
                lot,
                get_next_status(NEXT_STATUS_CHANGE, 'asset', lot['status'],
                                'finish'),
            )
            if result is False:
                log_assets_message(
                    logger, 'info',
                    "Assets {assets} will be repatched to 'pending'",
                    lot['relatedProcesses'])
                self.clean_asset_related_processes(asset_added_rPs)
                result, _ = self.patch_assets(
                    lot,
                    get_next_status(NEXT_STATUS_CHANGE, 'asset', lot['status'],
                                    'fail'))
                if result is False:
                    log_broken_lot(self.db, logger, self.errors_doc, lot,
                                   'patching assets to active')
                return False
            else:
                result, lot_patched_rPs = self._patch_lot_asset_related_processes(
                    lot)

                if not result and lot_patched_rPs:
                    lot_with_patched_rPs = {
                        'id': lot['id'],
                        'relatedProcesses': lot_patched_rPs
                    }
                    self._patch_lot_asset_related_processes(
                        lot_with_patched_rPs, cleanup=True)
                    self.clean_asset_related_processes(asset_added_rPs)
                    self.patch_assets(lot, 'pending')
                    return False
                elif not result:
                    self.clean_asset_related_processes(asset_added_rPs)
                    self.patch_assets(lot, 'pending')
                    return False

                asset = self.assets_client.get_asset(
                    lot['relatedProcesses'][0]['relatedProcessID']).data

                to_patch = {
                    l_key: asset.get(a_key)
                    for a_key, l_key in KEYS_FOR_LOKI_PATCH.items()
                }
                to_patch['decisions'] = deepcopy(lot['decisions'])

                for dec in deepcopy(asset['decisions']):
                    dec.update({'relatedItem': asset['id']})
                    to_patch['decisions'].append(dec)

                result = self.patch_lot(
                    lot,
                    get_next_status(NEXT_STATUS_CHANGE, 'lot', lot['status'],
                                    'finish'), to_patch)
                if result is False:
                    self._patch_lot_asset_related_processes(lot, cleanup=True)
                    self.clean_asset_related_processes(asset_added_rPs)
                    self._process_lot_and_assets(lot, 'composing', 'pending')
                    log_broken_lot(self.db, logger, self.errors_doc, lot,
                                   'patching Lot to pending')
                    return False
                return True
예제 #5
0
    def process_lots(self, lot):
        """
        Performs the main processing of the lot. Checks the availability
        of a given lot and assets united by this lot and switches their
        statuses to required ones.

        Lot considered as available, if it is in status 'verification'
        or 'pending.dissolution'. If this condition is not satisfied,
        lot will be skipped. Assets considered as available, if all of
        them are in status 'pending'. If this condition is not satisfied,
        lot status will be switched to 'pending'.

        In case lot is in status 'pending.dissolution', switches assets statuses
        to 'pending', sets None as value of asset field 'relatedLot' and switch lot
        status to 'dissolved'. In case processed lot is in status 'verification', at
        first, switches assets statuses to 'verification' and sets lot id as
        'relatedLot' field value and after that switches to 'active' status. If all
        PATCH requests were successful, switches lot to status 'active.salable'

        In case error occurs during switching assets statuses, tries to switch
        assets, which were patched successfully, back to status 'pending'. If
        error occurs during this patch as well, lot will be marked as broken
        and added to db document, specified in configuration file.

        If error occurs during switching lot status to 'active.salable', this lot
        will be considered as broken as well and added to db document, specified
        in configuration file.

        Args:
            lot: dictionary which contains some fields of lot
                 document from db: id, rev, status, assets, lotID.
        Returns:
            None
        """
        lot_available = self.check_lot(lot)
        if not lot_available:
            logger.info("Skipping Lot {}".format(lot['id']))
            return
        logger.info("Processing Lot {} in status {}".format(
            lot['id'], lot['status']))
        if lot['status'] in ['verification']:
            try:
                assets_available = self.check_assets(lot)
            except RequestFailed:
                logger.info(
                    "Due to fail in getting assets, Lot {} is skipped".format(
                        lot['id']))
            else:
                if assets_available:
                    result = self._add_assets_to_lot(lot)
                    if result:
                        self.lots_mapping.put(lot['id'], True)
                else:
                    self.patch_lot(
                        lot,
                        get_next_status(NEXT_STATUS_CHANGE, 'lot',
                                        lot['status'], 'fail'))
        else:
            result = self._process_lot_and_assets(
                lot,
                get_next_status(NEXT_STATUS_CHANGE, 'lot', lot['status'],
                                'finish'),
                get_next_status(NEXT_STATUS_CHANGE, 'asset', lot['status'],
                                'finish'))
            if result:
                self.lots_mapping.put(lot['id'], True)