Exemplo n.º 1
0
 def load(self):
     query = globals.db.query('tasks', order_by='due_date,active_date',                                       limit=10)
     # Exclude deleted cases via /cases/ LEFT JOIN
     query.join('LEFT JOIN cases USING (case_id)')
     subquery = query.sub_expr(conjunction='OR')
     subquery.where('NOT cases.deleted')
     subquery.where('cases.deleted IS null')
     subquery.where('tasks.case_id IS null')
     if 0:
         # Filter for tasks assigned to us
         subquery = query.sub_expr(conjunction = 'OR')
         task_subscription_query(subquery, self.credentials)
         # OR tasks assigned by us that are overdue
         overdue_query = subquery.sub_expr(conjunction = 'AND')
         uquery = overdue_query.sub_expr(conjunction = 'OR')
         uquery.where('assigner_id = %s', self.credentials.user.user_id)
         uquery.where('originator_id = %s', self.credentials.user.user_id)
         overdue_query.where('due_date <= CURRENT_TIMESTAMP')
     else:
         task_subscription_query(query, self.credentials)
     query.where('active_date <= CURRENT_TIMESTAMP')
     query.where('completed_date is null')
     query.join('LEFT JOIN persons USING (person_id)')
     now = datetime.now()
     self[:] = [QuickTask(now, *row) 
                for row in query.fetchcols(QuickTask.cols)]
Exemplo n.º 2
0
 def __init__(self, params, syndrome_id, title, row, column, page,
              empty_rowsncols=True,
              empty_pages=True):
     self.params = params
     self.syndrome_id = syndrome_id
     self.title = title
     self.row = row
     self.col = column
     self.page = page
     self.empty_rowsncols = empty_rowsncols
     self.empty_pages = empty_pages
     self.form_name = None
     self.form_table = None
     self.cols = []
     for axis in (self.row, self.col, self.page):
         if axis.form_name:
             if self.form_name and self.form_name != axis.form_name:
                 raise Error('Crosstab between different forms is not '
                             'supported')
             self.form_name = axis.form_name
             self.form_table = axis.table
         if axis.table:
             self.cols.append(axis.tabcol)
             axis.options.append((None, 'Missing'))
             axis.options.append((TOTAL, 'TOTAL'))
     self.date = datetime.now()
Exemplo n.º 3
0
 def new(cls,
         credentials,
         syndrome_id,
         from_search=None,
         use_person_id=None,
         defer_case_id=False,
         **kwargs):
     """
     Alternate constructor, used when case is new
     """
     if defer_case_id:
         case_id = None
     else:
         case_id = globals.db.nextval('cases', 'case_id')
     case_seed = dict(case_id=case_id,
                      syndrome_id=syndrome_id,
                      notification_datetime=datetime.now())
     if from_search is not None:
         if use_person_id is None:
             kwargs['seed_person'] = from_search.person
         if from_search.case_status != '!':
             case_seed['case_status'] = from_search.case_status
         if from_search.case_assignment != '!':
             case_seed['case_assignment'] = from_search.case_assignment
         case_seed['local_case_id'] = from_search.local_case_id
         # case_seed['notes'] = from_search.notes
         # case_seed['notification_datetime'] = from_search.notification_datetime
         # case_seed['onset_datetime'] = from_search.onset_datetime
         case_seed['notifier_name'] = from_search.notifier_name
         # case_seed['notifier_contact'] = from_search.notifier_contact
     case_row = globals.db.new_row('cases', **case_seed)
     case = cls(credentials, case_row, **kwargs)
     if use_person_id is not None:
         case.use_person_id(use_person_id)
