def create_or_update_measure(measure_id, end_date):
    """Create a measure object based on a measure definition

    """
    measure_json = parse_measures()[measure_id]
    v = arrays_to_strings(measure_json)

    try:
        measure = Measure.objects.get(id=measure_id)
    except Measure.DoesNotExist:
        measure = Measure(id=measure_id)

    measure.title = v['title']
    measure.description = v['description']
    measure.why_it_matters = v['why_it_matters']
    measure.name = v['name']
    measure.tags = v['tags']
    measure.tags_focus = v.get('tags_focus', [])
    measure.title = v['title']
    measure.description = v['description']
    measure.numerator_short = v['numerator_short']
    measure.denominator_short = v['denominator_short']
    measure.numerator_from = v['numerator_from']
    measure.numerator_where = v['numerator_where']
    measure.numerator_columns = v['numerator_columns']
    measure.denominator_from = v['denominator_from']
    measure.denominator_where = v['denominator_where']
    measure.denominator_columns = v['denominator_columns']
    measure.url = v['url']
    measure.is_cost_based = v['is_cost_based']
    measure.is_percentage = v['is_percentage']
    measure.low_is_good = v['low_is_good']
    measure.numerator_bnf_codes_query = v.get('numerator_bnf_codes_query')
    measure.numerator_is_list_of_bnf_codes = v.get(
        'numerator_is_list_of_bnf_codes', True)
    measure.numerator_bnf_codes = get_numerator_bnf_codes(measure, end_date)
    measure.save()

    return measure
def create_or_update_measure(measure_def, end_date):
    """Create a measure object based on a measure definition"""
    measure_id = measure_def["id"]
    v = arrays_to_strings(measure_def)

    for k, val in v.items():
        if isinstance(val, str):
            v[k] = val.strip()

    try:
        m = Measure.objects.get(id=measure_id)
    except Measure.DoesNotExist:
        m = Measure(id=measure_id)

    m.title = v["title"]
    m.description = v["description"]
    m.why_it_matters = v["why_it_matters"]
    m.name = v["name"]
    m.tags = v["tags"]
    m.tags_focus = v.get("tags_focus", [])
    m.title = v["title"]
    m.description = v["description"]
    m.numerator_short = v["numerator_short"]
    m.denominator_short = v["denominator_short"]
    m.url = v["url"]
    m.is_cost_based = v["is_cost_based"]
    m.is_percentage = v["is_percentage"]
    m.low_is_good = v["low_is_good"]
    m.include_in_alerts = v.get("include_in_alerts", True)

    m.numerator_type = v["numerator_type"]

    if m.numerator_type == "custom":
        m.numerator_columns = v["numerator_columns"]
        m.numerator_from = v["numerator_from"]
        m.numerator_where = v["numerator_where"]
        m.numerator_bnf_codes_query = v.get("numerator_bnf_codes_query")
        m.numerator_is_list_of_bnf_codes = v.get(
            "numerator_is_list_of_bnf_codes", True)
        if m.numerator_is_list_of_bnf_codes:
            m.numerator_bnf_codes = get_num_or_denom_bnf_codes(
                m, "numerator", end_date)

    else:
        if m.numerator_type == "bnf_items":
            m.numerator_columns = "SUM(items) AS numerator"
        elif m.numerator_type == "bnf_quantity":
            m.numerator_columns = "SUM(quantity) AS numerator"
        elif m.numerator_type == "bnf_cost":
            m.numerator_columns = "SUM(actual_cost) AS numerator"
        else:
            assert False, measure_id

        m.numerator_from = "{hscic}.normalised_prescribing"

        m.numerator_bnf_codes_filter = v.get("numerator_bnf_codes_filter")
        m.numerator_bnf_codes_query = v.get("numerator_bnf_codes_query")
        m.numerator_bnf_codes = get_bnf_codes(m.numerator_bnf_codes_query,
                                              m.numerator_bnf_codes_filter)

        m.numerator_where = build_where(m.numerator_bnf_codes)
        m.numerator_is_list_of_bnf_codes = True

    m.denominator_type = v["denominator_type"]

    if m.denominator_type == "custom":
        m.denominator_columns = v["denominator_columns"]
        m.denominator_from = v["denominator_from"]
        m.denominator_where = v["denominator_where"]
        m.denominator_bnf_codes_query = v.get("denominator_bnf_codes_query")
        if m.denominator_from and "normalised_prescribing" in m.denominator_from:
            m.denominator_is_list_of_bnf_codes = v.get(
                "denominator_is_list_of_bnf_codes", True)
        else:
            m.denominator_is_list_of_bnf_codes = False
        m.denominator_bnf_codes = get_num_or_denom_bnf_codes(
            m, "denominator", end_date)

    elif m.denominator_type == "list_size":
        m.denominator_columns = "SUM(total_list_size / 1000.0) AS denominator"
        m.denominator_from = "{hscic}.practice_statistics"
        m.denominator_where = "1 = 1"
        m.denominator_bnf_codes_query = None
        m.denominator_is_list_of_bnf_codes = False

    elif m.denominator_type == "star_pu_antibiotics":
        m.denominator_columns = "CAST(JSON_EXTRACT(MAX(star_pu), '$.oral_antibacterials_item') AS FLOAT64) AS denominator"
        m.denominator_from = "{hscic}.practice_statistics"
        m.denominator_where = "1 = 1"
        m.denominator_bnf_codes_query = None
        m.denominator_is_list_of_bnf_codes = False

    else:
        if m.denominator_type == "bnf_items":
            m.denominator_columns = "SUM(items) AS denominator"
        elif m.denominator_type == "bnf_quantity":
            m.denominator_columns = "SUM(quantity) AS denominator"
        elif m.denominator_type == "bnf_cost":
            m.denominator_columns = "SUM(actual_cost) AS denominator"
        else:
            assert False, measure_id

        m.denominator_from = "{hscic}.normalised_prescribing"

        m.denominator_bnf_codes_filter = v.get("denominator_bnf_codes_filter")
        m.denominator_bnf_codes_query = v.get("denominator_bnf_codes_query")
        m.denominator_bnf_codes = get_bnf_codes(m.denominator_bnf_codes_query,
                                                m.denominator_bnf_codes_filter)

        m.denominator_where = build_where(m.denominator_bnf_codes)
        m.denominator_is_list_of_bnf_codes = True

    if not v.get("no_analyse_url"):
        m.analyse_url = build_analyse_url(m)

    m.save()

    return m