Ejemplo n.º 1
0
def _process_CCD4(elements, headers):
    breakdown = headers["breakdown"]
    ccde = elements["ccde"]
    ccde_supplier_code = ccde[2]
    tcod = elements["TCOD"]

    tpref = TCOD_MAP[tcod[1]][ccde_supplier_code]

    bpri = elements["BPRI"]
    rate_key = tpref + "_rate"
    if rate_key not in breakdown:
        breakdown[rate_key] = set()
    rate = Decimal(bpri[0]) / Decimal("10000000")
    breakdown[rate_key].add(rate)

    nuct = elements["NUCT"]

    try:
        ctot = elements["CTOT"]
        breakdown[tpref + "_gbp"] += to_decimal(ctot) / Decimal("100")

        if ccde_supplier_code == "PPK":
            key = f"{tpref}_kwh"
        elif ccde_supplier_code == "PPD":
            key = f"{tpref}_days"

        breakdown[key] += to_decimal(nuct) / Decimal("1000")
    except KeyError:
        pass
Ejemplo n.º 2
0
def _process_VAT(elements, headers):
    breakdown = headers["breakdown"]
    vatp = elements["VATP"]
    if "vat_rate" not in breakdown:
        breakdown["vat_rate"] = set()
    breakdown["vat_rate"].add(to_decimal(vatp) / Decimal(100000))

    uvla = elements["UVLA"]
    headers["net"] += to_decimal(uvla) / Decimal("100")
    uvtt = elements["UVTT"]
    headers["vat"] += to_decimal(uvtt) / Decimal("100")
    ucsi = elements["UCSI"]
    headers["gross"] += to_decimal(ucsi) / Decimal("100")
Ejemplo n.º 3
0
def _process_CCD1(elements, headers):
    mtnr = elements["MTNR"]
    msn = mtnr[0]

    mloc = elements["MLOC"]

    # Bug in EDI where MPRN missing in second CCD 1
    if "mprn" not in headers:
        headers["mprn"] = mloc[0]

    prdt = elements["PRDT"]
    pvdt = elements["PVDT"]

    pres_read_date = to_date(prdt[0])
    prev_read_date = to_date(pvdt[0])

    prrd = elements["PRRD"]
    pres_read_value = Decimal(prrd[0])
    pres_read_type = READ_TYPE_MAP[prrd[1]]
    prev_read_value = Decimal(prrd[2])
    prev_read_type = READ_TYPE_MAP[prrd[3]]

    conb = elements["CONB"]
    unit = UNIT_MAP[conb[1]]
    headers["breakdown"]["units_consumed"] += to_decimal(conb) / Decimal(
        "1000")

    adjf = elements["ADJF"]
    correction_factor = Decimal(adjf[1]) / Decimal(100000)

    nuct = elements["NUCT"]

    headers["kwh"] += to_decimal(nuct) / Decimal("1000")

    headers["reads"].append({
        "msn": msn,
        "unit": unit,
        "correction_factor": correction_factor,
        "prev_date": prev_read_date,
        "prev_value": prev_read_value,
        "prev_type_code": prev_read_type,
        "pres_date": pres_read_date,
        "pres_value": pres_read_value,
        "pres_type_code": pres_read_type,
    })