Exemplo n.º 4
0
 def load(self):
     query = globals.db.query('tasks',
                              order_by='due_date,active_date',
                              limit=10)
     # Exclude deleted cases via /cases/ LEFT JOIN
     query.join('LEFT JOIN cases USING (case_id)')
     subquery = query.sub_expr(conjunction='OR')
     subquery.where('NOT cases.deleted')
     subquery.where('cases.deleted IS null')
     subquery.where('tasks.case_id IS null')
     if 0:
         # Filter for tasks assigned to us
         subquery = query.sub_expr(conjunction='OR')
         task_subscription_query(subquery, self.credentials)
         # OR tasks assigned by us that are overdue
         overdue_query = subquery.sub_expr(conjunction='AND')
         uquery = overdue_query.sub_expr(conjunction='OR')
         uquery.where('assigner_id = %s', self.credentials.user.user_id)
         uquery.where('originator_id = %s', self.credentials.user.user_id)
         overdue_query.where('due_date <= CURRENT_TIMESTAMP')
     else:
         task_subscription_query(query, self.credentials)
     query.where('active_date <= CURRENT_TIMESTAMP')
     query.where('completed_date is null')
     query.join('LEFT JOIN persons USING (person_id)')
     now = datetime.now()
     self[:] = [
         QuickTask(now, *row) for row in query.fetchcols(QuickTask.cols)
     ]
Exemplo n.º 5
0
 def _update(self, db, inplace=False, complete=False):
     if inplace:
         # Update in place
         task = self._locked_fetch(db, self.seed_task_id, self.this_user_id)
         if task is None:
             raise TaskError('Update failed - the task has been changed'
                             ' by another user')
         _set_unlocked(task)
         _clear_completed(task)
     else:
         # Create a new task, closing the old one if necessary.
         if self.seed_task_id is not None:
             task = self._locked_fetch(db, self.seed_task_id)
             if _our_lock(task, self.this_user_id):
                 _set_unlocked(task)
             _set_completed(task, self.this_user_id)
             task.db_update()
         task = db.new_row('tasks')
         task.parent_task_id = self.seed_task_id
         task.creation_date = datetime.now()
     self._copy(self, task)
     if not self.task_description or not self.task_description.strip():
         raise TaskError('Task must have a description')
     old_due = None
     if task.due_date and task.active_date:
         old_due = task.due_date - task.active_date
     if self.active_abs and self.active_abs.strip():
         try:
             active_abs = datetime.mx_parse_datetime(self.active_abs)
         except datetime.Error, e:
             raise TaskError('Start date: %s' % e)
         if not datetime.near(active_abs, task.active_date):
             task.active_date = active_abs
Exemplo n.º 6
0
 def new(cls, credentials, syndrome_id, 
         from_search=None, use_person_id=None, 
         defer_case_id=False, **kwargs):
     """
     Alternate constructor, used when case is new
     """
     if defer_case_id:
         case_id = None
     else:
         case_id = globals.db.nextval('cases', 'case_id')
     case_seed = dict(case_id=case_id,
                      syndrome_id=syndrome_id,
                      notification_datetime=datetime.now())
     if from_search is not None:
         if use_person_id is None:
             kwargs['seed_person'] = from_search.person
         if from_search.case_status != '!':
             case_seed['case_status'] = from_search.case_status
         if from_search.case_assignment != '!':
             case_seed['case_assignment'] = from_search.case_assignment
         case_seed['local_case_id'] = from_search.local_case_id
         # case_seed['notes'] = from_search.notes
         # case_seed['notification_datetime'] = from_search.notification_datetime
         # case_seed['onset_datetime'] = from_search.onset_datetime
         case_seed['notifier_name'] = from_search.notifier_name
         # case_seed['notifier_contact'] = from_search.notifier_contact
     case_row = globals.db.new_row('cases', **case_seed)
     case = cls(credentials, case_row, **kwargs)
     if use_person_id is not None:
         case.use_person_id(use_person_id)
     if from_search and from_search.tags:
         # This doesn't give the normal "seed" semantics.
         case.tags.cur = from_search.tags
     return case
