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')
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
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)