from copy import deepcopy
import numpy as np


import SpectrumCommon.Const.GB.GBConst as gbc
import SpectrumCommon.Modvars.GB.GBUtil as gbu
import SpectrumCommon.Const.PJ.PJNTags as pjmvt

import SpectrumCommon.Const.IH.IHConst as ihc
import SpectrumCommon.Const.IH.IHTags as ihmvt

import SpectrumCommon.Const.IC.ICTags as icmvt
import SpectrumCommon.Modvars.IC.ICModVarUtil as icmvu
import SpectrumCommon.Const.IC.ICModVarFields as icmvf


import SpectrumCommon.Const.IS.ISTags as ismvt
import SpectrumCommon.Modvars.IS.ISModVarUtil as ismvu

import SpectrumCommon.Const.HW.HWTags as hrmvt

import SpectrumCommon.Const.BG.BGConst as bgc
import SpectrumCommon.Const.BG.BGModVarFields as bgmvf
import SpectrumCommon.Modvars.BG.BGModVarDefs as bgmvd
import SpectrumCommon.Const.BG.BGTags as bgmvt
import SpectrumCommon.Modvars.BG.BGModVarUtil as bgmvu
import SpectrumCommon.Util.BG.BGUtil as bgu
import SpectrumCommon.Util.BG.BGUtilLink as bgul
import SpectrumCommon.Modvars.BG.BGReadDatabases as bgrd
import SpectrumCommon.Const.BG.BGConstLink as bgcl

# Notes:
#
#   1. The only tangible purpose of versions on MVs is to be able to update them appropriately for existing projections so those projections can run with the
#      current codebase. The only code that ever checks MV versions is in the XXUpdateModvars file. If you just added a new field, you could just check and see if
#      the field is in the MV and add it if it's not without changing the version on the MV. Similarly, if you added a new dimension, you could just extend the
#      dimension of a MV without creating a new version. Changing the version number of a MV does gives us more of a history to follow, but doesn't do more
#      for us programmatically. Also, if you change the version of a MV, all clients using that MV need to update their code to use the latest MV.
#      Changing the version of a MV is only really useful if the MV undergoes a major structural change that would make it difficult to
#      manipulate the existing version of that MV otherwise, or if we would like to apply a correction to all previous versions of a MV.
#
#   2. You cannot base logic on whether a current MV tag exists in the code below.  It will always exist, because before this gets called, all missing MVs
#      will get added to the projection.
#
#   3. To trigger this, create a projection, say on the client, save, and grab it's projection ID (in Chrome, F12 --> Application --> session storage).
#      Change GB_PM_Version in GBConst or UpdateModvars will get skipped.  Add proj ID to Postman environment. Call Login, then GetModvars to get the library ID and put that
#      into the Postman environment. Then call OpenProjection. Make sure to leave the projection on the client open  while doing this because the proj ID changes when
#      you open/close. Then call SaveProjection. You should now be able to call Calculate and see the modified MV there where it's used. Don't forget to change
#      the version number back after you finish testing and trash the test projection.
#
def BG_UpdateModvars(projection, created_projection):

    if BG_INDICATOR_RECORDS_IC_TAG_V1 in projection:
        _convert_indicator_IC_records_1(projection, BG_INDICATOR_RECORDS_IC_TAG_V1)
        _convert_indicator_IC_records_2(projection, bgmvt.BG_INDICATOR_RECORDS_IC_TAG)
        _convert_indicator_IC_records_3(projection, bgmvt.BG_INDICATOR_RECORDS_IC_TAG)

    elif BG_INDICATOR_RECORDS_IC_TAG_V2 in projection:
        _convert_indicator_IC_records_2(projection, BG_INDICATOR_RECORDS_IC_TAG_V2)
        _convert_indicator_IC_records_3(projection, bgmvt.BG_INDICATOR_RECORDS_IC_TAG)

    elif BG_INDICATOR_RECORDS_IC_TAG_V3 in projection:
        _convert_indicator_IC_records_3(projection, BG_INDICATOR_RECORDS_IC_TAG_V3)

    #####

    # Add new fields for IS indicator records
    for ind_rec in projection[bgmvt.BG_INDICATOR_RECORDS_IS_TAG]:
        if bgmvf.BG_IND_COSTING_SECT_ID_PC not in ind_rec:
            ind_rec[bgmvf.BG_IND_COSTING_SECT_ID_PC] = str(gbc.GB_NOT_FOUND)

        if bgmvf.BG_IND_COSTING_SUBSECT_ID_PC not in ind_rec:
            ind_rec[bgmvf.BG_IND_COSTING_SUBSECT_ID_PC] = str(gbc.GB_NOT_FOUND)

        if bgmvf.BG_IND_ACT_ID_PC not in ind_rec:
            ind_rec[bgmvf.BG_IND_ACT_ID_PC] = str(gbc.GB_NOT_FOUND)

    if BG_INDICATOR_RECORDS_IS_TAG_V1 in projection:
        _convert_indicator_IS_records_1(projection, BG_INDICATOR_RECORDS_IS_TAG_V1)
        _convert_indicator_IS_records_2(projection, bgmvt.BG_INDICATOR_RECORDS_IS_TAG)

    elif BG_INDICATOR_RECORDS_IS_TAG_V2 in projection:
        _convert_indicator_IS_records_2(projection, BG_INDICATOR_RECORDS_IS_TAG_V2)


    #####

    # Add new fields for HW indicator records
    for ind_rec in projection[bgmvt.BG_INDICATOR_RECORDS_HW_TAG]:
        if bgmvf.BG_IND_COSTING_SECT_ID_PC not in ind_rec:
            ind_rec[bgmvf.BG_IND_COSTING_SECT_ID_PC] = str(gbc.GB_NOT_FOUND)

        if bgmvf.BG_IND_COSTING_SUBSECT_ID_PC not in ind_rec:
            ind_rec[bgmvf.BG_IND_COSTING_SUBSECT_ID_PC] = str(gbc.GB_NOT_FOUND)

        if bgmvf.BG_IND_ACT_ID_PC not in ind_rec:
            ind_rec[bgmvf.BG_IND_ACT_ID_PC] = str(gbc.GB_NOT_FOUND)

    #####

    if BG_BUDGET_CAT_SHARE_RECORDS_IC_TAG_V1 in projection:
        _convert_budget_cat_share_IC_records_1(projection, BG_BUDGET_CAT_SHARE_RECORDS_IC_TAG_V1)

    # #####

    if BG_BUDGET_CAT_SHARE_RECORDS_IS_TAG_V1 in projection:
        _convert_budget_cat_share_IS_records_1(projection, BG_BUDGET_CAT_SHARE_RECORDS_IS_TAG_V1)

    # #####

    if BG_FUND_SOURCE_SHARE_RECORDS_IC_TAG_V1 in projection:
        _convert_funding_source_share_IC_records_1(projection, BG_FUND_SOURCE_SHARE_RECORDS_IC_TAG_V1)

    # #####

    if BG_FUND_SOURCE_SHARE_RECORDS_IS_TAG_V1 in projection:
        _convert_funding_source_share_IS_records_1(projection, BG_FUND_SOURCE_SHARE_RECORDS_IS_TAG_V1)

    #####

    if BG_QUICK_MAP_RECORDS_TAG_V1 in projection:
        _convert_quick_map_records_1(projection, BG_QUICK_MAP_RECORDS_TAG_V1)
        _convert_quick_map_records_2(projection, bgmvt.BG_QUICK_MAP_RECORDS_TAG)

    elif BG_QUICK_MAP_RECORDS_TAG_V2 in projection:
        _convert_quick_map_records_2(projection, BG_QUICK_MAP_RECORDS_TAG_V2)

    #####

    if BG_DEFAULT_BUDGET_LIST_META_TAG_V1 in projection:
        _convert_default_budget_list_meta(projection, BG_DEFAULT_BUDGET_LIST_META_TAG_V1)

    if BG_DEFAULT_BUDGET_LIST_META_TAG_V2 in projection:
        _convert_default_budget_list_meta(projection, BG_DEFAULT_BUDGET_LIST_META_TAG_V2)

    #####

    # Add new fields to existing budget records for Infrastucture costing section level
    for budget_rec in projection[bgmvt.BG_BUDGET_RECORDS_TAG]:
        if bgmvf.BG_BUDGET_COST_LEVEL_IS_ID not in budget_rec:
            budget_rec[bgmvf.BG_BUDGET_COST_LEVEL_IS_ID] = bgc.BG_COST_COSTING_SECTIONS_LEVEL_MST_ID

        if bgmvf.BG_BUDGET_COST_LEVEL_HW_ID not in budget_rec:
            budget_rec[bgmvf.BG_BUDGET_COST_LEVEL_HW_ID] = bgc.BG_COST_COSTING_SECTIONS_LEVEL_MST_ID,
    
        if bgmvf.BG_BUDGET_ACTIVE not in budget_rec:
            budget_rec[bgmvf.BG_BUDGET_ACTIVE] = True

    # A bug was discovered which caused logistics and supply chain budget records to not be created when a custom drug/supply was added 
    # for TB projections or IHT specific plan projections. This function corrects that error by creating the missing records.
    _add_missing_log_supply_chain_budget_records(projection)
            
    # delete tags
    for tag in BG_TagsForDeletion:
        if tag in projection:
            del projection[tag]

    return projection

