import datetime


def add_cls(record, packet, forms):
    """
    Adds CLS form to packet.

    According to the IVP Guidebook (v3.0, March 2015), Form CLS should be
    completed if the subject or co-participant indicates that the subject is
    Hispanic/Latino.

    Therefore, if the subject is not Hispanic/Latino, do not add a CLS.

    IVP Guidebook:
      https://www.alz.washington.edu/NONMEMBER/UDS/DOCS/VER3/UDS3_ivp_guidebook.pdf

    Form CLS:
      https://www.alz.washington.edu/NONMEMBER/UDS/DOCS/VER3/CLS/CLS_en.pdf
    """

    is_hispanic = record['hispanic'] == '1'
    if not is_hispanic:
        return

    fields_mapping = {
        'APREFLAN': 'eng_preferred_language',
        'AYRSPAN': 'eng_years_speak_spanish',
        'AYRENGL': 'eng_years_speak_english',
        'APCSPAN': 'eng_percentage_spanish',
        'APCENGL': 'eng_percentage_english',
        'ASPKSPAN': 'eng_proficiency_spanish',
        'AREASPAN': 'eng_proficiency_read_spanish',
        'AWRISPAN': 'eng_proficiency_write_spanish',
        'AUNDSPAN': 'eng_proficiency_oral_spanish',
        'ASPKENGL': 'eng_proficiency_speak_english',
        'AREAENGL': 'eng_proficiency_read_english',
        'AWRIENGL': 'eng_proficiency_write_english',
        'AUNDENGL': 'eng_proficiency_oral_english',
    }

    num_filled_fields = 0
    total_fields = len(fields_mapping)
    cls_form = forms.FormCLS()

    for key, val in fields_mapping.iteritems():
        if record[val].strip():
            setattr(cls_form, key, record[val])
            num_filled_fields += 1

    # If every field is blank, return
    if num_filled_fields == 0:
        return

    # If only some of the fields are filled, raise error.
    ptid = record.get('ptid', 'unknown')
    if num_filled_fields != total_fields:
        msg = "Could not parse packet as CLS form is incomplete for PTID: " \
            + ptid
        raise Exception(msg)

    # Otherwise, check percentages and dates before appending.

    # Check percentages
    try:
        pct_spn = int(record['eng_percentage_spanish'])
    except ValueError:
        raise Exception(
            "Could not parse packet as eng_percentage_spanish is not an "
            "integer for PTID: " + ptid
        )

    try:
        pct_eng = int(record['eng_percentage_english'])
    except ValueError:
        raise Exception(
            "Could not parse packet as eng_percentage_english is not an "
            "integer for PTID: " + ptid
        )

    if pct_eng + pct_spn != 100:
        message = "Could not parse packet as language proficiency " + \
            "percentages do not equal 100 for PTID : " + ptid
        raise Exception(message)

    visit_date = datetime.datetime(
        int(record['visityr']), int(record['visitmo']), 1)
    cls_added = datetime.datetime(2017, 6, 1)
    if visit_date < cls_added:
        message = "Could not parse packet as CLS forms should not be in " + \
            "packets from before June 1, 2017 for PTID: " + ptid
        raise Exception(message)

    if record['form_cls_linguistic_history_of_subject_complete'] != '2':
        message = "Could not parse packet as completed CLS form is not " + \
            "marked complete in REDCap for PTID: " + ptid
        raise Exception(message)

    packet.append(cls_form)

@@ -9,16 +9,27 @@
 atetime%0A
+import sys%0A
 %0A%0Adef ad
@@ -55,16 +55,32 @@
 t, forms
+, err=sys.stderr
 ):%0A    %22
@@ -1712,19 +1712,17 @@
 ed, 
-raise error
+make note
 .%0A  
@@ -1821,33 +1821,17 @@
  = %22
-Could not parse packet as
+%5BWARNING%5D
  CLS
@@ -1895,28 +1895,25 @@
     
-raise Exception(
+print %3E%3E err, 
 msg
-)
 %0A%0A  
@@ -2128,33 +2128,17 @@
    %22
-Could not parse packet as
+%5BWARNING%5D
  eng
@@ -2350,33 +2350,17 @@
    %22
-Could not parse packet as
+%5BWARNING%5D
  eng
@@ -2488,43 +2488,23 @@
    m
-essage = %22Could not parse packet as
+sg = %22%5BWARNING%5D
  lan
@@ -2601,32 +2601,25 @@
     
-raise Exception(message)
+print %3E%3E err, msg
 %0A%0A  
@@ -2801,43 +2801,23 @@
    m
-essage = %22Could not parse packet as
+sg = %22%5BWARNING%5D
  CLS
@@ -2923,32 +2923,25 @@
     
-raise Exception(message)
+print %3E%3E err, msg
 %0A%0A  

Stop most CLS errors from preventing packet upload