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.
293 lines
14 KiB
293 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')
|
|
|