BG_INDICATOR_RECORDS_IC_TAG_V1          = '<BG_IndicatorRecordsIC_V1>'
BG_INDICATOR_RECORDS_IC_TAG_V2          = '<BG_IndicatorRecordsIC_V2>'
BG_INDICATOR_RECORDS_IC_TAG_V3          = '<BG_IndicatorRecordsIC_V3>'
BG_INDICATOR_RECORDS_IS_TAG_V1          = '<BG_IndicatorRecordsIS_V1>'
BG_INDICATOR_RECORDS_IS_TAG_V2          = '<BG_IndicatorRecordsIS_V2>'
BG_QUICK_MAP_RECORDS_TAG_V1             = '<BG_QuickMapRecords_V1>'
BG_QUICK_MAP_RECORDS_TAG_V2             = '<BG_QuickMapRecords_V2>'
BG_DEFAULT_BUDGET_LIST_META_TAG_V1      = '<BG_DefaultBudgetList_Meta_V1>'
BG_DEFAULT_BUDGET_LIST_META_TAG_V2      = '<BG_DefaultBudgetList_Meta_V2>'
BG_BUDGET_CAT_SHARE_RECORDS_IC_TAG_V1   = '<BG_BudgetCategoryShareRecordsIC_V1>'
BG_BUDGET_CAT_SHARE_RECORDS_IS_TAG_V1   = '<BG_BudgetCategoryShareRecordsIS_V1>'
BG_FUND_SOURCE_SHARE_RECORDS_IC_TAG_V1  = '<BG_FundingSourceShareRecordsIC_V1>'
BG_FUND_SOURCE_SHARE_RECORDS_IS_TAG_V1  = '<BG_FundingSourceShareRecordsIS_V1>'

BG_TagsForDeletion = [
    BG_INDICATOR_RECORDS_IC_TAG_V1,
    BG_INDICATOR_RECORDS_IC_TAG_V2,
    BG_INDICATOR_RECORDS_IC_TAG_V3,
    BG_INDICATOR_RECORDS_IS_TAG_V1,
    BG_INDICATOR_RECORDS_IS_TAG_V2,
    BG_QUICK_MAP_RECORDS_TAG_V1,
    BG_QUICK_MAP_RECORDS_TAG_V2,
    BG_DEFAULT_BUDGET_LIST_META_TAG_V1,
    BG_DEFAULT_BUDGET_LIST_META_TAG_V2,
    BG_BUDGET_CAT_SHARE_RECORDS_IC_TAG_V1,
    BG_BUDGET_CAT_SHARE_RECORDS_IS_TAG_V1,
    BG_FUND_SOURCE_SHARE_RECORDS_IC_TAG_V1,
    BG_FUND_SOURCE_SHARE_RECORDS_IS_TAG_V1,
]

def _convert_default_budget_list_meta(projection, default_budget_list_meta_tag):
    # Note that because this is meta data, we can apply the same logic to each iteration of the tag when the defaults change.

    costing_mode_mod_vars = {
        pjmvt.GB_IHTOnTag       : projection[pjmvt.GB_IHTOnTag],
        pjmvt.GB_TBCostingOnTag : projection[pjmvt.GB_TBCostingOnTag],
        pjmvt.GB_LCOnTag        : projection[pjmvt.GB_LCOnTag],
    }
    costing_mode = gbu.get_costing_mode(costing_mode_mod_vars)

    budget_DB = bgrd.BG_load_budget_DB()
    default_budget_list_meta = bgrd.BG_init_default_budget_list_meta(budget_DB, costing_mode)

    if default_budget_list_meta_tag != bgmvt.BG_DEFAULT_BUDGET_LIST_META_TAG:
        projection[bgmvt.BG_DEFAULT_BUDGET_LIST_META_TAG] = deepcopy(default_budget_list_meta)

