You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
410 lines
20 KiB
410 lines
20 KiB
from ILE_MainWindow import Ui_MainWindow
|
|
from defLocs_Window2 import Ui_defaultLocationDiag
|
|
import sys
|
|
import os
|
|
import pandas as pd
|
|
import json
|
|
from PyQt5 import QtWidgets
|
|
from PyQt5.QtWidgets import QApplication, QDialog, QMainWindow, QPushButton
|
|
from datetime import datetime as dt
|
|
import ILExtract as ilx
|
|
|
|
print("Starting GUI... will anything else print?")
|
|
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|
def __init__(self, *args, obj=None, **kwargs):
|
|
super(MainWindow, self).__init__(*args, **kwargs)
|
|
self.setupUi(self)
|
|
self.setAcceptDrops(True)
|
|
|
|
self.inputFile = ""
|
|
self.outputFile = ""
|
|
self.inputCustomized = False
|
|
with open("settings.json") as s:
|
|
self.settings = json.loads(s.read())
|
|
self.curReportType = "ach"
|
|
self.extract_function = ilx.ach
|
|
|
|
cbs = self.copyButton.objectName()
|
|
self.report_type_change()
|
|
# Actions
|
|
self.inputFileButton.clicked.connect(self.getfile)
|
|
self.outputFileButton.clicked.connect(self.setOutput)
|
|
self.processReportButton.clicked.connect(self.process_selection)
|
|
self.copyButton.clicked.connect(self.to_clipboard)
|
|
self.reportTypeCB.currentTextChanged.connect(self.report_type_change)
|
|
self.openFolderButton.clicked.connect(lambda: self.openWithDefaultApp(self.outputFile.removesuffix(self.outputFile.split('/')[-1])))
|
|
self.openExcelButton.clicked.connect(lambda: self.openWithDefaultApp(self.outputFile))
|
|
self.action_Default_Locations.triggered.connect(self.df)
|
|
self.inputFilePreview.setText("Drag & Drop Input file here!")
|
|
|
|
def set_input(self, ifile):
|
|
with open(ifile, errors="replace") as inF:
|
|
txt = inF.read()
|
|
self.inputFilePreview.setText(txt)
|
|
self.inputFileLE.setText(ifile)
|
|
self.inputFile = ifile
|
|
# This gets the actual file name
|
|
inFileEnd = ifile.split('/')[-1]
|
|
# Takes just the root of the input file
|
|
outputRoot = self.inputFile.removesuffix(inFileEnd)
|
|
# Automatically sets output to be in the same file as input, with a naming scheme
|
|
# The report type selected in the combo box will dictate the naming
|
|
if self.reportTypeCB.currentText() == "Minv_C":
|
|
self.outputFile = f"{outputRoot}{self.reportTypeCB.currentText()}_{dt.now().strftime('%Y%m%d_%H%M')}.txt"
|
|
else:
|
|
self.outputFile = f"{outputRoot}{self.reportTypeCB.currentText().replace('/','')}_{dt.now().strftime('%Y%m%d_%H%M')}.xlsx"
|
|
self.outputFileLE.setText(self.outputFile)
|
|
self.inputCustomized = True
|
|
self.openExcelButton.setEnabled(False)
|
|
self.copyButton.setEnabled(False)
|
|
self.openFolderButton.setEnabled(True)
|
|
# Enables the process button
|
|
self.check_ready_to_process()
|
|
|
|
def getfile(self):
|
|
inFile = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file')
|
|
if inFile[0] == '':
|
|
return 1
|
|
else:
|
|
self.set_input(inFile[0])
|
|
|
|
def df(self):
|
|
dlg = defLocWindow(self)
|
|
dlg.exec()
|
|
with open("settings.json") as s:
|
|
self.settings = json.loads(s.read())
|
|
|
|
def dragEnterEvent(self, event):
|
|
if event.mimeData().hasUrls():
|
|
event.accept()
|
|
else:
|
|
event.ignore()
|
|
|
|
def dropEvent(self, event):
|
|
file = [u.toLocalFile() for u in event.mimeData().urls()][0]
|
|
print(file)
|
|
self.set_input(file)
|
|
|
|
def setOutput(self):
|
|
# This allows the user to change the automatic naming and location
|
|
outFile = QtWidgets.QFileDialog.getSaveFileName(self, "Output file name")
|
|
if outFile[0] == '': return ''
|
|
if self.reportTypeCB.currentText() == "Minv_C":
|
|
self.outputFileLE.setText(f"{outFile[0]}__{dt.now().strftime('%Y%m%d_%H_%M')}.txt")
|
|
else:
|
|
self.outputFileLE.setText(f"{outFile[0]}__{dt.now().strftime('%Y%m%d_%H_%M')}.xlsx")
|
|
print(f"Output: {outFile}")
|
|
self.outputFile = f"{outFile[0]}__{dt.now().strftime('%Y%m%d_%H_%M')}.xlsx"
|
|
self.check_ready_to_process()
|
|
|
|
def check_ready_to_process(self):
|
|
# Makes sure there is an input and output selected before allowing processing
|
|
rtp = True if ((self.inputFile != "") & (self.outputFile != "")) else False
|
|
if rtp :
|
|
self.processReportButton.setEnabled(True)
|
|
if self.outputFile == "":
|
|
self.openFolderButton.setEnabled(False)
|
|
|
|
def process_selection(self):
|
|
print("Processing selection...")
|
|
self.inputFilePreview.setText("Processing file...")
|
|
# If only this was python 3.10 and we could use switch statments
|
|
# but this should get the job done
|
|
#try:
|
|
# This is where the actual processing happens
|
|
# We create an ILReport object and pass in the nessecary information
|
|
print(self.inputFile)
|
|
print(self.outputFile)
|
|
dataframe = ilx.ILReport(
|
|
location= self.inputFile,
|
|
extraction_function=self.extract_function,
|
|
output_location=self.outputFile,
|
|
).process()
|
|
# The text preview box can have trouble loading the larger dataframes so
|
|
# they are trimmed to 500 so that the users can see if anything got messed up
|
|
smallDF = dataframe.iloc[0:500,:]
|
|
self.inputFilePreview.setText(smallDF.to_html(index=False))
|
|
#except:
|
|
# error = QtWidgets.QMessageBox()
|
|
# error.setWindowTitle('Error Processing File!')
|
|
# error.setText(f"Unable to process {self.inputFile}!\nPlease check input file!")
|
|
self.openExcelButton.setEnabled(True)
|
|
self.copyButton.setEnabled(True)
|
|
self.checked_for_saved()
|
|
self.openFolderButton.setEnabled(True)
|
|
self.inputCustomized = False
|
|
|
|
def preview_report(self):
|
|
df = pd.read_excel(self.outputFile)
|
|
self.inputFilePreview.setText(df.to_html())
|
|
|
|
def to_clipboard(self):
|
|
df = pd.read_excel(self.outputFile)
|
|
df.to_clipboard(excel=True)
|
|
|
|
def openFolder(self):
|
|
outputRoot = self.outputFile.removesuffix(self.outputFile.split('/')[-1])
|
|
os.startfile(outputRoot)
|
|
|
|
def openWithDefaultApp(self, item):
|
|
print(item)
|
|
outputRoot = self.outputFile.removesuffix(self.outputFile.split('/')[-1])
|
|
os.startfile(item)
|
|
|
|
def checked_for_saved(self):
|
|
if self.settings["defaultLocations"][self.curReportType]["dir"] == '':
|
|
self.settings["defaultLocations"][self.curReportType]["dir"] = ('/').join(self.inputFile.split('/')[:-1])
|
|
with open('settings.json', 'w') as s:
|
|
json.dump(self.settings, s)
|
|
|
|
def report_type_change(self):
|
|
# Adjust the report type according to the combo box
|
|
# This will be used in settings the the extract function and determining file locations
|
|
self.processReportButton.setEnabled(False)
|
|
if self.reportTypeCB.currentText() == "ACH":
|
|
self.curReportType = "ach"
|
|
self.extract_function = ilx.ach
|
|
elif self.reportTypeCB.currentText() == "Disposition":
|
|
self.curReportType = "disp"
|
|
self.extract_function = ilx.disposition
|
|
elif self.reportTypeCB.currentText() == "Gain Loss":
|
|
self.curReportType = "gl"
|
|
self.extract_function = ilx.gainloss
|
|
elif self.reportTypeCB.currentText() == "Lock Box":
|
|
self.curReportType = "lb"
|
|
self.extract_function = ilx.lockbox
|
|
elif self.reportTypeCB.currentText() == "Minv_C":
|
|
self.curReportType = "minv"
|
|
self.extract_function = ilx.minv
|
|
elif self.reportTypeCB.currentText() == "Net Inv. Loans":
|
|
self.curReportType = "niv"
|
|
self.extract_function = ilx.net_invest_trial_balance
|
|
elif self.reportTypeCB.currentText() == "NI Renewal":
|
|
self.curReportType = "ren"
|
|
self.extract_function = ilx.renewal_net_invest_trial_balance
|
|
elif self.reportTypeCB.currentText() == "NIV After":
|
|
self.curReportType = "niv"
|
|
self.extract_function = ilx.net_invest_trial_balance
|
|
elif self.reportTypeCB.currentText() == "PBP / Epay":
|
|
self.curReportType = "pymt"
|
|
self.extract_function = ilx.payment_transactions
|
|
elif self.reportTypeCB.currentText() == "Unapplied":
|
|
self.curReportType = "uap"
|
|
self.extract_function = ilx.unapplied
|
|
elif self.reportTypeCB.currentText() == "Past Due":
|
|
self.curReportType = "pastdue"
|
|
self.extract_function = ilx.pastdue
|
|
elif self.reportTypeCB.currentText() == "VMCC":
|
|
self.curReportType = "pymt"
|
|
self.extract_function = ilx.payment_transactions
|
|
elif self.reportTypeCB.currentText() == "Wires":
|
|
self.curReportType = "pymt"
|
|
self.extract_function = ilx.payment_transactions
|
|
elif self.reportTypeCB.currentText() == "Returned Check":
|
|
self.curReportType = "pymt"
|
|
self.extract_function = ilx.payment_transactions
|
|
inputRoot = self.settings["defaultLocations"][self.curReportType]["dir"]\
|
|
.replace("{dd}",dt.now().strftime('%d'))\
|
|
.replace("{mm}",dt.now().strftime('%m'))\
|
|
.replace("{yyyy}",dt.now().strftime('%Y')).replace("{yy}",dt.now().strftime('%y'))
|
|
inputFile = self.settings["defaultLocations"][self.curReportType]["fn"]\
|
|
.replace("{dd}",dt.now().strftime('%d'))\
|
|
.replace("{mm}",dt.now().strftime('%m'))\
|
|
.replace("{yyyy}",dt.now().strftime('%Y')).replace("{yy}",dt.now().strftime('%y'))
|
|
self.inputFile = f"{inputRoot}/{inputFile}" if (inputFile != '') else inputRoot
|
|
self.inputFileLE.setText(self.inputFile)
|
|
# Automatically sets output to be in the same file as input, with a naming scheme
|
|
# The report type selected in the combo box will dictate the naming
|
|
if self.inputFile == "":
|
|
outputroot = ('/').join(self.inputFileLE.text().split('/')[:-1])
|
|
else:
|
|
outputroot = inputRoot + '/'
|
|
if self.curReportType == "minv":
|
|
self.outputFile = f"{outputroot}{self.reportTypeCB.currentText()}_{dt.now().strftime('%Y%m%d_%H%M')}.txt"
|
|
else:
|
|
self.outputFile = f"{outputroot}{self.reportTypeCB.currentText().replace('/','')}_{dt.now().strftime('%Y%m%d_%H%M')}.xlsx"
|
|
self.outputFileLE.setText(self.outputFile)
|
|
self.openExcelButton.setEnabled(False)
|
|
self.copyButton.setEnabled(False)
|
|
self.openFolderButton.setEnabled(True)
|
|
print(self.inputFile)
|
|
print(self.outputFile)
|
|
self.check_ready_to_process()
|
|
|
|
class defLocWindow(QtWidgets.QDialog):
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
# Create an instance of the GUI
|
|
self.ui = Ui_defaultLocationDiag()
|
|
# Run the .setupUi() method to show the GUI
|
|
self.ui.setupUi(self)
|
|
with open("settings.json") as s:
|
|
self.settings = json.loads(s.read())
|
|
|
|
self.load_user_settings()
|
|
|
|
# Add dest folder buttons
|
|
# Lambdas are used to create anon functions to that they don't execute at init
|
|
self.ui.ach_B.clicked.connect(lambda : self.add_defloc(self.ui.ach_B.objectName(), True))
|
|
self.ui.disp_B.clicked.connect(lambda : self.add_defloc(self.ui.disp_B.objectName(), True))
|
|
self.ui.gl_B.clicked.connect(lambda : self.add_defloc(self.ui.gl_B.objectName(), True))
|
|
self.ui.lb_B.clicked.connect(lambda : self.add_defloc(self.ui.lb_B.objectName(), True))
|
|
self.ui.minv_B.clicked.connect(lambda : self.add_defloc(self.ui.minv_B.objectName(), True))
|
|
self.ui.niv_B.clicked.connect(lambda : self.add_defloc(self.ui.niv_B.objectName(), True))
|
|
self.ui.ren_B.clicked.connect(lambda : self.add_defloc(self.ui.ren_B.objectName(), True))
|
|
self.ui.pymt_B.clicked.connect(lambda : self.add_defloc(self.ui.pymt_B.objectName(), True))
|
|
self.ui.uap_B.clicked.connect(lambda : self.add_defloc(self.ui.uap_B.objectName(), True))
|
|
# Text Changes
|
|
self.ui.ach_LE.textChanged.connect(lambda : self.add_defloc(self.ui.ach_B.objectName(), False))
|
|
self.ui.disp_LE.textChanged.connect(lambda : self.add_defloc(self.ui.disp_B.objectName(), False))
|
|
self.ui.gl_LE.textChanged.connect(lambda : self.add_defloc(self.ui.gl_B.objectName(), False))
|
|
self.ui.lb_LE.textChanged.connect(lambda : self.add_defloc(self.ui.lb_B.objectName(), False))
|
|
self.ui.minv_LE.textChanged.connect(lambda : self.add_defloc(self.ui.minv_B.objectName(), False))
|
|
self.ui.niv_LE.textChanged.connect(lambda : self.add_defloc(self.ui.niv_B.objectName(), False))
|
|
self.ui.ren_LE.textChanged.connect(lambda : self.add_defloc(self.ui.ren_B.objectName(), False))
|
|
self.ui.pymt_LE.textChanged.connect(lambda : self.add_defloc(self.ui.pymt_B.objectName(), False))
|
|
self.ui.uap_LE.textChanged.connect(lambda : self.add_defloc(self.ui.uap_B.objectName(), False))
|
|
|
|
self.ui.ach_FN.textChanged.connect(lambda : self.add_fn(self.ui.ach_FN.objectName()))
|
|
self.ui.disp_FN.textChanged.connect(lambda : self.add_fn(self.ui.disp_FN.objectName()))
|
|
self.ui.gl_FN.textChanged.connect(lambda : self.add_fn(self.ui.gl_FN.objectName()))
|
|
self.ui.lb_FN.textChanged.connect(lambda : self.add_fn(self.ui.lb_FN.objectName()))
|
|
self.ui.minv_FN.textChanged.connect(lambda : self.add_fn(self.ui.minv_FN.objectName()))
|
|
self.ui.niv_FN.textChanged.connect(lambda : self.add_fn(self.ui.niv_FN.objectName()))
|
|
self.ui.ren_FN.textChanged.connect(lambda : self.add_fn(self.ui.ren_FN.objectName()))
|
|
self.ui.pymt_FN.textChanged.connect(lambda : self.add_fn(self.ui.pymt_FN.objectName()))
|
|
self.ui.uap_FN.textChanged.connect(lambda : self.add_fn(self.ui.uap_FN.objectName()))
|
|
|
|
self.ui.optionBBox.accepted.connect(self.save_changes)
|
|
|
|
def add_defloc(self, button_name, use_filebrowser: bool):
|
|
folder = QtWidgets.QFileDialog.getExistingDirectory() if use_filebrowser else None
|
|
if folder == '':
|
|
use_filebrowser = False
|
|
report_type = button_name.split('_')[0]
|
|
if report_type == "ach":
|
|
if use_filebrowser:
|
|
self.ui.ach_LE.setText(folder)
|
|
else:
|
|
folder = self.ui.ach_LE.text()
|
|
elif report_type == "disp":
|
|
if use_filebrowser:
|
|
self.ui.disp_LE.setText(folder)
|
|
else:
|
|
folder = self.ui.disp_LE.text()
|
|
elif report_type == "gl":
|
|
if use_filebrowser:
|
|
self.ui.gl_LE.setText(folder)
|
|
else:
|
|
folder = self.ui.gl_LE.text()
|
|
elif report_type == "lb":
|
|
if use_filebrowser:
|
|
self.ui.lb_LE.setText(folder)
|
|
else:
|
|
folder = self.ui.lb_LE.text()
|
|
elif report_type == "minv":
|
|
if use_filebrowser:
|
|
self.ui.minv_LE.setText(folder)
|
|
else:
|
|
folder = self.ui.minv_LE.text()
|
|
elif report_type == "niv":
|
|
if use_filebrowser:
|
|
self.ui.niv_LE.setText(folder)
|
|
else:
|
|
folder = self.ui.niv_LE.text()
|
|
elif report_type == "ren":
|
|
if use_filebrowser:
|
|
self.ui.ren_LE.setText(folder)
|
|
else:
|
|
folder = self.ui.ren_LE.text()
|
|
elif report_type == "pymt":
|
|
if use_filebrowser:
|
|
self.ui.pymt_LE.setText(folder)
|
|
else:
|
|
folder = self.ui.pymt_LE.text()
|
|
elif report_type == "uap":
|
|
if use_filebrowser:
|
|
self.ui.uap_LE.setText(folder)
|
|
else:
|
|
folder = self.ui.uap_LE.text()
|
|
if folder != "":
|
|
self.settings["defaultLocations"][report_type]["dir"] = folder
|
|
def chg_folder(self, button_name):
|
|
report_type = button_name.split('_')[0]
|
|
if report_type == "ach":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.ach_FN.text()
|
|
elif report_type == "disp":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.disp_FN.text()
|
|
elif report_type == "gl":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.gl_FN.text()
|
|
elif report_type == "lb":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.lb_FN.text()
|
|
elif report_type == "minv":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.minv_FN.text()
|
|
elif report_type == "niv":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.niv_FN.text()
|
|
elif report_type == "ren":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.ren_FN.text()
|
|
elif report_type == "pymt":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.pymt_FN.text()
|
|
elif report_type == "uap":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.uap_FN.text()
|
|
def add_fn(self, button_name):
|
|
report_type = button_name.split('_')[0]
|
|
if report_type == "ach":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.ach_FN.text()
|
|
elif report_type == "disp":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.disp_FN.text()
|
|
elif report_type == "gl":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.gl_FN.text()
|
|
elif report_type == "lb":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.lb_FN.text()
|
|
elif report_type == "minv":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.minv_FN.text()
|
|
elif report_type == "niv":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.niv_FN.text()
|
|
elif report_type == "ren":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.ren_FN.text()
|
|
elif report_type == "pymt":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.pymt_FN.text()
|
|
elif report_type == "uap":
|
|
self.settings["defaultLocations"][report_type]["fn"] = self.ui.uap_FN.text()
|
|
|
|
|
|
def load_user_settings(self):
|
|
self.ui.ach_LE.setText(self.settings["defaultLocations"]["ach"]["dir"])
|
|
self.ui.ach_FN.setText(self.settings["defaultLocations"]["ach"]["fn"])
|
|
self.ui.disp_LE.setText(self.settings["defaultLocations"]["disp"]["dir"])
|
|
self.ui.disp_FN.setText(self.settings["defaultLocations"]["disp"]["fn"])
|
|
self.ui.gl_LE.setText(self.settings["defaultLocations"]["gl"]["dir"])
|
|
self.ui.gl_FN.setText(self.settings["defaultLocations"]["gl"]["fn"])
|
|
self.ui.lb_LE.setText(self.settings["defaultLocations"]["lb"]["dir"])
|
|
self.ui.lb_FN.setText(self.settings["defaultLocations"]["lb"]["fn"])
|
|
self.ui.minv_LE.setText(self.settings["defaultLocations"]["minv"]["dir"])
|
|
self.ui.minv_FN.setText(self.settings["defaultLocations"]["minv"]["fn"])
|
|
self.ui.niv_LE.setText(self.settings["defaultLocations"]["niv"]["dir"])
|
|
self.ui.niv_FN.setText(self.settings["defaultLocations"]["niv"]["fn"])
|
|
self.ui.ren_LE.setText(self.settings["defaultLocations"]["ren"]["dir"])
|
|
self.ui.ren_FN.setText(self.settings["defaultLocations"]["ren"]["fn"])
|
|
self.ui.pymt_LE.setText(self.settings["defaultLocations"]["pymt"]["dir"])
|
|
self.ui.pymt_FN.setText(self.settings["defaultLocations"]["pymt"]["fn"])
|
|
self.ui.uap_LE.setText(self.settings["defaultLocations"]["uap"]["dir"])
|
|
self.ui.uap_FN.setText(self.settings["defaultLocations"]["uap"]["fn"])
|
|
|
|
def save_changes(self):
|
|
print(self.settings)
|
|
with open('settings.json', 'w') as s:
|
|
json.dump(self.settings, s)
|
|
print(self.settings)
|
|
|
|
|
|
|
|
|
|
|
|
app = QtWidgets.QApplication(sys.argv)
|
|
app.setStyle("Fusion")
|
|
|
|
window = MainWindow()
|
|
window.setWindowTitle("IL Extract")
|
|
window.show()
|
|
app.exec()
|
|
|