def validate_form_inputs(self): form = self.request.form title_template = form.get('titletemplate', None) id_template = form.get('idtemplate', None) if not (title_template and id_template): raise ValidationError(u'ID and Title template are both required.') if not ('{id}' in title_template and '{id}' in id_template): raise ValidationError(u'ID and Title templates must contain {id} ' u'for ID sequence substitution') try: seq_start = int(form.get('seq_start', None)) except: raise ValidationError( u'Sequence start and all counts must be integers') first_kit_limit = form.get('first_kit_limit', None) last_kit_limit = form.get('last_kit_limit', None) if not first_kit_limit or not last_kit_limit: raise ValidationError(u'Kits range is required. Or project select has no kits!') kits = self.kits_between_limits(first_kit_limit, last_kit_limit) count = len(kits) biospecimen_per_kit = int(form.get('biospecimen_per_kit', None)) biospecimen_count = count * biospecimen_per_kit # Check that none of the IDs conflict with existing items ids = [x.id for x in self.context.objectValues()] for x in range(biospecimen_count): check = id_template.format(id=seq_start + x) if check in ids: raise ValidationError( u'The ID %s exists, cannot be created.' % check) # Check that the storages selected has sufficient positions to contain # the biospecimen to generate. bio_storages = self.get_biospecimen_storages() if all([IManagedStorage.providedBy(storage) for storage in bio_storages]): nr_positions = self.count_storage_positions(bio_storages) if biospecimen_count > nr_positions: raise ValidationError( u"Not enough kit storage positions available. Please select " u"or create additional storages for kits.") return { 'title_template': title_template, 'id_template': id_template, 'seq_start': seq_start, 'first_kit_limit': first_kit_limit, 'last_kit_limit': last_kit_limit, 'kits': kits, 'biospecimen_per_kit': biospecimen_per_kit, 'biospecimen_count': biospecimen_count, 'storages': bio_storages }
def count_storage_positions(storages): """"Return the number of items that can be stored in storages. This method is called in case all the storages are of type Managed. """ count = 0 for storage in storages: # If storage is a ManagedStorage, increment count for each # available StoragePosition if IManagedStorage.providedBy(storage): count += storage.getFreePositions() else: raise ValidationError("Storage %s is not a valid storage type" % storage) return count
def filter_stockitems_by_storage_location(self, items): """Return stockitems in the selected storages """ si_storages = self.get_si_storages() stockitems = [] for storage in si_storages: if IUnmanagedStorage.providedBy(storage): sis = storage.getBackReferences('ItemStorageLocation') stockitems += [si for si in sis if si in items] elif IManagedStorage.providedBy(storage): sis = storage.only_items_of_portal_type('StockItem') stockitems += [si for si in sis if si in items] return stockitems
def filter_stock_items_by_storage(items, portal_catalog, storage_uids): """Return stock-items in the selected storage """ si_storage = get_si_storages(storage_uids, portal_catalog) stock_items = [] for storage in si_storage: if IUnmanagedStorage.providedBy(storage): sis = storage.getBackReferences('ItemStorageLocation') stock_items += [si for si in sis if si in items] elif IManagedStorage.providedBy(storage): sis = storage.only_items_of_portal_type('StockItem') stock_items += [si for si in sis if si in items] return stock_items
def store_samples(self, items, storages): """ store items inside selected storages """ wf = getToolByName(self.project, 'portal_workflow') for storage in storages: if IManagedStorage.providedBy(storage): free_positions = storage.get_free_positions() if len(items) <= len(free_positions): for i, item in enumerate(items): item.setStorageLocation(free_positions[i]) wf.doActionFor(free_positions[i], 'reserve') else: for i, position in enumerate(free_positions): items[i].setStorageLocation(position) wf.doActionFor(position, 'reserve')
def get_biospecimen_storages(self): """Take a list of UIDs from the form, and resolve to a list of Storages. Accepts ManagedStorage, UnmanagedStorage, or StoragePosition UIDs. """ uc = getToolByName(self.context, 'uid_catalog') bio_storages = [] # form_uids = self.form['StorageLocation_uid'].split(',') form_uids = self.form['StorageLocation_uid'].split( ',') if self.form['StorageLocation_uid'] else [] for uid in form_uids: brain = uc(UID=uid)[0] instance = brain.getObject() if IManagedStorage.providedBy(instance) \ or len(instance.get_free_positions()) > 0: bio_storages.append(instance) return bio_storages
def assign_kit_to_storage(self, kits, storages): """ assign position to created kits. Not used anymore! """ for storage in storages: if IManagedStorage.providedBy(storage): free_positions = storage.get_free_positions() if len(kits) <= len(free_positions): for i, kit in enumerate(kits): kit.setStorageLocation(free_positions[i]) self.wf.doActionFor(free_positions[i], 'occupy') else: for i, position in enumerate(free_positions): kits[i].setStorageLocation(position) self.wf.doActionFor(position, 'occupy') kits = kits[len(free_positions):] elif IUnmanagedStorage.providedBy(storage): # Case of unmanaged storage there is no limit in storage until # user manually set the storage as full. for kit in kits: kit.setStorageLocation(storage)
def assign_biospecimens_to_storages(self, biospecimens, storages): """ Assign positions to biospecimens inside storages """ wf = getToolByName(self.context, 'portal_workflow') for storage in storages: if IManagedStorage.providedBy(storage): free_positions = storage.get_free_positions() if len(biospecimens) <= len(free_positions): for i, biospecimen in enumerate(biospecimens): biospecimen.setStorageLocation(free_positions[i]) wf.doActionFor(free_positions[i], 'occupy') else: for i, position in enumerate(free_positions): biospecimens[i].setStorageLocation(position) wf.doActionFor(position, 'occupy') biospecimens = biospecimens[len(free_positions):] elif IUnmanagedStorage.providedBy(storage): # Case of unmanaged storage there is no limit in storage until # user manually set the storage as full. for biospecimen in biospecimens: biospecimen.setStorageLocation(storage)
def store_samples(self, items, storages): """ store items inside selected storages """ wf = getToolByName(self.project, 'portal_workflow') free_positions = [] for storage in storages: if IManagedStorage.providedBy(storage): free_positions_in_storage = storage.get_free_positions() for position in free_positions_in_storage: free_positions.append(position) for free_position in free_positions: if len(items) > 0: item = items.pop(0) item.setStorageLocation(free_position) wf.doActionFor(free_position, 'reserve') else: break
def assign_items_to_storages(context, items, storages): """ store items inside selected storages """ wf = getToolByName(context, 'portal_workflow') for storage in storages: if IManagedStorage.providedBy(storage): free_positions = storage.get_free_positions() if len(items) <= len(free_positions): for i, item in enumerate(items): item.setStorageLocation(free_positions[i]) wf.doActionFor(free_positions[i], 'occupy') else: for i, position in enumerate(free_positions): items[i].setStorageLocation(position) wf.doActionFor(position, 'occupy') items = items[len(free_positions):] elif IUnmanagedStorage.providedBy(storage): # Case of unmanaged storage there is no limit in storage until # user manually set the storage as full. for item in items: item.setStorageLocation(storage)
def assign_kit_to_storage(self, kits, storages): """ assign position to created kits. """ wf = getToolByName(self.context, 'portal_workflow') for storage in storages: if IManagedStorage.providedBy(storage): free_positions = storage.get_free_positions() if len(kits) <= len(free_positions): for i, kit in enumerate(kits): kit.setStorageLocation(free_positions[i]) wf.doActionFor(free_positions[i], 'occupy') else: for i, position in enumerate(free_positions): kits[i].setStorageLocation(position) wf.doActionFor(position) kits = kits[len(free_positions):] elif IUnmanagedStorage.providedBy(storage): # Case of unmanaged storage there is no limit in storage until # user manually set the storage as full. for kit in kits: kit.setStorageLocation(storage)
def count_storage_positions(storages): """Return the number of items that can be stored in storages. If any of these storages are "UnmanagedStorage" objects, then the result will be -1 as we cannot know how many items can be stored here. """ count = 0 for storage in storages: # If storage is an unmanaged storage, we no longer care about # "number of positions". if IUnmanagedStorage.providedBy(storage): return -1 # If storage is a StoragePosition, simply increment the count. elif IStoragePosition.providedBy(storage): count += 1 # If storage is a ManagedStorage, increment count for each # available StoragePosition elif IManagedStorage.providedBy(storage): count += storage.getFreePositions() else: raise ValidationError( "Storage %s is not a valid storage type" % storage) return count
def validate_form_inputs(self): form = self.request.form prefix_text = form.get('kits-prefix-text', None) leading_zeros = form.get('kits-leading-zeros', []) if not prefix_text: msg = u'Prefix text is required.' raise ValidationError(msg) # TODO: check if leading zeros has only zeros try: seq_start = int(form.get('seq-start', None)) kit_count = int(form.get('kit-count', None)) biospecimen_count = int(form.get('specimen-count', None)) except: raise ValidationError( u'Sequence start and all counts must be integers') # verify ID sequence start if seq_start < 1: raise ValidationError(u'Sequence Start must be > 0') # verify number of kits if kit_count < 1: raise ValidationError(u'Kit count must be > 0') # verify number of biospecimen per kit if biospecimen_count < 1: raise ValidationError( u'Number of biospecimens per kit must be > 0') # Kit template required kit_template_uid = self.form.get('kit_template_uid', None) # Stock Item storage (where items will be taken from), is required si_storage_uids = form.get('si-storage-uids', '') if not si_storage_uids and kit_template_uid: raise ValidationError( u'You must select the items storage to use for ' u'the kit assembling.') # Check that none of the IDs conflict with existing items ids = [x.id for x in self.context.objectValues()] for x in range(kit_count): id_kit = prefix_text + '-' + str(seq_start + x).zfill(len(leading_zeros) + 1) if id_kit in ids: raise ValidationError(u'The ID %s exists, cannot be created.' % id_kit) # Check there are enough stock items in stock to create the kits if kit_template_uid: kit_template = self.bika_setup_catalog( UID=kit_template_uid)[0].getObject() for product in kit_template.getProductList(): # items = self.product_stock_items(product['product_uid']) # items = self.filter_stock_items_by_storage(items) storage_uids = self.form['si-storage-uids'].split(',') items = product_stock_items(product['product_uid'], self.bika_setup_catalog) items = filter_stock_items_by_storage(items, self.portal_catalog, storage_uids) quantity = sum([item.getQuantity() for item in items]) if quantity < int(product['quantity']) * kit_count: raise ValidationError( u"There is insufficient stock items available for " u"product '%s'." % product['product']) # Biospecimen storage (where biospecimen items will be stored) is required to be booked field = self.context.bika_setup.getField('StoreKitBiospecimens') if field.getAccessor(self.context.bika_setup)(): biospecimen_storage_uids = form.get('biospecimen-storage-uids', '') if not biospecimen_storage_uids: raise ValidationError( u'You must select the Biospecimen Storage from where the ' u'specimen items will be stored.') # Check that the storage selected has sufficient positions to contain # the biospecimen to generate. biospecimens_per_kit = int(form.get('specimen-count', None)) biospecimen_count = kit_count * biospecimens_per_kit bio_storages = self.samples_gen.get_biospecimen_storages() if all([ IManagedStorage.providedBy(storage) for storage in bio_storages ]): nr_positions = self.samples_gen.count_storage_positions( bio_storages) if biospecimen_count > nr_positions: raise ValidationError( u"Not enough kit storage positions available. Please select " u"or create additional storage for kits.")
def validate_form_inputs(self): form = self.request.form prefix_text = form.get('kits-prefix-text', None) leading_zeros = form.get('kits-leading-zeros', None) if not prefix_text or not leading_zeros: msg = u'Prefix text and Leading zeros are both required.' raise ValidationError(msg) # TODO: check if leading zeros has only zeros try: seq_start = int(form.get('seq-start', None)) kit_count = int(form.get('kit-count', None)) except: raise ValidationError( u'Sequence start and all counts must be integers') # verify ID sequence start if seq_start < 1: raise ValidationError(u'Sequence Start should be > 0') # verify number of kits if kit_count < 1: raise ValidationError(u'Kit count should be > 0') # Kit template required kit_template_uid = self.form.get('kit-template-uid', None) if not kit_template_uid: raise ValidationError(u'Kit Template field is required.') # Kit storage destination is required field. kit_storage_uids = form.get('kit-storage-uids', '') if not kit_storage_uids: raise ValidationError(u'Kit storage required.') # Stock Item storage (where items will be taken from) is required si_storage_uids = form.get('si-storage-uids', '') if not si_storage_uids: raise ValidationError(u'You must select the Storage where the ' u'stock items will be taken from.') # Check that none of the IDs conflict with existing items ids = [x.id for x in self.context.objectValues()] for x in range(kit_count): id_kit = prefix_text + '-' + str(seq_start + x).zfill( len(leading_zeros)) if id_kit in ids: raise ValidationError(u'The ID %s exists, cannot be created.' % id_kit) # Check there are enough stock items in stock to create the kits kit_template = self.bsc(UID=kit_template_uid)[0].getObject() for item in kit_template.getProductList(): items = self.product_stockitems(item['product_uid']) items = self.filter_stockitems_by_storage_location(items) if len(items) < int(item['quantity']) * kit_count: raise ValidationError( u"There is insufficient stock available for " \ u"product '%s'." % item['product']) kit_storages = self.get_kit_storages() if all( [IManagedStorage.providedBy(storage) for storage in kit_storages]): nr_positions = self.count_storage_positions(kit_storages) if kit_count > nr_positions: raise ValidationError( u"Not enough kit storage positions available. Please select " u"or create additional storages for kits.") # Check that the storages selected has sufficient positions to contain # the biospecimen to generate. biospecimens_per_kit = int(form.get('specimen-count', None)) biospecimen_count = kit_count * biospecimens_per_kit bio_storages = self.samples_gen.get_biospecimen_storages() if all( [IManagedStorage.providedBy(storage) for storage in bio_storages]): nr_positions = self.samples_gen.count_storage_positions( bio_storages) if biospecimen_count > nr_positions: raise ValidationError( u"Not enough kit storage positions available. Please select " u"or create additional storages for kits.")