def _convert_quick_map_records_1(projection, quick_map_records_tag):
    quick_map_records_mv = projection[quick_map_records_tag]

    TB_costing_on = projection[pjmvt.GB_TBCostingOnTag]
    budget_records_mv = projection[bgmvt.BG_BUDGET_RECORDS_TAG]
    budget_cat_records_mv = projection[bgmvt.BG_BUDGET_CAT_RECORDS_TAG]

    if TB_costing_on:
        # We added PC and IS indicators for TB app and had to change a bunch of MVs as a result.  Use the quick map records as the MV whose version we will change so we don't have
        # to change them all.
        for budget_rec in budget_records_mv:
            budget_rec[bgmvf.BG_BUDGET_COST_LEVEL_PC_ID] = bgc.BG_COST_COSTING_SECTIONS_LEVEL_MST_ID

            for target_mst_ID in bgc.BG_QUICK_MAP_TARGET_MST_IDS:
                for ind_type_PC in [bgc.BG_PC_COST_SECT_IND_MST_ID, bgc.BG_PC_COST_SUBSECT_IND_MST_ID, bgc.BG_PC_ACTIVITY_IND_MST_ID]:
                    quick_map_rec = bgmvd.BG_create_quick_map_rec(budget_rec[bgmvf.BG_BUDGET_ID], gbc.GB_PC, target_mst_ID, ind_type_PC)
                    quick_map_records_mv.append(quick_map_rec)

                quick_map_rec = bgmvd.BG_create_quick_map_rec(budget_rec[bgmvf.BG_BUDGET_ID], gbc.GB_IS, target_mst_ID, bgc.BG_IS_MED_EQUIPMENT_IND_MST_ID)
                quick_map_records_mv.append(quick_map_rec)

        projection[bgmvt.BG_QUICK_MAP_RECORDS_TAG] = deepcopy(quick_map_records_mv)

        projection[bgmvt.BG_INDICATOR_RECORDS_PC_TAG] = bgu.BG_init_ind_PC_records({
            pjmvt.GB_IHTOnTag                           : projection[pjmvt.GB_IHTOnTag],
            pjmvt.GB_TBCostingOnTag                     : projection[pjmvt.GB_TBCostingOnTag],
            pjmvt.GB_LCOnTag                            : projection[pjmvt.GB_LCOnTag],

            bgmvt.BG_BUDGET_RECORDS_TAG                 : budget_records_mv,
            bgmvt.BG_BUDGET_CAT_RECORDS_TAG             : budget_cat_records_mv,
            bgmvt.BG_FUND_FW_RECORDS_TAG                : projection[bgmvt.BG_FUND_FW_RECORDS_TAG],
            bgmvt.BG_FUND_SOURCE_RECORDS_TAG            : projection[bgmvt.BG_FUND_SOURCE_RECORDS_TAG],

            bgcl.BG_PC_COSTING_SECT_RECORDS_TAG      : projection[bgcl.BG_PC_COSTING_SECT_RECORDS_TAG],
            bgcl.BG_PC_COSTING_SECT_RECORDS_PPLI_TAG : projection[bgcl.BG_PC_COSTING_SECT_RECORDS_PPLI_TAG],
            bgcl.BG_PC_ACT_RECORDS_TAG               : projection[bgcl.BG_PC_ACT_RECORDS_TAG],
            bgcl.BG_PC_ACT_RECORDS_PPLI_TAG          : projection[bgcl.BG_PC_ACT_RECORDS_PPLI_TAG],

            bgcl.BG_IH_PROG_AREA_RECORDS_TAG         :  projection[bgcl.BG_IH_PROG_AREA_RECORDS_TAG],
        })

        projection[bgmvt.BG_INDICATOR_RECORDS_IS_TAG] = bgu.BG_init_ind_IS_records({
            bgmvt.BG_BUDGET_RECORDS_TAG          : projection[bgmvt.BG_BUDGET_RECORDS_TAG],
            bgmvt.BG_BUDGET_CAT_RECORDS_TAG      : projection[bgmvt.BG_BUDGET_CAT_RECORDS_TAG],
            bgmvt.BG_FUND_FW_RECORDS_TAG         : projection[bgmvt.BG_FUND_FW_RECORDS_TAG],
            bgmvt.BG_FUND_SOURCE_RECORDS_TAG     : projection[bgmvt.BG_FUND_SOURCE_RECORDS_TAG],

            bgcl.BG_IH_PROG_AREA_RECORDS_TAG : projection[bgcl.BG_IH_PROG_AREA_RECORDS_TAG],
            bgcl.BG_IS_FACILITY_TYPE_RECORDS_TAG : projection[bgcl.BG_IS_FACILITY_TYPE_RECORDS_TAG],

            bgcl.BG_PC_COSTING_SECT_RECORDS_TAG      : projection[bgcl.BG_PC_COSTING_SECT_RECORDS_TAG],
            bgcl.BG_PC_ACT_RECORDS_TAG               : projection[bgcl.BG_PC_ACT_RECORDS_TAG],

            pjmvt.GB_TBCostingOnTag              : projection[pjmvt.GB_TBCostingOnTag],
            pjmvt.GB_IHTOnTag: projection[pjmvt.GB_IHTOnTag],
            pjmvt.PJN_IHTPlanTypeTag: projection[pjmvt.PJN_IHTPlanTypeTag]
        })

    if quick_map_records_tag != bgmvt.BG_QUICK_MAP_RECORDS_TAG:
        projection[bgmvt.BG_QUICK_MAP_RECORDS_TAG] = deepcopy(quick_map_records_mv)

