示例#1
0
    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
        }
示例#2
0
 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
示例#3
0
    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
示例#4
0
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
示例#5
0
 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')
示例#6
0
    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
示例#7
0
 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)
示例#8
0
 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)
示例#9
0
    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
示例#10
0
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)
示例#11
0
 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)
示例#12
0
    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
示例#13
0
    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.")
示例#14
0
    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.")