Exemplo n.º 7
0
 def _write_version(self, name, *args):
     form = self.to_form()
     if self.cred:
         form.author = self.cred.user.fullname
         form.username = self.cred.user.username
     form.update_time = datetime.now()
     globals.formlib.save(form, name, *args)
     self.root.update_time = form.update_time
     return form.version, form.update_time
Exemplo n.º 8
0
 def set_deleted(self, delete, reason=None):
     if delete:
         timestamp = datetime.now().mx()
     else:
         timestamp = None
         reason = None
     query = globals.db.query('case_form_summary')
     query.where('summary_id = %s', self.summary_id)
     query.update('deleted=%s, delete_reason=%s, delete_timestamp=%s',
                  delete, reason, timestamp)
     globals.db.commit()
     self.deleted = delete
Exemplo n.º 9
0
 def __init__(self, db, credentials, task_id):
     self.user_id = credentials.user.user_id
     self.task_id = task_id
     self.done = False
     task = self._locked_fetch(db, self.task_id)
     self._copy(task, self)
     self.assigner = unituser.users[task.assigner_id]
     self.was_locked = None
     if task.locked_by_id is not None and task.locked_by_id != self.user_id:
         username = unituser.users[task.locked_by_id].username
         self.was_locked = '%s %s' % (username,
                                      datetime.relative(task.locked_date))
     task.locked_by_id = self.user_id
     task.locked_date = datetime.now()
     task.db_update()
Exemplo n.º 10
0
 def load(self):
     query = globals.db.query('tasks')
     if self.queue_id is not None:
         query.where('queue_id = %s', self.queue_id)
     now = datetime.now()
     self.total = self.completed = self.active =\
         self.overdue = self.locked = 0
     cols = 'due_date', 'completed_date', 'locked_by_id'
     for due_date, completed_date, locked_by_id in query.fetchcols(cols):
         self.total += 1
         if completed_date is None:
             self.active += 1
             if due_date < now:
                 self.overdue += 1
             if locked_by_id is not None:
                 self.locked += 1
         else:
             self.completed += 1
Exemplo n.º 11
0
 def to_dobprec(self, now=None):
     """
     Given an integer age and unit code, return a DOB & precision
     """
     if self.units == 'y':
         age = DateTime.RelativeDateTime(years=self.age)
         prec = PREC_YEAR
     elif self.units == 'm':
         age = DateTime.RelativeDateTime(months=self.age)
         prec = PREC_MONTH
     elif self.units == 'w':
         age = DateTime.RelativeDateTime(weeks=self.age)
         prec = PREC_WEEK
     elif self.units == 'd':
         age = DateTime.RelativeDateTime(days=self.age)
         prec = PREC_DAY
     else:
         raise AssertionError('Bad age units: %s' % self.units)
     if now is None:
         now = datetime.now()
     return now - age, prec
Exemplo n.º 12
0
 def to_dobprec(self, now=None):
     """
     Given an integer age and unit code, return a DOB & precision
     """
     if self.units == 'y':
         age = DateTime.RelativeDateTime(years=self.age)
         prec = PREC_YEAR
     elif self.units == 'm':
         age = DateTime.RelativeDateTime(months=self.age)
         prec = PREC_MONTH
     elif self.units == 'w':
         age = DateTime.RelativeDateTime(weeks=self.age)
         prec = PREC_WEEK
     elif self.units == 'd':
         age = DateTime.RelativeDateTime(days=self.age)
         prec = PREC_DAY
     else:
         raise AssertionError('Bad age units: %s' % self.units)
     if now is None:
         now = datetime.now()
     return now - age, prec
Exemplo n.º 13
0
 def active(self):
     now = datetime.now()
     return (self.enabled 
             and (not self.post_date or self.post_date <= now)
             and (not self.expiry_date or self.expiry_date > now))