def _convert_quick_map_records_2(projection, quick_map_records_tag):
    quick_map_records_mv = projection[quick_map_records_tag]

    IHT_on = projection[pjmvt.GB_IHTOnTag]
    budget_records = projection[bgmvt.BG_BUDGET_RECORDS_TAG]
    budget_cat_records = projection[bgmvt.BG_BUDGET_CAT_RECORDS_TAG]
    fund_framework_records = projection[bgmvt.BG_FUND_FW_RECORDS_TAG]
    fund_source_records = projection[bgmvt.BG_FUND_SOURCE_RECORDS_TAG]
    staff_type_records = projection[hrmvt.HW_STAFF_TYPE_RECORDS_TAG_V1]
    costing_section_records = projection[bgcl.BG_PC_COSTING_SECT_RECORDS_TAG]
    activity_records = projection[bgcl.BG_PC_ACT_RECORDS_TAG]

    # Add HW indicators for IHT. Leave empty for TB for now. Use the quick map records as the MV whose version we will change so we don't have
    # to change them all.
    for budget_rec in budget_records:
        budget_rec[bgmvf.BG_BUDGET_AGGR_INSERV_TRAIN_ALL_STAFF_HW] = False
        budget_rec[bgmvf.BG_BUDGET_AGGR_PRESERV_TRAIN_ALL_STAFF_HW] = False
        budget_rec[bgmvf.BG_BUDGET_AGGR_TOTAL_COMPENS_ALL_STAFF_HW] = np.full((bgcl.BG_HW_NUM_STAFFING_LEVELS, bgcl.BG_HW_NUM_COMPENS_TYPES), False).tolist()
        budget_rec[bgmvf.BG_BUDGET_AGGR_STAFF_INSERV_TRAIN_ALL_STAFF_LEV_HW] = np.full((len(staff_type_records)), False).tolist()
        budget_rec[bgmvf.BG_BUDGET_AGGR_STAFF_LEV_INSERV_TRAIN_ALL_STAFF_HW] = np.full((bgcl.BG_HW_NUM_STAFFING_LEVELS), False).tolist()
        budget_rec[bgmvf.BG_BUDGET_AGGR_TOTAL_COMPENS_STAFF_LEV_COMPENS_TYPE_HW] = np.full((len(staff_type_records)), False).tolist()

        for target_mst_ID in bgc.BG_QUICK_MAP_TARGET_MST_IDS:
            for ind_type_HW in bgc.BG_HW_STAFF_TYPE_IND_SET:
                quick_map_rec = bgmvd.BG_create_quick_map_rec(budget_rec[bgmvf.BG_BUDGET_ID], gbc.GB_HW, target_mst_ID, ind_type_HW)
                quick_map_records_mv.append(quick_map_rec)

    projection[bgmvt.BG_QUICK_MAP_RECORDS_TAG] = deepcopy(quick_map_records_mv)

    required_mod_vars_HW = {
        pjmvt.GB_IHTOnTag                 : IHT_on,

        bgmvt.BG_BUDGET_RECORDS_TAG       : budget_records,
        bgmvt.BG_BUDGET_CAT_RECORDS_TAG   : budget_cat_records,
        bgmvt.BG_FUND_FW_RECORDS_TAG      : fund_framework_records,
        bgmvt.BG_FUND_SOURCE_RECORDS_TAG  : fund_source_records,

        bgcl.BG_HW_STAFF_TYPE_RECORDS_TAG : staff_type_records,

        bgcl.BG_PC_COSTING_SECT_RECORDS_TAG : costing_section_records,
        bgcl.BG_PC_ACT_RECORDS_TAG          : activity_records,
    }

    projection[bgmvt.BG_INDICATOR_RECORDS_HW_TAG] = bgu.BG_init_ind_HW_records(required_mod_vars_HW)

    if quick_map_records_tag != bgmvt.BG_QUICK_MAP_RECORDS_TAG:
        projection[bgmvt.BG_QUICK_MAP_RECORDS_TAG] = deepcopy(quick_map_records_mv)

def _convert_indicator_IC_records_1(projection, indicator_IC_records_tag):
    ind_records_IC_mv = projection[indicator_IC_records_tag]

    IHT_plan_type = projection[pjmvt.PJN_IHTPlanTypeTag]
    TB_costing_on = projection[pjmvt.GB_TBCostingOnTag]
    IHT_on = projection[pjmvt.GB_IHTOnTag]
    budget_records_mv = projection[bgmvt.BG_BUDGET_RECORDS_TAG]
    budget_cat_records_mv = projection[bgmvt.BG_BUDGET_CAT_RECORDS_TAG]
    fund_framework_records = projection[bgmvt.BG_FUND_FW_RECORDS_TAG]
    fund_source_records_mv = projection[bgmvt.BG_FUND_SOURCE_RECORDS_TAG]
    interv_records_mv = projection[icmvt.IC_INTERV_RECORDS_TAG]
    deliv_chan_records_mv = projection[ihmvt.IH_DELIV_CHAN_RECORDS_TAG_V1]

    # The visits and labor indicators did not exist for Intervention Costing
    if  (IHT_on and (IHT_plan_type == ihc.IH_SPECIFIC_PLAN)) or TB_costing_on:
        for ind_type_ID in [bgc.BG_IC_LABOR_COSTS_IND_MST_ID, bgc.BG_IC_VISIT_COSTS_IND_MST_ID]:
            for interv_rec in interv_records_mv:
                interv_ID = icmvu.get_IC_interv_ID(interv_rec)

                required_mod_vars = {
                    pjmvt.GB_IHTOnTag                 : IHT_on,

                    bgmvt.BG_INDICATOR_RECORDS_IC_TAG : ind_records_IC_mv,

                    bgmvt.BG_BUDGET_RECORDS_TAG       : budget_records_mv,
                    bgmvt.BG_BUDGET_CAT_RECORDS_TAG   : budget_cat_records_mv,
                    bgmvt.BG_FUND_FW_RECORDS_TAG      : fund_framework_records,
                    bgmvt.BG_FUND_SOURCE_RECORDS_TAG  : fund_source_records_mv,

                    bgcl.BG_IC_INTERV_RECORDS_TAG     : interv_records_mv,
                    bgcl.BG_IH_DELIV_CHAN_RECORDS_TAG : deliv_chan_records_mv,
                }

                bgu.BG_add_indicators_IC_for_interv(required_mod_vars, ind_type_ID, interv_ID)

        for budget_rec in budget_records_mv:
            bgmvu.set_BG_budget_cost_cat_IC_ID(budget_rec, bgc.BG_IC_DRUGS_SUPPLIES_CC_MST_ID)

    if indicator_IC_records_tag != bgmvt.BG_INDICATOR_RECORDS_IC_TAG:
        projection[bgmvt.BG_INDICATOR_RECORDS_IC_TAG] = deepcopy(ind_records_IC_mv)

