def __init__(self, click_handler, default_currency: str): self._click_handler = click_handler self._window = tkinter.Toplevel() self._window.wm_geometry(str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) cell_y = 0 self._date = LabeledTextbox( self._window, "Date", datetime.datetime.now().isoformat(), 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._description = LabeledTextbox(self._window, "Description", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._amount = AmountTextbox(self._window, "Amount", 0, default_currency, 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._cleared = LabeledCheckbox(self._window, "Clear", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] save_button = tkinter.Button(self._window, text="OK", command=self._ok_click, font=default_font()) save_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"], y=cell_y)
def __init__(self): self._window = tkinter.Toplevel() self._window.wm_geometry(str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) cell_y = 0 self._company = CompanyCombobox(self._window, "Bank", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._payment_date = LabeledTextbox(self._window, "Payment date", datetime.datetime.now().isoformat(), 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._amount = AmountTextbox( self._window, "Amount", 0, config.CONSTANTS["HOME_CURRENCY"], 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] save_button = tkinter.Button(self._window, text="OK", command=self._ok_click, font=default_font()) save_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"], y=cell_y)
def __init__(self): self._window = tkinter.Toplevel() self._window.wm_geometry( str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) cell_y = 0 self._company = CompanyCombobox(self._window, "Company", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._direction = LabeledCombobox(self._window, "Direction", ["I", "O"], 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._amount = AmountTextbox(self._window, "Amount", 0, config.CONSTANTS["HOME_CURRENCY"], 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._description = LabeledTextbox(self._window, "Description", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] save_button = tkinter.Button(self._window, text="OK", command=self._ok_click, font=default_font()) save_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"], y=cell_y)
def __init__(self): self._debut_activity = None # Initialization tkinter.Toplevel.__init__(self) self.wm_geometry( str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) cell_y = 0 # Project self._projects = Project.get_projects() self._project_combo_val = [] self._build_project_combo_values() self._project_combo = LabeledCombobox(self, "Project", self._project_combo_val, 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Duration self._duration = LabeledTextbox(self, "Duration", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Work self._work = LabeledTextbox(self, "Work", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Button save_button = tkinter.Button(self, text="Save", command=self._save_click, font=default_font()) save_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"], y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"]
def __init__(self, click_handler, label_text: str, text_value: str): self._click_handler = click_handler self._window = tkinter.Toplevel() self._window.wm_geometry( str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) self._labeled_textbox = LabeledTextbox(self._window, label_text, text_value, 0, 0) save_button = tkinter.Button(self._window, text="OK", command=self._ok_click) save_button.place(x=200, y=100)
def __init__(self): # Initialization tkinter.Toplevel.__init__(self) self.wm_geometry(str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) cell_y = 0 # GUID self._guid = LabeledTextbox(self, "GUID", "", 0, cell_y) self._guid.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Serial self._serial = LabeledTextbox(self, "Serial", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Payer self._payer_combo = CompanyCombobox(self, "Payer", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Invoice date self._invoice_date = LabeledTextbox(self, "Invoice date", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Due date self._due_date = LabeledTextbox(self, "Due date", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Amount self._amount = AmountTextbox( self, "Amount", 0, config.CONSTANTS["HOME_CURRENCY"], 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # VAT self._vat = LabeledTextbox(self, "VAT %", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # VAT amount self._vat_amount = LabeledTextbox(self, "VAT amount", "", 0, cell_y) self._vat_amount.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Total amount self._total_amount = LabeledTextbox(self, "Total amount", "", 0, cell_y) self._total_amount.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Income tax rate self._income_tax = LabeledTextbox(self, "Inc.Tax %", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Income tax amount self._income_tax_amount = LabeledTextbox(self, "Inc.Tax amount", "", 0, cell_y) self._income_tax_amount.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # File Path self._file_path = LabeledTextbox(self, "File path", "", 0, cell_y) cell_x = (config.CONSTANTS["GUI_CELL_WIDTH"] * 2) + InvoiceWindow._SPACE file_path_button = tkinter.Button(self, text="...", command=self._file_path_click) file_path_button.place(x=cell_x, y=cell_y) cell_x += InvoiceWindow._SMALL_SPACE file_open_button = tkinter.Button(self, text="!", command=self._file_open_click) file_open_button.place(x=cell_x, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Button save_button = tkinter.Button(self, text="Save", command=self._save_click, font=default_font()) save_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"], y=cell_y) save2_button = tkinter.Button(self, text="Save with payments", command=self._save_pay_click, font=default_font()) save2_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"] + InvoiceWindow._SPACE, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Status self._status_label = tkinter.Label(master=self, text="", font=default_font()) self._status_label.place( x=0, y=cell_y, width=self._WINDOW_WIDTH, height=config.CONSTANTS["GUI_CELL_HEIGHT"])
class InvoiceWindow(tkinter.Toplevel): """ Invoice window """ _SMALL_SPACE = 50 _SPACE = 100 _WINDOW_WIDTH = 525 _WINDOW_HEIGHT = 475 def __init__(self): # Initialization tkinter.Toplevel.__init__(self) self.wm_geometry(str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) cell_y = 0 # GUID self._guid = LabeledTextbox(self, "GUID", "", 0, cell_y) self._guid.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Serial self._serial = LabeledTextbox(self, "Serial", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Payer self._payer_combo = CompanyCombobox(self, "Payer", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Invoice date self._invoice_date = LabeledTextbox(self, "Invoice date", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Due date self._due_date = LabeledTextbox(self, "Due date", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Amount self._amount = AmountTextbox( self, "Amount", 0, config.CONSTANTS["HOME_CURRENCY"], 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # VAT self._vat = LabeledTextbox(self, "VAT %", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # VAT amount self._vat_amount = LabeledTextbox(self, "VAT amount", "", 0, cell_y) self._vat_amount.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Total amount self._total_amount = LabeledTextbox(self, "Total amount", "", 0, cell_y) self._total_amount.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Income tax rate self._income_tax = LabeledTextbox(self, "Inc.Tax %", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Income tax amount self._income_tax_amount = LabeledTextbox(self, "Inc.Tax amount", "", 0, cell_y) self._income_tax_amount.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # File Path self._file_path = LabeledTextbox(self, "File path", "", 0, cell_y) cell_x = (config.CONSTANTS["GUI_CELL_WIDTH"] * 2) + InvoiceWindow._SPACE file_path_button = tkinter.Button(self, text="...", command=self._file_path_click) file_path_button.place(x=cell_x, y=cell_y) cell_x += InvoiceWindow._SMALL_SPACE file_open_button = tkinter.Button(self, text="!", command=self._file_open_click) file_open_button.place(x=cell_x, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Button save_button = tkinter.Button(self, text="Save", command=self._save_click, font=default_font()) save_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"], y=cell_y) save2_button = tkinter.Button(self, text="Save with payments", command=self._save_pay_click, font=default_font()) save2_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"] + InvoiceWindow._SPACE, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Status self._status_label = tkinter.Label(master=self, text="", font=default_font()) self._status_label.place( x=0, y=cell_y, width=self._WINDOW_WIDTH, height=config.CONSTANTS["GUI_CELL_HEIGHT"]) def fill_with_invoice(self, invoice: model.timesheet.invoice.Invoice, browser: bool = False, invoice_dir: bool = False): """ Fills the window with the given invoice If browser == True, also opens a new browser window & address book. This functionality is typically used when creating a new invoice. """ self._guid.value = invoice.guid self._serial.value = invoice.serial self._invoice_date.value = str(invoice.invoice_date) self._due_date.value = str(invoice.due_date) self._amount.set_value(invoice.amount, invoice.currency) self._payer_combo.company_name = invoice.payer.name self._vat.value = str(invoice.vat_rate) self._vat_amount.value = str(invoice.vat_amount) self._total_amount.value = str(invoice.amount_plus_vat) self._income_tax.value = str(invoice.income_tax_rate) self._income_tax_amount.value = str(invoice.income_tax_amount) self._file_path.value = invoice.file_path if browser: startup_url("address_book", query_string=f"name={invoice.payer.name}") webbrowser.open(config.CONSTANTS["E_ARCHIVE_URL"]) if invoice_dir and "INVOICE_FILE_PATH" in config.CONSTANTS: subprocess.call(["open", "-R", config.CONSTANTS["INVOICE_FILE_PATH"]]) def _file_open_click(self): open_file(self._file_path.value) def _file_path_click(self): path = popup_open_file() if path is None or path == "": return self._file_path.value = path def _get_invoice_dict_from_gui(self) -> dict: return { "guid": self._guid.value, "serial": self._serial.value, "payer": self._payer_combo.company_name, "invoice_date": self._invoice_date.value, "due_date": self._due_date.value, "amount": self._amount.amount, "currency": self._amount.currency, "vat_rate": float(self._vat.value), "income_tax_rate": float(self._income_tax.value), "file_path": self._file_path.value } def _save_click(self): invoice_dict = self._get_invoice_dict_from_gui() model.timesheet.invoice.Invoice(invoice_dict).save() self._saved() def _save_pay_click(self): invoice_dict = self._get_invoice_dict_from_gui() invoice_obj = model.timesheet.invoice.Invoice(invoice_dict) invoice_obj.save() new_payments = payment.get_payment_objects_from_invoice(invoice_obj) for new_payment in new_payments: new_payment.save() self._saved() def _saved(self): self._set_status("Saved!") PrimeSingleton.get().refresh() self.after(1, self.destroy()) def _set_status(self, status: str): self._status_label["text"] = status self.update()
def __init__(self): # Initialization tkinter.Toplevel.__init__(self) self.wm_geometry( str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) cell_y = 0 # GUID self._guid = LabeledTextbox(self, "GUID", "", 0, cell_y) self._guid.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Name self._name = LabeledTextbox(self, "Name", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Type self._asset_types = asset_model.get_asset_types() self._asset_type_combo_val = [] self._build_asset_type_combo_values() self._asset_type_combo = LabeledCombobox(self, "Type", self._asset_type_combo_val, 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Purcase date self._purchase_date = LabeledTextbox( self, "Pur. Date", datetime.datetime.now().isoformat(), 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Purchase value self._purchase_value = LabeledTextbox(self, "Pur. value", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Sales value self._sales_value = LabeledTextbox(self, "Sales value", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Currency self._currency = LabeledTextbox(self, "Currency", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Quantity self._quantity = LabeledTextbox(self, "Quantity", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Percentage self._percentage = LabeledTextbox(self, "Percentage", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Bank self._bank = LabeledTextbox(self, "Bank", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # URL suffix self._url_suffix = LabeledTextbox(self, "URL suffix", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Income tax self._income_tax = LabeledCheckbox(self, "Income tax", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Button save_button = tkinter.Button(self, text="Save", command=self._save_click, font=default_font()) save_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"], y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Status self._status_label = tkinter.Label(master=self, text="", font=default_font()) self._status_label.place(x=0, y=cell_y, width=self._WINDOW_WIDTH, height=config.CONSTANTS["GUI_CELL_HEIGHT"])
class AssetWindow(tkinter.Toplevel): """ Asset window """ _WINDOW_WIDTH = 450 _WINDOW_HEIGHT = 500 def __init__(self): # Initialization tkinter.Toplevel.__init__(self) self.wm_geometry( str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) cell_y = 0 # GUID self._guid = LabeledTextbox(self, "GUID", "", 0, cell_y) self._guid.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Name self._name = LabeledTextbox(self, "Name", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Type self._asset_types = asset_model.get_asset_types() self._asset_type_combo_val = [] self._build_asset_type_combo_values() self._asset_type_combo = LabeledCombobox(self, "Type", self._asset_type_combo_val, 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Purcase date self._purchase_date = LabeledTextbox( self, "Pur. Date", datetime.datetime.now().isoformat(), 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Purchase value self._purchase_value = LabeledTextbox(self, "Pur. value", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Sales value self._sales_value = LabeledTextbox(self, "Sales value", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Currency self._currency = LabeledTextbox(self, "Currency", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Quantity self._quantity = LabeledTextbox(self, "Quantity", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Percentage self._percentage = LabeledTextbox(self, "Percentage", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Bank self._bank = LabeledTextbox(self, "Bank", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # URL suffix self._url_suffix = LabeledTextbox(self, "URL suffix", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Income tax self._income_tax = LabeledCheckbox(self, "Income tax", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Button save_button = tkinter.Button(self, text="Save", command=self._save_click, font=default_font()) save_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"], y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Status self._status_label = tkinter.Label(master=self, text="", font=default_font()) self._status_label.place(x=0, y=cell_y, width=self._WINDOW_WIDTH, height=config.CONSTANTS["GUI_CELL_HEIGHT"]) def fill_with_asset(self, asset: dict): """ Fills window with given activity """ self._guid.value = asset["guid"] self._name.value = asset["name"] self._asset_type_combo.selected_value = asset["type"] self._purchase_date.value = asset["purchase_date"] self._purchase_value.value = asset["purchase_value"] self._sales_value.value = asset["sales_value"] self._currency.value = asset["currency"] self._quantity.value = asset["quantity"] self._percentage.value = asset["own_percentage"] self._url_suffix.value = asset["url_suffix"] self._income_tax.checked = asset["income_tax"] if "bank" in asset: self._bank.value = asset["bank"] else: self._bank.value = "" def _build_asset_type_combo_values(self): for asset_type in self._asset_types: self._asset_type_combo_val.append(asset_type) def _save_click(self): asset = { "guid": self._guid.value, "name": self._name.value, "type": self._asset_type_combo.selected_value, "purchase_date": self._purchase_date.value, "purchase_value": float(self._purchase_value.value), "sales_value": float(self._sales_value.value), "currency": self._currency.value, "quantity": float(self._quantity.value), "own_percentage": float(self._percentage.value), "bank": self._bank.value, "url_suffix": self._url_suffix.value, "income_tax": self._income_tax.checked, "value_history": [] } asset_model.set_asset(asset) self._set_status("Saved!") self.after(1, self.destroy()) def _set_status(self, status: str): self._status_label["text"] = status self.update()
def __init__(self): # Initialization tkinter.Toplevel.__init__(self) self.wm_geometry( str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) cell_x = 0 cell_y = 0 self._payment = None ########## # Payment ########## # GUID self._guid = LabeledTextbox(self, "GUID", "", cell_x, cell_y) self._guid.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Creation date self._creation_date = LabeledTextbox(self, "Creation", "", cell_x, cell_y) self._creation_date.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Company self._company_combo = CompanyCombobox(self, "Company", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Description self._description = LabeledTextbox(self, "Description", "", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Invoice GUID self._invoice_guid = LabeledTextbox(self, "Invoice GUID", "", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Direction self._direction = LabeledCombobox(self, "Direction", payment_model.get_direction_values(), cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Amount self._amount = AmountTextbox(self, "Amount", 0, config.CONSTANTS["HOME_CURRENCY"], cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Open amount self._open_amount = AmountTextbox(self, "Open Amount", 0, config.CONSTANTS["HOME_CURRENCY"], cell_x, cell_y) self._open_amount.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Cleared self._cleared = LabeledCheckbox(self, "Cleared", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Tax self._is_vat = LabeledCheckbox(self, "Is VAT", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._is_income_tax = LabeledCheckbox(self, "Is Income Tax", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] cell_y_bookmark = cell_y ########## # Scheme ########## cell_x = (config.CONSTANTS["GUI_CELL_WIDTH"] * 2) + self._SPACING cell_y = 0 # Frequency self._frequency = LabeledTextbox(self, "Frequency", "", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Period self._period = LabeledCombobox(self, "Period", payment_model.get_period_values(), cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Start self._start = LabeledTextbox(self, "Start", "", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Repeat self._repeat = LabeledTextbox(self, "Repeat", "", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Notes self._notes = LabeledTextarea(self, "Notes", "", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] ########## # Recurrence ########## cell_x = 0 cell_y = cell_y_bookmark + config.CONSTANTS["GUI_CELL_HEIGHT"] # Visual tkinter.Label(self, text="Recurrence:").place(x=cell_x, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._recurrence_tree = tkinter.ttk.Treeview(self) tree_height = config.CONSTANTS["GUI_CELL_HEIGHT"] * 5 self._recurrence_tree.place(x=cell_x, y=cell_y, width=self._WINDOW_WIDTH, height=tree_height) cell_y += tree_height self._recurrence_tree["columns"] = ("Exp.Date", "Amount", "Open Amount", "Cleared") self._recurrence_tree.heading("Exp.Date", text="Exp.Date") self._recurrence_tree.heading("Amount", text="Amount") self._recurrence_tree.heading("Open Amount", text="Open Amount") self._recurrence_tree.heading("Cleared", text="Cleared") self._recurrence_tree.bind("<<TreeviewSelect>>", self._recurrence_select) self._recurrence_tree.bind("<Double-1>", self._recurrence_double_click) recurrence_clear_button = tkinter.Button( self, text="Clear", command=self._clear_recurrence, font=default_font()) recurrence_clear_button.place(x=0, y=cell_y) recurrence_postpone_button = tkinter.Button( self, text="Postpone", command=self._rec_postpone_popup, font=default_font()) recurrence_postpone_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"], y=cell_y) recurrence_add_button = tkinter.Button(self, text="Add", command=self._recurrence_popup, font=default_font()) recurrence_add_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"] * 2, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Data self._recurrence_tree_content = {} ########## # Collections ########## cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] tkinter.Label(self, text="Collections:").place(x=cell_x, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._collection_tree = tkinter.ttk.Treeview(self) self._collection_tree.place(x=cell_x, y=cell_y, width=self._WINDOW_WIDTH, height=tree_height) cell_y += tree_height self._collection_tree["columns"] = ("Description", "Amount") self._collection_tree.heading("Description", text="Description") self._collection_tree.heading("Amount", text="Amount") add_collection_button = tkinter.Button(self, text="Add", command=self._collection_popup, font=default_font()) add_collection_button.place(x=0, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Data self._collection_tree_content = {} ########## # Final ########## cell_x = 0 status_button = tkinter.Button(self, text="Status", command=self._status, font=default_font()) status_button.place(x=cell_x, y=cell_y) cell_x += PaymentWindow._SPACING recon_button = tkinter.Button(self, text="Reconc.", command=self._reconciliation, font=default_font()) recon_button.place(x=cell_x, y=cell_y) cell_x += PaymentWindow._SPACING save_button = tkinter.Button(self, text="Save", command=self._save, font=default_font()) save_button.place(x=cell_x, y=cell_y) cell_x += PaymentWindow._SPACING del_button = tkinter.Button(self, text="Delete", command=self._delete, font=default_font()) del_button.place(x=cell_x, y=cell_y) cell_x += 100 self._delete_warning_label = tkinter.Label(self, text="!") self._delete_warning_label.place(x=cell_x, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"]
class PaymentWindow(tkinter.Toplevel): """ Payment window """ _SPACING = 150 _WINDOW_WIDTH = 1200 _WINDOW_HEIGHT = 1000 def __init__(self): # Initialization tkinter.Toplevel.__init__(self) self.wm_geometry( str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) cell_x = 0 cell_y = 0 self._payment = None ########## # Payment ########## # GUID self._guid = LabeledTextbox(self, "GUID", "", cell_x, cell_y) self._guid.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Creation date self._creation_date = LabeledTextbox(self, "Creation", "", cell_x, cell_y) self._creation_date.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Company self._company_combo = CompanyCombobox(self, "Company", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Description self._description = LabeledTextbox(self, "Description", "", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Invoice GUID self._invoice_guid = LabeledTextbox(self, "Invoice GUID", "", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Direction self._direction = LabeledCombobox(self, "Direction", payment_model.get_direction_values(), cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Amount self._amount = AmountTextbox(self, "Amount", 0, config.CONSTANTS["HOME_CURRENCY"], cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Open amount self._open_amount = AmountTextbox(self, "Open Amount", 0, config.CONSTANTS["HOME_CURRENCY"], cell_x, cell_y) self._open_amount.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Cleared self._cleared = LabeledCheckbox(self, "Cleared", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Tax self._is_vat = LabeledCheckbox(self, "Is VAT", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._is_income_tax = LabeledCheckbox(self, "Is Income Tax", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] cell_y_bookmark = cell_y ########## # Scheme ########## cell_x = (config.CONSTANTS["GUI_CELL_WIDTH"] * 2) + self._SPACING cell_y = 0 # Frequency self._frequency = LabeledTextbox(self, "Frequency", "", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Period self._period = LabeledCombobox(self, "Period", payment_model.get_period_values(), cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Start self._start = LabeledTextbox(self, "Start", "", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Repeat self._repeat = LabeledTextbox(self, "Repeat", "", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Notes self._notes = LabeledTextarea(self, "Notes", "", cell_x, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] ########## # Recurrence ########## cell_x = 0 cell_y = cell_y_bookmark + config.CONSTANTS["GUI_CELL_HEIGHT"] # Visual tkinter.Label(self, text="Recurrence:").place(x=cell_x, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._recurrence_tree = tkinter.ttk.Treeview(self) tree_height = config.CONSTANTS["GUI_CELL_HEIGHT"] * 5 self._recurrence_tree.place(x=cell_x, y=cell_y, width=self._WINDOW_WIDTH, height=tree_height) cell_y += tree_height self._recurrence_tree["columns"] = ("Exp.Date", "Amount", "Open Amount", "Cleared") self._recurrence_tree.heading("Exp.Date", text="Exp.Date") self._recurrence_tree.heading("Amount", text="Amount") self._recurrence_tree.heading("Open Amount", text="Open Amount") self._recurrence_tree.heading("Cleared", text="Cleared") self._recurrence_tree.bind("<<TreeviewSelect>>", self._recurrence_select) self._recurrence_tree.bind("<Double-1>", self._recurrence_double_click) recurrence_clear_button = tkinter.Button( self, text="Clear", command=self._clear_recurrence, font=default_font()) recurrence_clear_button.place(x=0, y=cell_y) recurrence_postpone_button = tkinter.Button( self, text="Postpone", command=self._rec_postpone_popup, font=default_font()) recurrence_postpone_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"], y=cell_y) recurrence_add_button = tkinter.Button(self, text="Add", command=self._recurrence_popup, font=default_font()) recurrence_add_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"] * 2, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Data self._recurrence_tree_content = {} ########## # Collections ########## cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] tkinter.Label(self, text="Collections:").place(x=cell_x, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] self._collection_tree = tkinter.ttk.Treeview(self) self._collection_tree.place(x=cell_x, y=cell_y, width=self._WINDOW_WIDTH, height=tree_height) cell_y += tree_height self._collection_tree["columns"] = ("Description", "Amount") self._collection_tree.heading("Description", text="Description") self._collection_tree.heading("Amount", text="Amount") add_collection_button = tkinter.Button(self, text="Add", command=self._collection_popup, font=default_font()) add_collection_button.place(x=0, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Data self._collection_tree_content = {} ########## # Final ########## cell_x = 0 status_button = tkinter.Button(self, text="Status", command=self._status, font=default_font()) status_button.place(x=cell_x, y=cell_y) cell_x += PaymentWindow._SPACING recon_button = tkinter.Button(self, text="Reconc.", command=self._reconciliation, font=default_font()) recon_button.place(x=cell_x, y=cell_y) cell_x += PaymentWindow._SPACING save_button = tkinter.Button(self, text="Save", command=self._save, font=default_font()) save_button.place(x=cell_x, y=cell_y) cell_x += PaymentWindow._SPACING del_button = tkinter.Button(self, text="Delete", command=self._delete, font=default_font()) del_button.place(x=cell_x, y=cell_y) cell_x += 100 self._delete_warning_label = tkinter.Label(self, text="!") self._delete_warning_label.place(x=cell_x, y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] def add_collection(self, collection: payment_model.Collection, clear=False): """ Adds a new payment collection """ rec = self._get_selected_recurrence() if rec is None: return rec.add_collection(collection) if clear: rec.cleared = True self._paint_recurrences() self._clear_collection_tree() def add_recurrence(self, date: str): """ Adds a new payment recurrence """ amount, currency = self._payment.amount recurrence_json = { "recurrence_date": date, "expected_payment_date": date, "amount": amount, "currency": currency, "cleared": False, "collections": [] } recurrence_obj = payment_model.Recurrence(recurrence_json) self._payment.scheme.add_recurrence(recurrence_obj) self._paint_recurrences() def fill_with_new_payment(self): """ Fills the form with a new payment """ payment_json = { "creation_date": datetime.datetime.now().isoformat(), "scheme": { "frequency": 1, "period": "D", "repeat": 1, "recurrence": [] } } new_payment = payment_model.Payment(payment_json) self.fill_with_payment(new_payment) def fill_with_payment(self, pay: payment_model.Payment): """ Fills the form with the given payment """ # Preparation self._payment = pay amount, currency = self._payment.amount open_amount, open_currency = self._payment.open_amount # Payment self._guid.value = self._payment.guid self._creation_date.value = self._payment.creation_date.isoformat() self._company_combo.company_name = self._payment.company.name self._description.value = self._payment.description self._notes.value = self._payment.notes self._invoice_guid.value = self._payment.invoice_guid self._direction.selected_value = self._payment.direction self._amount.set_value(amount, currency) self._open_amount.set_value(open_amount, open_currency) self._cleared.checked = self._payment.cleared self._is_vat.checked = self._payment.is_vat self._is_income_tax.checked = self._payment.is_income_tax # Scheme scheme = self._payment.scheme frequency, period = scheme.frequency repeat = scheme.repeat self._frequency.value = frequency self._period.selected_value = period self._start.value = scheme.start_date self._repeat.value = str(repeat) # Recurrences self._paint_recurrences() # warning label del_warning_text = "!" if repeat > 1: del_warning_text = "!RECURRING" self._delete_warning_label["text"] = del_warning_text def postpone_recurrence(self, date_txt: str): """ Click handler for postpone """ rec = self._get_selected_recurrence() rec.expected_payment_date = date_time.parse_json_date(date_txt) self._paint_recurrences() def _clear_collection_tree(self): self._collection_tree_content = {} self._collection_tree.delete(*self._collection_tree.get_children()) self.update() def _clear_recurrence(self): selected_recurrence = self._get_selected_recurrence() if selected_recurrence is not None: selected_recurrence.toggle_cleared() self._paint_recurrences() def _collection_popup(self): Collection(self.add_collection, self._payment.currency) def _get_selected_recurrence(self) -> payment_model.Recurrence: try: item = self._recurrence_tree.selection()[0] except Exception: return None clicked_date_txt = self._recurrence_tree.item(item, "text") clicked_year = int(clicked_date_txt[:4]) clicked_month = int(clicked_date_txt[5:7]) clicked_day = int(clicked_date_txt[8:10]) clicked_recurrence = self._payment.scheme.get_recurrence_on_date( clicked_year, clicked_month, clicked_day) return clicked_recurrence def _delete(self): payment_model.delete_payments([self._payment.guid]) PrimeSingleton.get().refresh() self.destroy() def _paint_recurrences(self): self._recurrence_tree_content = {} self._recurrence_tree.delete(*self._recurrence_tree.get_children()) self.update() recurrences = self._payment.scheme.recurrences for recurrence in recurrences: amount, currency = recurrence.amount open_amount, open_currency = recurrence.open_amount tree_val = (date_time.get_formatted_date( recurrence.expected_payment_date), util_amount.get_formatted_amount(amount) + currency, util_amount.get_formatted_amount(open_amount) + open_currency, str(recurrence.cleared)) id_in_tree = self._recurrence_tree.insert( '', 'end', text=date_time.get_formatted_date(recurrence.recurrence_date), value=tree_val) self._recurrence_tree_content[id_in_tree] = recurrence self.update() def _recurrence_double_click(self, event): pass def _recurrence_popup(self): PopupWithSingleValue(self.add_recurrence, "Date", datetime.datetime.now().isoformat()) def _rec_postpone_popup(self): rec = self._get_selected_recurrence() PopupWithSingleValue(self.postpone_recurrence, "Date", rec.expected_payment_date) def _recurrence_select(self, dummy): # pylint: disable=W0613 # Prepare self._clear_collection_tree() # Get clicked recurrence payments clicked_recurrence = self._get_selected_recurrence() if clicked_recurrence is None: return collections = clicked_recurrence.collections # Paint for collection in collections: amount, currency = collection.amount tree_val = (collection.description, util_amount.get_formatted_amount(amount) + currency) id_in_tree = self._collection_tree.insert( '', 'end', text=date_time.get_formatted_date(collection.date), value=tree_val) self._collection_tree_content[id_in_tree] = collection self.update() def _save(self): self._payment.company = self._company_combo.company_name self._payment.description = self._description.value self._payment.notes = self._notes.value self._payment.invoice_guid = self._invoice_guid.value self._payment.direction = self._direction.selected_value self._payment.set_amount(self._amount.amount, self._amount.currency) self._payment.cleared = self._cleared.checked self._payment.is_vat = self._is_vat.checked self._payment.is_income_tax = self._is_income_tax.checked scheme = self._payment.scheme scheme.set_frequency(int(self._frequency.value), self._period.selected_value) scheme.set_start_date_from_iso(self._start.value) scheme.repeat = int(self._repeat.value) self._payment.save() PrimeSingleton.get().refresh() self.destroy() def _status(self): startup_url("payment_status", query_string=f"guid={self._payment.guid}") def _reconciliation(self): query = "names=" + urllib.parse.quote(self._payment.company.name, safe='') startup_url("reconciliation", query_string=query)
def __init__(self): # Initialization tkinter.Toplevel.__init__(self) self.wm_geometry( str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) cell_y = 0 # GUID self._guid = LabeledTextbox(self, "GUID", "", 0, cell_y) self._guid.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Project self._projects = Project.get_projects() self._project_combo_val = [] self._build_project_combo_values() self._project_combo = LabeledCombobox(self, "Project", self._project_combo_val, 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Location self._locations = model.location.get_locations() self._location_combo_val = [] self._build_location_combo_values() self._location_combo = LabeledCombobox(self, "Location", self._location_combo_val, 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Date self._date = LabeledTextbox(self, "Date", datetime.datetime.now().isoformat(), 0, cell_y) save_button = tkinter.Button(self, text="Ecz", command=self._ecz_click, font=default_font()) save_button.place(x=(config.CONSTANTS["GUI_CELL_WIDTH"] * 2 + 150), y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Duration self._duration = LabeledTextbox(self, "Duration", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Work self._work = LabeledTextbox(self, "Work", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Button save_button = tkinter.Button(self, text="Save", command=self._save_click, font=default_font()) save_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"], y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Status self._status_label = tkinter.Label(master=self, text="", font=default_font()) self._status_label.place(x=0, y=cell_y, width=self._WINDOW_WIDTH, height=config.CONSTANTS["GUI_CELL_HEIGHT"])
class ActivityWindow(tkinter.Toplevel): """ Activity window """ _WINDOW_WIDTH = 550 _WINDOW_HEIGHT = 300 def __init__(self): # Initialization tkinter.Toplevel.__init__(self) self.wm_geometry( str(self._WINDOW_WIDTH) + "x" + str(self._WINDOW_HEIGHT)) cell_y = 0 # GUID self._guid = LabeledTextbox(self, "GUID", "", 0, cell_y) self._guid.disable() cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Project self._projects = Project.get_projects() self._project_combo_val = [] self._build_project_combo_values() self._project_combo = LabeledCombobox(self, "Project", self._project_combo_val, 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Location self._locations = model.location.get_locations() self._location_combo_val = [] self._build_location_combo_values() self._location_combo = LabeledCombobox(self, "Location", self._location_combo_val, 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Date self._date = LabeledTextbox(self, "Date", datetime.datetime.now().isoformat(), 0, cell_y) save_button = tkinter.Button(self, text="Ecz", command=self._ecz_click, font=default_font()) save_button.place(x=(config.CONSTANTS["GUI_CELL_WIDTH"] * 2 + 150), y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Duration self._duration = LabeledTextbox(self, "Duration", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Work self._work = LabeledTextbox(self, "Work", "", 0, cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Button save_button = tkinter.Button(self, text="Save", command=self._save_click, font=default_font()) save_button.place(x=config.CONSTANTS["GUI_CELL_WIDTH"], y=cell_y) cell_y += config.CONSTANTS["GUI_CELL_HEIGHT"] # Status self._status_label = tkinter.Label(master=self, text="", font=default_font()) self._status_label.place(x=0, y=cell_y, width=self._WINDOW_WIDTH, height=config.CONSTANTS["GUI_CELL_HEIGHT"]) def fill_with_activity(self, act: model.timesheet.activity.Activity): """ Fills window with given activity """ proj = act.project clnt = proj.client self._project_combo.selected_value = clnt.name + " - " + proj.name self._location_combo.selected_value = act.location self._date.value = act.date.isoformat() self._duration.value = str(act.hours) self._work.value = act.work self._guid.value = act.guid def fill_with_last_activity(self): """ Fills window with last activity """ last_activity = Activity.get_last_activity() if last_activity == {}: return act_obj = model.timesheet.activity.Activity(last_activity) act_obj.guid = "" act_obj.date = datetime.datetime.today() self.fill_with_activity(act_obj) self._set_status("(filled with last activity)") def _build_project_combo_values(self): for prj in self._projects["projects"]: self._project_combo_val.append(prj["client_name"] + " - " + prj["project_name"]) def _build_location_combo_values(self): for loc in self._locations: self._location_combo_val.append(loc) def _ecz_click(self): sap_date = self._date.value[:12].replace("-", "") daily_activity = ecz_daha.get_daily_activity(sap_date) self._duration.value = daily_activity["hours"] self._work.value = daily_activity["comment"] def _save_click(self): project_full = self._project_combo.selected_value client, project = project_full.split(" - ") location = self._location_combo.selected_value date = self._date.value duration = self._duration.value work = self._work.value guid = self._guid.value act = { "date": date, "client_name": client, "project_name": project, "location": location, "duration": duration, "work": work, "guid": guid } model.timesheet.activity.Activity(act).save() self._set_status("Saved!") PrimeSingleton.get().refresh() self.after(1, self.destroy()) def _set_status(self, status: str): self._status_label["text"] = status self.update()