def __init__(self, context, request): super(ContainersView, self).__init__(context, request) self.title = context.Title() self.form_id = "list_storage_containers" self.show_select_column = True self.contentFilter = { "sort_on": "sortable_title", "sort_order": "ascending", "path": { "query": "/".join(context.getPhysicalPath()), "depth": 1, } } self.columns = collections.OrderedDict(( ("Title", { "title": _("Name"), "index": "sortable_index"}), ("Id", { "title": _("ID")}), ("Temperature", { "title": _("Temperature"),}), ("SamplesUsage", { "title": _("Samples"),}), ("Samples", { "title": _("Samples usage"),}), ("ContainersUsage", { "title": _("Containers"),}), ("Containers", { "title": _("Containers usage"),}), )) self.review_states = [{ "id": "default", "contentFilter": {"review_state": "active"}, "title": _("Active"), "transitions": [], "confirm_transitions": ["recover_samples"], "columns": self.columns.keys(), },] imgs_path = "++resource++senaite.storage.static/img" icon_name = "container_big.png" if IStorageFacility.providedBy(self.context): icon_name = "facility_big.png" self.icon = "{}/{}/{}".format(self.portal_url, imgs_path, icon_name) self.context_actions = collections.OrderedDict() if not IStorageSamplesContainer.providedBy(self.context): self.context_actions[_("Add container")] = { "url": "createObject?type_name=StorageContainer", "icon": "{}/{}".format(imgs_path, "container.png") } if IStorageContainer.providedBy(self.context): self.context_actions[_("Add samples container")] = { "url": "createObject?type_name=StorageSamplesContainer", "icon": "{}/{}".format(imgs_path, "box.png") }
def add_stored_review_state(self): """Adds the "stored" review state to the listing's review_states pool """ # Columns to hide hide = ["getAnalysesNum", "getDateVerified", "getDatePreserved", "getDatePublished", "getDueDate", "getStorageLocation", "Printed" "Progress", "SamplingDate",] columns = filter(lambda c: c not in hide, self.listing.columns.keys()) # Custom transitions print_stickers = { "id": "print_stickers", "title": _("Print stickers"), "url": "workflow_action?action=print_stickers" } # "stored" review state stored = { "id": "stored", "title": _("Stored"), "contentFilter": { "review_state": ("stored",), "sort_on": "created", "sort_order": "descending", }, "transitions": [], "custom_transitions": [print_stickers], "columns": columns, } # Add the review state utils.add_review_state(self.listing, stored, after="published") # Add the column "DateStored" to "stored" review_state column_values = { "title": _("Date stored"), "index": "getDateStored", "toggle": True} utils.add_column(self.listing, "getDateStored", column_values, after="getDateReceived", review_states=("stored",)) # Add Samples Container column, but only if the current user logged in # is not a client contact if not api.get_current_client(): column_values = { "title": _("Storage"), "attr": "getSamplesContainerID", "replace_url": "getSamplesContainerURL", "toggle": True } utils.add_column(self.listing, "getSamplesContainer", column_values, after="getDateStored", review_states=("stored", ))
def __call__(self): form = self.request.form # Form submit toggle form_submitted = form.get("submitted", False) form_store = form.get("button_store", False) form_cancel = form.get("button_cancel", False) # Get the container container = self.get_container() if not container: return self.redirect(message=_s("No items selected"), level="warning") if not IStorageSamplesContainer.providedBy(container): logger.warn("Not a samples container: {}").format(repr(container)) self.redirect(redirect_url=self.get_next_url()) # If container is full, there is no way to add more samples there if container.is_full(): message = _("Cannot store samples. Samples container {} is full") return self.redirect(message=message.format(api.get_id(container)), level="warning") # Handle store if form_submitted and form_store: alpha_position = form.get("position") sample_uid = form.get("sample_uid") if not alpha_position or not api.is_uid(sample_uid): message = _("No position or not valid sample selected") return self.redirect(message=message) sample = api.get_object(sample_uid) logger.info("Storing sample {} in {} at {}".format( api.get_id(sample), api.get_id(container), alpha_position)) # Store position = container.alpha_to_position(alpha_position) if container.add_object_at(sample, position[0], position[1]): message = _("Stored sample {} at position {}").format( api.get_id(sample), alpha_position) if container.is_full(): return self.redirect(redirect_url=self.get_next_url()) return self.redirect(redirect_url=self.get_fallback_url(), message=message) # Handle cancel if form_submitted and form_cancel: return self.redirect(message=_("Sample storing canceled")) return self.template()
def __init__(self, context, request): super(StorageRootFolderContentsView, self).__init__(context, request) self.title = self.context.translate(_("Samples storage")) self.form_id = "list_storagerootfolder" self.contentFilter = dict(portal_type="StorageFacility", sort_on="sortable_title", sort_order="ascending") self.icon = "{}/{}".format( self.portal_url, "++resource++senaite.storage.static/img/storage_big.png") self.columns = collections.OrderedDict(( ("Title", { "title": _("Name"), "index": "sortable_index" }), ("SamplesUsage", { "title": _("Samples"), }), ("Samples", { "title": _("Samples usage"), }), ("Containers", { "title": _("Containers"), }), ("Phone", { "title": _("Phone"), }), ("EmailAddress", { "title": _("Email"), }), )) self.review_states = [ { "id": "default", "contentFilter": { "review_state": "active" }, "title": _("Active"), "transitions": [], "columns": self.columns.keys(), }, ] # Add Facility button self.context_actions[_("Add Facility")] = { "url": "createObject?type_name=StorageFacility", "icon": "++resource++bika.lims.images/add.png" }
def before_render(self): # Add stored review state print_stickers = { "id": "print_stickers", "title": _("Print stickers"), "url": "workflow_action?action=print_stickers" } base_column_ids = self.listing.columns.keys() hide = ["getDateVerified", "getDatePublished"] columns = filter(lambda col: col not in hide, base_column_ids) stored = { "id": "stored", "title": _("Stored"), "contentFilter": { "review_state": ("stored",), "sort_on": "created", "sort_order": "descending", }, "transitions": [], "custom_transitions": [print_stickers], "columns": columns, } utils.add_review_state(self.listing, stored, after="published") # Add the column Date Stored to the "stored" review state column_values = { "title": _("Date stored"), "index": "getDateStored", "attr": "getId", "toggle": True} utils.add_column(self.listing, "getDateStored", column_values, after="getDateReceived", review_states=("stored",)) # Add Samples Container column, but only if the current user logged in # is not a client contact if not api.get_current_client(): column_values = { "title": _("Storage"), "attr": "getSamplesContainerID", "replace_url": "getSamplesContainerURL", "toggle": True } utils.add_column(self.listing, "getSamplesContainer", column_values, after="getDateStored", review_states=("stored", ))
def __init__(self, context, request): super(StorageListing, self).__init__(context, request) self.sort_on = "sortable_title" self.show_select_row = False self.show_select_all_checkboxes = False self.show_select_column = False request.set("disable_border", 1) self.columns = collections.OrderedDict(( ("Title", { "title": _("Name"), "index": "sortable_title"}), ("Id", { "title": _("ID")}), ("SamplesUsage", { "title": _("% Samples"),}), ("Samples", { "title": _("Samples"),}), ("Containers", { "title": _("Containers"),}), )) self.review_states = [ { "id": "default", "contentFilter": {"review_state": "active"}, "title": _("Active"), "transitions": [], "columns": self.columns.keys(), }, ]
from Products.Archetypes.Field import StringField from Products.Archetypes.Schema import Schema from Products.Archetypes.Widget import StringWidget from Products.Archetypes.atapi import registerType from bika.lims.browser.fields.addressfield import AddressField from bika.lims.browser.widgets.addresswidget import AddressWidget from bika.lims.content.bikaschema import BikaFolderSchema from bika.lims.idserver import renameAfterCreation from plone.app.folder.folder import ATFolder from senaite.storage import PRODUCT_NAME from senaite.storage import senaiteMessageFactory as _ from senaite.storage.interfaces import IStorageFacility, IStorageLayoutContainer from zope.interface import implements Phone = StringField(name='Phone', widget=StringWidget(label=_("Phone"))) EmailAddress = StringField(name='EmailAddress', widget=StringWidget(label=_("Email Address"), ), validators=('isEmail', )) Address = AddressField( name='Address', widget=AddressWidget( label=_("Address"), render_own_label=True, showCopyFrom=False, ), subfield_validators={ 'country': 'inline_field_validator', 'state': 'inline_field_validator',
ExpressionValidator from bika.lims import api from bika.lims import alphanumber from bika.lims.content.bikaschema import BikaFolderSchema from bika.lims.idserver import renameAfterCreation from plone.app.folder.folder import ATFolder from senaite.storage import logger from senaite.storage import senaiteMessageFactory as _ from senaite.storage.interfaces import IStorageLayoutContainer, IStorageFacility from zope.interface import implements Rows = IntegerField( name="Rows", default=1, widget=IntegerWidget( label=_("Rows"), description=_("Alphabet letters will be used to represent a row " "within the container")), validators=(ExpressionValidator('python: int(value) > 0'), ExpressionValidator( 'python: here.get_minimum_size()[0] <= int(value)'))) Columns = IntegerField( name="Columns", default=1, widget=IntegerWidget( label=_("Columns"), description=_("Number of positions per row. Numbers will be used to " "represent a column within a row")), validators=(ExpressionValidator('python: int(value) > 0'), ExpressionValidator(
from Products.Archetypes.Schema import Schema from Products.Archetypes.atapi import registerType from bika.lims import api from bika.lims.browser.widgets.decimal import DecimalWidget from senaite.storage import PRODUCT_NAME from senaite.storage import senaiteMessageFactory as _ from senaite.storage.content.storagelayoutcontainer import \ StorageLayoutContainer from senaite.storage.content.storagelayoutcontainer import schema from senaite.storage.interfaces import IStorageContainer from zope.interface import implements Temperature = FloatField( name="Temperature", widget=DecimalWidget( label=_("Expected temperature"), description=_("Expected temperature of this container"))) schema = schema.copy() + Schema((Temperature, )) class StorageContainer(StorageLayoutContainer): """Container for the storage of other storage containers """ implements(IStorageContainer) schema = schema def is_object_allowed(self, object_brain_uid): """Returns whether the type of object can be stored or not in this container. This function returns true if the object is allowed, even if the container already contains the object
from Products.Archetypes.Widget import StringWidget from Products.Archetypes.atapi import registerType from bika.lims.browser.fields.addressfield import AddressField from bika.lims.browser.widgets.addresswidget import AddressWidget from bika.lims.content.bikaschema import BikaFolderSchema from bika.lims.idserver import renameAfterCreation from plone.app.folder.folder import ATFolder from senaite.storage import PRODUCT_NAME from senaite.storage import senaiteMessageFactory as _ from senaite.storage.interfaces import IStorageFacility, IStorageLayoutContainer from zope.interface import implements Phone = StringField( name = 'Phone', widget = StringWidget( label = _("Phone") ) ) EmailAddress = StringField( name = 'EmailAddress', widget = StringWidget( label=_("Email Address"), ), validators = ('isEmail',) ) Address = AddressField( name = 'Address', widget = AddressWidget( label=_("Address"),
def __init__(self, context, request): super(SamplesListing, self).__init__(context, request) request.set("disable_sorder", 1) self.title = context.Title() self.form_id = "list_storage_samples" self.sort_on = "sortable_title" self.show_select_row = False self.show_select_all_checkboxes = False self.show_select_column = True self.catalog = CATALOG_ANALYSIS_REQUEST_LISTING self.contentFilter = { "UID": context.get_samples_uids(), "sort_on": "sortable_title", "sort_order": "ascending" } self.columns = collections.OrderedDict(( ("position", { "title": _("Position"), "sortable": True, "toggle": True }), ("getId", { "title": _s("Sample ID"), "attr": "getId", "replace_url": "getURL", "index": "getId" }), ("getDateSampled", { "title": _s("Date Sampled"), "toggle": True }), ("getDateReceived", { "title": _s("Date Received"), "toggle": True }), ("Client", { "title": _s("Client"), "index": "getClientTitle", "attr": "getClientTitle", "replace_url": "getClientURL", "toggle": True }), ("getClientReference", { "title": _s("Client Ref"), "sortable": True, "index": "getClientReference", "toggle": False }), ("getClientSampleID", { "title": _s("Client SID"), "toggle": False }), ("getSampleTypeTitle", { "title": _s("Sample Type"), "sortable": True, "toggle": True }), )) self.review_states = [ { "id": "default", "contentFilter": {}, "title": _s("All"), "transitions": [], "columns": self.columns.keys(), }, ] imgs_path = "++resource++senaite.storage.static/img" self.icon = "{}/{}/{}".format(self.portal_url, imgs_path, "box_big.png") if not context.is_full(): uid = api.get_uid(context) self.context_actions = collections.OrderedDict() self.context_actions[_("Add Samples")] = { "url": "storage_store_container?uids={}".format(uid), "icon": "{}/{}".format(self.portal_url, "/++resource++bika.lims.images/sample.png") }