def _convert_indicator_IC_records_2(projection, indicator_IC_records_tag):
    # Two new indicators were added for TB app.
    ind_records_IC_mv = projection[indicator_IC_records_tag]

    TB_costing_on = projection[pjmvt.GB_TBCostingOnTag]
    # budget_records_mv = projection[bgmvt.BG_BUDGET_RECORDS_TAG]
    # budget_cat_records_mv = projection[bgmvt.BG_BUDGET_CAT_RECORDS_TAG]
    # fund_framework_records = projection[bgmvt.BG_FUND_FW_RECORDS_TAG]
    # fund_source_records_mv = projection[bgmvt.BG_FUND_SOURCE_RECORDS_TAG]
    drug_supply_records_mv = projection[icmvt.IC_DRUG_SUPPLY_RECORDS_TAG]
    # deliv_chan_records_mv = projection[ihmvt.IH_DELIV_CHAN_RECORDS_TAG_V1]

    required_mod_vars = {
        pjmvt.GB_IHTOnTag                  : projection[pjmvt.GB_IHTOnTag],
        pjmvt.PJN_IHTPlanTypeTag           : projection[pjmvt.PJN_IHTPlanTypeTag],
        pjmvt.GB_TBCostingOnTag            : projection[pjmvt.GB_TBCostingOnTag],
        bgmvt.BG_INDICATOR_RECORDS_IC_TAG  : projection[indicator_IC_records_tag],
        bgmvt.BG_BUDGET_RECORDS_TAG        : projection[bgmvt.BG_BUDGET_RECORDS_TAG],
        bgmvt.BG_BUDGET_CAT_RECORDS_TAG    : projection[bgmvt.BG_BUDGET_CAT_RECORDS_TAG],
        bgmvt.BG_FUND_FW_RECORDS_TAG       : projection[bgmvt.BG_FUND_FW_RECORDS_TAG],
        bgmvt.BG_FUND_SOURCE_RECORDS_TAG   : projection[bgmvt.BG_FUND_SOURCE_RECORDS_TAG],
        bgmvt.BG_QUICK_MAP_RECORDS_TAG     : projection[bgmvt.BG_QUICK_MAP_RECORDS_TAG],
        bgcl.BG_IH_DELIV_CHAN_RECORDS_TAG  : projection[ihmvt.IH_DELIV_CHAN_RECORDS_TAG_V1],
        bgcl.BG_IC_DRUG_SUPPLY_RECORDS_TAG : projection[bgcl.BG_IC_DRUG_SUPPLY_RECORDS_TAG],
        bgcl.BG_IH_PROG_AREA_RECORDS_TAG   : projection[bgcl.BG_IH_PROG_AREA_RECORDS_TAG],
    }

    # New indicator types were added to Budget Mapping for TB app costing. Both are by drug and supply only.
    if TB_costing_on:
        for ind_type_ID in [bgc.BG_IC_LOG_SUPPLY_CHAIN_COSTS_MST_ID, bgc.BG_IC_WASTAGE_COSTS_MST_ID]:
            for drug_supply_rec in drug_supply_records_mv:
                drug_supply_ID = icmvu.get_IC_drug_supply_ID(drug_supply_rec)
                bgu.BG_add_new_indicators_IC(required_mod_vars, ind_type_ID, drug_supply_ID)


    if indicator_IC_records_tag != bgmvt.BG_INDICATOR_RECORDS_IC_TAG:
        projection[bgmvt.BG_INDICATOR_RECORDS_IC_TAG] = deepcopy(ind_records_IC_mv)

def _convert_indicator_IC_records_3(projection, indicator_IC_records_tag):
    # Two IC indicator types were changed to vary by prog area in specific plan mode.
    ind_records_IC_mv = projection[indicator_IC_records_tag]

    IHT_on = projection[pjmvt.GB_IHTOnTag]
    IHT_plan_type = projection[pjmvt.PJN_IHTPlanTypeTag]

    if IHT_on and (IHT_plan_type == bgcl.BG_IH_SPECIFIC_PLAN):

        budget_records_mv = projection[bgmvt.BG_BUDGET_RECORDS_TAG]
        budget_cat_records_mv = projection[bgmvt.BG_BUDGET_CAT_RECORDS_TAG]
        fund_framework_records_mv = projection[bgmvt.BG_FUND_FW_RECORDS_TAG]
        fund_source_records_mv = projection[bgmvt.BG_FUND_SOURCE_RECORDS_TAG]

        drug_supply_records_mv = projection[bgcl.BG_IC_DRUG_SUPPLY_RECORDS_TAG]
        prog_area_records_mv = projection[bgcl.BG_IH_PROG_AREA_RECORDS_TAG]

        ind_records_IC_mv = [ind_rec for ind_rec in ind_records_IC_mv if (
            ((ind_rec[bgmvf.BG_IND_TYPE_ID] in bgc.BG_IC_TB_IHT_SPEC_IND_TYPE_MST_IDS)
            and (bgmvf.BG_IND_PROG_AREA_ID_PC in ind_rec))
            or (ind_rec[bgmvf.BG_IND_TYPE_ID] not in bgc.BG_IC_TB_IHT_SPEC_IND_TYPE_MST_IDS)
        )]

        for ind_type_ID in bgc.BG_IC_TB_IHT_SPEC_IND_TYPE_MST_IDS:

            fund_sources_by_framework = bgu.BG_init_fund_sources_by_framework_dict(fund_framework_records_mv, fund_source_records_mv)

            for budget_rec in budget_records_mv:
                budget_ID = bgmvu.get_BG_budget_ID(budget_rec)

                # Get the budget category records associated with this budget. At least one budget category (Unallocated) should exist for the
                # budget already.
                budget_cat_records_curr_budget = bgmvu.get_BG_budget_cat_records(budget_cat_records_mv, budget_ID)
                # Map the indicator to the first budget category unless told otherwise.
                budget_cat_ID = bgmvu.get_BG_budget_cat_ID(budget_cat_records_curr_budget[0])

                for drug_supply_rec in drug_supply_records_mv:

                    drug_supply_ID = bgul.BG_get_IC_drug_supply_ID(drug_supply_rec)
                    drug_supply_name = bgul.BG_get_IC_drug_supply_name(drug_supply_rec)

                    # Now add the indicator record for each programme area.
                    for prog_area_rec in prog_area_records_mv:
                        prog_area_ID = bgul.get_IH_prog_area_ID(prog_area_rec)

                        ind_rec = bgmvd.BG_create_indicator_rec_IC(budget_ID, ind_type_ID, drug_supply_ID, budget_cat_ID, drug_supply_name)
                        bgmvu.set_BG_ind_prog_area_ID_PC(ind_rec, prog_area_ID)
                        bgmvu.set_BG_ind_fund_source_by_framework_dict(ind_rec, deepcopy(fund_sources_by_framework))

                        ind_records_IC_mv.append(ind_rec)

    if indicator_IC_records_tag != bgmvt.BG_INDICATOR_RECORDS_IC_TAG:
        projection[bgmvt.BG_INDICATOR_RECORDS_IC_TAG] = deepcopy(ind_records_IC_mv)

