Skip to content

Instantly share code, notes, and snippets.

@wenboown
Last active December 15, 2022 21:02
Show Gist options
  • Select an option

  • Save wenboown/df1f1d707bf11b7ff5b5fb1c87dea93e to your computer and use it in GitHub Desktop.

Select an option

Save wenboown/df1f1d707bf11b7ff5b5fb1c87dea93e to your computer and use it in GitHub Desktop.
A simple script to parse Tmobile's monthly bill and extract billing of individual number line into an xlsx file.
'''
Bo Wen
v1: Dec 25, 2019
v2: Nov 21, 2020
v3: Jun, 2021 - updated for tmobile's new summary pdf layout
v4: Dec 2022 - check phone number exists in the summary before processing to avoid error
require:
Python3
pipenv install pdfplumber
pipenv install xlsxwriter
'''
import xlsxwriter
import pdfplumber
import re
import argparse
# the final xlsx report will follow the number order and list bill from left to right
phone_list=['(123)\xa0456-7890',
'(123)\xa0456-7891',
'(123)\xa0456-7892',
]
# helper functions:
def search_next(lis, word):
return next((i for i,v in enumerate(lis) if v.startswith(word)), None)
def parse_dollar(word):
if word == '-':
return 0
else:
v=word.split('$')[-1]
if ')' in v:
return -float(v.split(')')[0])
else:
return float(v)
# main function:
def Parse_file(filename, phone_list):
alltext=''
parsed_dict={}
ind_dict={}
if '.pdf' in filename:
filename = filename.split('.pdf')[0]
with pdfplumber.open(filename+'.pdf') as pdf:
for p in pdf.pages:
temp = p.extract_text(x_tolerance=3, y_tolerance=3)
if temp is not None:
alltext=alltext+temp
lines=re.split(r'\s{2,}|\n', alltext)
workbook = xlsxwriter.Workbook(filename+'.xlsx')
worksheet = workbook.add_worksheet()
parsed_dict['Bill period']=lines[1].split(' XXXXXXXXX',1)[0] # replace "XXXXXXXXX" with your actual tmobile account number, near top right of the pdf
parsed_dict['Tmobile billed amount']=parse_dollar(lines[search_next(lines, "Here's your bill")-1].split()[0])
parsed_dict['plan charge']=parse_dollar(lines[search_next(lines, "Account")].split("$")[-1])
worksheet.write('A1', 'Bill period = '+parsed_dict['Bill period'])
worksheet.write('B1', parsed_dict['Tmobile billed amount'])
worksheet.write('A2', 'account + tax (sevice for next month)')
worksheet.write('C2', parsed_dict['plan charge'])
row=3
col=0
pos_ = search_next(lines, "THIS BILL SUMMARY")
pos_end = search_next(lines, "DETAILED CHARGES")
for phone in phone_list:
if any(phone in s for s in lines[pos_:pos_end]):
print(f"processing {phone}")
phone_line = lines[pos_ + search_next(lines[pos_: pos_ + 20], phone)]
phone_items = phone_line.split('$', 1)[1].split()
plans_charge = parse_dollar(phone_items[0])
eq_charge = parse_dollar(phone_items[1])
service_charge = parse_dollar(phone_items[2])
one_time_charge = parse_dollar(phone_items[3])
if plans_charge > 10:
plans_charge = plans_charge - 10
worksheet.write(row, col, plans_charge)
worksheet.write(row + 1, col, eq_charge)
worksheet.write(row + 2, col, service_charge)
worksheet.write(row + 3, col, one_time_charge)
col = col + 1
else:
print(f"{phone} doesn't exist, skip")
workbook.close()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='tmobile bill parser')
parser.add_argument('-f', '--file', required=True, help='bill pdf file')
# parser.add_argument('-p', '--phone_list', required=False, help='phone number list json')
args = parser.parse_args()
Parse_file(args.file, phone_list)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment