def _try_to_reconcile(form_number, code, user): form_types, projects = get_forms() keyed_forms = Form.objects.filter(form_number=form_number, form_code=code) for f in keyed_forms: mixin(DataEntryForm, form_types[f.form_code]) usrs = [User.objects.get(id = uid) for uid in list(set([ f.user_id for f in keyed_forms ]))] keyed_numbers = [ len([f for f in keyed_forms if f.user_id == u.id ]) for u in usrs ] tf = DataEntryForm() reconcilable = len(filter(lambda n: n > 0, keyed_numbers)) >= tf.min_authors # Check if already has been reconciled rids = [f.reconciled_id for f in keyed_forms] # check if reconciled when it shouldn't be if not reconcilable and len(filter(None, rids)) > 0: unreconcile_forms(form_number, code) for form in keyed_forms: form.fields_dict = form.fields_dict() if reconcilable: done = len(filter(None, rids)) == len(keyed_forms) and len(set(rids)) == 1 good = True goodfields = dict(form_number = form_number) for fn in tf.field_names(): vals = [] for form in keyed_forms: if not form.fields_dict.has_key(fn): continue vals.append(form.fields_dict[fn]) vals = list(set([str(v) for v in vals])) if len(vals) == 1: goodfields[fn] = vals[0] if len(vals) > 1: good = False if good and not done: form = DataEntryForm(goodfields) if form.is_valid() and form.is_really_valid(goodfields): reconcile_forms(user, form_number, form) return True if not good and done: unreconcile_forms(form_number, code)
def reconcile(request, code, form_number): """Reconciliation screen""" form_types, projects = get_forms() referrer = request.META.get('HTTP_REFERER') all_forms = Form.objects.filter(form_number=form_number, form_code=code) usernames = dict([ (u.id, u.first_name or u.username) for u in User.objects.all()]) fts = list(set([f.form_code for f in all_forms])) if len(fts) != 1: assert False, "More than one form type for form %s !" % form_number # Do we have permission... code = fts[0] mixin(DataEntryForm, form_types[code]) if not request.user.has_perm("%s.reconciler" % DataEntryForm.project): return redirect(referrer) postform = None if request.method == 'POST': postform = DataEntryForm(request.POST) # postform.clean = postform.reconcile_clean if postform.is_valid() and postform.is_really_valid(): reconcile_forms(request.user, form_number, postform) referrer = request.POST['referrer'] if request.POST.has_key('import'): returnto = postform.importurl(form_number) elif referrer and referrer != 'None': returnto = referrer else: returnto = reverse('dataentry.views.show_forms', kwargs=dict(project = postform.project)) returnto = returnto + '#' + postform.cleaned_data['form_number'] return redirect(returnto) else: logging.debug(postform.errors) tf = DataEntryForm() for form in all_forms: form.fields_dict = form.fields_dict() form.groomed = {} tf.groom_all(form.groomed, form.fields_dict) fields = Field.objects.filter(form=form) form.fields_name_dict = {} for field in fields: if not field.name in form.fields_name_dict: form.fields_name_dict[field.name] = [] form.fields_name_dict[field.name].append(field) f = dict(form_number = form_number) info = dict() for fn in tf.field_names(): vals = [] groomed = False for form in all_forms: if not form.fields_dict.has_key(fn): continue vals.append(form.fields_dict[fn]) if form.groomed.has_key(fn): groomed = True def cmp_dates(a,b): return cmp(b.date_entered, a.date_entered) history = list( reduce( set.union, [set(frm.fields_name_dict[fn] if fn in frm.fields_name_dict else []) for frm in all_forms] ) ) history.sort(cmp_dates) history = [ dict( value = fi.value, user = usernames[fi.user_id], date_entered = fi.date_entered.strftime('%d %b %Y %H:%M'), ) for fi in history ] history = dedupe(history, lambda h: "**".join(h.values())) history_groomed = (len(list(set([ h['value'] for h in history ]))) > 1 and all_forms[0].reconciled != None) info[fn] = dict( groomed = groomed and len(list(set(vals))) == 1, vals = list(set([str(v) for v in vals])), frms = dict([ (form.id, form.fields_dict.get(fn,"")) for form in all_forms]), history = history, history_groomed = history_groomed, ) if len(set([str(v) for v in vals])) == 1: f[fn] = vals[0] else: f[fn] = '' # load up the comments comments = [] for fm in all_forms: comments.append(dict( comment = fm.comment, user = fm.user, )) if postform: form = postform errors = postform.errors else: form = DataEntryForm(f) form.is_really_valid(f) errors = form.errors importable = hasattr(form_types[code], 'imported_forms') and (code, form_number) not in form_types[code].imported_forms() extra = None if hasattr(form_types[code], 'ft_annotate'): extra = form.ft_annotate(form_number) return render_to_response("dataentry/reconcile.html", dict( form_number = form_number, forms = all_forms, form = form, reconciled = all_forms[0].reconciled, reconciling = True, comments = comments, info = simplejson.dumps(info), errors = simplejson.dumps(errors), referrer = referrer, importable = importable, menuname = 'dataentry', extra = extra, ), context_instance=RequestContext(request))