Ejemplo n.º 4
0
    def make_raw_bills(self):
        raw_bills = []
        message_type = breakdown = raw_lines = None
        for self.line_number, code in enumerate(self.parser):
            if code == "ADJ":
                # seqa = self.parser.elements[0]
                # seqb = self.parser.elements[1]
                adjf = self.parser.elements[2]
                if adjf[0] == 'CV':
                    cv = Decimal(adjf[1]) / Decimal(100000)

            if code == "BCD":
                ivdt = self.parser.elements[0]
                issue_date = to_date(ivdt[0])

                invn = self.parser.elements[2]
                reference = invn[0]

                btcd = self.parser.elements[5]
                bill_type_code = btcd[0]

                sumo = self.parser.elements[7]
                start_date = to_date(sumo[0])
                finish_date = to_date(sumo[1]) + relativedelta(days=1) - HH

            elif code == "MHD":
                typ = self.parser.elements[1]
                message_type = typ[0]
                if message_type == "UTLBIL":
                    issue_date = None
                    start_date = None
                    finish_date = None
                    reference = None
                    net = Decimal('0.00')
                    vat = Decimal('0.00')
                    gross = Decimal('0.00')
                    kwh = Decimal(0)
                    reads = []
                    bill_type_code = None
                    mprn = None
                    raw_lines = []
                    breakdown = defaultdict(int,
                                            {'units_consumed': Decimal(0)})
                    cv = None
            elif code == "CCD":
                ccde = self.parser.elements[1]
                consumption_charge_indicator = ccde[0]

                if consumption_charge_indicator == "1":

                    # tmod = self.parser.elements[3]

                    mtnr = self.parser.elements[4]
                    msn = mtnr[0]

                    mloc = self.parser.elements[5]

                    # Bug in EDI where MPRN missing in second CCD 1
                    if mprn is None:
                        mprn = mloc[0]

                    prdt = self.parser.elements[6]
                    pvdt = self.parser.elements[7]

                    pres_read_date = to_date(prdt[0])
                    prev_read_date = to_date(pvdt[0])

                    prrd = self.parser.elements[9]
                    pres_read_value = Decimal(prrd[0])
                    pres_read_type = READ_TYPE_MAP[prrd[1]]
                    prev_read_value = Decimal(prrd[2])
                    prev_read_type = READ_TYPE_MAP[prrd[3]]

                    # cons = self.parser.elements[10]

                    conb = self.parser.elements[11]
                    unit = UNIT_MAP[conb[1]]
                    breakdown['units_consumed'] += \
                        to_decimal(conb) / Decimal('1000')

                    adjf = self.parser.elements[12]
                    correction_factor = Decimal(adjf[1]) / Decimal(100000)

                    # cona = self.parser.elements[13]
                    # bpri = self.parser.elements[14]

                    nuct = self.parser.elements[15]

                    kwh += to_decimal(nuct) / Decimal('1000')

                    reads.append({
                        'msn': msn,
                        'unit': unit,
                        'correction_factor': correction_factor,
                        'prev_date': prev_read_date,
                        'prev_value': prev_read_value,
                        'prev_type_code': prev_read_type,
                        'pres_date': pres_read_date,
                        'pres_value': pres_read_value,
                        'pres_type_code': pres_read_type
                    })

                elif consumption_charge_indicator == '3':
                    ccde_supplier_code = ccde[2]
                    tcod = self.parser.elements[2]

                    tpref = TCOD_MAP[tcod[1]][ccde_supplier_code]

                    # tmod = self.parser.elements[3]

                    mtnr = self.parser.elements[4]
                    mloc = self.parser.elements[5]
                    prdt = self.parser.elements[6]
                    pvdt = self.parser.elements[7]
                    # ndrp = self.parser.elements[8]
                    prrd = self.parser.elements[9]
                    # cons = self.parser.elements[10]
                    conb = self.parser.elements[11]
                    adjf = self.parser.elements[12]
                    # cona = self.parser.elements[13]

                    bpri = self.parser.elements[14]
                    rate_key = tpref + '_rate'
                    if rate_key not in breakdown:
                        breakdown[rate_key] = set()
                    rate = Decimal(bpri[0]) / Decimal('10000000')
                    breakdown[rate_key].add(rate)

                    nuct = self.parser.elements[15]

                    # csdt = self.parser.elements[16]
                    # cedt = self.parser.elements[17]
                    # cppu = self.parser.elements[18]

                    try:
                        ctot = self.parser.elements[19]
                        breakdown[tpref + '_gbp'] += \
                            to_decimal(ctot) / Decimal('100')

                        # tsup = self.parser.elements[20]
                        # vatc = self.parser.elements[21]
                        # vatp = self.parser.elements[22]
                        # msad = self.parser.elements[23]
                        if ccde_supplier_code == 'PPK':
                            key = tpref + '_kwh'
                        elif ccde_supplier_code == 'PPD':
                            key = tpref + '_days'

                        breakdown[key] += to_decimal(nuct) / Decimal('1000')
                    except IndexError:
                        pass

            elif code == "MTR":
                if message_type == 'UTLBIL':
                    for k, v in tuple(breakdown.items()):
                        if isinstance(v, set):
                            breakdown[k] = sorted(v)

                    for read in reads:
                        read['calorific_value'] = cv

                    raw_bills.append({
                        'raw_lines': '\n'.join(raw_lines),
                        'mprn': mprn,
                        'reference': reference,
                        'account': mprn,
                        'reads': reads,
                        'kwh': kwh,
                        'breakdown': breakdown,
                        'net_gbp': net,
                        'vat_gbp': vat,
                        'gross_gbp': gross,
                        'bill_type_code': bill_type_code,
                        'start_date': start_date,
                        'finish_date': finish_date,
                        'issue_date': issue_date
                    })

            elif code == "VAT":
                vatp = self.parser.elements[4]
                if 'vat_rate' not in breakdown:
                    breakdown['vat_rate'] = set()
                breakdown['vat_rate'].add(vatp[0])

                uvla = self.parser.elements[5]
                net += to_decimal(uvla) / Decimal('100')
                uvtt = self.parser.elements[6]
                vat += to_decimal(uvtt) / Decimal('100')
                ucsi = self.parser.elements[7]
                gross += to_decimal(ucsi) / Decimal('100')

            if raw_lines is not None:
                raw_lines.append(self.parser.line)

        return raw_bills
