diff --git a/Housing Outcomes.py b/Housing Outcomes.py index 51414f6..9ba69e2 100644 --- a/Housing Outcomes.py +++ b/Housing Outcomes.py @@ -1,75 +1,96 @@ __author__ = "David Marienburg" -__version__ = "1.11" +__version__ = "1.12" """ This script is for processing the Housing Services - Housing Outcomes v2.0 report that is used by -the follow-ups specialistself. +the follow-ups specialist. This script should identify when it is being run and adjust its date parameters to reflect being run on the first of the month or after it. This well prevent future staff members from needing to fiddle with the code every time they run the report. """ +# import required libraries import pandas as pd -from datetime import date from datetime import datetime -from calendar import monthrange -from dateutil.relativedelta import relativedelta from tkinter.filedialog import askopenfilename from tkinter.filedialog import asksaveasfilename -class RunDate: - """ - This class is not currently used by the CreateRequiredFollowUps class but I would like to - eventually make it so that the sheetnames output by that class are modified by the relation to - the current month. - """ - def __init__(self): - self.today = datetime.now().date() - self.check_date() - - def check_date(self): - if self.today.day <= 5: - last_month = self.today + relativedelta(months=-1) - end_of_month = date( - year=last_month.year, - month=last_month.month, - day=monthrange(last_month.year, last_month.month)[1] - ) - return end_of_month - else: - end_of_month = date( - year=self.today.year, - month=self.today.month, - day=monthrange(self.today.year, self.today.month)[1] - ) - return end_of_month - - class CreateRequiredFollowUps: def __init__(self, file_path): - self.raw_data = pd.read_excel(file_path) - self.run_date = RunDate() + # read the excel report into a pandas data frames + self.raw_fu_data = pd.read_excel(file_path, sheet_name="FollowUps") + self.raw_placement_data = pd.read_excel(file_path, sheet_name="Placements") + self.raw_address_data = pd.read_excel(file_path, sheet_name="Addresses") + # create a immutable list of unique months during which follow-ups are + # due self.month_range = set( - [value.strftime("%B") for value in self.raw_data["Follow Up Due Date(2512)"]] + [value.strftime("%B") for value in self.raw_fu_data["Follow Up Due Date(2512)"]] ) + # create month and year name variables for the name of the processed + # report self.current_month = datetime.now().month + self.current_year = datetime.now().year def process(self): - data = self.raw_data + # create a local copy of the self.raw_data data frame then merge that + # copy with the address and placement data frames to ensure that all + # followups are related to a TPI placement and that the Addresses + # provided are the newest addresses. + data = self.raw_fu_data.merge( + self.raw_address_data.sort_values( + by=["Client Unique Id", "Date Added (61-date_added)"], + ascending=False + ).drop_duplicates(subset="Client Unique Id"), + how="left", + on="Client Unique Id" + ).merge( + self.raw_placement_data, + how="inner", + left_on=["Client Unique Id", "Initial Placement/Eviction Prevention Date(2515)"], + right_on=["Client Unique Id", "Placement Date(3072)"] + ) + # initiate the ExcelWriter object variable writer = pd.ExcelWriter( - asksaveasfilename(title="Save the Required Follow-ups Report"), + asksaveasfilename( + title="Save the Required Follow-ups Report", + defaultextension=".xlsx", + initialfile="Required Follow-ups for {} {}".format( + self.current_month, + self.current_year + ) + ), engine="xlsxwriter" ) + # loop through the values of the self.month_range set creating dataframes + # where the value of Follow Up Due Date(2512) column is equal to the set + # item's value creating excel sheets for each of these data drames for month in self.month_range: month_data = data[ (data["Follow Up Due Date(2512)"].dt.strftime("%B") == month) & data["Actual Follow Up Date(2518)"].isna() - ].drop_duplicates(subset="Client Uid") - month_data.to_excel(writer, sheet_name="{} Follow-Ups".format(month), index=False) + ].drop_duplicates( + subset="Client Unique Id" + ).drop( + ["Client Unique Id", "Client Uid_y", "Placement Date(3072)"], + axis=1 + ) + month_data.to_excel( + writer, + sheet_name="{} Follow-Ups".format(month), + index=False + ) + # create an excel sheet containing the raw data + data[ + (data["Follow-Up Status(2729)"] == "Attempted, Unable to contact client") | + (data["Is Client Still in Housing?(2519)"] == "Is Client Still in Housing?(2519)") + ].to_excel(writer, sheet_name="Contact Attempted", index=False) data.to_excel(writer, sheet_name="Raw Data", index=False) + # save the spreadsheet writer.save() if __name__ == "__main__": - run = CreateRequiredFollowUps(askopenfilename(title="Open the Housing Outcomes v2.0 Report")) + run = CreateRequiredFollowUps( + askopenfilename(title="Open the Housing Outcomes v2.3 Report") + ) run.process() diff --git a/mid_month_addresses.py b/mid_month_addresses.py index 5709dcb..81dd1f5 100644 --- a/mid_month_addresses.py +++ b/mid_month_addresses.py @@ -14,12 +14,13 @@ class CreateAddressList: def __init__(self, file_path): - self.raw_data = pd.read_excel(file_path) + self.raw_data = pd.read_excel(file_path, sheet_name="FollowUps") + self.raw_addresses = pd.read_excel(file_path, sheet_name="Addresses") self.current_month = dt.now().month self.current_year = dt.now().year def process(self): - data = self.raw_data[ + fu_data = self.raw_data[ ~(self.raw_data["Follow-Up Status(2729)"] == "Client contacted") & ~(self.raw_data["Follow-Up Status(2729)"] == "Other verifiable source contacted") & (self.raw_data["Follow Up Due Date(2512)"].dt.month == self.current_month) & @@ -30,7 +31,36 @@ def process(self): ).drop_duplicates( subset="Client Uid", keep="first" - ) + )[[ + "Client Uid", + "Client First Name", + "Client Last Name", + "Initial Placement/Eviction Prevention Date(2515)", + "Follow Up Due Date(2512)", + "Actual Follow Up Date(2518)", + "Follow-Up Status(2729)", + "Is Client Still in Housing?(2519)" + ]] + + address_data = self.raw_addresses[ + self.raw_addresses["Client Uid"].isin(fu_data["Client Uid"]) + ].sort_values( + by=["Client Uid", "Date Added (61-date_added)"], + ascending=False + ).drop_duplicates( + subset="Client Uid", + keep="first" + )[[ + "Client Uid", + "Client's Street Address(62)", + "Client's Apartment Number(71)", + "Client's City(509)", + "Client's State(510)", + "Client's ZIP(496)", + "Home Phone Number(511)" + ]] + + writer = pd.ExcelWriter( asafn( title="Save the Non-Contacted Follow-Ups Report", @@ -39,7 +69,11 @@ def process(self): ), engine="xlsxwriter" ) - data.to_excel(writer, sheet_name="Data", index=False) + fu_data.merge( + address_data, + on="Client Uid", + how="left" + ).to_excel(writer, sheet_name="Data", index=False) writer.save() if __name__ == "__main__":