Hello everyone. I work with Mekom Solutions a contributing organization to OpenMRS and we are currently working on the OpenMRS 3.
For OpenMRS 3 we are using SENAITE as the LIMS component. Due to the way we will package our OpenMRS 3 distributions it will not be practical to manually configure the various components and we have already built tools for most of the components that we are using (OpenMRS itself, Odoo, … etc) that allow us to initialize them at start up without requiring user interventions
We are able to initialize SENAITE by uploading an xlsx file on the web UI which works great. But we need to be able do it at startup as well.
For our use case I have made an attempt to create a python script to initialize SENAITE given a configuration file. The code below may look familiar because it is adapted from here
from plone import api as ploneapi from Products.CMFCore.utils import getToolByName from bika.lims import PMF from bika.lims import logger from bika.lims.interfaces import ISetupDataImporter from openpyxl import load_workbook from pkg_resources import resource_filename from zope.component import getAdapters import traceback import tempfile import transaction try: from zope.component.hooks import getSite except: # Plone < 4.3 from zope.app.component.hooks import getSite class LoadSetupData(): def __init__(self, context): self.context = context # dependencies to resolve self.deferred =  def solve_deferred(self, deferred=None): unsolved =  deferred = deferred if deferred else self.deferred for d in self.deferred: src_obj = d['src_obj'] src_field = src_obj.getField(d['src_field']) multiValued = src_field.multiValued src_mutator = src_field.getMutator(src_obj) src_accessor = src_field.getAccessor(src_obj) tool = getToolByName(self.context, d['dest_catalog']) try: proxies = tool(d['dest_query']) except: continue if len(proxies) > 0: obj = proxies.getObject() if multiValued: value = src_accessor() value.append(obj.UID()) else: value = obj.UID() src_mutator(value) else: unsolved.append(d) self.deferred = unsolved return len(unsolved) def load_data(self): self.dataset_project = 'bika.lims' self.dataset_name = 'test' workbook = None try: workbook = load_workbook(filename='/home/enyachoke/Code/Mekom/senaite/senaitelims/src/collective.initializer/src/collective/initializer/configuration.xlsx') # , use_iterators=True) except AttributeError: print "" print traceback.format_exc() print "Error while loading " adapters = [[name, adapter] for name, adapter in list(getAdapters((self.context, ), ISetupDataImporter))] for sheetname in workbook.get_sheet_names(): transaction.savepoint() ad_name = sheetname.replace(" ", "_") if ad_name in [a for a in adapters]: adapter = [a for a in adapters if a == ad_name] adapter(self, workbook, self.dataset_project, self.dataset_name) adapters = [a for a in adapters if a != ad_name] transaction.commit() for name, adapter in adapters: transaction.savepoint() adapter(self, workbook, self.dataset_project, self.dataset_name) transaction.commit() check = len(self.deferred) while len(self.deferred) > 0: new = self.solve_deferred() logger.info("solved %s of %s deferred references" % ( check - new, check)) if new == check: raise Exception("%s unsolved deferred references: %s" % ( len(self.deferred), self.deferred)) check = new logger.info("Rebuilding bika_setup_catalog") bsc = getToolByName(self.context, 'bika_setup_catalog') bsc.clearFindAndRebuild() logger.info("Rebuilding bika_catalog") bc = getToolByName(self.context, 'bika_catalog') bc.clearFindAndRebuild() logger.info("Rebuilding bika_analysis_catalog") bac = getToolByName(self.context, 'bika_analysis_catalog') bac.clearFindAndRebuild() message = PMF("Changes saved.") self.context.plone_utils.addPortalMessage(message) def main(app): loader = LoadSetupData(app.senaite) loader.load_data() if "app" in locals(): main(app)
I have tested the script with the
collective.recipe.plonesite and it seems to work okay. My concern is that my combined experience working with Plone and SENAITE is less that 2 weeks and am not sure if my approach is any good. @Espurna @xispa any thoughts on this.