class ECQResult(ATCTContent, HistoryAwareMixin): """A quiz result.""" """ This class contains all the candidate-specific information for an ECQuiz. They are: questionResults: A dictionary that contains all the information concerning a single question, e. g. the suggested answer, the answer given by the candidate, the grade. The keys are the UIDs of the question. questionContainerIds: A list of the IDs of the 'ECQAbstractGroup' instances that the candidate saw. questionUIDs: A list of IDs of the questions that the candidate saw in their quiz. Unfortunately 'questionResults.keys()' cannot be used since it does not preserve the order of the UIDs. timeStart: The time when the candidate first saw the quiz. timeFinish: The time when the candidate submitted their quiz. """ schema = ATContentTypeSchema.copy() + Schema(( ObjectField( 'questionResults', read_permission=PERMISSION_RESULT_READ, default={}, ), ObjectField( 'possiblePointsCache', read_permission=PERMISSION_RESULT_READ, default={}, ), ObjectField( 'candidatePointsCache', read_permission=PERMISSION_RESULT_READ, default={}, ), ObjectField( 'questionContainerIds', read_permission=PERMISSION_RESULT_READ, default=[], ), ObjectField( 'questionUIDs', read_permission=PERMISSION_RESULT_READ, default=[], ), DateTimeField( 'timeStart', read_permission=PERMISSION_RESULT_READ, ), DateTimeField( 'timeFinish', read_permission=PERMISSION_RESULT_READ, default=None, ), IntegerField( 'currentPageNum', read_permission=PERMISSION_RESULT_READ, write_permission=PERMISSION_RESULT_WRITE, default=0, ), ), ) # Don't list this type in the portal navigation. navigation_exclude = True security = ClassSecurityInfo() security.declarePrivate('getQR') def getQR(self, caller, question, dontThrow=False): questionUID = question.UID() qrs = self.getQuestionResults() retVal = qrs.get(questionUID, None) if (retVal is not None) or dontThrow: return retVal else: txt = "%s() called for questionUID not in self.questionUIDs\n" \ "questionUID: %s\n" \ "self.questionUIDs: %s" \ % (caller, repr(questionUID), repr(self.getQuestionUIDs())) log(txt) raise Exception(txt) security.declarePrivate('storeQR') def storeQR(self, question, result): qrs = self.getQuestionResults() qrs[question.UID()] = result # Instead of saving "qrs" directly, save a copy of it, # "dict(qrs)". If we don't do that, there is a chance that # Zope will return an old, cached value the next time # "self.getQuestionResults()" is called because it *thinks* # the cached dictionary is the same as the stored one because # the memory location didn't change. self.setQuestionResults(dict(qrs)) security.declarePrivate('setSuggestedAnswer') def setSuggestedAnswer(self, question, suggestedAnswer): """ Saves the suggested answer values to a question the candidate was asked. @param suggestedAnswer The value or list of values of the answer suggested to the candidate. @param question The question that the answer belongs to. @param questionContainerId The ID of the question container that contains the question. """ # The list 'questionContainerIds' is neccessary because # 'self.questionResults.keys()' does not return the # questionUIDs in the order they were added. questionContainerId = getParent(question).getId() questionUID = question.UID() questionContainerIds = self.getQuestionContainerIds() if questionContainerId not in questionContainerIds: self.setQuestionContainerIds(questionContainerIds + [questionContainerId]) questionUIDs = self.getQuestionUIDs() if questionUID not in questionUIDs: self.setQuestionUIDs(questionUIDs + [questionUID]) qr = QuestionResult(suggestedAnswer) self.storeQR(question, qr) security.declareProtected(PERMISSION_RESULT_READ, 'getSuggestedAnswer') def getSuggestedAnswer(self, question): """ Returns the suggested answer values for a question the candidate was asked. With the standard question and answer types this will be a list of IDs of answer objects. """ qr = self.getQR("getAnswer", question) return qr.getSuggestedAnswer() security.declareProtected(PERMISSION_RESULT_READ, 'getCandidateAnswer') def getCandidateAnswer(self, question): """ Returns the candidate's answer to the question. If this question was not part of their quiz, an exception will be raised. """ qr = self.getQR("getCandidateAnswer", question) return qr.getCandidateAnswer() security.declareProtected(PERMISSION_RESULT_WRITE, 'setCandidateAnswer') def setCandidateAnswer(self, question, answerValue): """ Saves the candidate's answer to a question. @param answerValue The value or list of values of the answer(s) the candidate gave. With the standard question and answer types this will be the ID (list of IDs) of the answer(s) the candidate selected. """ qr = self.getQR("setCandidateAnswer", question) qr.setCandidateAnswer(answerValue) self.storeQR(question, qr) security.declareProtected(PERMISSION_RESULT_WRITE, 'unsetCandidateAnswer') def unsetCandidateAnswer(self, question): """ Removes the candidate's answer to a question. @param answerValue The value or list of values of the belongs to. """ qr = self.getQR("unsetCandidateAnswer", question) qr.unsetCandidateAnswer() self.storeQR(question, qr) ## Points caching: start # Points for an individual question security.declareProtected(PERMISSION_RESULT_READ, 'getCachedQuestionPoints') def getCachedQuestionPoints(self, question): """ """ qr = self.getQR("getCachedQuestionPoints", question) return qr.cachedPoints security.declareProtected(PERMISSION_RESULT_WRITE, 'setCachedQuestionPoints') def setCachedQuestionPoints(self, question, value): """ """ qr = self.getQR("setCachedQuestionPoints", question) qr.cachedPoints = value self.storeQR(question, qr) # Tutor-assigned points for an individual question security.declareProtected(PERMISSION_GRADE, 'setTutorPoints') def getTutorPoints(self, question): """ """ qr = self.getQR("getTutorPoints", question) return qr.tutorPoints security.declareProtected(PERMISSION_GRADE, 'setTutorPoints') def setTutorPoints(self, question, value): """ """ qr = self.getQR("setTutorPoints", question) qr.tutorPoints = value self.storeQR(question, qr) # clear related cache info test = getParent(question) if test.portal_type == ECQGroup.portal_type: questionGroup = test test = getParent(questionGroup) else: questionGroup = None self.setCachedCandidatePoints(test, None) #log("%s: CachedCandidatePoints: %s" % (str(self), str(test))) if questionGroup: self.setCachedCandidatePoints(questionGroup, None) #log("%s: CachedCandidatePoints: %s" % (str(self), # str(questionGroup))) #log("") security.declareProtected(PERMISSION_GRADE, 'unsetTutorPoints') def unsetTutorPoints(self, question): """ """ self.setTutorPoints(question, None) # this also clears any # related caches # Retract to "pending" because the result can't be "graded" if # some grades are missing userId = self.portal_membership.getAuthenticatedMember().getId() comment = "Retracted by %s: tutor grades were deleted" % userId self.tryWorkflowAction('retract_pending', ignoreErrors=True, comment=comment) # Possible points for a question group security.declareProtected(PERMISSION_RESULT_READ, 'getCachedPossiblePoints') def getCachedPossiblePoints(self, questionGroup): """ """ cache = self.getPossiblePointsCache() return cache.get(questionGroup.UID(), None) security.declareProtected(PERMISSION_RESULT_WRITE, 'setCachedPossiblePoints') def setCachedPossiblePoints(self, questionGroup, value): """ """ cache = self.getPossiblePointsCache() cache[questionGroup.UID()] = value self.setPossiblePointsCache(dict(cache)) # Achieved points for a question group security.declareProtected(PERMISSION_RESULT_READ, 'getCachedCandidatePoints') def getCachedCandidatePoints(self, questionGroup): """ """ cache = self.getCandidatePointsCache() return cache.get(questionGroup.UID(), None) security.declareProtected(PERMISSION_RESULT_WRITE, 'setCachedCandidatePoints') def setCachedCandidatePoints(self, questionGroup, value): """ """ cache = self.getCandidatePointsCache() cache[questionGroup.UID()] = value self.setCandidatePointsCache(dict(cache)) # Delete all cached points security.declarePrivate('unsetAllCachedPoints') def unsetAllCachedPoints(self): # Delete cached points for the questions qrs = self.getQuestionResults() for qr in qrs.values(): qr.cachedPoints = None self.setQuestionResults(dict(qrs)) # Delete the caches for possible and candidate points in a # question group self.setPossiblePointsCache({}) self.setCandidatePointsCache({}) #log("%s: deleted all cached points" % (str(self))) # Clear all cached points related to the question [question], # i. e. clear cache for possible and achieved (candidate) points # for the question and the question group and the test that # contain this question security.declarePrivate('unsetCachedQuestionPoints') def unsetCachedQuestionPoints(self, question): """ """ if self.getQR("", question, dontThrow=True) is not None: test = getParent(question) if test.portal_type == ECQGroup.portal_type: questionGroup = test test = getParent(questionGroup) else: questionGroup = None self.setCachedQuestionPoints(question, None) #log("%s: CachedQuestionPoints: %s" % (str(self), str(question))) self.setCachedPossiblePoints(test, None) #log("%s: CachedPossiblePoints: %s" % (str(self), str(test))) self.setCachedCandidatePoints(test, None) #log("%s: CachedCandidatePoints: %s" % (str(self), str(test))) if questionGroup: self.setCachedPossiblePoints(questionGroup, None) #log("%s: CachedPossiblePoints: %s" % (str(self), # str(questionGroup))) self.setCachedCandidatePoints(questionGroup, None) #log("%s: CachedCandidatePoints: %s" % (str(self), # str(questionGroup))) #log("") ## Points caching: end security.declareProtected(PERMISSION_RESULT_READ, 'haveCandidateAnswer') def haveCandidateAnswer(self, question): qr = self.getQR("haveCandidateAnswer", question) return qr.haveCandidateAnswer() security.declareProtected(PERMISSION_RESULT_WRITE, 'startWatch') def startWatch(self, question): qr = self.getQR("startWatch", question) if not qr.isWatchRunning(): qr.addTimeStart(datetime.now()) #log("startWatch: %s" % str(question)) self.storeQR(question, qr) makeTransactionUnundoable() security.declareProtected(PERMISSION_RESULT_WRITE, 'stopWatch') def stopWatch(self, question): qr = self.getQR("stopWatch", question) if qr.isWatchRunning(): #log("stopWatch: %s" % str(question)) qr.addTimeFinish(datetime.now()) self.storeQR(question, qr) security.declareProtected(PERMISSION_RESULT_READ, 'isWatchRunning') def isWatchRunning(self, question): qr = self.getQR("isWatchRunning", question) return qr.isWatchRunning() security.declareProtected(PERMISSION_RESULT_READ, 'getTimeSpent') def getTimeSpent(self, question): """@return A Python timedelta object.""" qr = self.getQR("getTimeSpent", question) return qr.getTimeSpent() security.declareProtected(PERMISSION_RESULT_READ, 'getSetCount') def getSetCount(self, question): """@return The number of times the candidate changed his answer.""" qr = self.getQR("getTimeSpent", question) return qr.getSetCount() security.declarePublic('getWorkflowState') def getWorkflowState(self): """Determine the Plone workflow state.""" wtool = self.portal_workflow wf = wtool.getWorkflowsFor(self)[0] return wf.getInfoFor(self, 'review_state', '') security.declarePublic('hasState') def hasState(self, state): return self.getWorkflowState() == state security.declarePrivate('tryWorkflowAction') def tryWorkflowAction(self, action, ignoreErrors=False, comment=None): wtool = self.portal_workflow wf = wtool.getWorkflowsFor(self)[0] if wf.isActionSupported(self, action): if comment is None: userId = getSecurityManager().getUser().getId() comment = 'State changed by ' + userId wtool.doActionFor(self, action, comment=comment) elif not ignoreErrors: raise TypeError('Unsupported workflow action %s for object %s.' % (repr(action), repr(self))) security.declarePublic('isGradable') def isGradable(self): mcTest = getParent(self) return mcTest.isTutorGraded(self) and \ (self.getWorkflowState() in ("pending", "graded",)) security.declareProtected(PERMISSION_RESULT_WRITE, 'submit') def submit(self): self.setTimeFinish(DateTime()) mcTest = getParent(self) results = mcTest.contentValues(filter={ 'Creator': self.Creator(), 'portal_type': self.portal_type, }) for res in results: # determine workflow action: submit for self and supersede # for all the others if res == self: if mcTest.isTutorGraded(self): action = 'submit_pending' else: action = 'submit_graded' commentAction = 'Submitted' else: action = 'supersede' commentAction = 'Superseded' # execute the action comment = '%s by %s' % (commentAction, self.Creator()) res.tryWorkflowAction(action, ignoreErrors=True, comment=comment) security.declarePublic('isNewer') def isNewer(self, other): return self.getTimeStart() > other.getTimeStart() security.declarePublic('isMoreFinal') def isMoreFinal(self, other): STATES = [ 'unsubmitted', 'superseded', 'pending', 'graded', #'invalid', ] indexes = [STATES.index(o.getWorkflowState()) for o in self, other] return indexes[0] > indexes[1] security.declarePrivate('getViewerNames') def getViewerNames(self): """ Get the names of the users and/or groups which have the local role ROLE_RESULT_VIEWER. This allows reviewers to quickly check who may view an assignment. @return list of user and/or group names """ principalIds = self.users_with_local_role(ROLE_RESULT_VIEWER) names = [] for id in principalIds: if self.portal_groups.getGroupById(id): names.append( self.portal_groups.getGroupById(id).getGroupName()) else: names.append(self.ecq_tool.getFullNameById(id)) return names security.declarePublic('getIndicators') def getIndicators(self): """ Returns a list of dictionaries which contain information necessary to display the indicator icons. """ retVal = [] user = self.portal_membership.getAuthenticatedMember() isOwner = user.has_role(['Owner', 'Reviewer', 'Manager'], self) isGrader = self.userIsGrader(user) viewers = self.getViewerNames() if viewers: if isOwner: retVal.append({ 'src': 'ec_shared.png', 'alt': 'Released', 'alt_msgid': 'label_released', 'title': '; '.join(viewers), }) elif isGrader: retVal.append({ 'src': 'ec_shared.png', 'alt': 'Released', 'alt_msgid': 'label_released', 'title': 'These quiz results have been released for viewing.', 'title_msgid': 'tooltip_released_icon', }) # if self.feedback: # feedback = str(self.feedback) # title = re.sub('[\r\n]+', ' ', feedback)[0:76] # retVal.append({'icon':'comment.png', # 'alt':'Feedback', # 'alt_msgid':'label_feedback', # 'title':title, # }) # if isGrader and hasattr(self, 'remarks') and self.remarks: # remarks = str(self.remarks) # title = re.sub('[\r\n]+', ' ', remarks)[0:76] # retVal.append({'icon':'ecab_remarks.png', # 'alt':'Remarks', # 'alt_msgid':'label_remarks', # 'title':title, # }) return retVal security.declarePublic('translateIndicators') def translateIndicators(self, indicators): # Translate [alt] and [title] for d in indicators: for k_msgid, k_msg in (( 'alt_msgid', 'alt', ), ( 'title_msgid', 'title', )): msgid = d.get(k_msgid, None) if msgid is not None: msg = d[k_msg] d[k_msg] = self.translate(msgid=k_msg, domain=I18N_DOMAIN, default=msg) d.pop(k_msgid) return indicators
widget=atapi.FileWidget(label=_("Attachment"), ), ), UIDReferenceField( 'AttachmentType', required=0, allowed_types=('AttachmentType', ), widget=ReferenceWidget(label=_("Attachment Type"), ), ), atapi.StringField( 'AttachmentKeys', searchable=True, widget=atapi.StringWidget(label=_("Attachment Keys"), ), ), DateTimeField( 'DateLoaded', required=1, default_method='current_date', widget=DateTimeWidget(label=_("Date Loaded"), ), ), ), ) schema['id'].required = False schema['title'].required = False class Attachment(atapi.BaseFolder): security = ClassSecurityInfo() displayContentsTab = False schema = schema _at_rename_after_creation = True
required=False, vocabulary='vocabulary_useCases', widget=InAndOutWidget( label='Story Use Case(s)', descrpiton="Please select use cases for this story", ), ), # planned completed date, 90% finish deadline DateTimeField( 'xppm_completion_date', searchable=False, required=True, widget=CalendarWidget( label='90% Completion Deadline', description= 'Specify the date when this task should be completed at less 90%', #starting_year = 2007, show_hm=False, ), schemata='Manage', ), # Progress Status in percentage. 0% - 100% FloatField( 'xppm_story_progress_percent', searchable=False, required=False, default=0.0, ),
'columnName': 'Title', 'width': '60', 'label': _('Title') }, { 'columnName': 'ClientID', 'width': '20', 'label': _('Client ID') }], ), ), StringField('ClientBatchID', required=0, widget=StringWidget(label=_("Client Batch ID"))), DateTimeField( 'BatchDate', required=False, widget=DateTimeWidget(label=_('Date'), ), ), LinesField('BatchLabels', vocabulary="BatchLabelVocabulary", accessor="getLabelNames", widget=MultiSelectionWidget( label=_("Batch Labels"), format="checkbox", )), RemarksField('Remarks', searchable=True, widget=RemarksWidget(label=_('Remarks'), )), ReferenceField( 'InheritedObjects', required=0,
), ), ReferenceField('Invoice', vocabulary_display_path_bound=sys.maxsize, allowed_types=('Invoice',), referenceClass=HoldingReference, relationship='OrderInvoice', ), DateTimeField( 'OrderDate', required=1, default_method='current_date', widget=DateTimeWidget( label=_("Order Date"), size=12, render_own_label=True, visible={ 'edit': 'visible', 'view': 'visible', 'add': 'visible', 'secondary': 'invisible' }, ), ), DateTimeField('DateDispatched', widget=DateTimeWidget( label=_("Date Dispatched"), ), ), TextField( "Remarks", allowable_content_types=("text/plain",),
from Products.ATContentTypes.content.schemata import ATContentTypeSchema from Products.ATContentTypes.content.schemata import finalizeATCTSchema from Products.ATContentTypes.permission import ChangeEvents from Products.ATContentTypes.content import base from Products.ATContentTypes.lib.constraintypes import ConstrainTypesMixinSchema RegisterableEventSchema = ATContentTypeSchema.copy( ) + ConstrainTypesMixinSchema + Schema(( DateTimeField( 'startDate', required=True, searchable=False, accessor='start', write_permission=ChangeEvents, default_method=DateTime, languageIndependent=True, widget=CalendarWidget( description="", description_msgid="help_event_start", label="Event Starts", label_msgid="label_event_start", i18n_domain="plone", ), ), BooleanField( 'ignore_hours', default=False, searchable=False, widget=BooleanWidget( label='Do not display event hours', description= 'Check this box if no hours should be displayed for this event',
), ReferenceField( 'Preservation', allowed_types=('Preservation', ), relationship='SamplePartitionPreservation', required=0, multiValued=0, ), BooleanField('Separate', default=False), UIDReferenceField( 'Analyses', allowed_types=('Analysis', ), required=0, multiValued=1, ), DateTimeField('DatePreserved', ), StringField('Preserver', searchable=True), DurationField('RetentionPeriod', ), )) schema['title'].required = False class SamplePartition(BaseContent, HistoryAwareMixin): implements(ISamplePartition) security = ClassSecurityInfo() displayContentsTab = False schema = schema _at_rename_after_creation = True
widget=bika_ReferenceWidget( label=_("Freezer"), visible={ 'edit': 'visible', 'view': 'visible' }, size=30, showOn=True, description=_("Select monitoring device."), )), DateTimeField( 'DateTimeIn', default_method=DateTime, widget=CalendarWidget( label='Datetime In', description='Datetime the device was placed inside the freezer', ampm=1, visible={ 'edit': 'visible', 'view': 'visible' })), DateTimeField( 'DateTimeOut', default_method=DateTime, widget=CalendarWidget( label='Datetime out', description='Datetime the device was removed from the freezer', ampm=1, visible={ 'edit': 'visible', 'view': 'visible'
required=True, default_output_type='text/x-html-safe', widget=RichWidget( label=u'Iteration Plan', description=u'The details plan about this iteration.', rows=25, ), ), # target completed date. DateTimeField( 'xppm_completion_date', searchable=False, required=True, widget=CalendarWidget( label='Target Completion Date', description= 'Specify the date when this iteration should be completed', show_hm=False, ), ), # iteration type: major, minor, MAYBE MORE... # iteration status: open close ), ) # finalize the content schema finalizeATCTSchema(PPMIterationSchema) # hide the description field.
from AccessControl import ClassSecurityInfo from Products.Archetypes.public import BaseContent from Products.Archetypes.public import DateTimeField from Products.Archetypes.public import registerType from Products.Archetypes.public import Schema from bika.lims.browser.widgets import DateTimeWidget from bika.lims.content.bikaschema import BikaSchema from bika.health.config import PROJECTNAME from bika.lims import bikaMessageFactory as _b from bika.health import bikaMessageFactory as _ schema = BikaSchema.copy() + Schema(( DateTimeField( 'StartDate', schemata='default', required=True, widget=DateTimeWidget(label=_("Epidemiological year start date"), ), ), DateTimeField( 'EndDate', schemata='default', required=True, widget=DateTimeWidget(label=_("Epidemiological year end date"), ), ), )) schema['description'].widget.visible = False schema['description'].schemata = 'default' class EpidemiologicalYear(BaseContent):
from leocornus.bookkeeping.interface import IBKTransaction __author__ = 'Sean Chen' __email__ = '*****@*****.**' # define a PPMProject as a folder in plone site. BKTransactionSchema = ATContentTypeSchema.copy() + Schema(( # transaction date. DateTimeField( 'bk_transaction_date', accessor='transactionDate', searchable=False, required=True, widget=CalendarWidget( label='Transaction Date', description='Please select the transaction date.', # available format: flex, select, radio format='%Y-%m-%d', show_hm=False, starting_year=2010, ), ), # transaction type. StringField( 'bk_transaction_type', accessor='transactionType', searchable=False, required=True, default='Expense', vocabulary='vocabularyTrxTypes',
from Products.Archetypes.public import BaseFolder from Products.Archetypes.public import registerType from Products.Archetypes.Marshall import PrimaryFieldMarshaller from AccessControl import ClassSecurityInfo from Products.CMFCore import permissions from Products.CMFCore.utils import getToolByName from Products.Quills.config import PROJECTNAME import DateTime WeblogArchiveSchema = BaseFolderSchema + Schema( ( DateTimeField( 'date', required=1, searchable=1, accessor='ArchiveDate', ), StringField( 'archive_type', required=1, searchable=0, accessor='ArchiveType', ), ), marshall=PrimaryFieldMarshaller(), ) class WeblogArchive(BaseFolder): """Weblog Archive: There are 4 basic styles, root, year, month, day"""