Exemplo n.º 14
0
        try:
            case_row.notification_datetime = \
                datetime.mx_parse_datetime(case_row.notification_datetime)
        except datetime.Error, e:
            raise ValidationError('%s: %s' %
                                  (_label('notification_datetime'), e))
        if datetime.is_later_than(self.case_row.onset_datetime,
                                  self.case_row.notification_datetime):
            raise ValidationError(
                '%s must be after %s' %
                (_label('notification_datetime'), _label('onset_datetime')))
        if datetime.is_later_than(self.person.DOB,
                                  self.case_row.onset_datetime):
            raise ValidationError('%s must be after %s' %
                                  (_label('onset_datetime'), _label('DOB')))
        if datetime.is_later_than(self.person.DOB, datetime.now()):
            raise ValidationError('\'%s\': %s must not be in the future' %
                                  (self.person.DOB, _label('DOB')))
        if datetime.is_later_than(self.case_row.onset_datetime,
                                  datetime.now()):
            raise ValidationError(
                '\'%s\': %s must not be in the future' %
                (self.case_row.onset_datetime, _label('onset_datetime')))
        if datetime.is_later_than(self.case_row.notification_datetime,
                                  datetime.now()):
            raise ValidationError('\'%s\': %s must not be in the future' %
                                  (self.case_row.notification_datetime,
                                   _label('notification_datetime')))

    def has_changed(self):
        return (self.tags.has_changed() or self.case_row.db_has_changed()
Exemplo n.º 15
0
 def page_rows(self, cred):
     self.page_jump()
     # Fetch task rows
     results = paged_search.SortablePagedSearch.page_rows(self)
     # Fetch associated entities
     case_dict = self.db.table_dict('cases')
     user_dict = self.db.table_dict('users')
     unit_dict = self.db.table_dict('units')
     person_dict = self.db.table_dict('persons')
     queue_dict = self.db.table_dict('workqueues')
     for task in results:
         if task.case_id is not None:
             case_dict.want(task.case_id)
         if task.originator_id is not None:
             user_dict.want(task.originator_id)
         if task.assigner_id is not None:
             user_dict.want(task.assigner_id)
         if task.locked_by_id is not None:
             user_dict.want(task.locked_by_id)
         if task.completed_by_id is not None:
             user_dict.want(task.completed_by_id)
         queue_dict.want(task.queue_id)
     queue_dict.preload()
     for queue in queue_dict.values():
         if queue.unit_id is not None:
             unit_dict.want(queue.unit_id)
         if queue.user_id is not None:
             user_dict.want(queue.user_id)
     case_dict.preload()
     unit_dict.preload()
     user_dict.preload()
     for case in case_dict.itervalues():
         person_dict.want(case.person_id)
     person_dict.preload()
     # Now join it all together
     now = datetime.now()
     for task in results:
         task.active_relative = datetime.relative(task.active_date, now)
         active_days = (now - task.active_date).days
         task.active_color = trafficlight.web_trafficlight(active_days, 30)
         if task.completed_date:
             task.complete_color = '#cccccc'
             if task.action == tasks.ACTION_THREAD_DELETED:
                 task.complete_relative = 'DELETED'
             else:
                 task.complete_relative = 'completed'
             completed_by = user_dict.get(task.completed_by_id)
             if completed_by is not None:
                 task.complete_relative += ' by %s ' % completed_by.username
             task.complete_relative += str(task.completed_date)
         elif task.due_date is None:
             task.complete_color = 'transparent'
             task.complete_relative = ''
         else:
             due_days = (now - task.due_date).days + 15
             task.complete_color = trafficlight.web_trafficlight(
                 due_days, 30)
             task.complete_relative = datetime.relative(task.due_date, now)
         task.originator = user_dict.get(task.originator_id)
         task.assigner = user_dict.get(task.assigner_id)
         task.locked_by = user_dict.get(task.locked_by_id)
         task.locked_relative = datetime.relative(task.locked_date, now)
         queue = queue_dict.get(task.queue_id)
         if queue is None:
             task.assignee = ''
         elif queue.unit_id is not None:
             task.assignee = '%s: %s' %\
                 (config.unit_label, unit_dict.get(queue.unit_id).name)
         elif queue.user_id is not None:
             task.assignee = 'User: %s' %\
                 user_dict.get(queue.user_id).username
         else:
             task.assignee = 'Queue: %s' % queue.name
         task.case_summary = task.contact_summary = ''
         if task.case_id is not None:
             task.case_summary = case_summary(self.db, task.case_id,
                                              case_dict, person_dict)
         task.action_summary = tasks.action_desc.get(task.action, 'unknown')
     return results
Exemplo n.º 16
0
    def merge(self, credentials):
        # lock the relevent cases
        case_a, case_b = self._fetch_cases(for_update=True)
        # Safety checks:
        not_same_person = (case_a.person_id != case_b.person_id)
        syndrome_mismatch = (case_a.syndrome_id != case_b.syndrome_id)
        if not_same_person or syndrome_mismatch:
            raise MergeError('Unable to merge - consistency check failed')
        for mc in self.fields:
            try:
                mc.apply(case_a, case_b)
            except CaseHasChanged:
                case_a.db_revert()
                case_b.db_revert()
                self.init_fields(case_a, case_b)
                raise
        # Which direction to merge?
        if self.keep == 'a':
            update_case, delete_case = case_a, case_b
        else:
            update_case, delete_case = case_b, case_a
        update_desc = update_case.db_desc()
        delete_desc = delete_case.db_desc()
        # XXX Describe tag changes - how?
        if not update_desc:
            update_desc = 'no edits required'
        if not delete_desc:
            delete_desc = 'no edits required'
        if update_case.deleted and not delete_case.deleted:
            update_case.deleted = False
            update_case.delete_reason = None
            update_case.delete_timestamp = None
        delete_case.deleted = True
        delete_case.delete_reason = 'Merged to %s' % update_case.case_id
        delete_case.delete_timestamp = datetime.now()
        curs = globals.db.cursor()
        try:
            # merge contacts
            dbobj.execute(
                curs, 'UPDATE case_contacts SET contact_id=%s'
                ' WHERE contact_id=%s'
                '  AND case_id != %s'
                '  AND case_id NOT IN'
                '   (SELECT case_id FROM case_contacts'
                '     WHERE contact_id=%s)',
                (update_case.case_id, delete_case.case_id, update_case.case_id,
                 update_case.case_id))
            dbobj.execute(
                curs, 'UPDATE case_contacts SET case_id=%s'
                ' WHERE case_id=%s'
                '  AND contact_id != %s'
                '  AND contact_id NOT IN'
                '   (SELECT contact_id FROM case_contacts'
                '     WHERE case_id=%s)',
                (update_case.case_id, delete_case.case_id, update_case.case_id,
                 update_case.case_id))
            dbobj.execute(
                curs, 'DELETE FROM case_contacts'
                ' WHERE case_id=%s OR contact_id=%s',
                (delete_case.case_id, delete_case.case_id))

            # case_form_summary
            dbobj.execute(
                curs, 'UPDATE case_form_summary SET case_id=%s'
                ' WHERE case_id=%s',
                (update_case.case_id, delete_case.case_id))
            # case_acl
            dbobj.execute(curs, 'UPDATE case_acl SET case_id=%s'
                          ' WHERE case_id=%s',
                          (update_case.case_id, delete_case.case_id))
            # tasks
            dbobj.execute(curs, 'UPDATE tasks SET case_id=%s'
                          ' WHERE case_id=%s',
                          (update_case.case_id, delete_case.case_id))
            dbobj.execute(curs, 'UPDATE tasks SET case_id=%s'
                          ' WHERE case_id=%s',
                          (update_case.case_id, delete_case.case_id))
            dbobj.execute(curs, 'UPDATE user_log SET case_id=%s'
                          ' WHERE case_id=%s',
                          (update_case.case_id, delete_case.case_id))
            dbobj.execute(curs, 'UPDATE user_log SET case_id=%s'
                          ' WHERE case_id=%s',
                          (update_case.case_id, delete_case.case_id))
        finally:
            curs.close()
        update_case.db_update()
        tag_desc = casetags.set_case_tags(update_case.case_id,
                                          update_case.tags)
        delete_case.db_update()
        desc = 'Merge System ID %s into %s, UPDATED %s %s, DELETED %s' %\
                    (delete_case.case_id, update_case.case_id,
                     update_desc, tag_desc, delete_desc)
        credentials.user_log(globals.db, desc, case_id=update_case.case_id)
        return update_case, delete_case
Exemplo n.º 17
0
def _set_completed(task, user_id):
    assert user_id is not None
    if not task.completed_date:
        task.completed_date = datetime.now()
        task.completed_by_id = user_id
Exemplo n.º 18
0
 def page_rows(self, cred):
     self.page_jump()
     # Fetch task rows
     results = paged_search.SortablePagedSearch.page_rows(self)
     # Fetch associated entities
     case_dict = self.db.table_dict('cases')
     user_dict = self.db.table_dict('users')
     unit_dict = self.db.table_dict('units')
     person_dict = self.db.table_dict('persons')
     queue_dict = self.db.table_dict('workqueues')
     for task in results:
         if task.case_id is not None:
             case_dict.want(task.case_id)
         if task.originator_id is not None:
             user_dict.want(task.originator_id)
         if task.assigner_id is not None:
             user_dict.want(task.assigner_id)
         if task.locked_by_id is not None:
             user_dict.want(task.locked_by_id)
         if task.completed_by_id is not None:
             user_dict.want(task.completed_by_id)
         queue_dict.want(task.queue_id)
     queue_dict.preload()
     for queue in queue_dict.values():
         if queue.unit_id is not None:
             unit_dict.want(queue.unit_id)
         if queue.user_id is not None:
             user_dict.want(queue.user_id)
     case_dict.preload()
     unit_dict.preload()
     user_dict.preload()
     for case in case_dict.itervalues():
         person_dict.want(case.person_id)
     person_dict.preload()
     # Now join it all together
     now = datetime.now()
     for task in results:
         task.active_relative = datetime.relative(task.active_date, now)
         active_days = (now - task.active_date).days
         task.active_color = trafficlight.web_trafficlight(active_days, 30)
         if task.completed_date:
             task.complete_color = '#cccccc'
             if task.action == tasks.ACTION_THREAD_DELETED:
                 task.complete_relative = 'DELETED'
             else:
                 task.complete_relative = 'completed'
             completed_by = user_dict.get(task.completed_by_id)
             if completed_by is not None:
                 task.complete_relative += ' by %s ' % completed_by.username
             task.complete_relative += str(task.completed_date)
         elif task.due_date is None:
             task.complete_color = 'transparent'
             task.complete_relative = ''
         else:
             due_days = (now - task.due_date).days + 15
             task.complete_color = trafficlight.web_trafficlight(due_days, 30)
             task.complete_relative = datetime.relative(task.due_date, now)
         task.originator = user_dict.get(task.originator_id)
         task.assigner = user_dict.get(task.assigner_id)
         task.locked_by = user_dict.get(task.locked_by_id)
         task.locked_relative = datetime.relative(task.locked_date, now)
         queue = queue_dict.get(task.queue_id)
         if queue is None:
             task.assignee = ''
         elif queue.unit_id is not None:
             task.assignee = '%s: %s' %\
                 (config.unit_label, unit_dict.get(queue.unit_id).name)
         elif queue.user_id is not None:
             task.assignee = 'User: %s' %\
                 user_dict.get(queue.user_id).username
         else:
             task.assignee = 'Queue: %s' % queue.name
         task.case_summary = task.contact_summary = ''
         if task.case_id is not None:
             task.case_summary = case_summary(self.db, task.case_id,
                                              case_dict, person_dict)
         task.action_summary = tasks.action_desc.get(task.action, 'unknown')
     return results
Exemplo n.º 19
0

def run_report(ctx, reportparams):
    try:
        rpt = reportparams.report(ctx.locals._credentials, msgs=ctx)
    except reports.ReportParamError, e:
        ctx.add_error(e)
    else:
        if ctx.have_errors():
            return
        if not rpt:
            raise reports.ReportParamError('No matching records found')
        else:
            ctx.push_page('report_' + rpt.render, rpt)


def report_export(ctx, reportparams):
    # Consistency check (form versions)
    msgs = reportparams.check()
    ctx.add_messages(msgs)
    if msgs.have_errors():
        # XXX Uh oh - warnings go into a black hole?
        return
    try:
        row_gen = reportparams.export_rows(ctx.locals._credentials)
    except reports.ReportParamError, e:
        ctx.add_error(e)
    else:
        filename = datetime.now().strftime(config.appname + '-%Y%m%d-%H%M.csv')
        page_common.csv_download(ctx, row_gen, filename)
Exemplo n.º 20
0

def run_report(ctx, reportparams):
    try:
        rpt = reportparams.report(ctx.locals._credentials, msgs=ctx)
    except reports.ReportParamError, e:
        ctx.add_error(e)
    else:
        if ctx.have_errors():
            return
        if not rpt:
            raise reports.ReportParamError('No matching records found')
        else:
            ctx.push_page('report_' + rpt.render, rpt)


def report_export(ctx, reportparams):
    # Consistency check (form versions)
    msgs = reportparams.check()
    ctx.add_messages(msgs)
    if msgs.have_errors():
        # XXX Uh oh - warnings go into a black hole?
        return
    try:
        row_gen = reportparams.export_rows(ctx.locals._credentials)
    except reports.ReportParamError, e:
        ctx.add_error(e)
    else:
        filename = datetime.now().strftime(config.appname + '-%Y%m%d-%H%M.csv')
        page_common.csv_download(ctx, row_gen, filename)
Exemplo n.º 21
0
def _set_assigned(task, user_id):
    assert user_id is not None
    task.assigner_id = user_id
    task.assignment_date = datetime.now()
Exemplo n.º 22
0
        try:
            case_row.notification_datetime = \
                datetime.mx_parse_datetime(case_row.notification_datetime)
        except datetime.Error, e:
            raise ValidationError('%s: %s' % 
                                  (_label('notification_datetime'), e))
        if datetime.is_later_than(self.case_row.onset_datetime,
                                  self.case_row.notification_datetime):
            raise ValidationError('%s must be after %s' %
                                  (_label('notification_datetime'), 
                                   _label('onset_datetime')))
        if datetime.is_later_than(self.person.DOB,
                                  self.case_row.onset_datetime):
            raise ValidationError('%s must be after %s' %
                                  (_label('onset_datetime'), _label('DOB')))
        if datetime.is_later_than(self.person.DOB, datetime.now()):
            raise ValidationError('\'%s\': %s must not be in the future' %
                    (self.person.DOB, _label('DOB')))
        if datetime.is_later_than(self.case_row.onset_datetime, datetime.now()):
            raise ValidationError('\'%s\': %s must not be in the future' %
                    (self.case_row.onset_datetime, _label('onset_datetime')))
        if datetime.is_later_than(self.case_row.notification_datetime,
                                  datetime.now()):
            raise ValidationError('\'%s\': %s must not be in the future' %
                    (self.case_row.notification_datetime, 
                     _label('notification_datetime')))

    def has_changed(self):
        return (
            self.tags.has_changed() or
            self.case_row.db_has_changed() or 
Exemplo n.º 23
0
    def merge(self, credentials):
        # lock the relevent cases
        case_a, case_b = self._fetch_cases(for_update=True)
        # Safety checks:
        not_same_person = (case_a.person_id != case_b.person_id)
        syndrome_mismatch = (case_a.syndrome_id != case_b.syndrome_id)
        if not_same_person or syndrome_mismatch:
            raise MergeError('Unable to merge - consistency check failed')
        for mc in self.fields:
            try:
                mc.apply(case_a, case_b)
            except CaseHasChanged:
                case_a.db_revert()
                case_b.db_revert()
                self.init_fields(case_a, case_b)
                raise
        # Which direction to merge?
        if self.keep == 'a':
            update_case, delete_case = case_a, case_b
        else:
            update_case, delete_case = case_b, case_a
        update_desc = update_case.db_desc()
        delete_desc = delete_case.db_desc()
        # XXX Describe tag changes - how?
        if not update_desc:
            update_desc = 'no edits required'
        if not delete_desc:
            delete_desc = 'no edits required'
        if update_case.deleted and not delete_case.deleted:
            update_case.deleted = False
            update_case.delete_reason = None
            update_case.delete_timestamp = None
        delete_case.deleted = True
        delete_case.delete_reason = 'Merged to %s' % update_case.case_id
        delete_case.delete_timestamp = datetime.now()
        curs = globals.db.cursor()
        try:
            # merge contacts
            dbobj.execute(curs, 'UPDATE case_contacts SET contact_id=%s'
                                ' WHERE contact_id=%s'
                                '  AND case_id != %s'
                                '  AND case_id NOT IN'
                                '   (SELECT case_id FROM case_contacts'
                                '     WHERE contact_id=%s)',
                            (update_case.case_id, delete_case.case_id,
                             update_case.case_id, update_case.case_id))
            dbobj.execute(curs, 'UPDATE case_contacts SET case_id=%s'
                                ' WHERE case_id=%s'
                                '  AND contact_id != %s'
                                '  AND contact_id NOT IN'
                                '   (SELECT contact_id FROM case_contacts'
                                '     WHERE case_id=%s)',
                            (update_case.case_id, delete_case.case_id,
                             update_case.case_id, update_case.case_id))
            dbobj.execute(curs, 'DELETE FROM case_contacts'
                                ' WHERE case_id=%s OR contact_id=%s',
                            (delete_case.case_id, delete_case.case_id))

            # case_form_summary
            dbobj.execute(curs, 'UPDATE case_form_summary SET case_id=%s'
                                ' WHERE case_id=%s',
                          (update_case.case_id, delete_case.case_id))
            # case_acl
            dbobj.execute(curs, 'UPDATE case_acl SET case_id=%s'
                                ' WHERE case_id=%s',
                          (update_case.case_id, delete_case.case_id))
            # tasks
            dbobj.execute(curs, 'UPDATE tasks SET case_id=%s'
                                ' WHERE case_id=%s',
                          (update_case.case_id, delete_case.case_id))
            dbobj.execute(curs, 'UPDATE tasks SET case_id=%s'
                                ' WHERE case_id=%s',
                          (update_case.case_id, delete_case.case_id))
            dbobj.execute(curs, 'UPDATE user_log SET case_id=%s'
                                ' WHERE case_id=%s',
                          (update_case.case_id, delete_case.case_id))
            dbobj.execute(curs, 'UPDATE user_log SET case_id=%s'
                                ' WHERE case_id=%s',
                          (update_case.case_id, delete_case.case_id))
        finally:
            curs.close()
        update_case.db_update()
        tag_desc = casetags.set_case_tags(update_case.case_id, update_case.tags)
        delete_case.db_update()
        desc = 'Merge System ID %s into %s, UPDATED %s %s, DELETED %s' %\
                    (delete_case.case_id, update_case.case_id, 
                     update_desc, tag_desc, delete_desc)
        credentials.user_log(globals.db, desc, case_id=update_case.case_id)
        return update_case, delete_case
Exemplo n.º 24
0
 def get_default(self):
     if self.default == 'now':
         return datetime.now()
     else:
         return self.default