Ejemplo n.º 5
0
    def make_raw_bills(self):
        raw_bills = []
        message_type = breakdown = raw_lines = None
        for self.line_number, line, code, elements in parse_edi(self.edi_str):
            if code == "ADJ":
                adjf = elements["ADJF"]
                if adjf[0] == "CV":
                    cv = Decimal(adjf[1]) / Decimal(100000)

            if code == "BCD":
                ivdt = elements["IVDT"]
                issue_date = to_date(ivdt[0])

                invn = elements["INVN"]
                reference = invn[0]

                btcd = elements["BTCD"]
                bill_type_code = btcd[0]

                sumo = elements["SUMO"]
                start_date = to_date(sumo[0])
                finish_date = to_date(sumo[1]) + relativedelta(days=1) - HH

            elif code == "MHD":
                typ = elements["TYPE"]
                message_type = typ[0]
                if message_type == "UTLBIL":
                    issue_date = None
                    start_date = None
                    finish_date = None
                    reference = None
                    net = Decimal("0.00")
                    vat = Decimal("0.00")
                    gross = Decimal("0.00")
                    kwh = Decimal(0)
                    reads = []
                    bill_type_code = None
                    mprn = None
                    raw_lines = []
                    breakdown = defaultdict(int, {"units_consumed": Decimal(0)})
                    cv = None
            elif code == "CCD":
                ccde = elements["CCDE"]
                consumption_charge_indicator = ccde[0]

                if consumption_charge_indicator == "1":

                    mtnr = elements["MTNR"]
                    msn = mtnr[0]

                    mloc = elements["MLOC"]

                    # Bug in EDI where MPRN missing in second CCD 1
                    if mprn is None:
                        mprn = mloc[0]

                    prdt = elements["PRDT"]
                    pvdt = elements["PVDT"]

                    pres_read_date = to_date(prdt[0])
                    prev_read_date = to_date(pvdt[0])

                    prrd = elements["PRRD"]
                    pres_read_value = Decimal(prrd[0])
                    pres_read_type = READ_TYPE_MAP[prrd[1]]
                    prev_read_value = Decimal(prrd[2])
                    prev_read_type = READ_TYPE_MAP[prrd[3]]

                    conb = elements["CONB"]
                    unit = UNIT_MAP[conb[1]]
                    breakdown["units_consumed"] += to_decimal(conb) / Decimal("1000")

                    adjf = elements["ADJF"]
                    correction_factor = Decimal(adjf[1]) / Decimal(100000)

                    nuct = elements["NUCT"]

                    kwh += to_decimal(nuct) / Decimal("1000")

                    reads.append(
                        {
                            "msn": msn,
                            "unit": unit,
                            "correction_factor": correction_factor,
                            "prev_date": prev_read_date,
                            "prev_value": prev_read_value,
                            "prev_type_code": prev_read_type,
                            "pres_date": pres_read_date,
                            "pres_value": pres_read_value,
                            "pres_type_code": pres_read_type,
                        }
                    )

                elif consumption_charge_indicator == "2":
                    ccde_supplier_code = ccde[2]
                    tcod = elements["TCOD"]

                    tpref = TCOD_MAP[tcod[1]][ccde_supplier_code]

                    mtnr = elements["MTNR"]
                    mloc = elements["MLOC"]
                    prdt = elements["PRDT"]
                    pvdt = elements["PVDT"]
                    prrd = elements["PRRD"]
                    conb = elements["CONB"]
                    adjf = elements["ADJF"]

                    bpri = elements["BPRI"]
                    rate_key = tpref + "_rate"
                    if rate_key not in breakdown:
                        breakdown[rate_key] = set()
                    rate = Decimal(bpri[0]) / Decimal("10000000")
                    breakdown[rate_key].add(rate)

                    nuct = elements["NUCT"]

                    try:
                        ctot = elements["CTOT"]
                        breakdown[tpref + "_gbp"] += to_decimal(ctot) / Decimal("100")

                        if ccde_supplier_code == "PPK":
                            key = tpref + "_kwh"
                        elif ccde_supplier_code == "PPD":
                            key = tpref + "_days"

                        breakdown[key] += to_decimal(nuct) / Decimal("1000")
                    except KeyError:
                        pass

                elif consumption_charge_indicator == "3":
                    ccde_supplier_code = ccde[2]
                    tcod = elements["TCOD"]

                    tpref = TCOD_MAP[tcod[1]][ccde_supplier_code]

                    mtnr = elements["MTNR"]
                    mloc = elements["MLOC"]
                    prdt = elements["PRDT"]
                    pvdt = elements["PVDT"]
                    prrd = elements["PRRD"]
                    conb = elements["CONB"]
                    adjf = elements["ADJF"]
                    bpri = elements["BPRI"]
                    rate_key = tpref + "_rate"
                    if rate_key not in breakdown:
                        breakdown[rate_key] = set()
                    rate = Decimal(bpri[0]) / Decimal("10000000")
                    breakdown[rate_key].add(rate)

                    nuct = elements["NUCT"]

                    try:
                        ctot = elements["CTOT"]
                        breakdown[tpref + "_gbp"] += to_decimal(ctot) / Decimal("100")

                        if ccde_supplier_code == "PPK":
                            key = tpref + "_kwh"
                        elif ccde_supplier_code == "PPD":
                            key = tpref + "_days"

                        breakdown[key] += to_decimal(nuct) / Decimal("1000")
                    except KeyError:
                        pass

                elif consumption_charge_indicator == "4":
                    ccde_supplier_code = ccde[2]
                    tcod = elements["TCOD"]

                    tpref = TCOD_MAP[tcod[1]][ccde_supplier_code]

                    mtnr = elements["MTNR"]
                    mloc = elements["MLOC"]
                    prdt = elements["PRDT"]
                    pvdt = elements["PVDT"]
                    prrd = elements["PRRD"]
                    conb = elements["CONB"]
                    adjf = elements["ADJF"]
                    bpri = elements["BPRI"]
                    rate_key = tpref + "_rate"
                    if rate_key not in breakdown:
                        breakdown[rate_key] = set()
                    rate = Decimal(bpri[0]) / Decimal("10000000")
                    breakdown[rate_key].add(rate)

                    nuct = elements["NUCT"]

                    try:
                        ctot = elements["CTOT"]
                        breakdown[tpref + "_gbp"] += to_decimal(ctot) / Decimal("100")

                        if ccde_supplier_code == "PPK":
                            key = tpref + "_kwh"
                        elif ccde_supplier_code == "PPD":
                            key = tpref + "_days"

                        breakdown[key] += to_decimal(nuct) / Decimal("1000")
                    except KeyError:
                        pass

            elif code == "MTR":
                if message_type == "UTLBIL":
                    for k, v in tuple(breakdown.items()):
                        if isinstance(v, set):
                            breakdown[k] = sorted(v)

                    for read in reads:
                        read["calorific_value"] = cv

                    raw_bills.append(
                        {
                            "raw_lines": "\n".join(raw_lines),
                            "mprn": mprn,
                            "reference": reference,
                            "account": mprn,
                            "reads": reads,
                            "kwh": kwh,
                            "breakdown": breakdown,
                            "net_gbp": net,
                            "vat_gbp": vat,
                            "gross_gbp": gross,
                            "bill_type_code": bill_type_code,
                            "start_date": start_date,
                            "finish_date": finish_date,
                            "issue_date": issue_date,
                        }
                    )

            elif code == "VAT":
                vatp = elements["VATP"]
                if "vat_rate" not in breakdown:
                    breakdown["vat_rate"] = set()
                breakdown["vat_rate"].add(to_decimal(vatp) / Decimal(100000))

                uvla = elements["UVLA"]
                net += to_decimal(uvla) / Decimal("100")
                uvtt = elements["UVTT"]
                vat += to_decimal(uvtt) / Decimal("100")
                ucsi = elements["UCSI"]
                gross += to_decimal(ucsi) / Decimal("100")

            if raw_lines is not None:
                raw_lines.append(line)

        return raw_bills
