datawinners/entity/entity_export_helper.py
from django.utils.translation import ugettext_lazy as _, ugettext, gettext
import xlwt
from mangrove.form_model.field import UniqueIdField,ShortCodeField,field_attributes
BEHALF_OF = "I am submitting this data on behalf of"
def get_styles():
bold = xlwt.easyfont('bold true, height 220, name Helvetica Neue')
brown = xlwt.easyfont('color_index brown, name Helvetica Neue, height 220')
italic = xlwt.easyfont('color_index gray50, italic true, name Helvetica Neue, height 220')
gray = xlwt.easyfont('color_index gray50, name Helvetica Neue, height 220')
return bold, brown, italic, gray
def add_to_header(headers, label, instruction, example):
bold, brown, italic, gray = get_styles()
headers.append(((label, bold), (u"\n\n%s" % instruction, brown), (u"\n\n%s" % example, italic)))
def get_subject_headers(form_model):
fields = form_model.form_fields
headers = []
for field in fields:
context = InstructionContext(field, form_model.entity_type)
instruction, example = SubjectInstructionBuilder.fetch_instruction(context)
add_to_header(headers, field["label"], instruction, example)
return headers
def get_submission_headers(fields, form_model, is_org_user=False):
headers = []
if is_org_user:
add_to_header(headers, gettext(BEHALF_OF).decode('utf-8'),
_("If you are sending data on behalf of someone, you can enter their Data Sender ID. Otherwise you can leave it blank."), \
_("Example: rep42"))
for field in fields:
context = InstructionContext(field, form_model.entity_type)
instruction, example = SubmissionInstructionBuilder.fetch_instruction(context)
add_to_header(headers, field["label"], instruction, example)
return headers
class TextFieldInstruction:
@staticmethod
def matches_criteria(context):
return context.field["type"] == "text"
@staticmethod
def get_instruction(context):
field = context.field
if "constraints" in field and field["constraints"][0][0] == "length" and "max" in field["constraints"][0][1]:
return _("Answer must be a word %s characters maximum") % field["constraints"][0][1].get("max"), ""
return _("Answer must be a word"), ""
class IntegerFieldInstruction:
@staticmethod
def matches_criteria(context):
return context.field["type"] == "integer"
@staticmethod
def get_instruction(context):
field = context.field
if "constraints" in field and field["constraints"][0][0] == "range":
max = field["constraints"][0][1].get("max")
min = field["constraints"][0][1].get("min")
if max and min:
return _("Enter a number between %s-%s.") % (min, max), ""
if max and not min:
return _("Answer must be a number. The maximum is %s") % max, ""
if not max and min:
return _("Answer must be a number. The minimum is %s") % min, ""
return _("Enter a number"), ""
class GeoCodeFieldInstruction:
@staticmethod
def matches_criteria(context):
return context.field["type"] == "geocode"
@staticmethod
def get_instruction(context):
return _("Answer must be GPS coordinates in the following format (latitude,longitude)."), _(
"Example: -18.1324,27.6547")
class ListFieldInstruction:
@staticmethod
def matches_criteria(context):
return context.field["type"] == "list"
@staticmethod
def get_instruction(context):
return _("Enter name of the location."), _("Example: Nairobi")
class SingleSelectFieldInstruction:
@staticmethod
def matches_criteria(context):
return context.field["type"] == "select1"
@staticmethod
def get_instruction(context):
return _("Enter 1 answer from the list."), _("Example: a")
class MultiSelectFieldInstruction:
@staticmethod
def matches_criteria(context):
return context.field["type"] == "select"
@staticmethod
def get_instruction(context):
return _("Enter 1 or more answers from the list."), _("Example: a or ab")
class TelephoneNumberFieldInstruction:
@staticmethod
def matches_criteria(context):
return context.field["type"] == "telephone_number"
@staticmethod
def get_instruction(context):
return _("Answer must be country code plus telephone number"), _("Example: 261333745269")
class DateFieldInstruction:
@staticmethod
def matches_criteria(context):
return context.field["type"] == "date"
@staticmethod
def get_instruction(context):
date_format_mapping = {
"mm.yyyy": (
ugettext("Answer must be a date in the following format:") + " " + ugettext("month.year"),
ugettext("Example: %s") % '12.2011'),
"dd.mm.yyyy": (
ugettext("Answer must be a date in the following format:") + " " + ugettext("day.month.year"),
ugettext("Example: %s") % '25.12.2011'),
"mm.dd.yyyy": ((ugettext("Answer must be a date in the following format:") + " " + ugettext("month.day.year")),
ugettext("Example: %s" % '12.25.2011'))
}
return date_format_mapping.get(context.field["date_format"])
class EntityIdRegistrationInstruction:
@staticmethod
def matches_criteria(context):
return context.field.get("type") == field_attributes.SHORT_CODE_FIELD
@staticmethod
def get_instruction(context):
return _("Assign a unique ID for each Identification Number."), _(
"Leave this column blank if you want DataWinners to assign an ID for you.")
class EntityProjectSubmissionInstruction:
@staticmethod
def matches_criteria(context):
return context.field.get("type") == field_attributes.UNIQUE_ID_FIELD
@staticmethod
def get_instruction(context):
unique_id_type = context.field['unique_id_type']
page_name = _("Identification Numbers") if context.has_multiple_unique_ids else "%s" % unique_id_type
return _("Enter the unique ID for each %s.\nYou can find the %s List on the My %s page.") % (
unique_id_type, unique_id_type, page_name), (_("Example: %s")) % 'cli01'
class SubjectInstructionBuilder:
field_instructions = [EntityProjectSubmissionInstruction,
EntityIdRegistrationInstruction, IntegerFieldInstruction, TextFieldInstruction,
GeoCodeFieldInstruction, DateFieldInstruction, MultiSelectFieldInstruction,
SingleSelectFieldInstruction, TelephoneNumberFieldInstruction, ListFieldInstruction]
@classmethod
def fetch_instruction(cls, context):
for field_instruction in cls.field_instructions:
if field_instruction.matches_criteria(context):
return field_instruction.get_instruction(context)
return None
class SubmissionInstructionBuilder:
field_instructions = [
EntityProjectSubmissionInstruction,
IntegerFieldInstruction, TextFieldInstruction,
GeoCodeFieldInstruction, DateFieldInstruction, MultiSelectFieldInstruction,
SingleSelectFieldInstruction
]
@classmethod
def fetch_instruction(cls, context):
for field_instruction in cls.field_instructions:
if field_instruction.matches_criteria(context):
return field_instruction.get_instruction(context)
return None
class InstructionContext():
def __init__(self, field, unique_id_types):
self.field = field
self.has_multiple_unique_ids = unique_id_types is not None and len(unique_id_types) > 1