CS4820-Winter2020 student project to create a COUNTER SUSHI R5 harvester and related functionality app for Windows and Mac
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.

294 lines
14 KiB

import json
from PyQt5.QtWidgets import QDialog
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QFont
import ManageDB
import ManageVendors
from Settings import SettingsModel
from ui import CostsTab, ReportTypeDialog
from Constants import *
from GeneralUtils import *
class CostsController:
"""Controls the Costs tab
:param costs_ui: the UI for the costs_widget
:param settings: the user's settings"""
def __init__(self, costs_ui: CostsTab.Ui_costs_tab, settings: SettingsModel):
self.costs_ui = costs_ui
self.settings = settings
# set parameters
self.report_parameter_combobox = costs_ui.costs_report_parameter_combobox
self.report_parameter_combobox.addItems(REPORT_TYPE_SWITCHER.keys())
self.report_parameter = None
self.vendor_parameter_combobox = costs_ui.costs_vendor_parameter_combobox
self.vendor_parameter = None
self.year_parameter_dateedit = costs_ui.costs_year_parameter_dateedit
self.year_parameter_dateedit.setDate(QDate.currentDate())
self.year_parameter = None
self.name_label = costs_ui.costs_name_parameter_label
self.name_parameter_combobox = costs_ui.costs_name_parameter_combobox
self.name_parameter = None
# set up values
self.cost_in_original_currency_doublespinbox = costs_ui.costs_cost_in_original_currency_doublespinbox
self.cost_in_original_currency = 0.0
self.original_currency_combobox = costs_ui.costs_original_currency_value_combobox
self.load_currency_list()
self.original_currency = ''
self.cost_in_local_currency_doublespinbox = costs_ui.costs_cost_in_local_currency_doublespinbox
self.cost_in_local_currency = 0.0
self.cost_in_local_currency_with_tax_doublespinbox = \
costs_ui.costs_cost_in_local_currency_with_tax_doublespinbox
self.cost_in_local_currency_with_tax = 0.0
# set up buttons
self.save_costs_button = costs_ui.costs_save_button
self.save_costs_button.clicked.connect(self.save_costs)
self.load_button = costs_ui.costs_load_button
self.load_button.clicked.connect(self.load_costs)
self.clear_button = costs_ui.costs_clear_button
self.clear_button.clicked.connect(self.clear_costs)
vendors_json_string = read_json_file(ManageVendors.VENDORS_FILE_PATH)
vendor_dicts = json.loads(vendors_json_string)
self.vendor_parameter_combobox.clear()
self.vendor_parameter_combobox.addItems([vendor_dict[NAME_KEY] for vendor_dict in vendor_dicts])
self.report_parameter_combobox.currentTextChanged.connect(self.on_report_parameter_changed)
self.vendor_parameter_combobox.currentTextChanged.connect(self.on_vendor_parameter_changed)
self.year_parameter_dateedit.dateChanged.connect(self.on_year_parameter_changed)
self.name_parameter_combobox.currentTextChanged.connect(self.on_name_parameter_changed)
self.names = []
self.costs_names = []
self.on_report_parameter_changed()
self.year_parameter = int(self.year_parameter_dateedit.text())
self.vendor_parameter = self.vendor_parameter_combobox.currentText()
self.fill_names()
self.cost_in_original_currency_doublespinbox.valueChanged.connect(self.on_cost_in_original_currency_changed)
self.original_currency_combobox.currentTextChanged.connect(self.on_original_currency_changed)
self.cost_in_local_currency_doublespinbox.valueChanged.connect(self.on_cost_in_local_currency_changed)
self.cost_in_local_currency_with_tax_doublespinbox.valueChanged.connect(
self.on_cost_in_local_currency_with_tax_changed)
self.import_costs_button = costs_ui.costs_import_costs_button
self.import_costs_button.clicked.connect(self.import_costs)
def update_settings(self, settings: SettingsModel):
"""Invoked when the settings are saved
:param settings: the new settings"""
self.settings = settings
self.load_currency_list()
def database_updated(self, code: int):
"""Invoked when the database is updated
:param code: the exit code of the update"""
self.fill_names()
def load_vendor_list(self, vendors: Sequence[ManageVendors.Vendor]):
"""Updates the vendor list combobox
:param vendors: the new list of vendors"""
self.vendor_parameter_combobox.clear()
self.vendor_parameter_combobox.addItems([vendor.name for vendor in vendors])
def load_currency_list(self):
"""Updates the original currency combobox"""
self.original_currency_combobox.clear()
self.original_currency_combobox.addItem(self.settings.default_currency)
self.original_currency_combobox.addItems([currency for currency in CURRENCY_LIST if currency !=
self.settings.default_currency])
self.original_currency_combobox.setCurrentText('')
def on_report_parameter_changed(self):
"""Invoked when the report parameter changes"""
self.report_parameter = self.report_parameter_combobox.currentText()
self.name_label.setText(NAME_FIELD_SWITCHER[self.report_parameter].capitalize())
if self.vendor_parameter:
self.fill_names()
def on_vendor_parameter_changed(self):
"""Invoked when the vendor parameter changes"""
self.vendor_parameter = self.vendor_parameter_combobox.currentText()
if self.report_parameter:
self.fill_names()
def on_year_parameter_changed(self):
"""Invoked when the year parameter changes"""
self.year_parameter = int(self.year_parameter_dateedit.text())
self.load_costs()
self.fill_names(True)
def fill_names(self, only_get_costs_names: bool = False):
"""Fills the name field combobox"""
self.name_parameter_combobox.clear()
connection = ManageDB.create_connection(DATABASE_LOCATION)
if connection is not None:
if not only_get_costs_names:
names_sql_text, names_data = ManageDB.get_names_sql_text(self.report_parameter, self.vendor_parameter)
names_results = ManageDB.run_select_sql(connection, names_sql_text, names_data)
if names_results:
self.names = [result[0] for result in names_results]
else:
self.names = []
if self.settings.show_debug_messages: print(names_results)
costs_sql_text, costs_data = ManageDB.get_names_with_costs_sql_text(self.report_parameter,
self.vendor_parameter,
self.year_parameter,
self.year_parameter)
costs_results = ManageDB.run_select_sql(connection, costs_sql_text, costs_data)
connection.close()
if costs_results:
self.costs_names = [result[0] for result in costs_results]
else:
self.costs_names = []
if self.settings.show_debug_messages: print(costs_results)
model = QStandardItemModel()
for name in self.names:
item = QStandardItem(name)
if name in self.costs_names:
font = QFont()
font.setBold(True)
item.setFont(font)
model.appendRow(item)
self.name_parameter_combobox.setModel(model)
else:
print('Error, no connection')
def on_name_parameter_changed(self):
"""Invoked when the name field parameter changes"""
self.name_parameter = self.name_parameter_combobox.currentText()
enable = False
if self.name_parameter:
enable = True
self.load_costs()
self.cost_in_original_currency_doublespinbox.setEnabled(enable)
self.original_currency_combobox.setEnabled(enable)
self.cost_in_local_currency_doublespinbox.setEnabled(enable)
self.cost_in_local_currency_with_tax_doublespinbox.setEnabled(enable)
def on_cost_in_original_currency_changed(self):
"""Invoked when the cost in original currency parameter changes"""
self.cost_in_original_currency = self.cost_in_original_currency_doublespinbox.value()
def on_original_currency_changed(self):
"""Invoked when the original currency parameter changes"""
self.original_currency = self.original_currency_combobox.currentText()
def on_cost_in_local_currency_changed(self):
"""Invoked when the cost in local currency parameter changes"""
self.cost_in_local_currency = self.cost_in_local_currency_doublespinbox.value()
def on_cost_in_local_currency_with_tax_changed(self):
"""Invoked when the cost in local currency with tax parameter changes"""
self.cost_in_local_currency_with_tax = self.cost_in_local_currency_with_tax_doublespinbox.value()
def save_costs(self):
"""Saves the cost data: if it is nonzero, add it to the database; if it is zero, delete it from the database"""
INSERT = 'insert'
DELETE = 'delete'
insert_or_delete = None
sql_text = None
data = None
if self.cost_in_original_currency > 0 and self.original_currency != '' \
and self.cost_in_local_currency > 0 and self.cost_in_local_currency_with_tax > 0:
insert_or_delete = INSERT
elif self.cost_in_original_currency == 0 and self.original_currency == '' \
and self.cost_in_local_currency == 0 and self.cost_in_local_currency_with_tax == 0:
insert_or_delete = DELETE
if insert_or_delete == INSERT:
sql_text, data = ManageDB.replace_costs_sql_text(self.report_parameter,
({NAME_FIELD_SWITCHER[self.report_parameter]:
self.name_parameter,
'vendor': self.vendor_parameter,
'year': self.year_parameter,
'cost_in_original_currency':
self.cost_in_original_currency,
'original_currency': self.original_currency,
'cost_in_local_currency': self.cost_in_local_currency,
'cost_in_local_currency_with_tax':
self.cost_in_local_currency_with_tax},))
elif insert_or_delete == DELETE:
sql_text, data = ManageDB.delete_costs_sql_text(self.report_parameter, self.vendor_parameter,
self.year_parameter, self.name_parameter)
if insert_or_delete in (INSERT, DELETE):
connection = ManageDB.create_connection(DATABASE_LOCATION)
if connection is not None:
ManageDB.run_sql(connection, sql_text, data)
connection.close()
ManageDB.backup_costs_data(self.report_parameter)
if insert_or_delete == INSERT:
show_message('Data inserted/replaced')
elif insert_or_delete == DELETE:
show_message('Data removed')
else:
show_message('Invalid entry')
def load_costs(self):
"""Fills the costs fields with data from the database"""
sql_text, data = ManageDB.get_costs_sql_text(self.report_parameter, self.vendor_parameter, self.year_parameter,
self.name_parameter)
results = []
connection = ManageDB.create_connection(DATABASE_LOCATION)
if connection is not None:
results = ManageDB.run_select_sql(connection, sql_text, data)
if not results:
results.append((0.0, '', 0.0, 0.0))
connection.close()
values = {}
index = 0
for field in COST_FIELDS:
values[field[NAME_KEY]] = results[0][index]
index += 1
self.cost_in_original_currency_doublespinbox.setValue(values['cost_in_original_currency'])
self.original_currency_combobox.setCurrentText(values['original_currency'])
self.cost_in_local_currency_doublespinbox.setValue(values['cost_in_local_currency'])
self.cost_in_local_currency_with_tax_doublespinbox.setValue(values['cost_in_local_currency_with_tax'])
self.cost_in_original_currency_doublespinbox.repaint()
def clear_costs(self):
"""Empties the costs fields"""
self.cost_in_original_currency_doublespinbox.setValue(0.0)
self.original_currency_combobox.setCurrentText('')
self.cost_in_local_currency_doublespinbox.setValue(0.0)
self.cost_in_local_currency_with_tax_doublespinbox.setValue(0.0)
def import_costs(self):
"""Import a file with costs data in it into the database"""
report_type_dialog = QDialog()
report_type_dialog_ui = ReportTypeDialog.Ui_report_type_dialog()
report_type_dialog_ui.setupUi(report_type_dialog)
report_type_dialog_ui.report_type_combobox.addItems(REPORT_TYPE_SWITCHER.keys())
report_type_dialog.show()
if report_type_dialog.exec_():
report_type = report_type_dialog_ui.report_type_combobox.currentText()
if report_type != '':
file_name = choose_file(TSV_FILTER + CSV_FILTER)
if file_name != '':
ManageDB.insert_single_cost_file(report_type, file_name)
ManageDB.backup_costs_data(report_type)
show_message('File ' + file_name + ' imported')
else:
print('Error, no file location selected')
else:
print('Error, no report type selected')