Ejemplo n.º 6
0
    def make_raw_bills(self):
        raw_bills = []
        breakdown = None
        for self.line_number, code in enumerate(self.parser):
            if code == "BCD":
                ivdt = self.parser.elements[0]
                issue_date = to_date(ivdt[0])

                invn = self.parser.elements[2]
                reference = invn[0]
                account = 'SA' + reference[:9]

                btcd = self.parser.elements[5]
                bill_type_code = btcd[0]

                sumo = self.parser.elements[7]
                start_date = to_date(sumo[0])
                finish_date = to_date(sumo[1]) + relativedelta(days=1) - HH

            elif code == "MHD":
                type = self.parser.elements[1]
                message_type = type[0]
                if message_type == "UTLBIL":
                    issue_date = None
                    start_date = None
                    finish_date = None
                    account = None
                    reference = None
                    net = Decimal('0.00')
                    vat = Decimal('0.00')
                    gross = Decimal('0.00')
                    kwh = Decimal(0)
                    reads = []
                    bill_type_code = None
                    mpan_cores = []
                    breakdown = defaultdict(int, {'raw-lines': []})
            elif code == "CCD":
                ccde = self.parser.elements[1]
                consumption_charge_indicator = ccde[0]

                if consumption_charge_indicator == "1":
                    prdt = self.parser.elements[6]
                    pvdt = self.parser.elements[7]

                    pres_read_date = to_date(prdt[0]) + relativedelta(
                        days=1) - HH

                    prev_read_date = to_date(pvdt[0]) + relativedelta(
                        days=1) - HH

                    tmod = self.parser.elements[3]
                    mtnr = self.parser.elements[4]
                    mloc = self.parser.elements[5]

                    mpan = mloc[0]
                    mpan = mpan[13:15] + ' ' + mpan[15:18] + ' ' + \
                        mpan[18:] + ' ' + mpan[:2] + ' ' + mpan[2:6] + ' ' + \
                        mpan[6:10] + ' ' + mpan[10:13]

                    prrd = self.parser.elements[9]
                    pres_read_type = read_type_map[prrd[1]]
                    prev_read_type = read_type_map[prrd[3]]

                    adjf = self.parser.elements[12]
                    cons = self.parser.elements[13]

                    coefficient = Decimal(adjf[1]) / Decimal(100000)
                    pres_reading_value = Decimal(prrd[0])
                    prev_reading_value = Decimal(prrd[2])
                    msn = mtnr[0]
                    tpr_native = tmod[0]
                    if tpr_native not in tmod_map:
                        raise BadRequest(
                            "The TPR code " + tpr_native +
                            " can't be found in the TPR list for mpan " +
                            mpan + ".")
                    tpr_code = tmod_map[tpr_native]
                    if tpr_code == 'kW':
                        units = 'kW'
                        tpr_code = None
                    elif tpr_code == 'kVA':
                        units = 'kVA'
                        tpr_code = None
                    else:
                        units = 'kWh'
                        kwh += to_decimal(cons) / Decimal('1000')

                    reads.append(
                        {
                            'msn': msn, 'mpan': mpan,
                            'coefficient': coefficient, 'units': units,
                            'tpr_code': tpr_code, 'prev_date': prev_read_date,
                            'prev_value': prev_reading_value,
                            'prev_type_code': prev_read_type,
                            'pres_date': pres_read_date,
                            'pres_value': pres_reading_value,
                            'pres_type_code': pres_read_type})
                elif consumption_charge_indicator == "2":
                    # tcod = self.parser.elements[2]
                    tmod = self.parser.elements[3]
                    mtnr = self.parser.elements[4]
                    mloc = self.parser.elements[5]

                    mpan = mloc[0]
                    mpan = mpan[13:15] + ' ' + mpan[15:18] + ' ' + \
                        mpan[18:] + ' ' + mpan[:2] + ' ' + mpan[2:6] + ' ' + \
                        mpan[6:10] + ' ' + mpan[10:13]

                    prdt = self.parser.elements[6]
                    pvdt = self.parser.elements[7]

                    pres_read_date = to_date(prdt[0]) + relativedelta(
                        days=1) - HH
                    prev_read_date = to_date(pvdt[0]) + relativedelta(
                        days=1) - HH

                    ndrp = self.parser.elements[8]
                    prrd = self.parser.elements[9]
                    pres_read_type = read_type_map[prrd[1]]
                    prev_read_type = read_type_map[prrd[3]]

                    adjf = self.parser.elements[12]
                    cona = self.parser.elements[13]

                    coefficient = Decimal(adjf[1]) / Decimal(100000)
                    pres_reading_value = Decimal(prrd[0])
                    prev_reading_value = Decimal(prrd[2])
                    msn = mtnr[0]
                    tpr_code = tmod[0]
                    if tpr_code not in tmod_map:
                        raise BadRequest(
                            "The TPR code " + tpr_code +
                            " can't be found in the TPR list for mpan " +
                            mpan + ".")
                    tpr = tmod_map[tpr_code]
                    if tpr == 'kW':
                        units = 'kW'
                        tpr = None
                        prefix = 'md-'
                    elif tpr == 'kVA':
                        units = 'kVA'
                        tpr = None
                        prefix = 'md-'
                    else:
                        units = 'kWh'
                        kwh += to_decimal(cona) / Decimal('1000')
                        prefix = tpr + '-'

                    nuct = self.parser.elements[15]
                    breakdown[prefix + 'kwh'] += \
                        to_decimal(nuct) / Decimal('1000')
                    cppu = self.parser.elements[18]
                    rate_key = prefix + 'rate'
                    if rate_key not in breakdown:
                        breakdown[rate_key] = set()
                    breakdown[rate_key].add(
                        to_decimal(cppu) / Decimal('100000'))
                    ctot = self.parser.elements[19]
                    breakdown[prefix + 'gbp'] += \
                        to_decimal(ctot) / Decimal('100')

                    reads.append(
                        {
                            'msn': msn, 'mpan': mpan,
                            'coefficient': coefficient, 'units': units,
                            'tpr_code': tpr, 'prev_date': prev_read_date,
                            'prev_value': prev_reading_value,
                            'prev_type_code': prev_read_type,
                            'pres_date': pres_read_date,
                            'pres_value': pres_reading_value,
                            'pres_type_code': pres_read_type})
                elif consumption_charge_indicator == '3':
                    # tcod = self.parser.elements[2]
                    tmod = self.parser.elements[3]
                    tmod0 = tmod[0]
                    if tmod0 == 'CCL':
                        prefix = kwh_prefix = 'ccl-'
                    elif tmod0 in ['CQFITC', 'CMFITC']:
                        prefix = 'fit-'
                        kwh_prefix = 'fit-msp-'
                    elif tmod0 == 'FITARR':
                        prefix = kwh_prefix = 'fit-reconciliation-'
                    else:
                        tpr_code = tmod0
                        if tpr_code not in tmod_map:
                            raise BadRequest(
                                "The TPR code " + tpr_code +
                                " can't be found in the TPR list for mpan " +
                                mpan + ".")
                        prefix = kwh_prefix = tmod_map[tpr_code] + '-'

                    mtnr = self.parser.elements[4]
                    ndrp = self.parser.elements[8]
                    cona = self.parser.elements[13]
                    nuct = self.parser.elements[15]
                    breakdown[kwh_prefix + 'kwh'] += \
                        to_decimal(nuct) / Decimal('1000')
                    cppu = self.parser.elements[18]

                    rate_key = prefix + 'rate'
                    if rate_key not in breakdown:
                        breakdown[rate_key] = set()
                    breakdown[rate_key].add(
                        to_decimal(cppu) / Decimal('100000'))

                    ctot = self.parser.elements[19]
                    breakdown[prefix + 'gbp'] += \
                        to_decimal(ctot) / Decimal('100')
                elif consumption_charge_indicator == '4':
                    # tcod = self.parser.elements[2]
                    tmod = self.parser.elements[3]
                    tmod0 = tmod[0]

                    mtnr = self.parser.elements[4]
                    ndrp = self.parser.elements[8]
                    if len(ndrp[0]) > 0:
                        breakdown['standing-days'] += \
                            to_decimal(ndrp)
                    cona = self.parser.elements[13]
                    nuct = self.parser.elements[15]
                    cppu = self.parser.elements[18]
                    ctot = self.parser.elements[19]
                    if len(ctot[0]) > 0:
                        breakdown['standing-gbp'] += \
                            to_decimal(ctot) / Decimal('100')
            elif code == "MTR":
                if message_type == "UTLBIL":
                    for k, v in tuple(breakdown.items()):
                        if isinstance(v, set):
                            breakdown[k] = ', '.join(sorted(map(str, v)))

                    raw_bills.append(
                        {
                            'bill_type_code': bill_type_code,
                            'account': account,
                            'mpan_cores': ', '.join(mpan_cores),
                            'reference': reference, 'issue_date': issue_date,
                            'start_date': start_date,
                            'finish_date': finish_date, 'kwh': kwh, 'net': net,
                            'vat': vat, 'gross': gross, 'breakdown': breakdown,
                            'reads': reads})
                    breakdown = None
            elif code == "MAN":
                madn = self.parser.elements[2]
                '''
                pc_code = madn[3]
                mtc_code = madn[4]
                llfc_code = madn[5]
                '''

                mpan_cores.append(''.join((madn[0], madn[1], madn[2])))
            elif code == "VAT":
                uvla = self.parser.elements[5]
                net += to_decimal(uvla) / Decimal('100')
                uvtt = self.parser.elements[6]
                vat += to_decimal(uvtt) / Decimal('100')
                ucsi = self.parser.elements[7]
                gross += to_decimal(ucsi) / Decimal('100')

            if breakdown is not None:
                breakdown['raw-lines'].append(self.parser.line)

        return raw_bills