def _convert_indicator_IS_records_1(projection, indicator_IS_records_tag):
    # New indicator was added for TB app.
    ind_records_IS_mv = projection[indicator_IS_records_tag]

    # A new indicator type was added to Budget Mapping for TB app costing
    # IHT_on = projection[pjmvt.GB_IHTOnTag]
    TB_costing_on = projection[pjmvt.GB_TBCostingOnTag]
    # budget_records_mv = projection[bgmvt.BG_BUDGET_RECORDS_TAG]
    # budget_cat_records_mv = projection[bgmvt.BG_BUDGET_CAT_RECORDS_TAG]
    # fund_framework_records = projection[bgmvt.BG_FUND_FW_RECORDS_TAG]
    # fund_source_records_mv = projection[bgmvt.BG_FUND_SOURCE_RECORDS_TAG]
    facility_type_records_mv = projection[ismvt.IS_FACILITY_TYPE_RECORDS_TAG]

    required_mod_vars = {
        pjmvt.GB_IHTOnTag                     : projection[pjmvt.GB_IHTOnTag],
        pjmvt.GB_TBCostingOnTag               : projection[pjmvt.GB_TBCostingOnTag],
        pjmvt.PJN_IHTPlanTypeTag              : projection[pjmvt.PJN_IHTPlanTypeTag],
        bgmvt.BG_INDICATOR_RECORDS_IS_TAG     : projection[indicator_IS_records_tag],
        bgmvt.BG_BUDGET_RECORDS_TAG           : projection[bgmvt.BG_BUDGET_RECORDS_TAG],
        bgmvt.BG_BUDGET_CAT_RECORDS_TAG       : projection[bgmvt.BG_BUDGET_CAT_RECORDS_TAG],
        bgmvt.BG_FUND_FW_RECORDS_TAG          : projection[bgmvt.BG_FUND_FW_RECORDS_TAG],
        bgmvt.BG_FUND_SOURCE_RECORDS_TAG      : projection[bgmvt.BG_FUND_SOURCE_RECORDS_TAG],
        bgmvt.BG_QUICK_MAP_RECORDS_TAG        : projection[bgmvt.BG_QUICK_MAP_RECORDS_TAG],
        bgcl.BG_IS_FACILITY_TYPE_RECORDS_TAG  : projection[ismvt.IS_FACILITY_TYPE_RECORDS_TAG],
        bgcl.IH_PROG_AREA_RECORDS_TAG_V1      : projection[bgcl.IH_PROG_AREA_RECORDS_TAG_V1],
    }

    if TB_costing_on:
        for facility_type_rec in facility_type_records_mv:
            facility_type_ID = ismvu.get_IS_facility_type_ID(facility_type_rec)

            # bgu.BG_add_indicators_IS_for_facility_type(
            #     IHT_on, TB_costing_on, ind_records_IS_mv, budget_records_mv, budget_cat_records_mv, fund_framework_records, fund_source_records_mv,
            #     facility_type_records_mv, bgc.BG_IS_MED_EQUIP_MAINT_CALIB_COSTS_TB_IND_MST_ID, facility_type_ID
            # )

            # Takes care of the annoying checkboxes as well.
            bgu.BG_add_new_indicators_IS_non_prog_mgmt(required_mod_vars, bgc.BG_IS_MED_EQUIP_MAINT_CALIB_COSTS_TB_IND_MST_ID, facility_type_ID)

    if indicator_IS_records_tag != bgmvt.BG_INDICATOR_RECORDS_IS_TAG:
        projection[bgmvt.BG_INDICATOR_RECORDS_IS_TAG] = deepcopy(ind_records_IS_mv)

def _convert_indicator_IS_records_2(projection, indicator_IS_records_tag):
    # New indicator was added for TB app.
    ind_records_IS_mv = projection[indicator_IS_records_tag]

    IHT_on = projection[pjmvt.GB_IHTOnTag]
    IHT_plan_type = projection[pjmvt.PJN_IHTPlanTypeTag]

    if IHT_on and (IHT_plan_type == bgcl.BG_IH_SPECIFIC_PLAN):

        budget_records_mv = projection[bgmvt.BG_BUDGET_RECORDS_TAG]
        budget_cat_records_mv = projection[bgmvt.BG_BUDGET_CAT_RECORDS_TAG]
        fund_framework_records_mv = projection[bgmvt.BG_FUND_FW_RECORDS_TAG]
        fund_source_records_mv = projection[bgmvt.BG_FUND_SOURCE_RECORDS_TAG]

        facility_type_records_mv = projection[bgcl.BG_IS_FACILITY_TYPE_RECORDS_TAG]
        prog_area_records_mv = projection[bgcl.BG_IH_PROG_AREA_RECORDS_TAG]

        ind_records_IS_mv = [ind_rec for ind_rec in ind_records_IS_mv if (
            ((ind_rec[bgmvf.BG_IND_TYPE_ID] in bgc.BG_IS_TB_IHT_SPEC_IND_TYPE_MST_IDS)
            and (bgmvf.BG_IND_PROG_AREA_ID_PC in ind_rec))
            or (ind_rec[bgmvf.BG_IND_TYPE_ID] not in bgc.BG_IS_TB_IHT_SPEC_IND_TYPE_MST_IDS)
        )]

        for ind_type_ID in bgc.BG_IS_TB_IHT_SPEC_IND_TYPE_MST_IDS:

            fund_sources_by_framework = bgu.BG_init_fund_sources_by_framework_dict(fund_framework_records_mv, fund_source_records_mv)

            for budget_rec in budget_records_mv:
                budget_ID = bgmvu.get_BG_budget_ID(budget_rec)

                # Get the budget category records associated with this budget. At least one budget category (Unallocated) should exist for the
                # budget already.
                budget_cat_records_curr_budget = bgmvu.get_BG_budget_cat_records(budget_cat_records_mv, budget_ID)
                # Map the indicator to the first budget category unless told otherwise.
                budget_cat_ID = bgmvu.get_BG_budget_cat_ID(budget_cat_records_curr_budget[0])

                for facility_type_rec in facility_type_records_mv:

                    facility_type_ID = bgul.BG_get_IS_facility_type_ID(facility_type_rec)
                    facility_type_name = bgul.BG_get_IS_facility_type_name(facility_type_rec)

                    # Now add the indicator record for each programme area.
                    for prog_area_rec in prog_area_records_mv:
                        prog_area_ID = bgul.get_IH_prog_area_ID(prog_area_rec)
                        ind_rec = bgmvd.BG_create_indicator_rec_IS(budget_ID, ind_type_ID, facility_type_ID, budget_cat_ID, facility_type_name)
                        bgmvu.set_BG_ind_prog_area_ID_PC(ind_rec, prog_area_ID)
                        bgmvu.set_BG_ind_fund_source_by_framework_dict(ind_rec, deepcopy(fund_sources_by_framework))
                        ind_records_IS_mv.append(ind_rec)

    if indicator_IS_records_tag != bgmvt.BG_INDICATOR_RECORDS_IS_TAG:
        projection[bgmvt.BG_INDICATOR_RECORDS_IS_TAG] = deepcopy(ind_records_IS_mv)

def _convert_budget_cat_share_IC_records_1(projection, budget_cat_share_IC_records_tag):
    budget_cat_share_IC_records_mv = projection[budget_cat_share_IC_records_tag]

    IHT_on = projection[pjmvt.GB_IHTOnTag]
    IHT_plan_type = projection[pjmvt.PJN_IHTPlanTypeTag]

    if IHT_on and (IHT_plan_type == bgcl.BG_IH_SPECIFIC_PLAN):

        prog_area_records_mv = projection[bgcl.BG_IH_PROG_AREA_RECORDS_TAG]

        records_without_prog_areas = [share_rec for share_rec in budget_cat_share_IC_records_mv if (
            ((share_rec[bgmvf.BG_BUDGET_CAT_SHARE_IND_TYPE_ID] in bgc.BG_IC_TB_IHT_SPEC_IND_TYPE_MST_IDS)
            and (bgmvf.BG_BUDGET_CAT_SHARE_PROG_AREA_ID_PC not in share_rec))
        )]

        budget_cat_share_IC_records_mv = [share_rec for share_rec in budget_cat_share_IC_records_mv if (
            ((share_rec[bgmvf.BG_BUDGET_CAT_SHARE_IND_TYPE_ID] in bgc.BG_IC_TB_IHT_SPEC_IND_TYPE_MST_IDS)
            and (bgmvf.BG_BUDGET_CAT_SHARE_PROG_AREA_ID_PC in share_rec))
            or (share_rec[bgmvf.BG_BUDGET_CAT_SHARE_IND_TYPE_ID] not in bgc.BG_IC_TB_IHT_SPEC_IND_TYPE_MST_IDS)
        )]

        # Now add the budget category share record for each programme area.
        for rec in records_without_prog_areas:
            for prog_area_rec in prog_area_records_mv:
                prog_area_ID = bgul.get_IH_prog_area_ID(prog_area_rec)
                rec_by_prog_area = deepcopy(rec)
                bgmvu.set_BG_budget_cat_share_prog_area_ID_PC(rec_by_prog_area, prog_area_ID)
                budget_cat_share_IC_records_mv.append(rec_by_prog_area)

    if budget_cat_share_IC_records_tag != bgmvt.BG_BUDGET_CAT_SHARE_RECORDS_IC_TAG:
        projection[bgmvt.BG_BUDGET_CAT_SHARE_RECORDS_IC_TAG] = deepcopy(budget_cat_share_IC_records_mv)

def _convert_budget_cat_share_IS_records_1(projection, budget_cat_share_IS_records_tag):
    budget_cat_share_IS_records_mv = projection[budget_cat_share_IS_records_tag]

    IHT_on = projection[pjmvt.GB_IHTOnTag]
    IHT_plan_type = projection[pjmvt.PJN_IHTPlanTypeTag]

    if IHT_on and (IHT_plan_type == bgcl.BG_IH_SPECIFIC_PLAN):

        prog_area_records_mv = projection[bgcl.BG_IH_PROG_AREA_RECORDS_TAG]

        records_without_prog_areas = [share_rec for share_rec in budget_cat_share_IS_records_mv if (
            ((share_rec[bgmvf.BG_BUDGET_CAT_SHARE_IND_TYPE_ID] in bgc.BG_IS_TB_IHT_SPEC_IND_TYPE_MST_IDS)
            and (bgmvf.BG_BUDGET_CAT_SHARE_PROG_AREA_ID_PC not in share_rec))
        )]

        budget_cat_share_IS_records_mv = [share_rec for share_rec in budget_cat_share_IS_records_mv if (
            ((share_rec[bgmvf.BG_BUDGET_CAT_SHARE_IND_TYPE_ID] in bgc.BG_IS_TB_IHT_SPEC_IND_TYPE_MST_IDS)
            and (bgmvf.BG_BUDGET_CAT_SHARE_PROG_AREA_ID_PC in share_rec))
            or (share_rec[bgmvf.BG_BUDGET_CAT_SHARE_IND_TYPE_ID] not in bgc.BG_IS_TB_IHT_SPEC_IND_TYPE_MST_IDS)
        )]

        # Now add the indicator record for each programme area.
        for rec in records_without_prog_areas:
            for prog_area_rec in prog_area_records_mv:
                prog_area_ID = bgul.get_IH_prog_area_ID(prog_area_rec)
                rec_by_prog_area = deepcopy(rec)
                bgmvu.set_BG_budget_cat_share_prog_area_ID_PC(rec_by_prog_area, prog_area_ID)
                budget_cat_share_IS_records_mv.append(rec_by_prog_area)

    if budget_cat_share_IS_records_tag != bgmvt.BG_BUDGET_CAT_SHARE_RECORDS_IS_TAG:
        projection[bgmvt.BG_BUDGET_CAT_SHARE_RECORDS_IS_TAG] = deepcopy(budget_cat_share_IS_records_mv)

def _convert_funding_source_share_IC_records_1(projection, funding_source_share_IC_records_tag):
    funding_source_share_IC_records_mv = projection[funding_source_share_IC_records_tag]

    IHT_on = projection[pjmvt.GB_IHTOnTag]
    IHT_plan_type = projection[pjmvt.PJN_IHTPlanTypeTag]

    if IHT_on and (IHT_plan_type == bgcl.BG_IH_SPECIFIC_PLAN):

        prog_area_records_mv = projection[bgcl.BG_IH_PROG_AREA_RECORDS_TAG]

        records_without_prog_areas = [share_rec for share_rec in funding_source_share_IC_records_mv if (
            ((share_rec[bgmvf.BG_FUND_SOURCE_SHARE_IND_TYPE_ID] in bgc.BG_IC_TB_IHT_SPEC_IND_TYPE_MST_IDS)
            and (bgmvf.BG_FUND_SOURCE_SHARE_PROG_AREA_ID_PC not in share_rec))
        )]

        funding_source_share_IC_records_mv = [share_rec for share_rec in funding_source_share_IC_records_mv if (
            ((share_rec[bgmvf.BG_FUND_SOURCE_SHARE_IND_TYPE_ID] in bgc.BG_IC_TB_IHT_SPEC_IND_TYPE_MST_IDS)
            and (bgmvf.BG_FUND_SOURCE_SHARE_PROG_AREA_ID_PC in share_rec))
            or (share_rec[bgmvf.BG_FUND_SOURCE_SHARE_IND_TYPE_ID] not in bgc.BG_IC_TB_IHT_SPEC_IND_TYPE_MST_IDS)
        )]

        # Now add the budget category share record for each programme area.
        for rec in records_without_prog_areas:
            for prog_area_rec in prog_area_records_mv:
                prog_area_ID = bgul.get_IH_prog_area_ID(prog_area_rec)
                rec_by_prog_area = deepcopy(rec)
                bgmvu.set_BG_fund_source_share_prog_area_ID_PC(rec_by_prog_area, prog_area_ID)
                funding_source_share_IC_records_mv.append(rec_by_prog_area)

    if funding_source_share_IC_records_tag != bgmvt.BG_FUND_SOURCE_SHARE_RECORDS_IC_TAG:
        projection[bgmvt.BG_FUND_SOURCE_SHARE_RECORDS_IC_TAG] = deepcopy(funding_source_share_IC_records_mv)

