def position_check(data, constraints): """ Check the position of fields """ dic = data._Data_data___ indexes = constraints.get('indexes', {}) errors = {} for pt in indexes: pt_fld = '{}_fields'.format(pt) if pt_fld in dic: dic_pt_flds = field_list(dic, pt_fld) for (fld, i) in indexes[pt]: if dic_pt_flds.index(fld) + 1 != i: if pt not in errors: errors[pt] = [] errors[pt].append((fld, i)) msg = u'' for pt in errors: fields = [ _(u"'${fld}' at position ${i}", mapping={ 'fld': constraints['titles'][pt][fld], 'i': i }) for (fld, i) in errors[pt] ] msg += _(u"for '${type}' type => ${fields}. ", mapping={ 'type': _(pt), 'fields': ', '.join(fields) }) if msg: raise Invalid( _(u'Some fields have to be at a specific position: ${msg}', mapping={'msg': msg}))
def mandatory_check(data, constraints): """ Check the presence of mandatory fields """ dic = data._Data_data___ mandatory = constraints.get('mandatory', {}) missing = {} for pt in mandatory: pt_fld = '{}_fields'.format(pt) if pt_fld in dic: dic_pt_flds = field_list(dic, pt_fld) for mand in mandatory[pt]: if mand not in dic_pt_flds: missing_pt = missing.setdefault(pt, []) missing_pt.append(mand) msg = u'' for pt in missing: fields = [ u"'{}'".format(constraints['titles'][pt][fld]) for fld in missing[pt] ] msg += _(u"for '${type}' type => ${fields}. ", mapping={ 'type': _(pt), 'fields': ', '.join(fields) }) if msg: raise Invalid( _(u'Missing mandatory fields: ${msg}', mapping={'msg': msg}))
class IAnalyticBudget(model.Schema): """Budget field""" analytic_budget = schema.List( title=_(u"Analytic budget"), required=False, readonly=True, value_type=DictRow(title=_("Analytic budget"), schema=IAnalyticBudgetSchema, required=False), ) form.widget("analytic_budget", AnalyticBudgetDataGridFieldFactory, display_table_css_class="listing nosort") projection = schema.List( title=_(u"Projection"), required=False, readonly=True, value_type=DictRow(title=_("Projection"), schema=IProjectionSchema, required=False), ) form.widget("projection", ProjectionDataGridFieldFactory, display_table_css_class="listing nosort") form.order_before(projection='budget') form.order_before(analytic_budget='budget')
class IVocabularySchema(Interface): """ Schema used for the vocabulary datagrid field. """ label = schema.TextLine( title=_("Label"), required=True, ) key = schema.ASCIILine( title=_("Key"), required=True, )
class IProjectFieldsSchema(Interface): field_name = schema.Choice( title=_(u'Field name'), vocabulary=u'imio.project.core.ProjectFieldsVocabulary', ) read_tal_condition = schema.TextLine( title=_("Read TAL condition"), required=False, ) write_tal_condition = schema.TextLine( title=_("Write TAL condition"), required=False, )
def get_pt_fields_voc(pt, excluded, constraints={}): """ Returns a vocabulary with the given portal type fields, not excluded. Mandatory ones are suffixed with asterisk. """ terms = [] mandatory = constraints.get('mandatory', {}).get(pt, []) positions = { fld: pos for fld, pos in constraints.get('indexes', {}).get(pt, []) } empty = constraints.get('empty', {}).get(pt, []) if pt not in constraints.setdefault('titles', {}): constraints['titles'][pt] = {} for name, field in get_schema_fields(type_name=pt, prefix=True): if name in excluded: continue title = _(field.title) constraints['titles'][pt][name] = title if name in mandatory: title = u'{} *'.format(title) if name in positions: title = u'{} {}'.format(title, positions[name]) if name in empty: title = u'{} -'.format(title) terms.append(SimpleTerm(name, title=title)) return SimpleVocabulary(terms)
def __call__(self, context): pw = api.portal.get_tool('portal_workflow') for workflow in pw.getWorkflowsFor('project'): states = [value for value in workflow.states.values()] terms = [] for state in states: terms.append( SimpleTerm(state.id, title=_(safe_unicode(state.title), domain='plone'))) return SimpleVocabulary(terms)
class IResultIndicatorSchema(Interface): """Schema used for the datagrid field 'result_indicator' of IProject.""" label = schema.TextLine( title=_("Label"), required=True, ) value = schema.Int( title=_("Expected value"), required=True, ) reached_value = schema.Int( title=_("Reached value"), required=True, default=0, ) year = schema.Choice( title=_(u'Year'), # description=_(u"Choose a year."), vocabulary=u'imio.project.core.content.project.year_vocabulary', defaultFactory=default_year, )
class IProjectionSchema(Interface): """Schema used for the datagrid field 'projection' of IProject""" service = schema.TextLine( title=_(u"Budget Service"), required=True, ) btype = schema.TextLine( title=_(u"Budget Type"), required=True, ) group = schema.TextLine( title=_(u"Budget Group"), # description=_(u"Define the budget article."), required=True, ) title = schema.TextLine( title=_(u"Budget Title"), # description=_(u"Define the budget article."), required=True, ) year = schema.Choice( title=_(u"Year"), # description=_(u"Choose a year."), vocabulary=u"imio.project.core.content.project.year_vocabulary", required=True, defaultFactory=default_year, ) amount = schema.Float(title=_("Amount"), required=True, default=0.0)
class IBudgetSchema(Interface): """Schema used for the datagrid field 'budget' of IProject.""" budget_type = schema.Choice( title=_(u'Budget_type'), # description=_(u"Choose a budget type."), vocabulary=u'imio.project.core.content.project.budget_type_vocabulary', ) year = schema.Choice( title=_(u'Year'), # description=_(u"Choose a year."), vocabulary=u'imio.project.core.content.project.year_vocabulary', defaultFactory=default_year, ) amount = schema.Float( title=_("Amount"), required=True, default=0.0, ) budget_comment = schema.TextLine( title=_(u"Budget_comment"), required=False, )
class IProjectSpace(model.Schema): """ Project schema, field ordering """ last_reference_number = schema.Int( title=_(u"Last reference number"), # description=_(u""), required=False, default=0, ) categories_values = schema.List( title=_(u'Categories values'), description=_( u"Enter one different value by row. Label is the displayed value. Key is the stored value:" " in lowercase, without space."), required=True, value_type=DictRow(title=u"", schema=IVocabularySchema, required=False), ) directives.widget('categories_values', DataGridFieldFactory, display_table_css_class='listing', allow_reorder=True) priority_values = schema.List( title=_(u'Priority values'), description=_( u"Enter one different value by row. Label is the displayed value. Key is the stored value:" " in lowercase, without space."), required=True, value_type=DictRow(title=u"", schema=IVocabularySchema, required=False), ) directives.widget('priority_values', DataGridFieldFactory, display_table_css_class='listing', allow_reorder=True) budget_types = schema.List( title=_(u'Budget types values'), description=_( u"Enter one different value by row. Label is the displayed value. Key is the stored value:" " in lowercase, without space."), required=True, value_type=DictRow(title=u"", schema=IVocabularySchema, required=False), ) directives.widget('budget_types', DataGridFieldFactory, display_table_css_class='listing', allow_reorder=True) budget_years = schema.List( title=_(u'Budget concerned years'), # description=_(u"Select all years concerned by budget."), required=True, value_type=schema.Choice(vocabulary=possible_years)) directives.widget('budget_years', SelectFieldWidget, multiple='multiple', size=6) project_budget_states = schema.List( title=_(u"${type} budget globalization states", mapping={'type': _('Project')}), description= _(u'Put states on the right for which you want to globalize budget fields.' ), required=False, value_type=schema.Choice( vocabulary=u'imio.project.core.ProjectStatesVocabulary'), ) use_ref_number = schema.Bool( title=_(u'Use reference number'), description=_(u'Used in Title, documents, etc.'), default=True, ) INS_code = schema.TextLine( title=_(u'INS Code'), # description=_(u'5-character code statistically representing the town'), required=False, ) current_fiscal_year = schema.Int( title=_(u'Current fiscal year'), # description=_(u''), required=False, ) plan_values = schema.List( title=_(u'Plan values'), description=_( u"Enter one different value by row. Label is the displayed value. Key is the stored value:" " in lowercase, without space."), required=True, value_type=DictRow(title=u"", schema=IVocabularySchema, required=False), ) directives.widget('plan_values', DataGridFieldFactory, display_table_css_class='listing', allow_reorder=True) project_fields = schema.List( title=_(u"${type} fields display", mapping={'type': _('Project')}), description=_( u'Put fields on the right to display it. Flags are : ...'), value_type=DictRow(title=_(u'Field'), schema=IProjectFieldsSchema, required=False), ) directives.widget('project_fields', DataGridFieldFactory, display_table_css_class='listing', allow_reorder=True, auto_append=False) organization_type = schema.Choice( title=_(u'Organization type'), vocabulary= u'imio.project.core.content.projectspace.organization_type_vocabulary', default='ac', ) colorize_project_rows = schema.Bool( title=_(u"colorize project's rows"), description=_(u"Visual way to highlight internal panes in dashboards"), default=False, ) @invariant def validateSettings(data): mandatory_check(data, field_constraints) position_check(data, field_constraints)
def _validateKeyNotUsed(context, value, stored_value, attribute_using_keys, sub_attribute_using_key=None, portal_types=[]): """ Check if a key was removed in the given p_value regarding p_stored_value on context. If a key was removed, check that no given p_portal_types is using it. It suppose that given p_value is a list of dicts with 'key' and 'label' as existing keys. Given p_attribute_using_keys is the name of the attribute of sub objects using this key. Given p_sub_attribute_using_key is in the case of a datagridfield using this vocabulary, it is the name of the column using the vocabulary...""" # we only go further if a key was actually removed # so compare stored values to new given values storedKeys = [stored['key'] for stored in stored_value] newKeys = [newValue['key'] for newValue in value] removedKeys = set(storedKeys).difference(set(newKeys)) if not removedKeys: return # if we found removed keys, then check that it was not used params = { 'path': { 'query': '/'.join(context.getPhysicalPath()) }, } if portal_types: params['portal_type'] = portal_types catalog = getToolByName(context, 'portal_catalog') brains = catalog(**params) for brain in brains: # do not validate context... (root element). While doing a query on path, the context is also found... if brain.portal_type == context.portal_type: continue obj = brain.getObject() if not base_hasattr(obj, attribute_using_keys): continue used_value = getattr(obj, attribute_using_keys, ()) # we need a tuple so 'set' here under works... # this is because we want this method to be a bit generic... if isinstance(used_value, unicode): used_value = (used_value, ) # if we use a datagridfield, we have to get the relevant column if sub_attribute_using_key: # it means that we use a datagridfield and that data is stored # in a dict contained in the list... tmpres = [] for line in used_value or (): tmpres.append(line[sub_attribute_using_key]) used_value = tuple(tmpres) if not used_value: continue intersectionValues = set(used_value).intersection(removedKeys) if intersectionValues: wrong_removed_key = intersectionValues.pop() raise Invalid( _(ERROR_VALUE_REMOVED_IS_IN_USE, mapping={ 'removed_key': wrong_removed_key, 'used_by_url': obj.absolute_url(), }))
class IProject(model.Schema): """Project schema, field ordering.""" dexteritytextindexer.searchable('description_rich') description_rich = RichText( title=_PMF(u'label_description', default=u'Summary'), required=False, ) dexteritytextindexer.searchable('reference_number') reference_number = schema.Int( title=_(u"Reference number"), # description=_(u"Unique identification"), required=False, default=0, ) categories = schema.List( title=_(u'Categories'), # description=_(u"Choose categories."), required=False, value_type=schema.Choice( source='imio.project.core.content.project.categories_vocabulary'), defaultFactory=default_categories, ) directives.widget('categories', AjaxChosenMultiFieldWidget, populate_select=True) priority = schema.Choice( title=_(u'Priority'), # description=_(u"Choose a priority."), vocabulary=u'imio.project.core.content.project.priority_vocabulary', ) budget = schema.List( title=_(u'Budget'), # description=_(u"Enter budget details. If you have comments about budget, " # "use the field here above."), required=False, value_type=DictRow(title=_("Budget"), schema=IBudgetSchema, required=False), ) directives.widget('budget', BudgetInfosDataGridFieldFactory, display_table_css_class='listing nosort') budget_comments = RichText( title=_(u"Budget comments"), # description=_(u"Write here comments you have about budget."), required=False, allowed_mime_types=('text/html', ), ) manager = LocalRolesField( title=_(u"Manager"), # description=_(u"Choose principals that will manage this project."), value_type=schema.Choice( vocabulary='imio.project.core.content.project.manager_vocabulary'), required=True, min_length=1, ) directives.widget('manager', AjaxChosenMultiFieldWidget, populate_select=True) visible_for = LocalRolesField( title=_(u"Visible for"), # description=_(u"Choose principals that can see this project."), required=False, value_type=schema.Choice( vocabulary= 'imio.project.core.content.project.visible_for_vocabulary'), ) extra_concerned_people = schema.Text( title=_(u"Extra concerned people"), # description=_(u"Specify here concerned people that do not have access " # "to the application, this will just be informational."), required=False, ) result_indicator = schema.List( title=_(u'Result indicator'), description=_(u"Enter one indicator by row. Value is a number. " "Label must precise the signification of this number."), required=False, value_type=DictRow(title=_("Result indicator"), schema=IResultIndicatorSchema, required=False), ) directives.widget('result_indicator', DataGridFieldFactory, display_table_css_class='listing nosort') planned_begin_date = schema.Date( title=_(u'Planned begin date'), # description=_(u"Enter the planned begin date."), required=False, # defaultFactory=datetime.date.today, ) directives.widget(planned_begin_date=DateFieldWidget) effective_begin_date = schema.Date( title=_(u'Effective begin date'), # description=_(u"Enter the effective begin date."), required=False, # defaultFactory=datetime.date.today, ) directives.widget(effective_begin_date=DateFieldWidget) planned_end_date = schema.Date( title=_(u'Planned end date'), # description=_(u"Enter the planned end date."), required=False, # defaultFactory=datetime.date.today, ) directives.widget(planned_end_date=DateFieldWidget) effective_end_date = schema.Date( title=_(u'Effective end date'), # description=_(u"Enter the effective end date."), required=False, # defaultFactory=datetime.date.today, ) directives.widget(effective_end_date=DateFieldWidget) progress = schema.Int( title=_(u"Progress"), description=_(u"Progress estimation in %."), required=False, default=0, ) observation = RichText( title=_(u"Observation"), # description=_(u"Prior determination"), required=False, allowed_mime_types=('text/html', ), ) comments = RichText( title=_(u"Comments"), # description=_(u"Various comments"), required=False, allowed_mime_types=('text/html', ), ) plan = schema.List( title=_(u'Plan'), # description=_(u"Choose plan."), required=False, value_type=schema.Choice( source='imio.project.core.content.project.plan_vocabulary'), defaultFactory=default_plan, ) directives.widget('plan', AjaxChosenMultiFieldWidget, populate_select=True)