Ejemplo n.º 7
0
    def make_raw_bills(self):
        raw_bills = []
        breakdown = None

        for self.line_number, code in enumerate(self.parser):
            if code == "BCD":
                ivdt = self.parser.elements[0]
                issue_date = to_utc(to_ct_date(ivdt[0]))

                invn = self.parser.elements[2]
                reference = invn[0]
                account = "SA" + reference[:9]

                btcd = self.parser.elements[5]
                bill_type_code = btcd[0]

                sumo = self.parser.elements[7]
                start_date = to_start_date(sumo[0])
                if to_ct_date(sumo[1]) in (
                        ct_datetime(2020, 4, 1),
                        ct_datetime(2020, 3, 16),
                ):
                    finish_date = to_start_date(sumo[1]) - HH
                else:
                    finish_date = to_finish_date(sumo[1])

            elif code == "MHD":
                type = self.parser.elements[1]
                message_type = type[0]
                if message_type == "UTLBIL":
                    issue_date = None
                    start_date = None
                    finish_date = None
                    account = None
                    reference = None
                    net = Decimal("0.00")
                    vat = Decimal("0.00")
                    gross = Decimal("0.00")
                    kwh = Decimal(0)
                    reads = []
                    bill_type_code = None
                    mpan_core = None
                    breakdown = defaultdict(int, {"raw-lines": []})

            elif code == "CCD":
                ccde = self.parser.elements[1]
                consumption_charge_indicator = ccde[0]

                if consumption_charge_indicator == "1":
                    prdt = self.parser.elements[6]
                    pvdt = self.parser.elements[7]

                    pres_read_date = to_finish_date(prdt[0])
                    prev_read_date = to_finish_date(pvdt[0])

                    tmod = self.parser.elements[3]
                    mtnr = self.parser.elements[4]
                    mloc = self.parser.elements[5]

                    mpan = mloc[0]
                    mpan_core = " ".join(
                        [mpan[:2], mpan[2:6], mpan[6:10], mpan[10:13]])
                    mpan = (mpan[13:15] + " " + mpan[15:18] + " " + mpan[18:] +
                            " " + mpan_core)

                    prrd = self.parser.elements[9]
                    pres_read_type = read_type_map[prrd[1]]
                    prev_read_type = read_type_map[prrd[3]]

                    adjf = self.parser.elements[12]
                    cons = self.parser.elements[13]

                    coefficient = Decimal(adjf[1]) / Decimal(100000)
                    pres_reading_value = Decimal(prrd[0])
                    prev_reading_value = Decimal(prrd[2])
                    msn = mtnr[0]
                    tpr_native = tmod[0]
                    if tpr_native not in tmod_map:
                        raise BadRequest(
                            "The TPR code " + tpr_native +
                            " can't be found in the TPR list for mpan " +
                            mpan + ".")
                    tpr_code = tmod_map[tpr_native]
                    if tpr_code == "kW":
                        units = "kW"
                        tpr_code = None
                    elif tpr_code == "kVA":
                        units = "kVA"
                        tpr_code = None
                    else:
                        units = "kWh"
                        kwh += to_decimal(cons) / Decimal("1000")

                    if mpan_core in WRONG_TPRS and pres_read_date == to_utc(
                            ct_datetime(2020, 4, 1, 23, 30)):
                        pres_read_date = to_utc(ct_datetime(
                            2020, 4, 1, 22, 30))
                        reads.append({
                            "msn":
                            "Separator Read",
                            "mpan":
                            mpan,
                            "coefficient":
                            coefficient,
                            "units":
                            units,
                            "tpr_code":
                            tpr_code,
                            "prev_date":
                            to_utc(ct_datetime(2020, 4, 1, 23)),
                            "prev_value":
                            0,
                            "prev_type_code":
                            "N",
                            "pres_date":
                            to_utc(ct_datetime(2020, 4, 1, 23)),
                            "pres_value":
                            0,
                            "pres_type_code":
                            "N",
                        })
                    reads.append({
                        "msn": msn,
                        "mpan": mpan,
                        "coefficient": coefficient,
                        "units": units,
                        "tpr_code": tpr_code,
                        "prev_date": prev_read_date,
                        "prev_value": prev_reading_value,
                        "prev_type_code": prev_read_type,
                        "pres_date": pres_read_date,
                        "pres_value": pres_reading_value,
                        "pres_type_code": pres_read_type,
                    })

                elif consumption_charge_indicator == "2":
                    # tcod = self.parser.elements[2]
                    tmod = self.parser.elements[3]
                    mtnr = self.parser.elements[4]
                    mloc = self.parser.elements[5]

                    mpan = mloc[0]
                    mpan_core = " ".join(
                        [mpan[:2], mpan[2:6], mpan[6:10], mpan[10:13]])
                    mpan = (mpan[13:15] + " " + mpan[15:18] + " " + mpan[18:] +
                            " " + mpan_core)

                    prdt = self.parser.elements[6]
                    pvdt = self.parser.elements[7]

                    pres_read_date = to_finish_date(prdt[0])
                    prev_read_date = to_finish_date(pvdt[0])

                    ndrp = self.parser.elements[8]
                    prrd = self.parser.elements[9]
                    pres_read_type = read_type_map[prrd[1]]
                    prev_read_type = read_type_map[prrd[3]]

                    adjf = self.parser.elements[12]
                    cona = self.parser.elements[13]

                    coefficient = Decimal(adjf[1]) / Decimal(100000)
                    pres_reading_value = Decimal(prrd[0])
                    prev_reading_value = Decimal(prrd[2])
                    msn = mtnr[0]
                    tpr_code = tmod[0]
                    if tpr_code not in tmod_map:
                        raise BadRequest(
                            "The TPR code " + tpr_code +
                            " can't be found in the TPR list for mpan " +
                            mpan + ".")
                    tpr = tmod_map[tpr_code]
                    if tpr == "kW":
                        units = "kW"
                        tpr = None
                        prefix = "md-"
                    elif tpr == "kVA":
                        units = "kVA"
                        tpr = None
                        prefix = "md-"
                    else:
                        units = "kWh"
                        kwh += to_decimal(cona) / Decimal("1000")
                        prefix = tpr + "-"

                    nuct = self.parser.elements[15]
                    breakdown[prefix +
                              "kwh"] += to_decimal(nuct) / Decimal("1000")
                    cppu = self.parser.elements[18]
                    rate_key = prefix + "rate"
                    if rate_key not in breakdown:
                        breakdown[rate_key] = set()
                    breakdown[rate_key].add(
                        to_decimal(cppu) / Decimal("100000"))
                    ctot = self.parser.elements[19]
                    breakdown[prefix +
                              "gbp"] += to_decimal(ctot) / Decimal("100")

                    if mpan_core in WRONG_TPRS and pres_read_date == to_utc(
                            ct_datetime(2020, 4, 1, 23, 30)):
                        pres_read_date = to_utc(ct_datetime(
                            2020, 4, 1, 22, 30))
                        reads.append({
                            "msn":
                            "Separator Read",
                            "mpan":
                            mpan,
                            "coefficient":
                            coefficient,
                            "units":
                            units,
                            "tpr_code":
                            tpr,
                            "prev_date":
                            to_utc(ct_datetime(2020, 4, 1, 23)),
                            "prev_value":
                            0,
                            "prev_type_code":
                            "N",
                            "pres_date":
                            to_utc(ct_datetime(2020, 4, 1, 23)),
                            "pres_value":
                            0,
                            "pres_type_code":
                            "N",
                        })

                    reads.append({
                        "msn": msn,
                        "mpan": mpan,
                        "coefficient": coefficient,
                        "units": units,
                        "tpr_code": tpr,
                        "prev_date": prev_read_date,
                        "prev_value": prev_reading_value,
                        "prev_type_code": prev_read_type,
                        "pres_date": pres_read_date,
                        "pres_value": pres_reading_value,
                        "pres_type_code": pres_read_type,
                    })

                elif consumption_charge_indicator == "3":
                    # tcod = self.parser.elements[2]
                    tmod = self.parser.elements[3]
                    tmod0 = tmod[0]
                    if tmod0 == "CCL":
                        prefix = kwh_prefix = "ccl-"
                    elif tmod0 in ["CQFITC", "CMFITC"]:
                        prefix = "fit-"
                        kwh_prefix = "fit-msp-"
                    elif tmod0 == "FITARR":
                        prefix = kwh_prefix = "fit-reconciliation-"
                    else:
                        tpr_code = tmod0
                        if tpr_code not in tmod_map:
                            raise BadRequest(
                                "The TPR code " + tpr_code +
                                " can't be found in the TPR list for mpan " +
                                mpan + ".")
                        prefix = kwh_prefix = tmod_map[tpr_code] + "-"

                    mtnr = self.parser.elements[4]
                    ndrp = self.parser.elements[8]
                    cona = self.parser.elements[13]
                    nuct = self.parser.elements[15]
                    breakdown[kwh_prefix +
                              "kwh"] += to_decimal(nuct) / Decimal("1000")
                    cppu = self.parser.elements[18]

                    rate_key = prefix + "rate"
                    if rate_key not in breakdown:
                        breakdown[rate_key] = set()
                    breakdown[rate_key].add(
                        to_decimal(cppu) / Decimal("100000"))

                    ctot = self.parser.elements[19]
                    breakdown[prefix +
                              "gbp"] += to_decimal(ctot) / Decimal("100")
                elif consumption_charge_indicator == "4":
                    # tcod = self.parser.elements[2]
                    tmod = self.parser.elements[3]
                    tmod0 = tmod[0]

                    mtnr = self.parser.elements[4]
                    ndrp = self.parser.elements[8]
                    if len(ndrp[0]) > 0:
                        breakdown["standing-days"] += to_decimal(ndrp)
                    cona = self.parser.elements[13]
                    nuct = self.parser.elements[15]
                    cppu = self.parser.elements[18]
                    ctot = self.parser.elements[19]
                    if len(ctot[0]) > 0:
                        breakdown["standing-gbp"] += to_decimal(
                            ctot) / Decimal("100")
            elif code == "MTR":
                if message_type == "UTLBIL":

                    if mpan_core is None:
                        sess = Session()
                        era = (sess.query(Era).filter(
                            Era.imp_supplier_account == account).first())
                        if era is not None:
                            mpan_core = era.imp_mpan_core
                        sess.close()

                    raw_bill = {
                        "bill_type_code": bill_type_code,
                        "account": account,
                        "mpan_core": mpan_core,
                        "reference": reference,
                        "issue_date": issue_date,
                        "start_date": start_date,
                        "finish_date": finish_date,
                        "kwh": kwh,
                        "net": net,
                        "vat": vat,
                        "gross": gross,
                        "breakdown": breakdown,
                        "reads": reads,
                    }
                    raw_bills.append(raw_bill)
                    breakdown = None

            elif code == "MAN":
                madn = self.parser.elements[2]
                """
                pc_code = madn[3]
                mtc_code = madn[4]
                llfc_code = madn[5]
                """

                mpan_core = parse_mpan_core("".join(
                    (madn[0], madn[1], madn[2])))

            elif code == "VAT":
                uvla = self.parser.elements[5]
                net += to_decimal(uvla) / Decimal("100")
                uvtt = self.parser.elements[6]
                vat += to_decimal(uvtt) / Decimal("100")
                ucsi = self.parser.elements[7]
                gross += to_decimal(ucsi) / Decimal("100")

            if breakdown is not None:
                breakdown["raw-lines"].append(self.parser.line)

        return raw_bills