def _convert_funding_source_share_IS_records_1(projection, funding_source_share_IS_records_tag):
    funding_source_share_IS_records_mv = projection[funding_source_share_IS_records_tag]

    IHT_on = projection[pjmvt.GB_IHTOnTag]
    IHT_plan_type = projection[pjmvt.PJN_IHTPlanTypeTag]

    if IHT_on and (IHT_plan_type == bgcl.BG_IH_SPECIFIC_PLAN):

        prog_area_records_mv = projection[bgcl.BG_IH_PROG_AREA_RECORDS_TAG]

        records_without_prog_areas = [share_rec for share_rec in funding_source_share_IS_records_mv if (
            ((share_rec[bgmvf.BG_FUND_SOURCE_SHARE_IND_TYPE_ID] in bgc.BG_IS_TB_IHT_SPEC_IND_TYPE_MST_IDS)
            and (bgmvf.BG_FUND_SOURCE_SHARE_PROG_AREA_ID_PC not in share_rec))
        )]

        funding_source_share_IS_records_mv = [share_rec for share_rec in funding_source_share_IS_records_mv if (
            ((share_rec[bgmvf.BG_FUND_SOURCE_SHARE_IND_TYPE_ID] in bgc.BG_IS_TB_IHT_SPEC_IND_TYPE_MST_IDS)
            and (bgmvf.BG_FUND_SOURCE_SHARE_PROG_AREA_ID_PC in share_rec))
            or (share_rec[bgmvf.BG_FUND_SOURCE_SHARE_IND_TYPE_ID] not in bgc.BG_IS_TB_IHT_SPEC_IND_TYPE_MST_IDS)
        )]

        # Now add the indicator record for each programme area.
        for rec in records_without_prog_areas:
            for prog_area_rec in prog_area_records_mv:
                prog_area_ID = bgul.get_IH_prog_area_ID(prog_area_rec)
                rec_by_prog_area = deepcopy(rec)
                bgmvu.set_BG_fund_source_share_prog_area_ID_PC(rec_by_prog_area, prog_area_ID)
                funding_source_share_IS_records_mv.append(rec_by_prog_area)

    if funding_source_share_IS_records_tag != bgmvt.BG_FUND_SOURCE_SHARE_RECORDS_IS_TAG:
        projection[bgmvt.BG_FUND_SOURCE_SHARE_RECORDS_IS_TAG] = deepcopy(funding_source_share_IS_records_mv)

def _add_missing_log_supply_chain_budget_records(projection):
    IHT_on = projection[pjmvt.GB_IHTOnTag]
    TB_costing_on = projection[pjmvt.GB_TBCostingOnTag]
    IHT_plan_type = projection[pjmvt.PJN_IHTPlanTypeTag]

    # Records should be added for TB projections and IHT specific plan projections
    if ((IHT_on and IHT_plan_type == bgcl.BG_IH_SPECIFIC_PLAN) or TB_costing_on):
        drug_supply_records = projection[icmvt.IC_DRUG_SUPPLY_RECORDS_TAG]
        ind_records_IC = projection[bgmvt.BG_INDICATOR_RECORDS_IC_TAG]
        budget_records = projection[bgmvt.BG_BUDGET_RECORDS_TAG]
        budget_cat_records = projection[bgmvt.BG_BUDGET_CAT_RECORDS_TAG]
        fund_framework_records = projection[bgmvt.BG_FUND_FW_RECORDS_TAG]
        fund_source_records = projection[bgmvt.BG_FUND_SOURCE_RECORDS_TAG]
        quick_map_records = projection[bgmvt.BG_QUICK_MAP_RECORDS_TAG]
        drug_supply_records = projection[icmvt.IC_DRUG_SUPPLY_RECORDS_TAG]
        deliv_chan_records = projection[ihmvt.IH_DELIV_CHAN_RECORDS_TAG_V1]
        prog_area_records = projection[ihmvt.IH_PROG_AREA_RECORDS_TAG_V1]

        log_supply_record_ids = [rec[bgmvf.BG_IND_ID] for rec in ind_records_IC if rec[bgmvf.BG_IND_TYPE_ID] == bgc.BG_IC_LOG_SUPPLY_CHAIN_COSTS_MST_ID]
        wastage_record_ids = [rec[bgmvf.BG_IND_ID] for rec in ind_records_IC if rec[bgmvf.BG_IND_TYPE_ID] == bgc.BG_IC_WASTAGE_COSTS_MST_ID]

        record_map = {
            bgc.BG_IC_LOG_SUPPLY_CHAIN_COSTS_MST_ID: log_supply_record_ids,
            bgc.BG_IC_WASTAGE_COSTS_MST_ID: wastage_record_ids,
        }

        for ind_type_ID, record_ids in record_map.items():
            for drug_supply_rec in drug_supply_records:
                ind_ID = drug_supply_rec[icmvf.IC_DRUG_SUPPLY_ID]
                if ind_ID not in record_ids:
                    bgu.BG_add_new_indicators_IC({
                        pjmvt.GB_IHTOnTag                    : IHT_on,
                        pjmvt.GB_TBCostingOnTag              : TB_costing_on,
                        pjmvt.PJN_IHTPlanTypeTag             : IHT_plan_type,
                        bgmvt.BG_BUDGET_RECORDS_TAG          : budget_records,
                        bgmvt.BG_BUDGET_CAT_RECORDS_TAG      : budget_cat_records,
                        bgmvt.BG_FUND_FW_RECORDS_TAG         : fund_framework_records,
                        bgmvt.BG_FUND_SOURCE_RECORDS_TAG     : fund_source_records,
                        bgmvt.BG_INDICATOR_RECORDS_IC_TAG    : ind_records_IC,
                        bgmvt.BG_QUICK_MAP_RECORDS_TAG       : quick_map_records,
                        icmvt.IC_DRUG_SUPPLY_RECORDS_TAG     : drug_supply_records,
                        ihmvt.IH_DELIV_CHAN_RECORDS_TAG_V1   : deliv_chan_records,
                        ihmvt.IH_PROG_AREA_RECORDS_TAG_V1    : prog_area_records,
                    }, ind_type_ID, ind_ID)

        projection[bgmvt.BG_INDICATOR_RECORDS_IC_TAG] = deepcopy(ind_records_IC)