示例#1
0
    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)
示例#3
0
    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)
示例#4
0
    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)
示例#6
0
    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"])
示例#7
0
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()
示例#8
0
    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"])
示例#9
0
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()
示例#10
0
    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"]
示例#11
0
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)
示例#12
0
    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"])
示例#13
0
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()