Ejemplo n.º 8
0
    def make_raw_bills(self):
        raw_bills = []
        for self.line_number, code in enumerate(self.parser):
            if code == "CLO":
                cloc = self.parser.elements[0]
                account = cloc[1]
            elif code == "BCD":
                ivdt = self.parser.elements[0]
                invn = self.parser.elements[2]
                btcd = self.parser.elements[5]

                reference = invn[0]
                bill_type_code = btcd[0]
                issue_date = to_date(ivdt[0])
            elif code == "MHD":
                typ = self.parser.elements[1]
                message_type = typ[0]
                if message_type == "UTLBIL":
                    issue_date = None
                    start_date = None
                    finish_date = None
                    account = None
                    reference = None
                    net = Decimal(0.00)
                    vat = Decimal(0.00)
                    reads = []
                    mpan_strings = []
            elif code == "CCD":
                ccde = self.parser.elements[1]
                consumption_charge_indicator = ccde[0]
                charge_type = ccde[2]
                if consumption_charge_indicator != "5" and \
                        charge_type in ["7", "8", "9"]:
                    prev_read_date = to_date(self.parser.elements[7][0])
                if hh_after(start_date, prev_read_date):
                    start_date = prev_read_date
                register_finish_date = to_date(self.parser.elements[6][0])
                if finish_date is None or finish_date < register_finish_date:
                    finish_date = register_finish_date
                if charge_type == "7":
                    tmod = self.parser.elements[3]
                    mtnr = self.parser.elements[4]
                    mloc = self.parser.elements[5]
                    prrd = self.parser.elements[9]
                    adjf = self.parser.elements[12]
                    pres_read_type = read_type_map[prrd[1]]
                    prev_read_type = read_type_map[prrd[3]]
                    coefficient = Decimal(adjf[1]) / Decimal(100000)
                    pres_read_value = Decimal(prrd[0]) / Decimal(1000)
                    prev_read_value = Decimal(prrd[2]) / Decimal(1000)
                    msn = mtnr[0]
                    tpr_code = tmod[0].zfill(5)
                    reads.append({
                        'msn': msn,
                        'mpan': mloc[0],
                        'coefficient': coefficient,
                        'units': 'kWh',
                        'tpr_code': tpr_code,
                        'prev_date': prev_read_date,
                        'prev_value': prev_read_value,
                        'prev_type_code': prev_read_type,
                        'pres_date': register_finish_date,
                        'pres_value': pres_read_value,
                        'pres_type_code': pres_read_type
                    })
            elif code == "MTR":
                if message_type == "UTLBIL":
                    raw_bills.append({
                        'bill_type_code': bill_type_code,
                        'account': account,
                        'mpans': mpan_strings,
                        'reference': reference,
                        'issue_date': issue_date,
                        'start_date': start_date,
                        'finish_date': finish_date,
                        'kwh': Decimal(0),
                        'net': net,
                        'vat': vat,
                        'gross': Decimal('0.00'),
                        'breakdown': {},
                        'reads': reads
                    })
            elif code == "MAN":
                madn = self.parser.elements[2]
                pc_code = "0" + madn[3]
                mtc_code = madn[4]
                llfc_code = madn[5]

                mpan_strings.append(pc_code + " " + mtc_code + " " +
                                    llfc_code + " " + madn[0] + " " + madn[1] +
                                    madn[2])
            elif code == "VAT":
                uvla = self.parser.elements[5]
                net = Decimal('0.00') + to_decimal(uvla)
                uvtt = self.parser.elements[6]
                vat = Decimal('0.00') + to_decimal(uvtt)
        return raw_bills
Ejemplo n.º 9
0
    def make_raw_bills(self):
        raw_bills = []
        for self.line_number, code in enumerate(self.parser):
            if code == "CLO":
                cloc = self.parser.elements[0]
                account = cloc[1]

            elif code == "BCD":
                ivdt = self.parser.elements[0]
                invn = self.parser.elements[2]
                btcd = self.parser.elements[5]

                reference = invn[0]
                bill_type_code = btcd[0]
                issue_date = to_date(ivdt[0])

            elif code == "MHD":
                typ = self.parser.elements[1]
                message_type = typ[0]
                if message_type == "UTLBIL":
                    issue_date = None
                    start_date = None
                    finish_date = None
                    account = None
                    reference = None
                    net = Decimal(0.00)
                    vat = Decimal(0.00)
                    reads = []
                    mpan_core = None

            elif code == "CCD":
                ccde = self.parser.elements[1]
                consumption_charge_indicator = ccde[0]
                charge_type = ccde[2]
                if consumption_charge_indicator != "5" and charge_type in [
                        "7",
                        "8",
                        "9",
                ]:
                    prev_read_date = to_date(self.parser.elements[7][0])
                if hh_after(start_date, prev_read_date):
                    start_date = prev_read_date
                register_finish_date = to_date(self.parser.elements[6][0])
                if finish_date is None or finish_date < register_finish_date:
                    finish_date = register_finish_date
                if charge_type == "7":
                    tmod = self.parser.elements[3]
                    mtnr = self.parser.elements[4]
                    mloc = self.parser.elements[5]
                    prrd = self.parser.elements[9]
                    adjf = self.parser.elements[12]
                    pres_read_type = read_type_map[prrd[1]]
                    prev_read_type = read_type_map[prrd[3]]
                    coefficient = Decimal(adjf[1]) / Decimal(100000)
                    pres_read_value = Decimal(prrd[0]) / Decimal(1000)
                    prev_read_value = Decimal(prrd[2]) / Decimal(1000)
                    msn = mtnr[0]
                    tpr_code = tmod[0].zfill(5)
                    read = {
                        "msn": msn,
                        "mpan": mloc[0],
                        "coefficient": coefficient,
                        "units": "kWh",
                        "tpr_code": tpr_code,
                        "prev_date": prev_read_date,
                        "prev_value": prev_read_value,
                        "prev_type_code": prev_read_type,
                        "pres_date": register_finish_date,
                        "pres_value": pres_read_value,
                        "pres_type_code": pres_read_type,
                    }
                    reads.append(read)

            elif code == "MTR":
                if message_type == "UTLBIL":
                    raw_bill = {
                        "bill_type_code": bill_type_code,
                        "account": account,
                        "mpan_core": mpan_core,
                        "reference": reference,
                        "issue_date": issue_date,
                        "start_date": start_date,
                        "finish_date": finish_date,
                        "kwh": Decimal(0),
                        "net": net,
                        "vat": vat,
                        "gross": Decimal("0.00"),
                        "breakdown": {},
                        "reads": reads,
                    }
                    raw_bills.append(raw_bill)

            elif code == "MAN":
                madn = self.parser.elements[2]
                # pc_code = "0" + madn[3]
                # mtc_code = madn[4]
                # llfc_code = madn[5]

                mpan_core = parse_mpan_core(madn[0] + " " + madn[1] + madn[2])

            elif code == "VAT":
                uvla = self.parser.elements[5]
                net = Decimal("0.00") + to_decimal(uvla)
                uvtt = self.parser.elements[6]
                vat = Decimal("0.00") + to_decimal(uvtt)

        return raw_bills